I am having a problem with accumulator code in Verilog. I simply generate pseudo random signals. Then, change the random signal level -1 to 1 from 0 to 1 so it is signed. Later, obtained 'acmin'. In this point, I need to accumulate 'acmin' signals. Debugger doesn't give me any error but I can't see any result. Can you help me to find problem?
module lfsr(clk, rst, seed, load, R, acc);
input [3:0] R;
input [26:0] seed;
input load;
input rst;
input clk;
reg [3:0]q;
wire [3:0] S;
wire overflow;
wire [3:0] acmin ;
wire [26:0] state_out;
wire [26:0] state_in;
output [7:0] acc;
reg [7:0] acc;
flipflop F[26:0] (state_out, clk, rst, state_in);
mux M1[26:0] (state_in, load, seed, {state_out[25],state_out[24],state_out[23],state_out[22],state_out[21],state_out[20],state_out[19],state_out[18],state_out[17],state_out[16],state_out[15],state_out[14],state_out[13],state_out[12],state_out[11],state_out[10],state_out[9],state_out[8],state_out[7],state_out[6],state_out[5],state_out[4],state_out[3],state_out[2], state_out[1], state_out[0], nextbit});
xor G1(nextbit, state_out[5], state_out[2], state_out[1], state_out[26]);
// Pseudorandom generator
always#(clk) begin
if (state_out[26]==0)
q=4'b1111; // 0 to -1
else
q=4'b0001; //1 to 1
end
assign acmin= R*q; // accumulator input
always#(clk) begin
if(rst)
acc = 8'b00000000;
else
acc = acc + acmin;
end
endmodule
Test bench;
module lfsrtst;
reg [3:0] R;
reg clk;
reg rst;
reg [26:0] seed;
reg load;
wire [7:0] acc;
lfsr lfsr(clk, rst, seed, load, R, acc);
initial
begin
clk = 0;
load = 0;
seed = 0;
rst = 0;
R=0;
#10 rst = 1;
#10 rst = 0;
#50 R = 4'b0111;
#50 R = 4'b0010;
#100 R = 4'b1111;
#50 R = 4'b1011;
#150 R = 4'b1101;
#50 R = 4'b1000;
end
// drive clock
always
#50 clk = !clk;
// program lfsr
initial begin
#100 seed = 27'b000000110000011000001000001;
load = 1;
#100 load = 0;
#1400 $stop;
end
endmodule
I have 'acmin' as I desired. I want to accumulate 'acmin' variable every time the edge of the clock rises and falls. However, 'acc' results nothing so what is the error?
Thanks.
The main problem that I see is that you have a synchronous reset:
always#(clk) begin
if(rst)
acc = 8'b00000000;
else
acc = acc + acmin;
end
But in your testbench you only strobe the reset for #20
#10 rst = 1;
#10 rst = 0;
This is too short, and the reset is never detected.
If you make these delays longer, then the problem should be fixed.
#100 rst = 1;
#100 rst = 0;
// then later
// program lfsr
initial begin
# also delay this so that it comes after the reset
#300 seed = 27'b000000110000011000001000001;
Alternatively you could make the reset asynchronous.
always#(clk or posedge rst) begin
I would try imply a flip-flop here by adding the posedge and converting to '<='
always#(posedge clk) begin
if(rst)
acc <= 8'b00000000;
else
acc <= acc + acmin;
end
Related
I'm trying to write a counter that simply tracks the positive edge of a clock and increments a variable when it does. The caveat is this circuit must switch between different clock sources. The counter and clock multiplexer function as intended for the default clock in simulation, but the counter does not seem to be seeing the positive edges of the second clock signal. I've tested the multiplexer on its own, and it passes the clock signal through correctly. Any thoughts?
The top module:
module hw1_top(reset, updown, inp, clkSwitch, Clk100MHz, testClock2, out);
input reset, updown, Clk100MHz, testClock2;
input [15:0] inp;
input [3:0] clkSwitch;
output [15:0] out;
wire muxtoclk;
ClockMux mux(
.c1(Clk100MHz),
.c2(testClock2),
.switch(clkSwitch),
.cOut(muxtoclk)
);
UDCounter counter(
.RST(reset),
.UD(updown),
.INP(inp),
.CLK(muxtoclk),
.OUT(out)
);
endmodule
Counter:
module UDCounter(RST, UD, INP, CLK, OUT);
input RST, UD, CLK; //1 bit inputs
input [15:0] INP; //16 bit input
output reg [15:0] OUT; //16 bit output, must be reg for sequential
initial
OUT <= INP; //when we start, counter initializes to whatever the input is
always#(posedge CLK or posedge RST) //on every positive edge of the clock cycle, or if reset is triggered...
if(RST == 1'b1) //if reset is high, set counter back to the initial input
OUT <= INP;
else //if reset isn't triggered...
if(UD == 1'b0) //if up/down is in up position, count up
begin
OUT <= OUT + 1;
end
else //if in down, count down
begin
OUT <= OUT -1;
end
endmodule
Multiplexer:
module ClockMux(c1,c2,switch,cOut);switch,cOut);
input c1,c2;
input [3:0] switch;
output reg cOut;
always#(switch,c1,c2) //updates whenever the switch or clock changes
case(switch)
4'b0000: cOut <= c1;
4'b0001: cOut <= c2;
endcase
endmodule
Top level testbench and waveform:
module hw1_top_tb();
reg reset, updown, Clk100MHz, testClock2;
reg [15:0] inp;
wire [15:0] out;
reg [3:0] switchValue;
hw1_top topmod(
.reset(reset),
.updown(updown),
.inp(inp),
.clkSwitch(switchValue),
.Clk100MHz(Clk100MHz),
.out(out)
);
initial Clk100MHz = 0;
always #5 Clk100MHz = ~Clk100MHz;
initial testClock2 = 0;
always #3 testClock2 = ~testClock2;
initial begin
reset = 0; updown = 0; inp = 16'b0; switchValue = 4'b0000;
#10;
reset = 1; updown = 0; inp = 16'b0; switchValue = 4'b0000;
#10; //toggles the reset briefly to clear dc's
reset = 0; updown = 0; inp = 16'b0; switchValue = 4'b0000;
#40;
reset = 1; updown = 0; inp = 16'b0; switchValue = 4'b0001; //counter is not listening here
#10;
reset = 0; updown = 0; inp = 16'b0; switchValue = 4'b0001; //counter is not listening here
#23;
reset = 1; updown = 0; inp = 16'b0; switchValue = 4'b0000; //when we switch back, it's doing great
#13;
reset = 0; updown = 0; inp = 16'b0; switchValue = 4'b0000;
#23;
$finish;
end
endmodule
You never connected testClock2 in your instantiation topmod of hw1_top:
hw1_top topmod(
.reset(reset),
.updown(updown),
.inp(inp),
.clkSwitch(switchValue),
.Clk100MHz(Clk100MHz),
.testClock2(testClock2), // this is missing
.out(out)
);
I'm building a Single Cycle Processor for a class assignment in Verilog and I can't seem to get the correct output with my test bench. I've got everything wired correctly and it is producing zeros for the first half of my test bench like it should, but once I start putting data in, it stays at zero. So I know my reset and clock works, but somewhere in the write section, I am overlooking something. I could use a fresh set of eyes and any help is appreciated. TIA.
RegisterFile.v:
module registerfile(read1, read2, writeto, writedat, writeenable, out1, out2, clock, reset);
input [4:0] read1;
input [4:0] read2;
input [4:0] writeto;
input [31:0] writedat;
input writeenable, clock, reset;
output [31:0] out1, out2;
// 32 bit registers x 32
reg [31:0] RF[31:0];
reg [31:0] out1;
reg [31:0] out2;
integer i;
always #(posedge reset)
begin
for (i = 0; i < 32; i++)
RF[i] <= 0;
out1 <= 32'h00000000;
out2 <= 32'h00000000;
end
always #(posedge clock)
begin
if (writeenable)
RF[writeto] <= writedat;
out1 <= RF[read1];
out2 <= RF[read2];
end
endmodule
RegisterFile_tb.v:
module registerfile_tb ();
reg [4:0] read1;
reg [4:0] read2;
wire [31:0] out1;
wire [31:0] out2;
reg [4:0] writeto;
reg [31:0] writedat;
reg writeenable;
reg clock;
reg reset;
registerfile DUT(read1, read2, writeto, writedat, writeenable, out1, out2, clock, reset);
initial
begin
clock <= 1;
reset <= 1;
#21 reset <= 0;
#100;
read1 <= 5'b0;
read2 <= 5'b0;
writeto <= 5'b00101;
writedat <= 32'd0;
writeenable <= 1;
#100;
#21 read1 <= 5'b11010;
#21 read2 <= 5'b00101;
#21 read1 <= 5'b00001;
#21 writedat <= 32'd1; //
#21 read2 <= 5'b11111;
#21 read1 <= 5'b01010;
#21 read2 <= 5'b01110;
end
always #(read1 or read2)
#21 $display("| read1 = %d | read2 = %d | out1 = %d | out2 = %d |", read1, read2, out1, out2);
endmodule
Your clock is not toggling. There should be an always #10 clk = !clk; in your test bench (you may want a different delay).
Your display statement is a bit odd. Consider changing it to a monitor and move it near the top of the initial block.
FYI. Your code will not synthesis. To me synthesizable a register must be assigned by only one always block. You have separate blocks for the clock and reset. To have asynchronous reset use the structure below. For synchronous reset (required for most FPGAs) then omit the or posedge reset
always #(posedge clock or posedge reset)
begin
if (reset) begin
for (i = 0; i < 32; i++)
RF[i] <= 0;
out1 <= 32'h00000000;
out2 <= 32'h00000000;
end
else begin
if (writeenable)
RF[writeto] <= writedat;
out1 <= RF[read1];
out2 <= RF[read2];
end
end
I'm somewhat new to verilog. So this question might be very simple.
I'm trying to simulate an finite state machine using verilog.
Brief description:
There are three states: 0,1 & 2. By default, State is 0.
The state changes to 1 only if input is 01.
The state changes to 2 only if input is 10.
The state changes back to 0 only if input is 00.
The code is getting simulated successfully, but I.m getting no output. Please help me with the problem.
Code: (State.v)
module State(
input clk,
input reset,
input [3:0] in,
output [3:0] out,
output [3:0] state
);
wire clk,reset;
wire [3:0] in;
reg [3:0] out;
reg [3:0] state;
always #(posedge clk or posedge reset)
begin
if (reset == 1)
begin
state = 0;
end
else
begin
case (state)
0: if(in == 2'b01)
state = 1;
else
state = 0;
1: if(in == 2'b10)
state = 2;
else
state = 1;
2: if(in == 2'b00)
state = 0;
else
state = 2;
default: state = 0;
endcase
end
end
always #(*)
begin
case (state)
0: out = 2'b00;
1: out = 2'b01;
2: out = 2'b10;
default: out = 2'b00;
endcase
end
endmodule
Testbench: (StateTestBench.v)
module StateTestBench;
// Inputs
reg clk;
reg reset;
reg [3:0] in;
// Outputs
reg [3:0] out;
reg [3:0] state;
always
begin
#1 clk = !clk;
end
// Instantiate the Unit Under Test (UUT)
State uut (
.clk(clk),
.reset(reset),
.in(in),
.out(out),
.state(state)
);
initial begin
// Initialize Inputs
clk = 0;
reset = 0;
#1 reset = 1;
#10 reset = 0;
#5 in = 2'b00;
#10 in = 2'b01;
#10 in = 2'b10;
end
endmodule
I guess you simulate state.v instead of StateTestBench.v. Because your testbench has a bug! Outputs out and state MUST be wires.
I want to write an eight bit ALU. I have written this code but when I simulate it, the output has x value,why did it happen? and I have another problem that I do not know how can I show 8 bit parameter in Modelsim simulation while I have just two value 0 or 1?
module eightBitAlu(clk, a, b,si,ci, opcode,outp);
input clk;
input [7:0] a, b;
input [2:0] opcode;
input si;
input ci;
output reg [7:0] outp;
always #(posedge clk)
begin
case (opcode)
3'b000: outp <= a - b;
3'b000 : outp <= a + b;
3'b001 : outp =0;
3'b010 : outp <= a & b;
3'b011 : outp <= a | b;
3'b100 : outp <= ~a;
endcase
end
endmodule
and this is my test module
module test_8bitAlu();
reg clk=0,a=3,b=1,si=0,ci=0,opcode=1;
eightBitAlu alu(clk, a, b,si,ci, opcode,outp);
initial begin
#200 clk=1;
#200 opcode=0;
#200 opcode=2;
#200 opcode=3;
#200 opcode=4;
#200;
end
endmodule
a and b are only 1 bit wide leaving the top 7 bits of your input ports un-driven.
reg clk=0,a=3,b=1,si=0,ci=0,opcode=1;
is equivalent to :
reg clk = 0;
reg a = 3;
reg b = 1;
reg si = 0;
reg ci = 0;
reg opcode = 1;
What you need is:
reg clk = 0;
reg [7:0] a = 3;
reg [7:0] b = 1;
reg si = 0;
reg ci = 0;
reg [2:0] opcode = 1;
wire [7:0] outp;
Further improvemnets would be to include the width on the integer assignment ie:
reg clk = 1'd0;
reg [7:0] a = 8'd3;
b for binary, d for decimal, o for octal and h for hexadecimal in width'formatValue
Note
outp if not defined will be an implicit 1 bit wire.
Your clock in the testharness also only has 1 positive edge. You may prefer to define your clock as:
initial begin
clk = 1'b0;
forever begin
#100 clk = ~clk;
end
end
A complete version of the above is demonstrated at EDAplayground.
Our assignment is to build a rudimentary single-cycle CPU in Verilog, but I'm not getting even more fundamental modules of it correct. For instance, to test the Instruction Memory module, we've been given a text file "hw3Test.txt" with instructions in hex, and I'm trying to slurp that into the IM.
00221820
AC010000
8C240000
10210001
00001820
00411822
When I run a testbench, I see that the only instructions that get into memory are the second, third, and fourth lines. Here's the IM module:
module IM(addr, clk, inst);
input [31:0] addr;
input clk;
output reg [31:0] inst;
reg [31:0] mem [255:0];
initial begin
$readmemh("hw3Test.txt", mem);
end
always #( posedge clk) begin
inst=mem[addr[31:2]];
end
endmodule
And the testbench:
module imtest;
// Inputs
reg [31:0] addr;
reg clk;
// Outputs
wire [31:0] inst;
// Instantiate the Unit Under Test (UUT)
IM uut (
.addr(addr),
.clk(clk),
.inst(inst)
);
initial begin
// Initialize Inputs
addr = 0;
clk = 0;
// Wait 100 ns for global reset to finish
#100;
// Add stimulus here
clk = 0;
addr = 0;
#100;
forever begin
#20;
clk = ~clk;
addr = addr + 4;
end
end
endmodule
I'm also not sure I'm even getting the PC-to-IM module correct, because aside from the initialized values, everything but the rst and clk signals show no valid values. Can anyone point out where I'm going wrong?
module pc_im(
// Inputs
rst, clk, PCin,
// Outputs
inst, PCout
);
input clk, rst;
input [31:0] PCin;
output reg [31:0] inst;
output reg [31:0] PCout;
PC mypc (
.clk(clk),
.rst(rst),
.PCin(PCin),
.PCout(PCout)
);
IM myim(
.clk(clk),
.addr(PCout),
.inst(inst)
);
endmodule
Here's the PC.v module:
module PC(rst, clk, PCin, PCout);
input clk, rst;
input [31:0] PCin;
output reg [31:0] PCout;
always #(posedge clk) begin
if (rst) PCout <= 0;
else PCout <= PCin + 4;
end
endmodule
And finally, the testbench:
module pcimtest;
// Inputs
reg rst;
reg clk;
reg [31:0] PCin;
// Outputs
wire [31:0] inst;
wire [31:0] PCout;
// Instantiate the Unit Under Test (UUT)
pc_im uut (
.rst(rst),
.clk(clk),
.PCin(PCin),
// Outputs
.inst(inst),
.PCout(PCout)
);
initial begin
// Initialize Inputs
rst = 1;
clk = 0;
PCin = 0;
// Wait 100 ns for global reset to finish
#100;
rst = 0;
forever begin
#100;
clk <= ~clk;
PCin <= PCout;
end
// Add stimulus here
end
endmodule
Here are a few things that look suspect.
Problem 1
It is normally good to use non-blocking assignments in blocks intended to infer registers.
i.e. change
always #( posedge clk) begin
inst=mem[addr[31:2]];
end
to
always #( posedge clk) begin
inst<=mem[addr[31:2]];
end
Problem 2
You are changing signals twice per clock cycle, once on negative edge and once on positive edge.
Change:
forever begin
#20;
clk = ~clk;
addr = addr + 4;
end
to
forever begin
#20;
clk = 1;
#20;
clk = 0;
addr = addr + 4;
end
Problem 3
You are using synchronous resets but not supplying a clock during reset.
Consider the code
always #(posedge clk) begin
if (rst) PCout <= 0;
else PCout <= PCin + 4;
end
This block will only activate on positive clock edges. However, you make reset high while the clock is paused so no reset will happen.
Change
rst = 1;
clk = 0;
PCin = 0;
// Wait 100 ns for global reset to finish
#100;
to
rst = 1;
clk = 0;
PCin = 0;
#20
clk = 1;
#20
clk = 0;
// Wait 100 ns for global reset to finish
#100;