What is the wrong with my verilog code? - verilog

i wanna write register file in verilog that is write and read data registers.
this is my code:
module registerfile(writeaddr1,writedata1,readaddr2,readdata2,readaddr3,readdata3,write,clock);
input [4:0] writeaddr1, readaddr2, readaddr3;
input [31:0] writedata1;
output[31:0]readdata2,readdata3;
reg [31:0]readdata2,readdata3;
input write,clock;
reg [31:0] cells [0:31];
always #(posedge clock)
begin
if (write == 1) cells[writeaddr1] =writedata1;
readdata2 = cells[readaddr2];
readdata3 = cells[readaddr3];
end
endmodule
and this is my test bench.
module testreg;
reg [3:0]addr1,addr2,addr3;
reg [31:0]data1;
reg write;
wire [31:0]data2,data3;
reg clock ; //Rising edge every 10 timesteps
registerfile regf(addr1,data1,addr2,data2,addr3,data3,write,clock);
initial begin
addr1=1;
addr2=2;
addr3=3;
write=0;
data1=32'bx;
clock=0;
#10
addr1=1;
addr2=1;
addr3=3;
write=1;
data1=30;
clock=1;
#10
$finish;
end
endmodule
but i don't know why data2 between 10 and 20 is xxx? I am write 30 in that location:(

If the period of clk is 20ns, Between 0ns and 20ns first write is applied, but data2 is not the same data1, because read and write is simultaneous and when you write a value on memory, at the next clk rising edge you can read the same value from memory. Then between 20ns and 40ns (on clk rising edge) data2 is equal to data1.
In the module testreg size of addr1 should be [4:0] :
reg [4:0] addr1,addr2,addr3;
As Greg said in the module registerfile it's better to use non-blocking assignments (<=) such as the following code :
always #(posedge clock)
if (write) begin
cells[writeaddr1] <= writedata1;
readdata2 <= cells[readaddr2];
readdata3 <= cells[readaddr3];
end
Just use the following code and continue to run simulation until 40ns :
initial begin
addr1=1;
data1=30;
addr2=1;
write=1;
end
initial begin
clock = 0;
forever #10 clock = ~clock;
end
I simulated your code with the above changes and could get the correct result.

Related

Delay a 32-bit signal with N clock cycle in verilog

I am trying to delay a 32-bit signal using shift register. My logic is a single flip flop delay a signal by 1 clk so I use shift register as it is combination of flip flop can someone guide me what is wrong with this code.
module delay_n_cycles (
input wire [31:0] data_in,
input wire clk,
output reg [31:0] data_out,
parameter N = 5
);
reg [31:0] shift_reg;
always #(posedge clk) begin
shift_reg <= {shift_reg[30:0], data_in};
if (N == 0) begin
data_out <= shift_reg[31];
end else begin
data_out <= shift_reg[N-1];
end
end
endmodule
First of all, your code is syntactically wrong. parameter cannot be declared in a way you provided.
Your shift register is only 32 bit wide. Usually, to delay multi-bit data this way, you need to keep N copies of data in the register, shift them at one end and read at the other. I guess the following should help:
module delay_n_cycles #(parameter N = 5)(
input wire [31:0] data_in,
input wire clk,
output reg [31:0] data_out
);
reg [N-1:0][31:0] shift_reg;
always #(posedge clk) begin
shift_reg <= (shift_reg << 32) | data_in;
data_out <= shift_reg[N-1];
end
endmodule
This code will work with system verilog because it used packed multi-dimensional arrays.
You need to shift the reg by 32 (width of the data) in packed version.
Here is an example of a testbench:
module tb();
bit clk;
int clkCount;
initial
forever begin
#5 clk = ~clk;
clkCount++;
end
logic [31:0] data_in, data_out;
initial begin
$monitor("%0t (%0d) [%h]: %0d --> %0d", $time, clkCount, ds.shift_reg[4], data_in, ds.data_out);
for(int i = 0; i < 20; i++) begin
#10 data_in = i;
end
$finish;
end
delay_n_cycles ds(data_in, clk, data_out);
endmodule

How to display data from memory file at the positive edge of the clock?

