-1

If I have a vector and I want to read a part of it starting somewhere. Can I use the syntax vector[staring_point +: output_length] with starting_point being an integer? Is it synthesizable?

If I write a code like this:

module my_mod(
    input logic din,
    input logic clk,
    input logic[2:0] start_ptr,
    output logic[3:0] dout);

logic[10:0] vector = 0;

always_ff@(posedge clk) vector <= {vector[9:0], din}; --shift register

always_comb dout <= vector[start_ptr +: 4];  

endmodule

The design is just this and the input and output are bounded to GPIOs. I'm expecting a mux for each output bit. Surprisingly Vivado will synthesize 1FF and 1LUTRAM that is an SRL16 so a shift register with integrated mux, but the primitive has only one output and the "dout" signal is driven only with the first bit.

The other 3bits are buffered to 0.

Is the syntax +: correct? Is that consistent or it's a bug of Vivado?

double-beep
  • 5,031
  • 17
  • 33
  • 41
dadduni
  • 3
  • 2
  • it has nothing to do with +:. But when you remove the last assignment, synthesizer most likely figures out that only one bit of 'vector' is needed which drives dout (other bits are just not used anywhere and can be optimized away). So, you are getting a different picture. – Serge Jan 31 '23 at 02:24
  • not sure if it affects the results, but there are at least two issues: 1) initializing of vector to '0' in *logic[10:0] vector = 0;* might not be interpreted correctly. You should provide a proper reset instead. 2) do not use nba in always_comb. And do not use vhdl comments in verilog code. Have you really synthesized your new code? It should be ok. But the results can also depend on the rest of the code that you have not shown. – Serge Jan 31 '23 at 12:52
  • initialization: I kept it out because of simplicity of this example, should be fine also like this but thank you for letting me notice. I added the comment late on the post to make it clear (and I write much more VHDL) so it was automatic for me. I synthesized that and the result was exactly the one posted by @Mikef. The first bit connected to the LUTM and the others connected to a 3buffer tied to 0 or to Z – dadduni Jan 31 '23 at 14:52
  • I looked closer, tried a few things and now believe its a bug. See my revised answer. – Mikef Jan 31 '23 at 17:17

1 Answers1

1

I cleaned code and built in Vivado 2020.2 As pointed out some outputs are inappropriately tied off in synthesis.
Cleaned up code:

module my_mod(
  input  logic din,
  input  logic clk,
  input  logic[2:0] start_ptr,
  output logic[3:0] dout);

logic[10:0] vector;

always_ff@(posedge clk)
  vector <= {vector[9:0], din}; //shift register

always_comb
  dout = vector[start_ptr +: 4];

endmodule    

And the RTL that the code infers:
enter image description here

Vivado is not doing the right thing (its a bug). This is worth reporting to Xilinx. The +: operator is capable of generating a mux/barrel shifter. How: Change the code to infer regs instead of SRL's (added a RTL reset) then it infers the design intent.

module my_mod(
    input logic din,
    input logic clk,
    input logic[2:0] start_ptr,
    input logic rst,
    output logic[3:0] dout);

logic[10:0] vector;

always_ff@(posedge clk)
  if(rst)
    vector <= 0;
  else
    vector <= {vector[9:0], din}; //shift register

always_comb
  dout = vector[start_ptr +: 4];

endmodule

enter image description here

To stay closer to what you posted (no reset) you can use the right shift operator. This also infers the mux as intended. This does not give an initial value of 0, in the reg, so you need to add the reset if you need an initial value.

module my_mod(
  input  logic din,
  input  logic clk,
  input  logic[2:0] start_ptr,
  output logic[3:0] dout);

logic[10:0] vector;

always_ff@(posedge clk)
  vector <= {vector[9:0], din}; //shift register

always_comb
  dout = vector >> start_ptr ;

endmodule

Here is the RTL view of the design using the shift operator (>>).
enter image description here

At one point I was thinking Xilinx intended for the +: and -: operators to be used at elaboration time only, for example in a generate loop. If that were the case then Xilinx should state that in the synthesis guide UG901 (they do not). Also Vivado infers the combinational logic for a design with registers, why should it not work with SRL's?
To me its a bug.
Good catch.

Mikef
  • 1,572
  • 2
  • 10
  • 21
  • I'm obtaining the exact same schematic. There no downstram circuit because I synthesized that as top level and assigned all the inputs to GPIOs. In your schematic you have only DOUT[0] connected to the SRL16 (1bit) and the other 3 bits connected to 3state buffers with fixed inputs. If I'm not wrong you too are obtaining a wrong synthesis – dadduni Jan 31 '23 at 14:42
  • Great job! I honestly didn't thought about "forcing" the register implementation. I can understand that Vivado cannot use SRL and a single mux, becasuse SRL has only one bit output. So you would need 10 SRL chains each one addressed with an incremetal address. The problem for me was that I started with a VHDL similar question (different syntax) and it works with the exact same bug! Answare accepted, case closed. Thank you – dadduni Feb 01 '23 at 08:29