`timescale 1ns / 1ps
module Signadder(
input wire [3:0] a,
input wire [3:0] b,
output reg [3:0] sum
);
reg [2:0] mag_a, mag_b,mag_sum, max, min;
reg sign_a, sign_b, sign_sum;
always #*
begin
mag_a = [2:0]a;
mag_b = [2:0]b;
sign_a = [3]a;
sign_b = [3]b;
if(mag_a>mag_b)
begin
max = mag_a;
min = mag_b;
sign_sum = sign_a;
end
else
begin
max = mag_b;
min = mag_a;
sign_sum = sign_b;
end
if (sign_a == sign_b)
mag_sum = mag_a +mag_b;
else
mag_sum = max - min;
assign sum = {sign_sum,mag_sum};
end
endmodule
I describe a Sign_mag adder with Verilog, but I get these errors when I synthesize:
Line 35: Syntax error near "[".
Line 36: Syntax error near "[".
Line 33: a is not a task
Line 34: b is not a task
I can't find any syntax error in my Verilog code, and with "a is not a task", I fix it by use intermediate register :
reg [3:0] a1;
reg [3:0]b1;
a1 = a;
b1 = b;
But, it still does not work. I hope somebody has any idea why.
The syntax error is due to the following lines:
mag_a = [2:0]a;
mag_b = [2:0]b;
sign_a = [3]a;
sign_b = [3]b;
The signal name should be to the left of the square brackets:
mag_a = a[2:0];
mag_b = b[2:0];
sign_a = a[3];
sign_b = b[3];
In addition to that, you are not following good coding practices for synthesizable code.
You should not use the assign keyword inside an always block.
You have combinational feedback loops inside your always block. You should not read from and assign to the same signal. For example, mag_a:
mag_a = a[2:0];
max = mag_a;
Related
In preparation for an exam, I want to go over some Verilog Code and I'm using https://www.jdoodle.com/ as a compiler. But for some reason the cases throw errors.
jdoodle.v:20: syntax error
jdoodle.v:20: error: Incomprehensible case expression.
jdoodle.v:21: syntax error
jdoodle.v:21: error: Incomprehensible case expression.
jdoodle.v:22: syntax error
jdoodle.v:22: error: Incomprehensible case expression.
jdoodle.v:23: syntax error
jdoodle.v:23: error: Incomprehensible case expression.
jdoodle.v:24: syntax error
jdoodle.v:24: error: Incomprehensible case expression.
module ALU (
input wire [2:0]OPCODE,
input wire [31:0]A,
B,
output reg [31:0]RESULT
);
`define ADD 0;
`define SUB 1;
`define MULT 2;
`define DIV 3;
`define MOD 4;
function [31:0] calculate (
input [31:0] A,
input [31:0] B,
input [2:0] OPCODE
);
case (OPCODE)
`ADD: calculate = A + B;
`SUB: calculate = A - B;
`MULT: calculate = A * B;
`DIV: calculate = A / B;
`MOD: calculate = A % B;
endcase
endfunction
always #(A or B or OPCODE)
RESULT = calculate(A, B, OPCODE);
endmodule
Would appreciate any kind of help.
Remove the semicolon at the end your defines.
You are defining ADD as 0;
Thus your code becomes:
case (OPCODE)
0; : calculate = A + B;
1; : calculate = A - B;
2; : calculate = A * B;
3; : calculate = A / B;
4; : calculate = A % B;
endcase
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}}.
I'm trying to implement in hardware (using Verilog) the function described by this pseudo code:
if A then
output [63:0] = b[63:56], c[X-1:0], b[Y-1:0]
else output [63:0] = c[X-1:0], b[Y-1:0]
A is a boolean value, while output, b and c are 64 bits long.
X and Y change at runtime so they can't be Verilog variables.
The value of X changes with A:
if A then
X = 56 - Y
else X = 63 - Y
while Y is read from a 6 bit register so it can be any number from 0 to 63.
So for both cases of A all 64 bits of output will be assigned.
I know bit masking and mux selection with A is required but it is a bit complex and I can't quite get a clear picture on how to implement this in Verilog.
The runtime dependent bit selection can be implemented with shift(<<), variable bit selection(a[k+:8]), a smartly designed for loop(a[i] = condition ? b:c) or a completely expressed case. And all of them should have similar synthesis result. Based on experience, the case implementation should have best area performance.
Here is an example (with testbench) for shift implementation:
`timescale 1ns/1ps
module example(
input A,
input [5:0] Y,
input [63:0] b, c,
output [63:0] result
);
reg [63:0] o_a, o_abar;
assign result = A ? o_a : o_abar;
wire [5:0] X = A ? (56-Y) : (63-Y);
reg [63:0] c1_tmp, b1_tmp, mask;
always#(*)begin
c1_tmp = (c << Y) & {8'd0, {56{1'b1}}};
mask = (({64{1'b1}}>>X) << Y) | ({64{1'b1}} >> (64-Y));
b1_tmp = mask & b;
o_a = c1_tmp | b1_tmp;
end
reg [63:0] c2_tmp, b2_tmp;
always#(*)begin
c2_tmp = c << Y;
b2_tmp = b & ({64{1'b1}} >> Y);
o_abar = c2_tmp | b2_tmp;
end
endmodule
module test;
reg A;
reg [5:0] Y;
reg [63:0] b, c;
wire [63:0] result;
example ex(.A(A), .Y(Y), .b(b), .c(c), .result(result));
initial begin
A = 1;
Y = 6;
c = -1;
b = 0;
#10
$display("%b", result);
$finish;
end
endmodule
module booth(num1,num2,prod);
input [22:0] num1,num2;
output [45:0] prod;
reg [22:0]num1_bar;
reg [46:0]sub_1;
reg [22:0]temp;
reg [22:0]result;
reg [1:0]sel;
reg [22:0]add;
reg [22:0]zeros;
assign temp = ~ num1;
assign num1_bar = temp + "00000000000000000000001";
assign sub_1 = {zeros[22:0], num2, "0"};
integer i;
always #* begin
for( i = 0; i < 22; i = i+1) begin
assign sel = sub_1[1:0];
if(sel == "10") begin
assign add = sub_1[46:24] + num1_bar;
assign sub_1 ={add[22],add,sub_1[23:1]};
end
elseif(sel == "01") begin
assign add = sub_1[46:24] + num1 ;
assign sub_1 ={add[22],add,sub_1[23:1]};
end
else begin
assign sub_1= {sub_1[46] ,sub_1[46:1]};
end
end
endmodule
I am trying to implement a floating point multiplier using carry look ahead adder and booth multiplier. After running the above code following errors has occurred only for the booth multiplier.
Please help me out.
ERRORS:
Summary Tue Apr 7 15:25:28 2015
Summary New
ERROR ProjectMgmt:806 - "D:/XILINX PROGRAM/bth/booth.v" Line 45. Syntax error near "begin".
ERROR ProjectMgmt:806 - "D:/XILINX PROGRAM/bth/booth.v" Line 49. Syntax error near "else".
ERROR ProjectMgmt:806 - "D:/XILINX PROGRAM/bth/booth.v" Line 54. Syntax error near "endmodule".
INFO ProjectMgmt:1845 - Analyzing Verilog file "D:/XILINX PROGRAM/bth/booth.v" into library work
You seem to have a confusion between VHDL and Verilog.
Vector constants in Verilog are in the form: Y'zXXXXXXX where Y is the number of bits of the vector, z is the base (b for binary, d for decimal, h for hexadecimal), and XXXX is the constante value in the specified base.
else if must separated
For example, the line:
if(sel == "10") begin
Must be rewritten as:
if(sel == 2'b10) begin
For large vectors, you can ommit the size specifier, and write the constant as this:
assign num1_bar = temp + 'b00000000000000000000001;
You are missing an end matching the begin of the always block.
(Once you have fixed that, you will see that there are other errors, too. See mcleod_ideafix's answer.)
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.