I am making an average that resets every period on EDA Playground. No errors are displayed on the simulator, Icarus Verilog, but the outputs are continually unassigned (which, of course, is not what I intended).
Here is my design:
module shift
(
input [13:0] in,
input clock,
output [31:0] sum,
output [14:0] avg);
integer reset;
reg [31:0] sum_reg;
reg [14:0] avg_reg;
always #(posedge clock)
if (reset == 8) begin
avg_reg = sum_reg >> 3;
sum_reg = 0;
reset = 0;
end else begin
sum_reg = sum_reg + in;
reset = reset + 1;
end
assign sum = sum_reg;
assign avg = avg_reg;
endmodule
Here is my testbench:
module shift_tb;
reg [13:0] in;
reg clock = 1'b0;
reg reset;
wire [31:0] sum;
wire [14:0] avg;
shift s
(
.in(in),
.clock(clock),
.sum(sum),
.avg(avg));
integer f;
initial begin
for (f = 9000; f < 10000; f = f + 10) begin
in = f;
$display("in = %d, sum = %d, avg = %d", in, sum, avg);
end
end
always
#1 clock = ~clock;
endmodule
What is wrong with this code?
One problem is reset is an integer that is initially x and stays that way. You need a way of initializing it to 0.
Another problem is your testbench for-loop has no delay. You should add #(nedgedge clk)
Related
I'm writing an ALU for a processor I'm designing (first RTL project) and I'm getting a high impedance output on ALU_out when I run my testbench, even though the flags do get set and are output correctly.
module alu(
input clk,
input reset,
input [7:0] A, B,
input [3:0] Op_Sel,
output [7:0] ALU_out,
output C, V, N, Z
);
reg [8:0] Result = 0;
reg [8:0] cn_temp = 0;
reg [7:0] v_temp = 0;
reg carry = 0;
reg overflow = 0;
reg negative = 0;
reg zero = 0;
assign ALU_Out = Result[7:0];
assign C = carry;
assign V = overflow;
assign N = negative;
assign Z = zero;
always #*
begin
if (reset)
begin
Result = 0;
cn_temp = 0;
v_temp = 0;
carry = 0;
overflow = 0;
negative = 0;
zero = 0;
end
end
always #(posedge clk)
begin
case(Op_Sel)
4'b0000: // Addition
begin
Result = A + B;
negative = Result[7];
zero = (Result[7:0] == 8'b00000000);
carry = Result[8];
v_temp = A[6:0] + B[6:0];
overflow = v_temp[7] ^ carry;
end
.
.
//The rest of the instructions
.
.
.
endcase
end
endmodule
//My testbench
module alu_testbench();
reg clk;
reg reset;
reg [7:0] A;
reg [7:0] B;
reg [3:0] Op_Sel;
wire [7:0] ALU_out;
wire C, V, N, Z;
always begin
#1
clk = ~clk;
end
initial begin
clk = 0;
reset = 0;
#1
reset = 1;
#1
reset = 0;
end
initial begin
#10
A=2;
B=3;
Op_Sel = 4'b0000;
#10
A=1;
end
alu alu (
.clk(clk),
.A(A),
.B(B),
.Op_Sel(Op_Sel),
.ALU_out(ALU_out),
.C(C),
.V(V),
.N(N),
.Z(Z));
endmodule
I believe I connected up the module to the testbench (through a wire), so why am I getting high impedance on ALU_out?
This was a tricky typo. You mistakenly used an upper-case "O" in the ALU_Out signal name. Since Verilog is case-sensitive, this is a different signal from ALU_out. It is not mandatory to declare all signals in Verilog. However, you can use the following compiler directive in your code to help catch this type of common problem:
`default_nettype none
Your simulator should generate an error.
To fix it, change:
assign ALU_Out = Result[7:0];
to:
assign ALU_out = Result[7:0];
My simulators also generated a warning message because you didn't drive the reset input of alu. Here is the fix:
alu alu (
.clk(clk),
.reset(reset), /// <------ add this
.A(A),
.B(B),
.Op_Sel(Op_Sel),
.ALU_out(ALU_out),
.C(C),
.V(V),
.N(N),
.Z(Z));
I am tasked with building an ALU. However, I must not understand how the self-checking testbench with file.tv should run. I have run other simple testbenches just fine. I am sure there is a problem in the way that my testbench module is written,
code compiles (using quartus)
made a text file with binary and turned it into a "test.tv" file
opened modelsim and added file
when I run it, is has an issue where it just keeps running blue errors..
Here is my code:
module ALU(input [31:0] a,b,
input [2:0] f,
output reg [31:0] y ,
output reg zero);
always #(*) begin
case(f)
3'b000: y = a & b;
3'b001: y = a | b;
3'b010: y = a + b;
3'b011: y = 32'b0;
3'b100: y = a & ~b;
3'b101: y = a | ~b;
3'b110: y = a - b;
3'b111: y = a < b;
default: y = 32'b0;
endcase
if(y==0)
zero=1'b1;
else
zero=1'b0;
end
endmodule
//**********************
module ALUtest();
reg clk;
reg [31:0] a, b, yexpected;
wire [31:0] y;
reg [2:0] f;
reg zeroexpected;
wire zero;
reg [31:0] vectornum, errors;
reg [100:0] testvectors[10000:0];
ALU dut(a,b,f,y,zero);
always
begin
clk = 1; #5; clk = 0; #5;
end
initial
begin
$readmemb("test.tv", testvectors);
vectornum = 0; errors = 0;
end
always#(posedge clk)
begin
#1; {a,b,f, yexpected,zeroexpected} = testvectors[vectornum];
end
always #(negedge clk)
begin
if (y !== yexpected) begin
$display("Error: inputs = %b", {a,b,f});
$display(" outputs = %b (%b expected)", y, yexpected);
errors = errors + 1;
end
vectornum = vectornum + 1;
if (testvectors[vectornum] === 4'bx) begin
$display("%d tests completed with %d errors", vectornum, errors);
$stop;
end
end
endmodule
//*************************************
CONTINUOUS ERROR THAT KEEPS RUNNING UNTIL I STOP IT:
Error: inputs = xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx
outputs = 00000000000000000000000000000000(xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx expected)
Error: inputs = xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx
outputs = 00000000000000000000000000000000(xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx expected)
Error: inputs = xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx
outputs = 00000000000000000000000000000000(xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx expected)
Error: inputs = xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx
outputs = 00000000000000000000000000000000(xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx expected)
This is what my "test.tv" file looks like in binary
00000000000000000000000000000000_00000000000000000000000000000000_010_00000000000000000000000000000000_1
00000000000000000000000000000000_11111111111111111111111111111111_010_11111111111111111111111111111111_0
00000000000000000000000000000000_01010101010101010101010101010101_010_01010101010101010101010101010101_0
I know this might seem stupid and simple, but I am really trying to learn this and obviously do not understand something. Can someone please help? Thanks in advance!
testvectors is declared as:
reg [100:0] testvectors[10000:0];
100:0 means testvectors is 101 bits wide, but you are comparing it to a 4-bit value (4'bx is the same as 4'bxxxx).
Change:
if (testvectors[vectornum] === 4'bx) begin
to:
if (testvectors[vectornum] === {101{1'bx}}) begin
This stops for me using your 3-line test.tv file.
Note that the LHS (32*3+3+1) is 100 bits, but the RHS is 101 bits in the following expression:
{a,b,f, yexpected,zeroexpected} = testvectors[vectornum]
Also, you only specify 100 bits in the test.tv file. Perhaps you should declare testvectors as 100 bits wide:
reg [99:0] testvectors[10000:0];
I'm trying to calculate times in which input x with 8 bits is repeated on every posedge clk.
I'm thinking about creating 256b counter to each value of these 8 bit to compare x with it, but I get error when I'm trying to compare each value of these counter with each input x on rising edge.
module counter_initial(x);
input[7:0] x;
//output [7:0] y;
//reg [7:0] y;
//reg [7:0] freq_tst,gap_tst;
reg [7:0] freq_num;
endmodule
module counter_256(clk,x,out);
input [7:0] x;
input clk;
// input [7:0] in;
output [7:0] out;
reg [7:0] out;
//reg [7:0] freq_tst,gap_tst;
reg [7:0] k=0;
// reg [] t=0;
genvar i;
generate
for (i=0;i<256;i=i+1)
begin
counter_initial m(i);
//t=m(i);
end
endgenerate
always #(posedge clk)
begin
if(k<256) begin
if (x==m[i])
//counter_initial[k]==x
begin
freq_num=freq_num+1;
end
//else
//begin gap_tst=gap_tst+1; end
k=k+1;
end
end
endmodule
You don't need an additional module to count. You can use a memory array. Example:
input [WIDTH-1:0] x;
reg [7:0] mem [WIDTH-1:0];
integer i;
always #(posedge clk) begin
if (reset) begin
for (i = 0; i < 2**WIDTH; i = i+1) begin
mem[i] <= 8'b0;
end
end
else if (mem[x] < 8'd255) begin // cap counting and prevent overflow
mem[x] <= mem[x] + 1'b1;
end
end
If you want to use separate modules then pass the clock to it. Example:
module counter (output reg [7:0] count, input increment, clk, reset);
always #(posedge clk) begin
if (reset) begin
count <= 8'b0;
end
else if (count < 8'd255) begin // cap counting and prevent overflow
count <= count + increment;
end
end
endmodule
module my_device ( /* ..., */ input [7:0] x, input clk, reset );
/* ... */
genvar i;
generate
for (i=0; i<256; i=i+1) begin
counter icount( .count(/* ... */), .increment(x==i), .* );
end
endgenerate
/* ... */
endmdoule
Reminder 8'd255 + 1 is 8'd0 because the MSB of 8'd256 is out of range. I capped the counters so the will not overflow and roll back to zero.
I've got this code which determines and integer square root of a 32 bit number.
output = floor(sqrt(input))
I want to get a fixed point result such as this {8 bit integer ,8 bit fractionary} but on an 8 bit input. So wire[7:0] input instead of [31:0].
My issue is that I don't know how to modify the algorithm to determine what I previously stated. Below you will find the code.
module sqrt32(clk, rdy, reset, x, .y(acc));
input clk;
output rdy;
input reset;
input [31:0] x;
output [15:0] acc;
// acc holds the accumulated result, and acc2 is the accumulated
// square of the accumulated result.
reg [15:0] acc;
reg [31:0] acc2;
// Keep track of which bit I'm working on.
reg [4:0] bitl;
wire [15:0] bit = 1 << bitl;
wire [31:0] bit2 = 1 << (bitl << 1);
// The output is ready when the bitl counter underflows.
wire rdy = bitl[4];
// guess holds the potential next values for acc, and guess2 holds
// the square of that guess. The guess2 calculation is a little bit
// subtle. The idea is that:
//
// guess2 = (acc + bit) * (acc + bit)
// = (acc * acc) + 2*acc*bit + bit*bit
// = acc2 + 2*acc*bit + bit2
// = acc2 + 2 * (acc<<bitl) + bit
//
// This works out using shifts because bit and bit2 are known to
// have only a single bit in them.
wire [15:0] guess = acc | bit;
wire [31:0] guess2 = acc2 + bit2 + ((acc << bitl) << 1);
task clear;
begin
acc = 0;
acc2 = 0;
bitl = 15;
end
endtask
initial clear;
always #(reset or posedge clk)
if (reset)
clear;
else begin
if (guess2 <= x) begin
acc <= guess;
acc2 <= guess2;
end
bitl <= bitl - 1;
end
endmodule
module main;
reg clk, reset;
reg [31:0] value;
wire [15:0] result;
wire rdy;
sqrt32 root(.clk(clk), .rdy(rdy), .reset(reset), .x(value), .y(result));
always #5 clk = ~clk;
always #(posedge rdy) begin
$display("sqrt(%d) --> %d", value, result);
$finish;
end
initial begin
clk = 0;
reset = 1;
$monitor($time,,"%m.acc = %b", root.acc);
#100 value = 63;
reset = 0;
end
endmodule /* main */
Improved version:
I've managed to get the algorithm to partially work, following Matt's advice.
There is still this issue:
for input = 70 the result should be output = 8.366
I get
for input = 70 the result is output = 8.5
Is it possible to get the right fractionary part?
I am not getting the right fractionary part and I don't know why or if it is possible: here is the improved algorithm:
module sqrt32(clk, rdy, reset, x, .y(acc));
input clk;
output rdy;
input reset;
input [7:0] x;
output [15:0] acc;
reg [15:0] xholder;
// acc holds the accumulated result, and acc2 is the accumulated
// square of the accumulated result.
reg [15:0] acc;
reg [15:0] acc2;
// Keep track of which bit I'm working on.
reg [4:0] bitl;
wire [15:0] bit = 1 << bitl;
wire [15:0] bit2 = 1 << (bitl << 1);
// The output is ready when the bitl counter underflows.
wire rdy = bitl[4];
// guess holds the potential next values for acc, and guess2 holds
// the square of that guess. The guess2 calculation is a little bit
// subtle. The idea is that:
//
// guess2 = (acc + bit) * (acc + bit)
// = (acc * acc) + 2*acc*bit + bit*bit
// = acc2 + 2*acc*bit + bit2
// = acc2 + 2 * (acc<<bitl) + bit
//
// This works out using shifts because bit and bit2 are known to
// have only a single bit in them.
wire [15:0] guess = acc | bit;
wire [15:0] guess2 = acc2 + bit2 + ((acc << bitl) << 1);
task clear;
begin
acc = 0;
acc2 = 0;
//bitl = 15;
bitl = 7;
assign xholder = x << 8;
end
endtask
initial clear;
always #(reset or posedge clk)
if (reset)
clear;
else begin
$display("xholder is %b", xholder);
if (guess2 <= xholder) begin
acc <= guess;
acc2 <= guess2;
end
bitl <= bitl - 1;
end
endmodule
module sqrtest;
reg clk, reset;
reg [7:0] value;
wire [15:0] result;
wire rdy;
sqrt32 root(.clk(clk), .rdy(rdy), .reset(reset), .x(value), .y(result));
always #5 clk = ~clk;
always #(posedge rdy) begin
$display("sqrt(%d) --> %d,%d", value, result[7:4], result[3:0]);
$finish;
end
initial begin
clk = 0;
reset = 1;
$monitor($time,"%m.acc = %b", root.acc);
#100 value = 70;
reset = 0;
end
endmodule /* main */
Just ran the simulation of the code with some values and came up with a simple solution.
Note: The code give in the question may not compile successfully as bit is a Verilog reserved word. Also, wire instantiations with assignments on the same line (such as wire [31:0] bit2 = 1 << (bitl << 1);) should really be split up into 2 separate lines (wire [15:0] bit2; assign bit2 = 1 << (bitl << 1);).
Anyways, your input that has 8 bits to represent the integer part and 8 bits to represent the fractional part is really the same as a 16 bit number, the only difference being that it is multiplied by 2^8. So, one possible solution would be to feed your '16' bit integer into the input of the sqrt32 module.
By doing this, you are really solving sqrt(X * 2^8). The output of the function would be sqrt(X) * 2^4. The answer would be the 8 LSBs of the output, where [7:4] is the integer part and [3:0] is the fractional part.
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.