I have a text file with hexadecimal data. I want to display the data at only the positive edge of the clock, thus controlling the frequency of the data. I have written the following code:
module testbench;
reg [15:0] in[0:5];
reg clk;
integer i;
initial
clk=1'b0;
always
#5 clk = ~clk;
initial
$readmemh("Input_rsvd.dat",in);
always # (posedge clk)
begin
for(i=0;i<5;i=i+1)
$display( "result = %h",in);
end
endmodule
Obviously, the code has some problem which I can not figure out. Can anybody help me with this?
When I try to run your code, I get a compile error on multiple simulators. You can not pass a memory variable to $display like that. I think you intended to print one value at a time. To fix it, change:
$display( "result = %h",in);
to:
$display( "result = %h",in[i]);
Also, if you want to print all 6 values, change:
for(i=0;i<5;i=i+1)
to:
for(i=0;i<6;i=i+1)
Here is the new code, using a more consistent layout:
module testbench;
reg [15:0] in [0:5];
reg clk;
integer i;
initial clk = 1'b0;
always #5 clk = ~clk;
initial $readmemh("Input_rsvd.dat", in);
always #(posedge clk) begin
for (i=0; i<6; i=i+1) $display("result = %h", in[i]);
end
endmodule

creating 12 Hz square signal 50MHz clock signal

I wrote code in Verilog that is supposed to create a 12Hz square signal at 50MHz clock signal.
Is it correct?
module w_m(clk, cnt);
input clk;
output [21:0] cnt;
reg [21:0] cnt = 0;
always #(posedge clk)
cnt = cnt + 1;
endmodule
module w_tf;
reg clk;
wire [21:0] cnt;
w_m uut
(
.clk(clk),
.cnt(cnt)
);
initial begin
// Initialize Inputs
clk = 0;
forever begin
#10
clk = !clk;
end
end
endmodule
Yes, it correctly simulates as described, assuming the timescale is set to 1ns.
The clk period is 20ns, and its frequency is 50MHz.
The MSB of cnt (cnt[21]) has a frequency of approximately 12Hz (11.921Hz, according to my simulation results).
You can verifiy this by running a simulation and looking at waveforms. You can post your code on edaplayground, for example.
The logic is right. However, there are some inaccuracies. I have varied the register size in order to run the simulation as allowed by EDA playground.
DUT:
module w_m(clk, clk_out);
input clk;
//output [21:0] cnt;
output clk_out;
reg [11:0] cnt = 0; // make 11 to 21
always #(posedge clk)
cnt = cnt + 1;
assign clk_out = cnt[11];
endmodule
Also, the testbench needs a $finish to stop the forever block from running infinite, taking up the disk space. Added a parallel path in order to run the sim, and exit after 10000ns. You can vary this as per your need.
TB:
module w_tf;
reg clk;
wire cnt;
w_m uut
(
.clk(clk),
.clk_out(cnt)
);
initial begin
// Initialize Inputs
clk = 0;
fork
begin
forever begin
#10 clk = !clk; end
end
begin
#10000000 $finish; // increase this number as per the simulation requirement
end
join
end
endmodule

4 bit countetr using verilog not incrementing

