How does SystemVerilog `force` work? - verilog

I have a hierarchy of modules where I am trying to do a force to get different value at different module interface. I am working on a component whose task is to inject transaction to a module down the hierarchy, bypassing the drives from the modules higher up in the hierarchy. I thought I could use force on the control signals in order to disengage drives from higher up modules and start driving into the module of interest. So I have been trying to see how force will work. The full code is at http://www.edaplayground.com/x/69PB.
In particular, I am trying to understand effect of these two statements within initial block:
force u_DataReceiveTop.u_DataReceiveWrap.DataReceiveIfWrp_inst.valid = 1'b0;
force u_DataReceiveTop.valid = 1'b1;
what I expected the values to be is:
u_DataReceiveTop.u_DataReceiveWrap.DataReceiveIfWrp_inst.valid == 0
u_DataReceiveTop.valid == 1
but I see from waves:
u_DataReceiveTop.u_DataReceiveWrap.DataReceiveIfWrp_inst.valid == 1
u_DataReceiveTop.valid == 1
It is as if the second force statement force u_DataReceiveTop.valid = 1'b1; has propagated down the hierarchy even though there is another force. What is happening here?

A wire in Verilog is a network of drivers and receivers all connected to the same signal. The value of that signal is some resolution function of all the drivers and the type of the wire. When you connect two wires through a port, the two wires get collapsed into a single signal, but you still have two different names for the same signal.
When you use the force statement on a wire, that overrides all the drivers on the network until encountering another force or release statement. In your example, the second force statement replaces the first force. I doesn't matter which hierarchical reference you use in the force because they all refer to the same signal.
If you want the behavior you are expecting, you need to use variables instead of wires. When you connect a variable to a port, SystemVerilog creates an implicit continuous assignment, depending on the direction of the port. SystemVerilog does not allow more than one continuous assignment to a variable, which is why you can't use variables with an inout port. So you will need to be more careful about the port directions then.

Related

Parameterized FIFO instantiation in Verilog

I wanted to have a parameterized FIFO instantiation so that I can call a single FIFO instance with change in depth(parameter).
e.g. I have written a code for FIFO with depth as a parameter.
I will know the depth of the FIFO only by the configuration from Microprocessor. Based on the register configuration, can i call this FIFO with variable parameter like value?
integer depth_param;
if(config_reg[1])
depth_param <= 128;
else
depth_param <= 512;
genfifo #(depth_param) (.din (din),.wr(wr)....);
fifo module is:
module gen_fifo #(depth = 128)
( din,wr,rd,clk....);
can you please suggest is there a way I can do this?
This is what the LRM says:
Parameters represent constants; hence, it is illegal to modify their
value at run time. However, module parameters can be modified at
compilation time to have values that are different from those
specified in the declaration assignment. This allows customization of
module instances. A parameter can be modified with the defparam
statement or in the module instance statement. Typical uses of
parameters are to specify delays and width of variables.
'run time' means during simulation, after elaboration. A synthesiser doesn't 'run' anything, but what you're doing is effectively "run time", and so is illegal.
This doesn't mean that you can't do it, though. Pass in your FIFO depth as a module port. I'm assuming that you know how to code a FIFO from first principles. If so, you will normally have a constant for the FIFO size; just replace this constant with the value at the port, and find some way to set the memory size. You'll obviously need to be careful when changing the FIFO size - you may need to reset it, for example. If you don't know how to code a FIFO you should ask with an FPGA or an electronics tag.

Module Instantitions for simulation

I want to simulate a module that has a simple Addr/Data interface. I want to create a separate module that will act as a transactor for this module. So for example, I can simply call a task in the transactor module that will perform a write of an addr and data. e.g.
Transactor.Write_Task(0, 123); //Writes 123 to Addr 0.
My question is, should I do an include to include the transactor module at the top of the testbench? Or is it a better approach to compile the transactor separately and instantiate it and wire it up, as if it was another unit under test? e.g:
\lib_Local_Bus.Local_Bus_Transactor Transactor
(
.i_LB_Clk(w_LB_Clk),
.o_LB_CS(w_LB_CS),
.o_LB_Wr_Rd_n(w_LB_Wr_Rd_n),
.o_LB_Addr8(w_LB_Addr8),
.o_LB_Wr_Data(w_LB_Wr_Data),
.i_LB_Rd_Data(w_LB_Rd_Data),
.i_LB_Rd_DV(w_LB_Rd_DV)
);
I feel like it's easier to simply include it with an include, but then I need to point to it correctly, which could be a problem. By precompiling it, instantiating it like a UUT, and wiring it up, there's more code, but it is more straightforward as to what is going on.
The classic approach is to treat it as any other module, meaning it lives as its own file and you instantiate the transactor and the DUT together in your top level test bench. This is how most vanilla Verilog environments I have worked on are coded.
The module can either present a queue-based interface to queue transactions into, or a task-based interface which can then be called from your test, e.g.
initial
begin : test_block
Transactor.Send(data1);
->stimulus_complete;
end

Always block not behaving as expected

