im unable to write output to text file in verilog .Please check what it is wrong - verilog

module fir_tb;
// Inputs
reg clk;
reg reset;
reg [7:0] inp;
reg [15:0]rom[1:8001];
reg [15:0]addr=0;
// Outputs
wire [7:0] outp;
// Instantiate the Unit Under Test (UUT)
fir uut (
.clk(clk),
.reset(reset),
.inp(inp),
.outp(outp)
);
initial
begin
$readmemb("file_out_flute.txt",rom);
reset=0;
inp ='b0;
#60;
//$display("rom size is ",rom);
end
always #(posedge clk)begin
inp = rom[addr]>>1;
addr = addr + 1;
if (addr==8000) ;//$finish;
end
initial
begin
clk=1'b1;
forever #10 clk=~clk;
end
integer f;
initial begin
f = $fopen("filter_output.txt","w");
end
always #(posedge clk)
begin
$fwrite(f,"%b\n",outp);
$fclose(f);
end
endmodule

$fclose() closes the file; further writes will be usually be ignored. $fclose() is often on of the last operations you you want to call in an simulator; often just before a $finish statement.
integer f;
initial begin
f = $fopen("filter_output.txt","w");
#100; // <== simulation run time
$fclose(f);
$finish; // <== end simulation
end
always #(posedge clk)
begin
$fwrite(f,"%b\n",outp);
end

Related

incrementing mod counter every n clock cycle

This is the verilog code for mod 64 counter, incrementing every clock cycle
module modulus64counter
#(parameter N=64,
parameter WIDTH=5)
(input clk,
input rstn,
output reg[WIDTH-1:0] out);
integer i;
always #(posedge clk) begin
if(!rstn) begin
out<=0;
end
else begin
if(out==N-1)
out<=0;
else
out<= out+1;
end
end
endmodule
and the test bench is
module modulus64countertb;
// Inputs
reg clk;
reg rstn;
// Outputs
wire [4:0] out;
// Instantiate the Unit Under Test (UUT)
modulus64counter uut (
.clk(clk),
.rstn(rstn),
.out(out)
);
always #10 clk = ~clk;
initial begin
// Initialize Inputs
clk = 1;
rstn = 0;
$monitor ("T=%0t rstn=%0b out=0X%h", $time,rstn,out);
repeat(2) #(posedge clk);
rstn <=1;
repeat(50) #(posedge clk);
$finish;
end
endmodule
Now if i want to increment the value of out every "n" clock cycle instead of consecutive clock cycle , how can i modify the program
Kindly help
Updated 20220131
Updated the code to produce output after every 2 clock cycles. Similarly, if you wish to delay for even more clock cycle, the simplest way is to continuously flopping it.
For a better implementation, you can try out a shift register.
module modulus64counter #(
parameter N=64,
parameter WIDTH=8,
parameter DELAY_CYCLE=2
)(
input clk,
input rstn,
output reg[WIDTH-1:0] out,
output reg[WIDTH-1:0] actual_out
);
integer i;
reg [WIDTH-1:0] cntr;
reg [WIDTH-1:0] dly1clk;
always #(posedge clk) begin
if(!rstn) begin
out <= 0;
dly1clk <= 0;
end else if(out == DELAY_CYCLE-1) begin
out <= 0;
dly1clk <= dly1clk + 1;
end else begin
out <= out + 1;
end
end
always #(posedge clk) begin
if(!rstn) begin
actual_out <= 0;
end else begin
actual_out <= dly1clk;
end
end
endmodule
The code below should work for you. You can always swap the out and actual_out if you insist on using out as the final counting variable.
Also, removing the out on the monitor line in the testbench will only print the value when it reaches mod n. I kept both out and actual_out on testbench's monitor to ease debugging purpose.
Verilog code
module modulus64counter #(
parameter N=64,
parameter WIDTH=8
)(
input clk,
input rstn,
output reg[WIDTH-1:0] out,
output reg[WIDTH-1:0] actual_out
);
integer i;
reg [WIDTH-1:0] cntr;
always #(posedge clk) begin
if(!rstn) begin
out <= 0;
actual_out <= 0;
end else if(out == N-1) begin
out <= 0;
actual_out <= actual_out + 1;
end else begin
out <= out + 1;
end
end
endmodule
Testbench
module modulus64countertb;
// Inputs
reg clk;
reg rstn;
// Outputs
wire [7:0] out;
wire [7:0] actual_out;
// Instantiate the Unit Under Test (UUT)
modulus64counter uut (
.clk(clk),
.rstn(rstn),
.out(out),
.actual_out(actual_out)
);
always #10 clk = ~clk;
initial begin
// Initialize Inputs
clk = 1;
rstn = 0;
$monitor ("T=%0t rstn=%0b out=%d actual_out=%d", $time,rstn,out,actual_out);
repeat(2) #(posedge clk);
rstn <=1;
repeat(200) #(posedge clk);
$finish;
end
endmodule
Output result simulated using edaplayground:

