Efficient packing of data for BlockRAMs, UltraRAMs

조회 수: 8 (최근 30일)
Charles
Charles 2023년 3월 22일
댓글: Ryan Baird 2023년 3월 29일
Hi,
I have a system where there's four channels of 18-bit data processed simultaneously and written to a RAM as 4096 words x 4 channels of data. HDL Coder seems to want to instantiate four separate RAMs (appears that way in the Verilog), and Vivado shows this too.
I'd like to see the four channels packed into a 72-bit word and written to one location in an UltraRAM. I specified "ultra" for the RAMDirective, and this "works" - the netlist shows four UltraRAMs in use, so at least we've got UltraRAMs.
But how do I get the data packed into a single 72-bit word? Is that something I need to do in the Simulink diagram?
Thanks,
Charles

채택된 답변

Ryan Baird
Ryan Baird 2023년 3월 22일
편집: Ryan Baird 2023년 3월 22일
The RAM block interprets vectors of data to mean you want separate RAM banks. In order to store and retreive the data as a single value, you currently need to combine the data before writing and separate the data after reading outside of the RAM block. The easiest way I'm aware of to do this is with the Bit Concat and Bit Slice blocks. You could use a Bit Concat block before the RAM block to combine the data, and use Bit Slice blocks after the RAM block to separate the read data back into 4 different values.
  댓글 수: 5
Charles
Charles 2023년 3월 23일
A follow-up about constucting a system that can use either fixdt(1, 18, 0) or double in the Bit Concat/Slice operations required to pack four vector elements into a word:
  • It doesn't work with doubles, because it would take a 256-bit word, and Simulink doesn't support more than 128 bits
  • Casting to single didn't work for me either. I tried various combinations of casting, using Stored Integer instead of Real-World Values (I assume that's like C++ reinterpret_cast<>), but couldn't get the system to work right with double. I gave up because I don't need this optimization that badly
  • To be clear, this does work with 18-bit ints, as would be needed for using UltraRAMs, but as I need to be able to run in either configuration for validation/verification, I won't be implementing it.
Thanks,
Charles
Ryan Baird
Ryan Baird 2023년 3월 23일
편집: Ryan Baird 2023년 3월 23일
One possibility is that you could concatenate one type and not the other. That might be easier to do with MATLAB Function blocks, e.g.:
function out = concatIfNotDouble(v)
if(isa(v(1), 'double'))
out = v;
else
% Assumed array of four 18 bit fixpt values
out = bitconcat(v(4), v(3), v(2), v(1));
end
end
function out = splitIfNotDouble(v)
if(isa(v(1), 'double'))
% 4 double values
out = v;
else
% Assumed 72 bit value to be split into four 18 bit values
out = fi(zeros(1,4), 0, 18, 0);
for i = 0:3
start=18*i+1;
out(i+1) = bitsliceget(v,start+17,start);
end
end
end

댓글을 달려면 로그인하십시오.

추가 답변 (2개)

Charles
Charles 2023년 3월 29일
Hello,
I am getting back to this now, as it does seem like we're going to need to be more efficient with memory use. The idea is workable as a concept, but there are some missing details, and I'm spending a lot of time in the Model Explorer messing with the dimensions of the output of the two functions.
Basically, I can only get this to work if I specify the correct dimensions in the Model Explorer for the output of the two Matlab function blocks. I'm attaching two systems demonstrating this. In the InitFcn you can change the data type to the opposite for each and see the issues I run into.
One thing that would be helpful is to know how to create a data type with either a "real-world value" or as "stored integer". I assume stored integer is the equivalent of a c++ reinterpret_cast<>, and I need it here to eliminate the type cast after splitIfNotDouble(). Also, I could not get bitsliceget() to accept variables as arguments.
Charles

Charles
Charles 2023년 3월 29일
Ok, I figured it out. The "size" field for a given variable in Model Explorer accepts a Matlab expression, so I set it to [1 Nsize], where Nsize = 1 for packed mode and 4 for regular vector mode.
It would be great to get the type conversion done inside splitIfNotDouble(). That might also fix a "Wrap on overflow" warning emanating from this type conversion.
Attached is the working sim.
Charles
  댓글 수: 1
Ryan Baird
Ryan Baird 2023년 3월 29일
There's a function "typecast" for converting between integer and floating point types, keeping the same underlying data (similar to a c++ reinterpret_cast), and there's a function "reinterpretcast" for converting between integer and fixedpoint types while keeping the same underlying data:

댓글을 달려면 로그인하십시오.

카테고리

Help CenterFile Exchange에서 HDL Code Generation에 대해 자세히 알아보기

제품


릴리스

R2022b

Community Treasure Hunt

Find the treasures in MATLAB Central and discover how the community can help you!

Start Hunting!

Translated by