I am new to systemverilog. Recently I am working on a project for decoding a data stream from a AVALON_ST. Using systemverilog. My target device is Stratix V and the clock is 200Mz.
module decoder( // clk and reset input logic reset_n, input logic clk, // avalon st input logic in_vld, input logic in_sop, input logic in_eop, input logic[255:0] in_data, input logic[4:0] in_eop_pos, // output output logic trigger ); // local logics shortint pos; shortint limit; shortint offset; logic[511:0] buffer; logic[255:0] remainning_data; business_object obj; // systemverilog struct for the packed data always_ff @(posedge clk or negedge reset_n) begin // (0) // handle reset_n // (1) // whenever in_vld, combine remainning_data (if any) and in_data // to buffer // (2) // update pos, limit and offset based on in_eop_pos // (3) // decode the buffer and populate business_object field by field // (4) // if a completed obj is decoded, applied the business rule to output trigger // (5) // if there are remainning data bits (either after a full decoded obj // or remainning bits that are not enough to pouplate business_object), // store it in remainning_data end endmodule
I use non-blocking assignment for part #0 and #4 and use blocking assignment for #1, #2, #3 and #5.
I use ModelSim to simulate the decoder. It works. However, it doesn't work in hardware.
After investigation, I found there are some red highlight in Quartus's Timing Analyzer saying that:
"The design contains failing setup paths with a worst-case slack of -9.561ns"
There are large combinational logic delay that exceed a clock period.
My questions are:
1) Does it matter to combinational logic delay if there are number of blocking assignments(#1,#2,#3,#5) within the always_ff block?
I know it is not the best practice to have blocking assignment inside always_ff but I learnt from somewhere that it is ok to have blocking assignment for local variable or the case that there are only one always_ff block in module.
If it does matter, can I reduce the delay by moving these blocking assignment logics to always_comb?
2) The avalon interface is 256 bits wide and I am already using pineline way in my design. Any other tips that can reduce the logic delay?
I look into the RTL schematic together with timing analyzer and tried to understand why there are such large number of logic levels and fan-out signals. I found the followings are consuming sufficient large amount of delay in the data path:
a) if/else statement / switch-case on
b) maths calculation (e.g.
I used general
shortint as data type for
limit, which were local signals for representing number of bits read / pending read bits / remaining bits etc.
The business data range of
pos is 12k bits (1500 bytes) and
offset 256 bits (32 bytes) so original I used
shortint (16 bits). I was too generous.
Now, I changed to
pos to represent number of BYTES read / pending. It reduces the ALM count of the module from 3800 to 1900, significantly reduce the data delay and the timing requirement is now met.
Thanks to all.