Verilog simple register testbench

I want to infer a simple flip flop using verilog. Here is the code.
module tb_simpleRegister();
reg clk;
reg a;
wire b;
simpleRegister dut
(
.clk(clk),
.a(a),
.b(b),
.c(c)
);
initial begin
clk=1;
a=0;
#10
a=1;
#10
a=0;
end
always #5 clk = ~clk;
endmodule
module simpleRegister(
input clk,
input a,
output reg b,
output reg c
);
always #(posedge clk) begin
b <= a;
c <= b;
end
endmodule
And here is the result when I run it. The b output of dut does not behave like a flip flop. However output c does. Any comments on why is this happening?
I would rewrite the test bench as follows:
initial begin
#(posedge clk);
a<=0;
#(posedge clk);
a<=1;
#(posedge clk);
a<=0;
end
//Clock in separate process
initial begin
clk=1;
forever begin
#5 clk = ~clk;
end
end
The non-blocking assignment will ensure the value of a is changed just after the clock edge giving the testbench a full cycle setup.

test bench for writing verilog output to a text file

i am unable to get correct output in a text file however simulation in modelsim is quite ok.. but while writing it to text file im getting XX for every input. may be there is some syntax error or some other. if any can help plz write down test bench for writing dout (output )of a flipflop (as an example) with every dout(output) showing in a new line in a text file.
Code:
module LFSR( clk,reset,out);
parameter width =4;
input clk,reset;
output [width-1:0] out ;
reg [width-1:0] lfsr;
integer r;
wire feedback = lfsr[width-1]^lfsr[width-2];
always #(posedge clk)
if (reset)
begin
lfsr <= 4'b1000;
end
else
begin
lfsr[0] <= feedback;
for(r=1;r<width;r=r+1)
lfsr[r]<=lfsr[r-1];
end
assign out=lfsr;
endmodule
Testbench:
module aaatest();
parameter width =4;
reg clk,reset;
wire [width-1:0] out;
reg [width-1:0] lfsr[13:0];
integer f,i;
initial
begin
f = $fopen("output.txt","w");
end
LFSR patt (clk,reset,out);
always #5 clk=~clk;
initial begin
clk=1; reset=1;
#10 reset=0;
# 140 $stop;
end
initial
begin
clk=1;
for (i = 0; i<14; i=i+1)
#(posedge clk)
lfsr[i]<= out;
end
initial begin
for (i = 0; i<14; i=i+1)
$fwrite(f,"%b\n",lfsr[i]);
end
initial begin
$display("clk out");
$monitor("%b,%b", clk, out);
end
initial
begin
$fclose(f);
end
endmodule
I would like you to think about these sections of code:
initial begin
f = $fopen("output.txt","w");
end
initial begin
for (i = 0; i<14; i=i+1)
$fwrite(f,"%b\n",lfsr[i]);
end
initial begin
$fclose(f);
end
When describing hardware we have a massively parallel simulation. All initials are meant to start at the same time, time 0.
If this works at all, as there is no guarantee that the file will be opened before you write to it, you are writing the file at time zero before you have even reset the logic your simulating.
Something like below might be more appropriate:
initial begin
f = $fopen("output.txt","w");
#(negedge reset); //Wait for reset to be released
#(posedge clk); //Wait for fisrt clock out of reset
for (i = 0; i<14; i=i+1) begin
$fwrite(f,"%b\n",lfsr[i]);
end
$fclose(f);
end
To follow up on Gregs suggestions the reset being released too early consider something similar to:
initial begin
clk=0; reset=1; //Clock low at time zero
#(posedge clk);
#(posedge clk);
reset=0;
# 140 $stop;
end
Which keep reset asserted for 2 clock rising edges.
Update with working example
There are a few odd things happening, you call $stop (Not $finish) after #140 but also try to loop 14 times, the $stop means only 4 loops are executed.
Your test program is made up of 2 initial begins working in parallel rather than one program that is sequentially executed. You had no delay in writing out your text file and you wrote the buffered version of the lfsr rather than the lfsr output directly.
The following example simulates correctly and writes the text file your looking for:
module aaatest();
parameter width =4;
reg clk,reset;
wire [width-1:0] out;
reg [width-1:0] lfsr[13:0];
integer f,i;
LFSR patt (clk,reset,out);
always #5 clk=~clk;
//Clock and reset release
initial begin
clk=0; reset=1; //Clock low at time zero
#(posedge clk);
#(posedge clk);
reset=0;
end
initial begin
f = $fopen("output.txt","w");
#(negedge reset); //Wait for reset to be released
#(posedge clk); //Wait for fisrt clock out of reset
for (i = 0; i<14; i=i+1) begin
#(posedge clk);
lfsr[i] <= out;
$display("LFSR %b", out);
$fwrite(f,"%b\n", out);
end
$fclose(f);
$finish;
end
endmodule

