How to get Simulink HDL Coder RAM with non power of 2 depth.
2 views (last 30 days)
Show older comments
Michael Pratt
on 28 May 2024
Commented: Kiran Kintali
on 29 May 2024
Simulink RAMs ask the user for the address bits instead of the data depth, and then generate HDL using a power-of-2 depth. This may result in extra, unused RAMs to be inferred by a synthesis tool. For example if your RAM could be implemented in 3 chained Block RAMs of depth 2^10 for a total depth of 3*2^10 but due to the Simulink RAM specifying a depth of 2^12 (based on needing 12 address bits) the tool will use 4 Block RAMs instead of the minimum 3.
Is it possible to get Simulink to generate RAM HDL with a specified depth? The output code would look something like below:
module SimpleDualPortRAM_generic
(clk,
wr_din,
wr_addr,
wr_en,
rd_addr,
dout);
parameter integer DataWidth = 9;
parameter integer DataDepth = 12288;
localparam AddrWidth = $clog2(DataDepth);
input clk;
input [DataWidth - 1:0] wr_din; // parameterized width
input [AddrWidth - 1:0] wr_addr; // parameterized width
input wr_en; // ufix1
input [AddrWidth - 1:0] rd_addr; // parameterized width
output [DataWidth - 1:0] dout; // parameterized width
reg [DataWidth - 1:0] ram [DataDepth - 1:0];
reg [DataWidth - 1:0] data_int;
always @(posedge clk)
begin : SimpleDualPortRAM_generic_process
if (wr_en == 1'b1) begin
ram[wr_addr] <= wr_din;
end
data_int <= ram[rd_addr];
end
assign dout = data_int;
endmodule // SimpleDualPortRAM_generic
0 Comments
Accepted Answer
Kiran Kintali
on 29 May 2024
Edited: Kiran Kintali
on 29 May 2024
Does this solve your usecase?
function y = ramBanksScalarInput(u, addr)
% addr --> 12bits
% u --> uint8
persistent ram1 ram2 ram3
if isempty(ram1)
ram1 = hdl.RAM;
ram2 = hdl.RAM;
ram3 = hdl.RAM;
end
% Input 'addr' is 12 bits (use the MSB two bits to figure out which RAM to populate)
% Each RAM instance itself is 2^10 size based on the ramAddr variable size
msb1 = bitget(addr, 12);
msb2 = bitget(addr, 11);
ramAddr = bitsliceget(addr,10,1);
if msb1 == 1 && msb2 == 1
y = ram1(u, ramAddr, true);
elseif msb1 == 1 && msb2 == 0
y = ram2(u, ramAddr, true);
elseif msb1 == 0 && msb2 == 1
y = ram3(u, ramAddr, true);
else
% error.
y = u;
end
4 Comments
More Answers (1)
Kiran Kintali
on 28 May 2024
I wonder if you can use the RAM banks feature in HDL Coder.
If your data signal is a vector, HDL Coder infers an array of parallel RAM banks.
With vector data input, the address and write enable inputs can be both scalars or vectors. When you specify scalar inputs for the write enable and address ports, the system object applies the same operation to each RAM bank. Similarly, When your input data is a bus, the address and write enable inputs must be scalar, and HDL Coder infers an array of parallel RAM banks.
Consider RAM usage that could be matched by modelling a banked RAM with 3 RAM banks and an address size of 10.
Attaching a sample example of banked RAM feature supported by HDL Coder.
See Also
Categories
Find more on Speed Optimization in Help Center and File Exchange
Community Treasure Hunt
Find the treasures in MATLAB Central and discover how the community can help you!
Start Hunting!