Sir,
I have done a 4 bit up counter using verilog. but it was not incrementing during simulation. A frequency divider circuit is used to provide necessory clock to the counter.please help me to solve this. The code is given below
module my_upcount(
input clk,
input clr,
output [3:0] y
);
reg [26:0] temp1;
wire clk_1;
always #(posedge clk or posedge clr)
begin
temp1 <= ( (clr) ? 4'b0 : temp1 + 1'b1 );
end
assign clk_1 = temp1[26];
reg [3:0] temp;
always #(posedge clk_1 or posedge clr)
begin
temp <= ( (clr) ? 4'b0 : temp + 1'b1 );
end
assign y = temp;
endmodule
Did you run your simulation for at least (2^27) / 2 + 1 iterations? If not then your clk_1 signal will never rise to 1, and your counter will never increment. Try using 4 bits for the divisor counter so you won't have to run the simulation for so long. Also, the clk_1 signal should activate when divisor counter reaches its max value, not when the MSB bit is one.
Apart from that, there are couple of other issues with your code:
Drive all registers with a single clock - Using different clocks within a single hardware module is a very bad idea as it violates the principles of synchronous design. All registers should be driven by the same clock signal otherwise you're looking for trouble.
Separate current and next register value - It is a good practice to separate current register value from the next register value. The next register value will then be assigned in a combinational portion of the circuit (not driven by the clock) and stored in the register on the beginning of the next clock cycle (check code below for example). This makes the code much more clear and understandable and minimises the probability of race conditions and unwanted inferred memory.
Define all signals at the beginning of the module - All signals should be defined at the beginning of the module. This helps to keep the module logic as clean as possible.
Here's you example rewritten according to my suggestions:
module my_counter
(
input wire clk, clr,
output [3:0] y
);
reg [3:0] dvsr_reg, counter_reg;
wire [3:0] dvsr_next, counter_next;
wire dvsr_tick;
always #(posedge clk, posedge clr)
if (clr)
begin
counter_reg <= 4'b0000;
dvsr_reg <= 4'b0000;
end
else
begin
counter_reg <= counter_next;
dvsr_reg <= dvsr_next;
end
/// Combinational next-state logic
assign dvsr_next = dvsr_reg + 4'b0001;
assign counter_next = (dvsr_reg == 4'b1111) ? counter_reg + 4'b0001 : counter_reg;
/// Set the output signals
assign y = counter_reg;
endmodule
And here's the simple testbench to verify its operation:
module my_counter_tb;
localparam
T = 20;
reg clk, clr;
wire [3:0] y;
my_counter uut(.clk(clk), .clr(clr), .y(y));
always
begin
clk = 1'b1;
#(T/2);
clk = 1'b0;
#(T/2);
end
initial
begin
clr = 1'b1;
#(negedge clk);
clr = 1'b0;
repeat(50) #(negedge clk);
$stop;
end
endmodule

Circuit behaves poorly in timing simulation but alright in behavioral - new to verilog

I'm new to verilog development and am having trouble seeing where I'm going wrong on a relatively simple counter and trigger output type design.
Here's the verilog code
Note the code returns the same result whether or not the reg is declared on the output_signal without the internal_output_buffer
`timescale 1ns / 1ps
module testcounter(
input wire clk,
input wire resetn,
input wire [31:0] num_to_count,
output reg [7:0] output_signal
);
reg [31:0] counter;
initial begin
output_signal = 0;
end
always#(negedge resetn) begin
counter = 0;
end
always#(posedge clk) begin
if (counter == num_to_count) begin
counter = 0;
if (output_signal == 0) begin
output_signal = 8'hff;
end
else begin
output_signal = 8'h00;
end
end
else begin
counter = counter + 1;
end
end
assign output_signal = internal_output_buffer;
endmodule
And the code is tested by
`timescale 1ns / 1ps
module testcounter_testbench(
);
reg clk;
reg resetn;
reg [31:0] num_to_count;
wire [7:0] output_signal;
initial begin
clk = 0;
forever #1 clk = ~clk;
end
initial begin
num_to_count = 20;
end
initial begin
#7 resetn = 1;
#35 resetn = 0;
end
testcounter A1(.clk(clk),.resetn(resetn),.num_to_count(num_to_count),.output_signal(output_signal));
endmodule
Behavioral simulation looks as I expected
But the timing simulation explodes
And for good measure: the actual probed execution blows up and looks like
Any tips would be appreciated. Thanks all.
The difference between the timing and functional simulations is that a timing simulation models the actual delay of logic gates while the functional simulation just checks if values are correct.
For e.g. if you have a simple combinational adder with two inputs a and b, and output c. A functional simulation will tell you that c=a+b. and c will change in the exact microsecond that a or b changes.
However, a timing simulation for the same circuit will only show you the result (a+b) on c after some time t, where t is the delay of the adder.
What is your platform? If you are using an FPGA it is very difficult to hit 500 MHz. Your clock statement:
forever #1 clk = ~clk;
shows that you toggle the clock every 1ns, meaning that your period is 2ns and your frequency is 500MHz.
The combinational delay through FPGA resources such as lookup tables, multiplexers and wire segments is probably more than 2ns. So your circuit violates timing constraints and gives wrong behaviour.
The first thing I would try is to use a much lower clock frequency, for example 100 MHz and test the circuit again. I expect it to produce the correct results.
forever #5 clk = ~clk;
Then to know the maximum safe frequency you can run at, look at your compilation reports in your design tools by running timing analysis. It is available in any FPGA CAD tool.
Your code seems working fine using Xilinx Vivado 14.2 but there is only one error which is the following line
assign output_signal = internal_output_buffer;
You can't assign registers by using "assign" and also "internal_output_buffer" is not defined.
I also personally recommend to set all registers to some values at initial. Your variables "resetn" and "counter" are not assigned initially. Basicly change your code like this for example
reg [31:0] counter = 32'b0;
Here is my result with your code:
Your verilog code in the testcounter looks broken: (a) you're having multiple drivers, and (b) like #StrayPointer notices, you're using blocking assignments for assigning Register (Flip-Flop) values.
I'm guessing your intent was the following, which could fix a lot of simulation mismatches:
module testcounter
(
input wire clk,
input wire resetn,
input wire [31:0] num_to_count,
output reg [7:0] output_signal
);
reg [31:0] counter;
always#(posedge clk or negedge resetn) begin
if (!resetn) begin
counter <= 0;
end else begin
if (counter == num_to_count) begin
counter <= 0;
end else begin
counter <= counter + 1;
end
end
end
assign output_signal = (counter == num_to_count) ? 8'hff : 8'h00;
endmodule

Resources