Problem with Verilog Dataflow testbench causing different errors on different sites - verilog

This program is in Dataflow Verilog. What I'm trying to do is make an adder and subtractor dependent on a selector. I am currently getting some errors that are either "syntax error in continuous assignment" for line 10, (the assign {cout...},) or "Error launching EPWave: [Could not parse file: $timescale not found in the header.]. Could not load './dataflow_hw_1.vcd'".
I have looked all over the internet in search of how to solve this problem, but I keep attempting the recommended solutions to no avail. I don't know what's wrong when trying to testbench it.
Here is the code:
module dataflow_1 (a[7:0],b[7:0],out[7:0],cout);
input a,b;
output out,cout;
//if a have odd number of 1s, output = a + b
//else if even positions have even number of 1s in total, output = a-b
assign selectorOdd = (a[1]^ a[3]^ a[5] ^ a[7]);
assign selectorEven = (~selectorOdd & ~(a[0] ^ a[2] ^ a[4] ^ a[6]));
assign {cout,out[7:0]} = (selectorOdd & ({a[7:0] + b[7:0}) | (selectorEven & ({a[7:0] - b[7:0]}));
endmodule
Here is the testbench code:
// Code your testbench here
module dataflow_1();
reg [7:0] a;
reg [7:0] b;
wire [7:0] out;
dataflow_1 test(
.a(a),
.b(b),
.out(out)
);
initial begin
$dumpfile("dump.vcd");
$dumpvars(0, out);
a = 8'b01010101;
b = 8'b00000001;
#100;
end
endmodule

The problem is on this line:
assign {cout,out[7:0]} = (selectorOdd & ({a[7:0] + b[7:0}) | (selectorEven & ({a[7:0] - b[7:0]}));
you used wrong {} and [], {} used to concatenate the bits. It should be fixed like this:
assign {cout,out} = selectorOdd ? (a + b) : (selectorEven ? (a - b) : {9{1'b0}});
Your code should have more the case for else all. In this code if selectorOdd and selectorEven are 0, I assign {cout,out}={9{1'b0}}.

Related

100-bit binary ripple carry adde

I am trying to write a 100-ripple carry adder. Fist I design a full adder. Then I need to connect 100 full adders.
I am getting errors:
Error (10170): Verilog HDL syntax error at top_module.v(11) near text:
"instance1"; expecting "<=", or "=", or "+=", or "-=", or "*=", or
"/=", or "%=", or "&=", or "|=", or "^=", or "<<=", or ">>=", or
"<<<=", or ">>>=", or "++", or "--". Check for and fix any syntax
errors that appear immediately before or at the specified keyword. The
Intel FPGA Knowledge Database contains many articles with specific
details on how to resolve this error. Visit the Knowledge Database at
https://www.altera.com/support/support-resources/knowledge-base/search.html
and search for this specific error message number. File:
/var/www/verilog/work/vlg7ccmQf_dir/top_module.v Line: 11
module top_module(
input [99:0] a, b,
input cin,
output [99:0] cout,
output [99:0] sum );
assign {cout[0],sum[0]}=a[0]+b[0]+cin;
always# (*)
begin
for (int i=1; i<$bits(a);i++)
full_adder instance1(
.a_1(a[i]),
.b_1(b[i]),
.cin_1(cout[i-1]),
.cout_1(cout[i]),
.sum_1(sum[i])
);
end
endmodule
module full_adder(
input a_1, b_1,
input cin_1,
output cout_1,
output sum_1
);
assign {cout_1,sum_1}=cin_1+a_1+b_1;
endmodule
well, you cannot instantiate a module inside of an always block. Try a generate block instead:
...
assign {cout[0],sum[0]}=a[0]+b[0]+cin;
genvar i;
for ( i=1; i<$bits(a);i=i+1)
full_adder instance1(
.a_1(a[i]),
.b_1(b[i]),
.cin_1(cout[i-1]),
.cout_1(cout[i]),
.sum_1(sum[i])
);
...
You cannot instantiate a module inside of a procedural block. Try to use generate block instead:
The final code should be like this:
module top_module(
input [99:0] a, b,
input cin,
output [99:0] cout,
output [99:0] sum
);
assign {cout[0],sum[0]}=a[0]+b[0]+cin;
genvar i;
generate
for ( i = 1; i < $size(a); i++ ) begin : gen
full_adder instance1(
.a_1(a[i]),
.b_1(b[i]),
.cin_1(cout[i-1]),
.cout_1(cout[i]),
.sum_1(sum[i])
);
end : gen
endgenerate
endmodule
module full_adder(
input a_1, b_1,
input cin_1,
output cout_1,
output sum_1
);
assign {cout_1,sum_1}=cin_1+a_1+b_1;
endmodule
Please pay attention to the for-label ":gen", it is necessary and the code will not work without it.

ALU in Verilog: "Unable to bind wire/reg/memory"

I am trying to make a simple 32 bit ALU with an overflow flag, and then output the inputs and results of the ALU to the screen, but I encountered some problems with connecting the elements for the test bench. I got this error:
test_32bALU.v:15: error: Wrong number of ports. Expecting 4, got 5.
test_32bALU.v:33: error: Unable to bind wire/reg/memory
test_unit.overflow' inalu_test'
2 error(s) during elaboration.
I am just starting with Verilog and I have a basic idea of the syntax. I know I am not supposed to ask debugging questions, but this is my only hope. My professor or TA wouldn't respond to me requests for help. I would appreciate it if anyone here could help me point out my mistakes.
This is my 32bALU.v file:
module alu(
input signed[31:0] a,b,
input[3:0] opcode;
output signed[31:0] c;
output overflow;
);
reg signed[31:0] result;
assign c = result;
reg tmp;
parameter
add = 4'b0000,
sub = 4'b0110,
sla = 4'b0001,
srai = 4'b0011;
always #(a,b,opcode)
begin
case(opcode)
add:
begin
c = a + b;
end
endcase
end
always #(c)
begin
if (c[32:31] == (2'b11 | 2'b10)) // Overflow
begin
tmp = 1'b1;
assign overflow = tmp;
end
else begin
tmp = 1'b0;
assign overflow = tmp;
end
end
assign result = c[31:0];
endmodule
test_32bALU.v
`timescale 1ns/1ps
module alu_test;
// Inputs
reg[31:0] a,b;
reg[2:0] opcode;
// Outputs
wire[31:0] c;
//wire [1:0] zero;
wire [1:0] overflow;
//wire [1:0] neg;
alu test_unit(
a,b, // Inputs
opcode,
c,
overflow
);
parameter
add = 4'b0000,
sub = 4'b0110,
sla = 4'b0001,
srai = 4'b0011;
initial begin
$display("op: a : b : c : reg_A : reg_B : reg_C");
$monitor(" %h:%h:%h:%h:%h:%h:%h",
opcode, a, b, c, test_unit.a, test_unit.b, test_unit.c);
$monitor("%h", test_unit.overflow);
//// add
#10 a=32'b0000_0000_0000_0000_0000_0000_0000_0001;
#10 b=32'b0000_0000_0000_0000_0000_0000_0000_0001;
opcode= add;//3'b000
#10 $finish;
end
endmodule
I am confused as to why it says "wrong number of ports"? I assume it's the number of parameters in module alu and alu test_unit? They have the same number of parameters (a, b, c, opcode and overflow), so what exactly am I missing? How exactly do I get the value of overflow? It works fine before I added the overflow parameter, so I assume I'm doing it wrong?
For the second error, I read somewhere on here that it might be due to a missing declaration, but I have declared all of them... so I am not sure what's making it wrong.
I am not sure if this is the issue, but your module definition is not correct. It should be as follows:
module alu(
input signed[31:0] a,b,
input[3:0] opcode,
output signed[31:0] c,
output overflow
);
Perhaps this may help with your issue.
Commas separate inputs and outputs in the module declaration.
NEVER rely on the order of arguments to modules and ALWAYS try to use, for a module called A;
module A(output wire c,
input wire a,
input wire b);
...
endmodule // A
use an instance of it using;
A yourAname(.c(Bar),
.a(Foo1),
.b(Foo2));
so that if the definition and order of the I/O of the module changes, this instantiation will track those changes and/or give appropriate errors when simulated/synethesised.
You might find it useful to follow a few simple rules in your source code when naming;
inputs are denoted by i_yourinputname
outputs are denoted by o_youroutputname
inout are denoted by io_yourinputoutputname
wire are denoted by w_yourwirename
reg are denoted by r_yourregname
as this avoid confusion and is a good habit to get into as soon as possible when starting to learn verilog.

Absolute value module in Verilog returning only unknown values

I am trying to implement a simple 16-bit absolute value module; however, I am only getting unknown values as output.
Below is the code that I've written:
module refabs(b, a);
input wire [15:0] a;
output reg signed [15:0] b;
always #* begin
b = ((a < 0) ? -a : a);
end
endmodule
module testbench;
reg [15:0] a;
wire [15:0] b;
refabs abs(b, a);
initial begin
a = -30000;
begin
$display("refabs(%x) = %x", a, b);
end
end
endmodule
The output I get is:
refabs(8ad0) = xxxx
In your example, the initial block executes with 0 delay without giving the always #* a chance to execute.
Either change your $display to $strobe, or add a delay before the $display statement.

Error (10170): Verilog HDL syntax error at mult.v(9) near text "="; expecting ".", or an identifier, or "["

I am trying to implement the circuit mentioned at this question: How to perform right shifting binary multiplication?
I am getting the error:
Error (10170): Verilog HDL syntax error at mult.v(9) near text "="; expecting ".", or an identifier, or "["
I tried to Google it, but I couldn't find anything
Code:
module mult (multiplier, multiplicand, result, clk);
input [3:0] multiplier;
input [4:0] multiplicand;
input clk;
output [8:0] result;
reg [8:0] product;
initial
begin
product [8:4] = 4'b00000;
product [3:0] = multiplier [3:0];
end
assign result = product;
always # (posedge clk)
begin
if (product[0] == 1)
begin
product = product >> 1; // shift right, and assign the most significant bit to 0
product[8:4] = product[7:3] + multiplicand[4:0]; // add 5-bits so we can handle the carry-out
end
else
begin
product = product >> 1; // shift to the right
end
end
endmodule
The reason for your syntax error is that you cannot just write:
product [7:4] = 4'b0000;
you must write
assign product [7:4] = 4'b0000;
But, unless you are using System-Verilog (and your old-fashioned style of coding suggests you are not), you will find that
assign product [7:4] = 4'b0000;
will not compile either, because the target of an assign statement must be a wire, not a reg. And if you change product to a wire, you will then find these statements give you and error:
product = product >> 1; // shift right, and assign the most significant bit to 0
product[7:3] = product[7:3] + multiplicand[4:0]; // add 5-bits so we can handle the carry-out
and
product = product >> 1; // shift to the right
because you cannot assign to a wire in an always (or initial) block.
You seem to be designing some kind of shift-and-add multiplier and presumably want to initialise product at the beginning of the calculation. (Assuming you sort the syntax) the lines
(assign) product [7:4] = 4'b0000;
(assign) product [3:0] = multiplier [3:0];
drive product continuously, for all time; they do not initialise product. You are designing hardware here, not writing software.

Signal EXCEPTION_ACCESS_VIOLATION received xilinx

I'm trying to make an arithmetic logic unit in verilog and I received the following error when I tried to simulate in ISim Simulator (No errors reported at Behavioral Check Syntax):
ERROR:Simulator:754 - Signal EXCEPTION_ACCESS_VIOLATION received
Here is the code:
module alu(
input [3:0] right,
input [3:0] left,
input [2:0] sel,
input CarryIn,
output reg CarryOut,
output reg [3:0] out
);
function [3:0] add;
input [3:0] a;
input [3:0] b;
input CarryIn;
assign add = a + b + CarryIn;
endfunction
function [3:0] substract;
input [3:0] a;
input [3:0] b;
input CarryIn;
assign subtract = a - b + (~CarryIn);
endfunction
function [3:0] AND;
input [3:0] a;
input [3:0] b;
assign AND = {1'b0 , a & b};
endfunction
function [3:0] OR;
input [3:0] a;
input [3:0] b;
assign OR = {1'b0 , a | b};
endfunction
function [3:0] XOR;
input [3:0] a;
input [3:0] b;
assign XOR = {1'b0 , a ^ b};
endfunction
function [3:0] increment;
input [3:0] a;
assign increment = a + 1;
endfunction
function [3:0] left_shift;
input [3:0] a;
assign left_shift = a << 1;
endfunction
function [3:0] right_shift;
input [3:0] a;
assign right_shift = a >> 1;
endfunction
always # (left or right or sel) begin
case (sel)
0 : {CarryOut , out} = add(left,right,CarryIn);
1 : {CarryOut , out} = substract(left,right,CarryIn);
2 : {CarryOut , out} = AND(left,right);
3 : {CarryOut , out} = OR(left,right);
4 : {CarryOut , out} = XOR(left,right) ;
5 : {CarryOut , out} = increment(left);
6 : begin
CarryOut = left[3];
out = left_shift(left);
end
7 : begin
CarryOut = left[0];
out = right_shift(left);
end
default : {CarryOut , out} = {1'b0,left};
endcase
end
endmodule
Any ideas ?
Remove the keyword assign from all your functions. assign statements are for continuous assignments that should only be declared in a module; not a task, function, initial or always.
There is a typo too. A couple places you have "substract" and should be "subtract".
You are also missing CarryIn from your sensitivity list. If your sensitivity list is not complete it will infer complex latching logic. Better yet, switch to a IEEE 1364-2001 coding style and use always #(*) or always #* instead of always # (left or right or sel or CarryIn). They auto construct the sensitivity list for combinational logic.
One of the reasons for happening this is that the simulator does not understand a syntax.
I had run into similar problem in VIVADO for a silly mistake while writing a verilog syntax. For a concatenation in verilog, mistakenly i used ":" instead of ",". That caused the same problem. To find out exactly which module is causing the problem it is good to look at the tcl console message. The module causing the problem is simply after compiling which module this message shows.
This is silly but sometimes it may take a lot of time to figure out.

Resources