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));
Related
This question already has answers here:
How do I use flip flop output as input for reset signal
(1 answer)
Why is my counter out value producing StX?
(2 answers)
Closed 2 months ago.
Trying to make a Binary adder and Subtractor in Verilog Output keeps coming out as X I don't think it is the testbench I believe is something wrong with the wires for the output F. The Flip Flops and the Multiplexer should be correct but I have no way of knowing for sure I do not get any error messages when I run this
module Subtractor(A, B, Bin, Bout , Sub); //Variables for subtractor
// 1-bit full binary subtractor.
input A;//Input variable
input B;//Input variable
input Bin;//Input variable
output Bout;
output Sub;
assign Bout=((~A)&(B))|((~A)&(Bin))|((B)&(Bin));
assign Sub=(A^B^Bin);
endmodule
module Adder(A, B, Cin, Cout, Sum);
// 1- bit full binary adder
input A, B, Cin;
output Cout, Sum;
assign Cout = ((A)&(Cin))|((B)&(Cin))|((A)&(B));
assign Sum = (A^B^Cin);
endmodule
module CarryFLIPFLOP(CLK,RESET,D,Q);
//Flip flop for carry value
input CLK,RESET,D;
output reg Q;
always #(posedge CLK)
begin
if(RESET)
Q<=0;
else
Q<=D;
end
endmodule
module BorrowFLIPFLOP(CLK,RESET,D,Q);
// 1- bit full binary adder
input CLK,RESET,D;
output reg Q;
//reg Q;
always #(posedge CLK)
begin
if(RESET)
Q<=0;
else
Q<=D;
end
endmodule
module Fplexer(Sum, Sub, S, F, clk);
input Sum, Sub, S, clk;
output reg F;
always#(posedge clk) begin
if(S==1) begin
F <= Sum;
end else begin
F <= Sub;
end
end
endmodule
module z_flag(clk,F,R,Z);
input clk,F,R;
output reg Z=1;
always#(posedge clk)begin
Z=R|(Z&~F);
end
endmodule
module top(A,B,S,R,clk,F,Z,N,V);
input A, B, S, R, clk;
output F, Z, N, V;
wire w0,w1,w2,w3,w4,w5,w6,w7,w8;
assign w7 = A;
assign w8 = B;
Subtractor S0(.A(w7), .B(w8), .Bin(w3), .Bout(w4), .Sub(w5));
BorrowFLIPFLOP Borrow(.CLK(clk), .RESET(R), .D(w2), .Q(w3));
Adder A0(.A(w7), .B(w8), .Cin(w0), .Cout(w1), .Sum(w2));
CarryFLIPFLOP Carry(.CLK(clk), .RESET(R), .D(w2), .Q(w0));
Fplexer multi(.Sum(w2), .Sub(w5), .S(S), .F(w6), .clk(clk));
assign V=(w0 & w1);
assign F = w6;
assign N = w6;
z_flag Zflag(.clk(clk), .F(w6), .R(R), .Z(Z));
endmodule
module testbench;
reg clk;
reg R;
reg A;
reg B;
reg S = 0;
wire F;
//intitialize clock/top
top UUT(A,B,S,R,clk,F,Z,N,V);
always
#5 clk = ~clk;
initial begin
$display("Testing +- Machine");
$monitor("%d - %d Is %d",A, B, F);
A = 0; B = 1; S = 0; R=0; #10;
clk = 1; #1;
clk = 0; #1;
clk = 1; #1;
A = 1; B = 1; #10;
clk = 1; #1;
clk = 0; #1;
clk = 1; #1;
A = 1; B = 0; #10;
clk = 1; #1;
clk = 0; #1;
clk = 1; #1;
end
endmodule
Your design has a reset signal and you never used it.
Your FLIPFLOP code does not have RESET in the sensitivity list.
You are making assignments to clk in an always block and in the initial block. Pick one place.
Learn how to save waveforms to see internal signals, not just the top level output.
I'm trying to build an 8-bit multiplier in Verilog, but I keep running in to this weird error when I go to simulate my module's test bench. It says:
Too many port connections. Expected 8, found 9
This doesn't really make any sense seeing as how both the module AND the test bench have 9 variables listed. Any help will be much appreciated!
Multiplier Module
module my8bitmultiplier (output [15:0] O, output Done, Cout, input [7:0] A, B, input Load, Clk, Reset, Cin);
reg Done;
reg [1:0] state;
reg [7:0] A_reg, B_reg;
reg [15:0] A_temp, B_temp, O_temp, O_reg;
my16bitadder Adding(O_temp, Cout,A_temp,B_temp, Cin);
always#(posedge Clk)
begin
if(Reset) assign state = {2'b00};
case(state)
0:
if(Load)
begin
A_reg = A;
B_reg = B;
O_reg = A_reg;
state = 1;
end
1:
begin
A_temp = A_reg;
B_temp = O_reg;
B_reg = B_reg - 1;
state = 2;
end
2:
begin
O_reg = O_temp;
if(B_temp)
begin
state = 1;
end
else
begin
state = 3;
Done = 1'b1;
end
end
3:
begin
Done = 1'b0;
state = 0;
end
endcase
end
endmodule
Testbench
module my8bitmultiplier_tb;
reg Load, Clk, Reset, Cin;
reg [7:0] A, B;
wire [15:0] O;
wire Done, Cout;
my8bitmultiplier dut(O, Done, Cout, A, B, Load, Clk, Reset, Cin);
always #5 Clk = ~Clk;
initial
begin
A = 8'b10;
B = 8'b10;
Load = 1;
Cin = 0;
#10 Load = 0;
#3000 A = 8'd100;
#3000 B = 8'd100;
#3000 Load = 1;
#3010 Load = 0;
#6000 A = 8'd150;
#6000 B = 8'd150;
#6000 Load = 1;
#6000 Load = 0;
begin
$display ($time,"A= %d B= %d O=%d ", A, B, O);
end
#10000 $finish;
end
endmodule
When I run you code on another simulator, I get a more helpful warning message:
reg Done;
|
xmvlog: *W,ILLPDX : Multiple declarations for a port not allowed in module with ANSI list of port declarations (port 'Done') [12.3.4(IEEE-2001)].
The warning goes away when I delete this line:
reg Done;
and change:
module my8bitmultiplier (output [15:0] O, output Done, Cout, input [7:0] A, B, input Load, Clk, Reset, Cin);
to:
module my8bitmultiplier (output [15:0] O, output reg Done, Cout, input [7:0] A, B, input Load, Clk, Reset, Cin);
Perhaps that solves your problem on modelsim. You can also try your code on different simulators on edaplayground. You will sometimes get more helpful messages.
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)
My code compiles but does not dump any dat file for gtkwave. I'm trying to implement a combination shift multiplier object. I don't think my tester is correct.
module combinational_mult(product,multiplier,multiplicand);
input [31:0] multiplier;
input[63:0] multiplicand;
output reg [63:0] product;
reg c;
reg [31:0] m;
integer i;
always #( multiplier or multiplicand )
begin
//initialize
product[63:32] = 16'b0000_0000_0000_0000;
product[32:16] = multiplier;
m = multiplicand;
c = 1'b0;
//add,shift algorithm for unsigned multiplication.
//following the notes.
for(i=0; i<32; i=i+1)
begin
if(product[0]) {c,product[63:32]} = product[63:32] + m ;
product[63:0] = {c,product[63:1]};
c = 0;
end
end
endmodule
module tester(output reg [31:0] multiplier, output reg [63:0] multiplicand, output reg [63:0] product, output reg c, output reg i);
initial begin
i = 0;
$dumpfile("USAMv1.dat");
$dumpvars;
#10 multiplier = 16'b1101_1001_1101_1001;
multiplicand = 16'b0110_1010_1101_1000;
#50 $finish;
end
endmodule
module testbench;
wire[31:0] multiplier;
wire[63:0] multiplicand;
wire[63:0] product;
wire c, i;
tester sim( multiplier, multiplicand, product, c, i);
combinational_mult dut ( product, multiplier, multiplicand);
endmodule
I have created a version on EDA Playground which removes the tester and just runs a test program in the testbench.
I have renamed the dump.dat to dump.vcd to work with EDA Playground. which should launch the wave form window when run.
No real changes to the code other than moving test program to the testbench, and adding a second data point to the test vectors so they can be observed. otherwise the VCD finishes at the point they change.
module testbench;
reg [31:0] multiplier;
reg [63:0] multiplicand;
initial begin
$dumpfile("dump.vcd");
$dumpvars;
#10ns;
multiplier = 16'b1101_1001_1101_1001;
multiplicand = 16'b0110_1010_1101_1000;
#50ns;
multiplier = 16'b0;
multiplicand = 16'b0;
$finish;
end
combinational_mult dut ( product, multiplier, multiplicand);
endmodule
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.