I am making a state machine in verilog to implement certain arithmetic functions based on user input. I've run into a snag, however; my first always block, the one that handles my reset and maintains the correct state, is not behaving as expected; it is not updating the state correctly. The code is as follows:
always # (posedge CLOCK_50 or negedge RESET) begin
if(RESET == 1'b0)
STATE <= BASE;
else
STATE <= NEXT_STATE; // this always block, and specifically this line, is //not executing correctly.
end
Here is the general output of the file when reset and then following three button presses (KEY[1]) with SW = 0000:
EDIT: waveform with actual CLOCK_50 and RESET signals added
http://imgur.com/0DUka21
As for my question, I just want to know what I am doing incorrectly with this section of code. I can think of no reason for it to behave this way. Thanks for any help you can provide.
EDIT2: FFS, I changed the block to negedge CLOCK_50 and now it's working. I'd really like to know why if you can tell.
Ah, I see what you did now. You're assigning STATE in both of your two always blocks (STATE <= STATE in the default of the case block). This is bad, as it's a race condition between the two blocks as to which gets actually assigned. In your case, the second block is overriding the first, such that STATE <= STATE gets executed every clock. You should not assign the same variable in more than one always block.
Also you should pay attention to those warnings, but they are referring to the always #(ENABLE) block. This is complaining because you are inferring weird latched behavior, because the output is depending on STATE and SW, but they are not in the sensitivity list. You should probably just make this a combinational block, and use the auto-sensitivity list always #*.
Every always block, as well as every statement outside of an always block, effectively runs in parallel.
Since you have "state" being driven by two always blocks, you're effectively having two wires feed into a single wire. In digital logic design, you just can't do that. (Excluding pull-up resistors and such, but that's another topic.)
In simulation, if the multiple wires driving that single wire have the same logical value, you can get the output you desire; but if they have different values, you'll get invalid or unpredictable output.
In synthesis, this will simply fail with a "multiple drivers" error.
Also, the sensitivity list for an always block should have one of three things in it:
A clock
A clock and an asynchronous reset
Every wire/reg that is used as an input to that always block (*)
Anything else can result in an unintentional latch, which will cause problems.
In case 3, you need to make sure that every wire driven in the always block has a default value. Anything else can result in an unintentional latch.
Lastly, you can't have circular assignments or you risk a logic loop. You have one by assigning next_state to itself. Anything "circular" requires a flip-flop, aka an always block of type 1 or 2 outlined above.

Verilog specify block within for-loop

I am trying to model path delays for an n-bit wide signal. I can do this fine if I explicitly define the delay for each individual bit, like this (n=3):
specify
(in_data[0] => delayed_data[0]) = 5;
(in_data[1] => delayed_data[1]) = 2;
(in_data[2] => delayed_data[2]) = 1;
endspecify
However, I want to be able to specify random delays for each bit of in_data when in_data is n-bits wide. My idea was something like this:
for (n=0;n<DATA_WIDTH-1;n=n+1)
begin
specify
(in_data[n] => delayed_data[n]) = {$random};
endspecify
end
This gives me an error: "near 'specify': syntax error, unexpected specify"
I also tried placing the for loop within the specify block. This resulted in the following error: "near 'begin': syntax error, unexpected begin, expecting endspecify"
I would really appreciate any tips on how to do this correctly
According to the Doulos Verilog Reference Guide (page 84) a specify block can only occur within module and endmodule tags, and not within anything else.
According to this Verilog reference website:
The Specify block was designed to define a delay across a module. It starts with specify and ends with the endspecify keyword. Inside the block the user can specify: specparam declaration, path declaration or system timing check.
This seems to imply it does not allow for-loops within specify blocks.
Hence it leads me to believe that you'll need to write out all the values one by one due to a limitation of the language.
One idea you could try is to restructure your modules to have a one bit input to a one bit output. Then each specify block will only have one delay to specify, and you can assign them each a random value. You can then generate these modules inside a generate block which will avoid you having to specify a delay for each bit manually.
However, this may be more tedious/awkward.

Verilog doesn't have something like main()?

I understand that modules are essentially like c++ functions. However, I didn't find something like a main() section that calls those functions. How does it work without a main() section?
Trying to find (or conceptually force) a main() equivalent in HDL is the wrong way to go about learning HDL -- it will prevent you from making progress. For synthesisable descriptions you need to make the leap from sequential thinking (one instruction running after another) to "parallel" thinking (everything is running all the time). Mentally, look at your code from left to right instead of top to bottom, and you may realize that the concept of main() isn't all that meaningful.
In HDL, we don't "call" functions, we instantiate modules and connect their ports to nets; again, you'll need to change your mental view of the process.
Once you get it, it all becomes much smoother...
Keep in mind that the normal use of Verilog is modeling/describing circuits. When you apply power, all the circuits start to run, so you need to write your reset logic to get each piece into a stable, usable operating state. Typically you'll include a reset line and do your initialization in response to that.
Verilog has initial blocks are kinda like main() in C. These are lists of statements that are scheduled to run from time 0. Verilog can have multiple initial blocks though, that are executed concurrently.
always blocks will also work as main() if they've an empty sensitivity list:
always begin // no sensitivity list
s = 4;
#10; // delay statements, or sim will infinite loop
s = 8;
#10;
end

Resources