How can I use display or monitor in verilog to check a register - verilog

I have 2 Modules. One is Register_File_Rf which is a file of 32 Registers I have created. I want to be able to see what every single register is storing.
Can I do this with $display or $monitor somehow?
Where these should be? In actual code or in Testbench, and how do I get the value in testbench when the stored Data is neither input or output?
module Register(
input Clk,
input [31:0] Data,
input WE,
output reg[31:0] Dout
);
reg [31:0] stored;
// With every Positive Edge of the Clock
always #(posedge Clk)begin
// If Write is Enabled we store the new Data
if (WE)begin
stored <= Data;
Dout <= stored;
end else
Dout <= stored;
end
module Register_File_RF(
input [4:0] Adr1,
input [4:0] Adr2,
input [4:0] Awr,
output reg[31:0] Dout1,
output reg[31:0] Dout2,
input [31:0] Din,
input WrEn,
input Clk
);
integer j;
genvar i;
wire [31:0]Temp_Dout[31:0];
reg W_E [31:0];
// Writing only in the first time R0 Register with 0
initial begin
W_E[0] = 1;
end
// Creating the R0 Register
Register register (.Clk(Clk),.WE(W_E[0]),.Data(0),.Dout(Temp_Dout[0]));
// Creating 30 Registers
for(i = 1; i < 32; i = i + 1)begin:loop
Register register (.Clk(Clk),.WE(W_E[i]),.Data(Din),.Dout(Temp_Dout[i]));
end:loop
// Assigning to Dout1 and Dout2 the Data from a spesific register
always #(Adr1, Adr2) begin
Dout1 = Temp_Dout[Adr1];
Dout2 = Temp_Dout[Adr2];
end
// Wrting Data to a specific register
always #(posedge Clk)begin
//Reseting Write Enable of the register to 0
for (j = 0; j < 32; j = j + 1)begin:loop2
W_E[j] = 0;
end:loop2
if(WrEn)begin
W_E[Awr] = WrEn;
end
end
endmodule

Yes, you can do this with either $display or $monitor.
Typically, $monitor would be called inside an initial block since it should only be called at one time in your simulation. It automatically displays values whenever one of its argument signals changes value.
Unlike $monitor, $display only displays values when it is called; it must be called whenever you want to display a signal value. It can be called in an initial block, but it is often called in an always block.
Regarding when to use either one, it is up to you to decide what you require.
If you are not planning to synthesize your modules, you could place monitor/display inside your design module directly. However, if you plan to synthesize, it might be better to place them in the testbench.
You can use hierarchical scoping to view internal signals from the testbench module. For example, assume you named the instance of the Register_File_RF module in the testbench as dut:
Register_File_RF dut (
// ports
);
always #(posedge Clk) begin
$display($time, " dout='h%x", dut.register.Dout);
end
initial begin
$monitor($time, " dout='h%x", dut.register.Dout);
end
$monitor will display a value every time Dout changes value, whereas $display will show the value at the posedge of the clock.
If your simulator supports SystemVerilog features, you can also use bind to magically add code to your design modules.

Related

Assign multiple values to one latch

