MATLAB Answers

0

Best way to do a dynamic bit slice?

Asked by Dara Parsavand on 5 Mar 2017
Latest activity Commented on by Dara Parsavand on 20 Mar 2017
I am still learning my way around HDL coder, but I'm starting to think I can't get optimal results in Verilog from the set of built in components. My current struggle is what I call a dynamic bit slice. In my case I need a single bit out of a ufixN input (I have N = 4, 16, 32, 71 in my current model). So I make a subsystem with N Extract Bits components (Bit Slice would work too, but these are unsigned inputs so Extract Bits works just as well) and an Nx1 switch. For N = 71, this results in a Verilog file that is 819 lines long and thus more annoying when doing a code audit. So I tried a function block:
function dout = fcn(din, sel)
% Take an unsigned integer (din) and output a given bit based on an input select (sel)
dout = bitget(din, sel+1);
That results in a much more compact Verilog file (57 lines), but it brings in lines of code that I don't I want. There are 4 lines starting with reg and there is a + 1 in one line using these reg variables and a -1 in another. Is this unavoidable because bitget uses Matlab indexing (starting with 1) and Verilog/Hardware uses 0? Now I realize synthesis tools may do their own optimization and I may not end up with two adders being consumed on an FPGA or ASIC, but I'd really rather not have it in the Verilog in the first place.
What is the right way to create a dynamic bit slice? I can't write in straight Verilog yet, but I'm guessing what I want is incredibly compact if I were hand coding HDL directly. And in my opinion, if you can't get HDL coder to put out as good a file as someone who is hand coding in a simple example, then that should be a top priority for improvement.
Whatever the right solution, I'd like the option of flattening into the subsystem above (i.e. I'd like just a few lines of Verilog inline with the other processing I'm doing when implementing this operation).
Thanks, Dara

  0 Comments

Sign in to comment.

1 Answer

Answer by Tim McBrayer on 7 Mar 2017
 Accepted Answer

Simulink has limited bit-manipulation capabilities; it's designed to address a higher level of abstraction, for the most part. That said, with the appropriate settings, your MATLAB function generates pretty good Verilog code. While the file is 53 lines long, the functional always block is only 6 lines, including two ends and range checking of the input:
always @(data, bitsel) begin
if (((bitsel + 8'd1) >= 8'd1) && ((bitsel + 8'd1) <= 8'd31)) begin
bit_idx = (bitsel + 8'd1) - 8'd1;
MATLAB_Function_out1 = data[bit_idx];
end
end
The array indexing issue does remain, due to Verilog being 0-based and MATLAB being 1-based, as you mentioned. The calculation of bit_idx will generate no logic in practice. To get this code all I needed to adjust was to deselect the saturation setting on the MATLAB code. To adjust this, open the file in the MATLAB editor and choose "Edit Data" from the Simulink section of the Edit ribbon.
The flattening of MATLAB Function Blocks into their parent subsystems is controlled globally for a design in HDL Coder. Open the Configuration Parameters dialog and choose the HDL Code Generation pane. Navigate to Global Settings > Coding style. In the "RTL customizations" section, select "Inline MATLAB Function block code".

  3 Comments

Tim,
Thanks for the tips on flattening, but it is still disappointing that I can't write a MATLAB function for Simulink that will give inline Verilog that looks like:
assign choose_bit_via_fcn_out1 = lreg_0_out1[bit_sel_counter_out1];
instead of what I get (which does simulate correctly):
assign add_temp = ({1'b0, bit_sel_counter_out1}) + 6'b000001;
assign s = {26'b0, add_temp};
assign sub_temp = s - 32'sd1;
assign bit_idx = sub_temp[7:0];
assign choose_bit_via_fcn_out1 = lreg_0_out1[bit_idx];
It turns out that in this case, I got some advice from a coworker that solved this problem with cleaner Verilog than my 32x1 switch or using a Matlab function. This involved using a bit rotate block and a grab LSB block (because I'm always selecting bits in order). After rotation, I hold the answer in a register and I just rotate the entire ufixN quantity.
Can you share the Simulink model? we may be able to suggest additional readability enhancements. Thanks
Kiran,
Yes, I do have a small test model in this case (I can't share any real models, but I try to reproduce issues in test models when I can and this one was easy). The model uses Simulink 2016b. Any other good references you can suggest besides the standard Mathworks PDF files on HDL coder (which I'm slowly going through) is also appreciated.
Thanks!
Dara

Sign in to comment.