質問

I've met a situation where I think I have to use blocking assignment in a @(posedge clk) block. The snippet below is from a tsetbench. I want to input the data to a DUT through the testbench. input_intf is the name of an interface and wcb is a clocking block synchronizing to wclk.

   @(posedge input_intf.wclk)
    begin
      input_intf.winc = 1;
      input_intf.wcb.wdata = 8'd7;
      input_intf.winc = 0;
    end

I want to do the following: after the positive clock edge, inc=1 and data reading is enabled. After data is read, let inc=0. I guess maybe winc signal has no need to be synchronous with wclk? If it's the case then the snippet should be like following.

input_intf.winc = 1;

@(posedge input_intf.wclk)
   input_intf.wcb.wdata <= 8'd7;

input_intf.winc = 0;

So is it true that we must use non-blocking assignment in a procedural block? When learning Verilog, I was told it's true.

Thanks!

役に立ちましたか?

解決

The statement input_intf.wcb.wdata = 8'd7; is illegal. You do not use blocking or non-blocking assignments to drive clocking block outputs. See 14.16.1 Drives and non-blocking assignments in the IEEE Std 1800-2012 LRM. For other non-clocking block variables inside your interface, you use the same rules that you learned with Verilog: use non-blocking assignments to write to variables that are synchronous to a clock, and will be read by other procedural blocks on the same clock edge. That is how you avoid races.

The use of clocking blocks is generally an all or nothing approach. you should not be mixing writing to clocking block and non-clocking variables in the same procedure, and you should only be using the clocking block event to synchronize your code.

@(input_intf.wcb) // do not use posedge of any signal here.
   input_intf.wcb.wdata <= 8'd7;

There are exceptions to these rules, of course, but I would make sure you know exactly how clocking blocks work before going there.

ライセンス: CC-BY-SA帰属
所属していません StackOverflow
scroll top