cancel
Showing results for 
Show  only  | Search instead for 
Did you mean: 
oz2kso
Newbie
Newbie
920 Views
Registered: ‎09-16-2020

Absolutely Verilog newbie question...

Hi

I have just started up again with a little playing around with my new CMOD S7 board.

Now i have come across a very strange behaviour that is very had to search for an explanation for, sorry!

Here it comes - how can the following code produce the trace out result below?

    reg [3:0] tmp_mem [11:0];
    reg [3:0] idx = 0;

initial begin
    tmp_mem[0]  <= 4'b0001;
    tmp_mem[1]  <= 4'b0011;
    tmp_mem[2]  <= 4'b0010;
    tmp_mem[3]  <= 4'b0110;
    tmp_mem[4]  <= 4'b0100;
    tmp_mem[5]  <= 4'b1100;
    tmp_mem[6]  <= 4'b1000;
    tmp_mem[7]  <= 4'b1100;
    tmp_mem[8]  <= 4'b0100;
    tmp_mem[9]  <= 4'b0110;
    tmp_mem[10] <= 4'b0010;
    tmp_mem[11] <= 4'b0011;
end

    always@(posedge clk)
        if (cd_count >= CD_COUNT_MAX-1) begin // 2Hz
            cd_count <= 'b0;
            idx <= idx + 1;
            $display ("idx1 = %0d", idx);
            if (idx > 10) begin
                idx <= 0;
            end
            $display ("idx2 = %0d", idx);
        end else begin
            cd_count <= cd_count + 1'b1;
        end        
    assign led = tmp_mem[idx];
    

 

Trace:

add_wave {{/top/clk}} 
add_force {/top/clk} -radix bin {1 0ns} {0 50000ps} -repeat_every 100000ps
run all
idx1 = 0
idx2 = 0
idx1 = 1
idx2 = 1
idx1 = 2
idx2 = 2
idx1 = 3
idx2 = 3
idx1 = 4
idx2 = 4
idx1 = 5
idx2 = 5
idx1 = 6
idx2 = 6
idx1 = 7
idx2 = 7
idx1 = 8
idx2 = 8
idx1 = 9
idx2 = 9
idx1 = 10
idx2 = 10
idx1 = 11
idx2 = 11
idx1 = 0
idx2 = 0
idx1 = 1
idx2 = 1
idx1 = 2
idx2 = 2
idx1 = 3
idx2 = 3
run: Time (s): cpu = 00:01:53 ; elapsed = 00:01:27 . Memory (MB): peak = 4192.309 ; gain = 0.000

 

It's not a simulation problem because it matches the result on the physical hardware...

In essence - how can this code snippet:

if (idx > 10) begin
idx <= 0;

allow the trace out idx2 to become 11???

idx1 = 10
idx2 = 10
idx1 = 11
idx2 = 11
idx1 = 0

 

Thanks,

Kenneth

 

 

 

 

0 Kudos
5 Replies
bruce_karaffa
Scholar
Scholar
914 Views
Registered: ‎06-21-2017

Works as written.

idx is 9,on clock edge if statement checks 9 is not greater than 10.  Add one to idx.  idx is now 10.  On clock edge, if statement checks 10 is not greater than 10.  Add 1 to idx.  idx is now 11.  If statement checks 11 is greater than 10.  idx becomes zero.

baltintop
Voyager
Voyager
904 Views
Registered: ‎06-28-2018

oz2kso
Newbie
Newbie
901 Views
Registered: ‎09-16-2020

Hi and thanks for you quick reply!

Okay, so an update to a variable as no effect on the following statements until the next clock cycle?!?

I just say that is, at best, extremely counter intuitive, but that might just be me ;o)

 

0 Kudos
bruce_karaffa
Scholar
Scholar
885 Views
Registered: ‎06-21-2017

idx and tmp_mem are not variables, they are outputs of registers.  Try drawing the circuit and you will understand why it functions as it does.

0 Kudos
avrumw
Expert
Expert
871 Views
Registered: ‎01-23-2009

Okay, so an update to a variable as no effect on the following statements until the next clock cycle?!?

Specifically, a non-blocking assignment (the <= assignment) is a deferred assignment; the completion of the assignment does not complete until all active events for this time tick are completed. So not the current "clock cycle" but (at least partly) the current "time tick". This is intentional and desired and required in order to model the behavior of some hardware constructs. 

Specifically, in order to ensure that multiple clocked processes with assignments in them (which are the behavioral description of flip-flops) work "properly" together, the assignments in them must be non-blocking assignments.

If you want immediate assignment, then use the blocking assignment (the = operator). This behaves more like an assignment in a procedural language like C. So (and I am not recommending this), if you were to change your non-blocking assignments to blocking assignments, then the behavior of the $display would be more like what you are expecting. However, if you did this, then this block would no longer reliably work in a system that has other modelled flip-flops in it (so don't use blocking assignments in the description of flip-flops).

Avrum