1
votes

I have done very simple module where I assign new value on posedge of clock:

module block_entry(
    input logic clk, 
    input entry entry_write,
    output entry entry_this
);
always_ff @(posedge clk)
begin
    entry_this <= entry_write;
    display("value of entry_write.add = %b", entry_write.address);
    display("value of entry_write.value = %b", entry_write.value);
end
endmodule

when i test this module, it works fine, new value is assigned, but in more advanced architecture, the new value is not set in time to be written at posedge, even though modelsim shows that it is set

this is my test module:

module entry_tst ();
    logic clk;
    entry entry_write, entry_this;
    block_entry entry (.*);

initial begin
    #10 clk = 1; entry_write = '0; 
end
endmodule

this is the outcome -> wave and dataflow

when testing the block, outcome is:

value of entry_write.add = 0000000000000000

value of entry_write.value = 0000000000000000

as you can see, clk transitions from x to 1 in the same time as input value changes - as result, output value is overwritten

but problem is when i use this module in my architecture, it doesnt behave the same - inputs are the same, but the value is not overwritten, as if the posedge is not triggered, but actually it appears that the value is not set in time of posedge. my architecture includes:

  • entry block

  • control block ('brain' of my architecture, chooses which value should be written to entry block, generates signal 'cont' to mux, also generates signal 'clk' to entry block when to assign value from mux, 'clk' is logic, so default value is x at the beginning)

  • mux (multiplexor that chooses what value will be written to entry block based on signal from control block)

initially i want to set entry value to 0, so I have an 'init' signal, when is init equal to 1, control sets 'cont' signal accordingly, so mux chooses stream that is set to 0 and sets 'clk' so entry block will rewrite old value to new (0)

always_ff @(posedge init) 
    if (init)
    begin   
    cont <= 2'b00;
    clk <= 1;
end

everything is ok - to entry block arrives new value and 'clk' signal is set, but new value is ignored this depicts the wave behavior of entry block as a part of architecture: wave and dataflow

when testing whole architecture, outcome is:

value of entry_write.add = xxxxxxxxxxxxxxxx

value of entry_write.value = xxxxxxxxxxxxxxxx

What is wrong? I am really hopeless, I am a systemverilog newbie.

Can timescale change something (it is set to default 1ns/1ns)? Also sometimes when i observe the dataflow, in the moment of change, clk is set to 1 but the value to be written is not set to 0 - can this be the problem? that the change of clk and value is not in fact happening in the same time, and when posedge is triggered value is still old?

How come the value is not distributed in time and how can I fix it? Also, why the wave and dataflow look OK?

EDIT:

I figured that the problem is racing condition, and that basically, the value is not in time there to be written: problem

i created a diagram that shows my implementation, how can i achieve that the entry_write is there in time before clk?? diagram

1
Two clarifying questions: 1) Where in the code thats having an issue is entry_write assigned? 2) Are you attempting to make an asynchronous circuit (because if this is supposed to be a synchronous design, you have a number of errors)?Unn
Could you please take a look at my diagram, that shows how i assigned each value? (in edit section of my post) Would be greatly grateful for any help that will lead the entry_this to be correct.Turbotrdlo

1 Answers

0
votes

The following expression in your code creates race condition:

always_ff @(posedge init) 
    if (init)
        clk <= 1;

if combined with

always_ff @(posedge clk)
    entry_this <= entry_write;

it causes a race int the NBA block and the results of the assignment here are unpredictable.

The rule of thumb is to never use non-blocking assignments in clocks.