I need a latch which can take multiple bus with one enable signal for each and when this signal is high, the latch takes the value of the associated bus, something like this :
I tried this :
module Test (
input [1:0] load,
input [15:0] bus,
output reg [7:0] value
);
wire [7:0] temp;
assign temp = (load[0]) ? bus[7:0] : (load[1]) ? bus[15:8] : 8'bZZ;
always #(load or temp) begin
// Latch value
if (load) begin
value <= temp;
end
end
endmodule
and this :
module Test (
input [1:0] load,
input [15:0] bus,
output reg [7:0] value
);
always #(load or bus) begin
// Latch value
if (load[0]) begin
value <= bus[7:0];
end
else
if (load[1]) begin
value <= bus[15:8];
end
end
endmodule
And this same warning appears on both (repeated for each bit) :
Warning (13012): Latch Test:test|value[0] has unsafe behavior
Warning (13013): Ports D and ENA on the latch are fed by the same signal load[0]
The only way that I found to avoid these warnings is like this :
module Test (
input [1:0] load,
input [15:0] bus,
output [7:0] value
);
reg [15:0] temp;
reg index;
always #(load or bus) begin
if (load[0]) begin
index <= 0;
end
else
if (load[1]) begin
index <= 1;
end
// Latch value
if (load) begin
temp <= bus;
end
end
assign value = temp[8*index+7 -:8];
endmodule
But it's a waste of memory because it saves the two buses instead of one, is it possible to do it with one reg and avoiding these warnings ?
I don't think you can get rid of the warnings in the first two examples—you have a bonafide race condition between the latch enable and the data feeding the latch. It is more obvious in your first example.
When load goes to 0, temp will be changing to Z ( a don't care most likely 0) at the same time the latch enable goes to 0. Which one happens first is clearly a race.

Quartus does not allow using a Generate block in Verilog

Pretty simple problem. Given the following code:
module main(
output reg [1:0][DATA_WIDTH-1:0] dOut,
input wire [1:0][DATA_WIDTH-1:0] dIn,
input wire [1:0][ADDR_WIDTH-1:0] addr,
input wire [1:0] wren,
input wire clk
);
parameter DATA_WIDTH = 16;
parameter ADDR_WIDTH = 6;
reg [DATA_WIDTH-1:0] ram [2**ADDR_WIDTH-1:0];
generate
genvar k;
for(k=0; k<2; k=k+1) begin: m
always #(posedge clk) begin
if(wren[k])
ram[addr[k]] <= dIn[k];
dOut[k] <= ram[addr[k]];
end
end
endgenerate
endmodule
quarus 13.0sp1 gives this error (and its 20 other ill-begotten fraternally equivalent siblings):
Error (10028): Can't resolve multiple constant drivers for net "ram[63][14]" at main.v(42)
But if I manually un-roll the generate loop:
module main(
output reg [1:0][DATA_WIDTH-1:0] dOut,
input wire [1:0][DATA_WIDTH-1:0] dIn,
input wire [1:0][ADDR_WIDTH-1:0] addr,
input wire [1:0] wren,
input wire clk
);
parameter DATA_WIDTH = 16;
parameter ADDR_WIDTH = 6;
reg [DATA_WIDTH-1:0] ram [2**ADDR_WIDTH-1:0];
always #(posedge clk) begin
if(wren[0])
ram[addr[0]] <= dIn[0];
dOut[0] <= ram[addr[0]];
end
always #(posedge clk) begin
if(wren[1])
ram[addr[1]] <= dIn[1];
dOut[1] <= ram[addr[1]];
end
endmodule
It all becomes okay with the analysis & synthesis step.
What's the cure to get the generate loop running?
I think the correct way is in the lines of what it's explained in this question: Using a generate with for loop in verilog
Which would be transferred to your code as this:
module main(
output reg [1:0][DATA_WIDTH-1:0] dOut,
input wire [1:0][DATA_WIDTH-1:0] dIn,
input wire [1:0][ADDR_WIDTH-1:0] addr,
input wire [1:0] wren,
input wire clk
);
parameter DATA_WIDTH = 16;
parameter ADDR_WIDTH = 6;
reg [DATA_WIDTH-1:0] ram [2**ADDR_WIDTH-1:0];
integer k;
always #(posedge clk) begin
for(k=0; k<2; k=k+1) begin:
if(wren[k])
ram[addr[k]] <= dIn[k];
dOut[k] <= ram[addr[k]];
end
end
endmodule
Keeping all accesses to your dual port RAM in one always block is convenient so the synthesizer can safely detect that you are efefctively using a dual port RAM at register ram.
Both the generate loop and unrolled versions should not have passed synthesis. In both cases the same address in ram can be assigned by both always blocks. Worse, if both bits of wren are high with both addresses being the same and data being different, then the result is indeterminable. The Verilog LRM states last assignment on a register wins and always blocks with the same trigger could be evaluated in any order.
Synthesis requires assignments to registers to be deterministic. Two (or more) always blocks having write access to the same bit is illegal because nondeterministic. If the unrolled is synthesizing correctly, then that means there are constants on wren and addr outside of the shown module that make it logically impossible for write conflict; for some reason the generate loop version is not getting the same optimization. Example of constraints that would allow optimization to prevent multi-always block write access:
One wren is hard coded to 0. Therefore only one block has exclusive access
Address have non overlapping sets of possible values. Ex addr[0] can only be even while addr[1] can only be odd, or addr[0] < 2**(ADDR_WIDTH/2) and addr[1] >= 2**(ADDR_WIDTH/2).
Synthesis is okay with dOut being assigned by two always blocks because each block has exclusive write access to its target bits (non overlapping sets of possible address values).
The single always block in mcleod_ideafix answer is the preferred solution. If both bits of wren are high with both addresses being the same, then wren[1] will always win. If wren[0] should have priority, then make the for-loop a count down.

How to assign initial value to an input reg: Design compiler delete the assignment

I'm newbie in ASIC design. I have a design with for example two inputs a ,b. I'm using the following code for initialize these two signals. But the Design compiler generating a warning that the register "a" is a constant and will be removed. When I'm trying to do post-synthesis simulation these two signals are all 'z'. So how can I apply initial signal assignment to avoid such a problem?
always #(posedge(clk) or posedge (rst)) begin
if (rst) begin
a<=4d'5;
b <=4'd10;
end
end
While describing hardware system, you need to consider that input signals to your module comes from another module/system and their values are decided by that signals. Inputs to any module can only be wire type.
You can think of a module as a box that has inputs and outputs. The values of output signals are decided by input signal + logic inside the box. However, the module cannot decide what its inputs should be. It is only possible if there is feedback, and even in that case it would depend on other signals that are outside of the module's control.
As a result, output signals can be declared as output reg but the same is not true for inputs. However there is solution to your problem, I think what you want can be designed using the following method:
module your_module(
input clk,
input rst,
//other inputs and outputs that you might need
input [3:0] a,
input [3:0] b
);
//define registers
reg [3:0] a_register;
reg [3:0] b_register;
/*
These registers are defined to make it possible to
to give any value to that logics when posedge rst
is detected, otherwise you can use them as your
input logics
*/
//use initial block if you need
always#(posedge clk or posedge rst) begin
if(rst) begin
a_register <= 4'd5;
b_register <= 4'd10;
end
else
begin
a_register <= a;
b_register <= b;
// and use a_register and b_register as you want to use a and b
end
end
endmodule

Running into errors while trying to move signal to external module

I have two modules namely main.v and signal.v.
In main.v, I have a few lines of code that update 16 bit reg tx with a value corresponding to a square wave.
reg [1:0] counter;
reg [15:0] tx;
always #(posedge clk) begin
counter = counter + 1;
if (counter[1] == 1) begin
tx[15:0] <= 16'b1010101010101010;
else
tx[15:0] <= 16'b0000000000000000;
end
This works fine. Eventually, though, I want to move this signal over to another file signal.v, because the signal that I pass to tx will grow steadily more complicated. I ran into errors when I try to do this. Initially, I tried to move all the above code to the file signal.v. Then used a wire between the two files as shown.
module signal(clk, get_tx);
input clk;
output reg get_tx;
reg [1:0] counter;
always #(posedge clk) begin
counter = counter + 1;
if (counter[1] == 1) begin
get_tx[15:0] <= 16'b1010101010101010;
else
get_tx[15:0] <= 16'b0000000000000000;
end
Then in main.v, I tried to add
wire get_tx;
reg [15:0] tx;
signal my_signal(.clk(clk), .get_tx(get_tx));
always #( get_tx ) begin
tx <= get_tx;
end
Based on what I see in the output oscilloscope, this method isn't working, and I'm not certain why this is. The first case seems to work fine, so I don't know why it is failing when I move to the second case (the signals just look completely different).
I would appreciate any help/advice!
First of all will be better to understand your connections and simulate your code if you add full code with modules declarations. The problems are in the signal types. Try to change output to wire. As well you need to declare bus, not just 1 bit signal. And give an initial value to your counter (in other case it will do follow operation 'X' +1 which gives 'X' in result and your condition if (counter[1] == 1) will never be achieved).
module signal(clk, get_tx);
input clk;
output [15:0] get_tx;
reg [15:0] tx_out;
reg [1:0] counter = 2'd0;
always #(posedge clk) begin
counter = counter + 1;
if (counter[1] == 1)
tx_out[15:0] <= 16'b1010101010101010;
else
tx_out[15:0] <= 16'b0000000000000000;
end
assign get_tx = tx_out;
endmodule
Next error in upper module, there you also need to declare bus rather than just one bit wire [15:0] get_tx;. Try to fix this errors and your modules will work.

1second down counter with initial value verilog code

I want to write the code of 1-second down counter that get the initial value from outside and count it down till 0. but there is a problem. How can I get the initial value. i tried some ways but ....
here is the code:
module second_counter ( input clk,
input top_num,
output reg [3:0] sec_num
);
parameter clk_frequency = 25;
reg [31:0]cnt;
wire [3:0]sec;
/// how can get the top_num and count it down.
assign sec=top_num;
always #(posedge clk)
begin
if (cnt==clk_frequency)
begin
sec <= sec -1;
cnt<=0;
end
else
cnt <=cnt+1;
end
What you basically need is a reset signal. Just like clock, reset is to be added in the sensitivity list.
After instantiation of module, you must apply a reset signal to initialize all the internal variables and registers of design.
Following code gives you initial value of cnt by reset application. This is an active low reset.
module second_counter ( input clk, input reset, input top_num, output reg [3:0] sec_num );
parameter clk_frequency = 25;
reg [31:0]cnt;
// wire [3:0]sec;
reg [3:0] sec;
///
// assign sec=top_num;
always #(posedge clk, negedge reset)
begin
if(!reset)
begin
cnt<=0; // initialize all internal variables and registers
sec<=0;
end
else
begin
if(sec == 0) // latch input when previous count is completed
sec<=top_num;
if (cnt==clk_frequency)
begin
sec <= sec -1;
cnt<=0;
end
else
cnt <=cnt+1;
end
end
Note that this is an asynchronous reset, means it does not depend on clocking signal. Synchronous reset is the one which only affects the registers at the clock pulse.
Edit:
Regarding to sec, I have modified the code. Now the design latches the inputs for one clock cycle and counts down to zero. Once the counter reaches zero, it again latches the input to re-count to zero.
Note that you cannot do like latching top_num at every clock and counting through zero (since top_num can change at every pulse). For latching at every clock pulse, you need more complex logic implementation.

Resources