Connecting a module output to a register

I have tried connecting a module output to a register, as follows:
module test
(
input rst_n,
input clk,
output reg [7:0] count
);
always #(posedge clk or negedge rst_n) begin
if(!rst_n) begin
count <= 7'h0;
end else begin
if(count == 8) begin
count <= count;
end else begin
count <= count + 1'b1;
end
end
end
endmodule
module test_tb;
reg clk;
reg rst_n;
reg [7:0] counter;
initial begin
clk = 1'b0;
rst_n = 1'b0;
# 10;
rst_n = 1'b1;
end
always begin
#20 clk <= ~clk;
end
test test1 (
.rst_n(rst_n),
.clk(clk),
.count(counter) /* This is the problematic line! */
);
endmodule
I got the error "Illegal output or inout port connection for "port 'count'" in ModelSim. Even though the error matches my code, I do not understand why, fundamentally, I cannot connect a module output to a register.
Why can I not connect a module output to a register in Verilog?
You can only assign a value to a reg within a procedural always block. You can not drive a reg from a module instance. That would be a continuous assisgnment.
Use a wire inside test_tb.

Simulation output is all zeroes

My code for the design block and the testbench compiles; however, when I simulate, I'm not getting the correct output. Can anyone tell me where I'm going wrong in my code?
Here is the code for testbench:
module testbench;
reg [511:0]FROM_LS;
reg CLK;
reg [63:0]TO_IF_ID;
initial
begin
CLK= 0;
TO_IF_ID[63:0]=63'b0;
FROM_LS[511:480]= 32'b00011_00000_00100_01100_11100_10111_01;
FROM_LS[479:448]=32'b00_11000_00100_01111_11111_00011_10000;
end
always
begin
#10 CLK= ~ CLK;
//FROM_LS[511:448]= ~ FROM_LS[511:448];
$display("FROM_LS= %b", FROM_LS);
$display("TO_IF_ID= %b", TO_IF_ID);
end
endmodule
and here is the code for the design block:
module inst_line_buffer(input wire [511:0]from_LS,
input wire clk,
output reg [63:0]to_if_id);
parameter mem_size=16;
integer k;
reg [31:0] ilb[0:mem_size-1];
initial
begin
for (k = 0; k < mem_size ; k = k + 1)
begin
ilb[k] = 32'b00;
//$display ("ilb= %b",ilb[k]);
end
end
always #(posedge clk)
begin
ilb[0]= from_LS[511:480];
ilb[1]= from_LS[479:448];
ilb[2]= from_LS[447:416];
ilb[3]= from_LS[415:384];
ilb[4]= from_LS[383:352];
ilb[5]= from_LS[351:320];
ilb[6]= from_LS[319:288];
ilb[7]= from_LS[287:256];
ilb[8]= from_LS[255:224];
ilb[9]= from_LS[223:192];
ilb[10]= from_LS[191:160];
ilb[11]= from_LS[159:128];
ilb[12]= from_LS[127:96];
ilb[13]= from_LS[95:64];
ilb[14]= from_LS[63:32];
ilb[15]= from_LS[31:00];
to_if_id [63:32]= ilb[0];
to_if_id [31:0]= ilb[1];
$display("ilb= %b", ilb[1]);
end
endmodule
I'm expecting that the value of TO_IF_ID should be 0001100000001000110011100101110100110000010001111111110001110000, but I'm getting all zeros.
When you run a simulation on your testbench module, TO_IF_ID is always 0 because you only assigned a value to it once at time 0 in your initial block. If you want the value to change, it needs to be driven somehow.
As Andy pointed out in a comment, you probably meant to instantiate the inst_line_buffer module in your testbench. Verilog will not do this magically for you. But then, you should declare TO_IF_ID as a wire instead of a reg and remove it from the initial block.
module testbench;
reg [511:0]FROM_LS;
reg CLK;
wire [63:0]TO_IF_ID;
inst_line_buffer inst_line_buffer (
.from_LS (FROM_LS),
.clk (CLK),
.to_if_id (TO_IF_ID)
);
initial begin
CLK= 0;
FROM_LS[511:480]= 32'b00011_00000_00100_01100_11100_10111_01;
FROM_LS[479:448]=32'b00_11000_00100_01111_11111_00011_10000;
#500 $finish;
end
always
begin
#10 CLK= ~ CLK;
//FROM_LS[511:448]= ~ FROM_LS[511:448];
$display("FROM_LS= %b", FROM_LS);
$display("TO_IF_ID= %b", TO_IF_ID);
end
endmodule

Resources