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
Related
`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;
I am wondering if it is possible in verilog to create an n-bit carry lookahead adder. With some help from the comments I've been able to come this far
module nbit_lookahead(x, y, cin, cout, s);
parameter n = 1;
integer i;
integer j;
input wire [n:0] x, y, cin;
output wire [n:0] cout, s;
wire [n:0] g, p;
reg cpp, gp;
generate
cpp = 1; // ERROR HERE -- Line 25
gpp = 1;
for(i = 0; i < n; i=i+1) begin : outer_loop
assign p[i] = x[i] | y[i];
assign g[i] = x[i] & y[i];
assign s[i] = cin[i]^x[i]^y[i];
for(j = i - 1; j >= 0; j=j-1) begin : inner_loop
cpp &= (cin[j] & p[j] & p[i]); // ERROR HERE -- Line 32
gp &= (g[j] & p[i]) & gp;
end
assign cout[n] = cpp | gp | (x[i] & y[i]);
end
endgenerate
endmodule
The challenge I'm having now is how to assign cpp and gp. I keep getting errors:
Error (10170): Verilog HDL syntax error at fourbit_lookahead.v(25) near text: "="; expecting ".", or "(". Check for and fix any syntax errors that appear immediately before or at the specified keyword.
Error (10170): Verilog HDL syntax error at fourbit_lookahead.v(32) near text: "&"; expecting ".", or "(". Check for and fix any syntax errors that appear immediately before or at the specified keyword.
I'm pretty rusty, but mixing wires and regs looks wrong to me in the for loop. The first thing I would try here is to make cpp and gpp bit vectors, so that everything is parallel. That way you don't have any reassignments in the inner loop. In generate, your have cpp[0]=1'b1, and gpp[0]=1'b1, then in the inner loop, assign cpp[i+1] and gpp[i+1] to your value. It also looks wrong to be setting cout[n] inside every iteration of the loop. You should be setting cout[i] based on cpp[i] and gpp[i].
I am trying to create a recursive logic in Systemverilog but I seem to be missing the right logic to carry the output of one iteration to the next.
Here is an example of the problem:
parameter WIDTH=4;
module test_ckt #(parameter WIDTH = 4)(CK, K, Z);
input CK;
input [WIDTH-1:0] K;
output reg Z;
wire [WIDTH/2-1:0] tt;
wire [WIDTH-1:0] tempin;
assign tempin = K;
genvar i,j;
generate
for (j=$clog2(WIDTH); j>0; j=j-1)
begin: outer
wire [(2**(j-1))-1:0] tt;
for (i=(2**j)-1; i>0; i=i-2)
begin
glitchy_ckt #(.WIDTH(1)) gckt (tempin[i:i], tempin[(i-1):i-1], tt[((i+1)/2)-1]);
end
// How do I save the value for the next iteration?
wire [(2**(j-1))-1:0] tempin;
assign outer[j].tempin = outer[j].tt;
end
endgenerate
always #(posedge CK)
begin
// How do I use the final output here?
Z <= tt[0];
end
endmodule
module glitchy_ckt #(parameter WIDTH = 1)(A1, B1, Z1);
input [WIDTH-1:0] A1,B1;
output Z1;
assign Z1 = ~A1[0] ^ B1[0];
endmodule
Expected topology:
S1 S2
K3--<inv>--|==
|XOR]---<inv>----|
K2---------|== |
|==
<--gckt---> |XOR]
|==
K1--<inv>--|== |
|XOR]------------|
K0---------|== <-----gckt---->
Example input and expected outputs:
Expected output:
A - 1010
----
S1 0 0 <- j=2 and i=3,1.
S2 1 <- j=1 and i=1.
Actual output:
A - 1010
----
S1 0 0 <- j=2 and i=3,1.
S2 0 <- j=1 and i=1. Here, because tempin is not updated, inputs are same as (j=2 & i=1).
Test-bench:
`timescale 1 ps / 1 ps
`include "test_ckt.v"
module mytb;
reg CK;
reg [WIDTH-1:0] A;
wire Z;
test_ckt #(.WIDTH(WIDTH)) dut(.CK(CK), .K(A), .Z(Z));
always #200 CK = ~CK;
integer i;
initial begin
$display($time, "Starting simulation");
#0 CK = 0;
A = 4'b1010;
#500 $finish;
end
initial begin
//dump waveform
$dumpfile("test_ckt.vcd");
$dumpvars(0,dut);
end
endmodule
How do I make sure that tempin and tt get updated as I go from one stage to the next.
Your code does not have any recursion in it. You were trying to solve it using loops, but generate blocks are very limited constructs and, for example, you cannot access parameters defined in other generate iterations (but you can access variables or module instances).
So, the idea is to use a real recursive instantiation of the module. In the following implementation the module rec is the one which is instantiated recursively. It actually builds the hierarchy from your example (I hope correctly).
Since you tagged it as system verilog, I used the system verilog syntax.
module rec#(WIDTH=1) (input logic [WIDTH-1:0]source, output logic result);
if (WIDTH <= 2) begin
always_comb
result = source; // << generating the result and exiting recursion.
end
else begin:blk
localparam REC_WDT = WIDTH / 2;
logic [REC_WDT-1:0] newSource;
always_comb // << calculation of your expression
for (int i = 0; i < REC_WDT; i++)
newSource[i] = source[i*2] ^ ~source[(i*2)+1];
rec #(REC_WDT) rec(newSource, result); // << recursive instantiation with WIDTH/2
end // else: !if(WIDTH <= 2)
initial $display("%m: W=%0d", WIDTH); // just my testing leftover
endmodule
The module is instantiated first time from the test_ckt:
module test_ckt #(parameter WIDTH = 4)(input logic CK, input logic [WIDTH-1:0] K, output logic Z);
logic result;
rec#(WIDTH) rec(K, result); // instantiate first time )(top)
always_ff #(posedge CK)
Z <= result; // assign the results
endmodule // test_ckt
And your testbench, a bit changed:
module mytb;
reg CK;
reg [WIDTH-1:0] A;
wire Z;
test_ckt #(.WIDTH(WIDTH)) dut(.CK(CK), .K(A), .Z(Z));
always #200 CK = ~CK;
integer i;
initial begin
$display($time, "Starting simulation");
CK = 0;
A = 4'b1010;
#500
A = 4'b1000;
#500 $finish;
end
initial begin
$monitor("Z=%b", Z);
end
endmodule // mytb
Use of $display/$monitor is more convenient than dumping traces for such small examples.
I did not do much testing of what I created, so there could be issues, but you can get basic ideas from it in any case. I assume it should work with any WIDTH which is power of 2.
I can't seem to figure out what the proper syntax is to do {c_out, result} = {a + b + c_in} within a case block. The c_out doesn't work in my test bench, if I add 32'hffffffff + 1'b1 I get c_out = 0, result = 32'b0. What's the correct way to do this?
module verification_alu(
input c_in
input [W-1:0] a, b,
input [2:0] operation,
output reg [W-1:0] result
output reg c_out
);
parameter W = 32;
always#*
begin
case(operation)
0: result = a;
1: result = ~a;
2: {c_out, result} = {a + b + c_in};
3: {c_out, result} = {a - b + c_in};
4: result = a | b;
5: result = a & b;
default: {c_out, result} = {W-2'b0}; // will this line fill with zeros properly?
endcase
end
endmodule
Also, side question, what should be the proper output of 32'b0 - 1'b1? Should I be getting 32'hffffffff?
The reason the addition and subtraction operations are not working is because you are wrapping the calculation in the concatenation operator ({}). Verilog determines the bit size of an operation partially based on the operands in an expression as well as by the context of that expression. In your case, the expression a + b + c_in is being evaluated as W-bits because the maximum length of any of the variables in that expression is W (ie, a and b are that length and because Verilog will first evaluate this addition (or two additions) before moving on to evaluating the {} operator wrapping it). By removing this unneeded step, you should get the proper (W+1)-bit evaluation of a + b + c_in; so the line would be: 3: {c_out, result} = a - b + c_in;. For more on this, see IEEE1800-2012, section 11.6.
To answer two of your other questions:
No, the expression {W-2'b0} will not zero fill but will instead result in the value W as you are telling the simulator to subtract 2'b0 from W. You are thinking of {(W-2){1'b0}}, or specially for zero filling '0 (because its so common, you can also use '1, 'x, or 'z for filling 1, don't care or high-Z respectively). (Note {c_out, result} has width W+1, not W-2 though)
Finally, 32'b0 - 1'b1 will most likely yield 32'hffffffff, but it is subject to the rules above on sizing (and sign extension rules as well).
A revised description:
module verification_alu #(parameter W=32) (
input wire c_in,
input wire [W-1:0] a,
input wire [W-1:0] b,
input wire [2:0] operation,
output reg [W-1:0] result,
output reg c_out
);
always #* begin
case(operation)
0: result = a;
1: result = ~a;
2: {c_out, result} = a + b + c_in;
3: {c_out, result} = a - b + c_in;
4: result = a | b;
5: result = a & b;
default: {c_out, result} = 0; // will this line fill with zeros properly?
endcase
end
endmodule
The point is to assure that at least one of the operands have the same size as the result you want, so I prepend a 0 bit to both a and b.
I have verified this to work even for sizes far beyond the size of an ordinary integer:
module tb;
reg c_in;
reg [127:0] a;
reg [127:0] b;
reg [2:0] op;
wire [127:0] res;
wire c_out;
verification_alu #(.W(128)) uut (c_in, a, b, op, res, c_out);
initial begin
c_in = 0;
a = 128'hFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF;
b = 128'h00000000000000000000000000000001;
op = 3'd2;
#100;
$display ("RES = %H C_OUT = %d\n", res, c_out);
#100;
c_in = 0;
a = 128'h00000000000000000000000000000000;
b = 128'h00000000000000000000000000000001;
op = 3;
#100;
$display ("RES = %H C_OUT = %d\n", res, c_out);
#100;
op = 7;
#100;
$display ("RES = %H C_OUT = %d\n", res, c_out);
$finish;
end
endmodule
Chronologic VCS simulator copyright 1991-2014
Contains Synopsys proprietary information.
Compiler version J-2014.12-SP1-1; Runtime version J-2014.12-SP1-1; Oct 11 17:47 2015
RES = 00000000000000000000000000000000 C_OUT = 1
RES = ffffffffffffffffffffffffffffffff C_OUT = 1
RES = 00000000000000000000000000000000 C_OUT = 0
$finish called from file "testbench.sv", line 35.
$finish at simulation time 500
You can edit and/or run the testbench along with the revised module at http://www.edaplayground.com/x/CJV
EDIT: ouch! I didn't realized the OP had used the concatenation operator { } for embracing the three operands. Yes! your code is way much simpler. I'll edit the code in my answer.
First of all as per your code the parameter definitions in the input ports will not be accessible by compiler and will throw syntax error, you have to mention the parameter definitions before your i/o declarations since it is been accessed in i/o declarations, verilog comes with a syntax as to avoid this
module module_name #(parameter W =value)
{} is a concatenation operator used with "," eg: a=1bit b= 1bit c=2bit so we can give c={a,b}; so the correct syntax is as simple as
2: {c_out, result} = a + b + c_in;
3: {c_out, result} = a - b + c_in;
to fill it with zeros a mix of parameter with curly braces will help in resolving (the inner curly brace will act as replication operator)
default: {c_out, result} = {(W-2){1'b0}};
I know how to design a 4x4 array multiplier , but if I follow the same logic , the coding becomes tedious.
4 x 4 - 16 partial products
64 x 64 - 4096 partial products.
Along with 8 full adders and 4 half adders, How many full adders and half adders do I need for 64 x 64 bit. How do I reduce the number of Partial products? Is there any simple way to solve this ?
Whenever tediously coding a repetitive pattern you should use a generate statement instead:
module array_multiplier(a, b, y);
parameter width = 8;
input [width-1:0] a, b;
output [width-1:0] y;
wire [width*width-1:0] partials;
genvar i;
assign partials[width-1 : 0] = a[0] ? b : 0;
generate for (i = 1; i < width; i = i+1) begin:gen
assign partials[width*(i+1)-1 : width*i] = (a[i] ? b << i : 0) +
partials[width*i-1 : width*(i-1)];
end endgenerate
assign y = partials[width*width-1 : width*(width-1)];
endmodule
I've verified this module using the following test-bench:
http://svn.clifford.at/handicraft/2013/array_multiplier/array_multiplier_tb.v
EDIT:
As #Debian has asked for a pipelined version - here it is. This time using a for loop in an always-region for the array part.
module array_multiplier_pipeline(clk, a, b, y);
parameter width = 8;
input clk;
input [width-1:0] a, b;
output [width-1:0] y;
reg [width-1:0] a_pipeline [0:width-2];
reg [width-1:0] b_pipeline [0:width-2];
reg [width-1:0] partials [0:width-1];
integer i;
always #(posedge clk) begin
a_pipeline[0] <= a;
b_pipeline[0] <= b;
for (i = 1; i < width-1; i = i+1) begin
a_pipeline[i] <= a_pipeline[i-1];
b_pipeline[i] <= b_pipeline[i-1];
end
partials[0] <= a[0] ? b : 0;
for (i = 1; i < width; i = i+1)
partials[i] <= (a_pipeline[i-1][i] ? b_pipeline[i-1] << i : 0) +
partials[i-1];
end
assign y = partials[width-1];
endmodule
Note that with many synthesis tools it's also possible to just add (width) register stages after the non-pipelined adder and let the tools register balancing pass do the pipelining.
[how to] reduce the number of partial products?
A method somewhat common used to be modified Booth encoding:
At the cost of more complicated addend selection, it at least almost halves their number.
In its simplest form, considering groups of three adjacent bits (overlapping by one) from one of the operands, say, b, and selecting 0, a, 2a, -2a or -a as an addend.
The code below generates only half of expected the output.
module arr_multi(a, b, y);
parameter w = 8;
input [w-1:0] a, b; // w-width
output [(2*w)-1:0] y; // p-partials
wire [(2*w*w)-1:0] p; //assign width as input bits multiplied by
output bits
genvar i;
assign p[(2*w)-1 : 0] = a[0] ? b : 0; //first output size bits
generate
for (i = 1; i < w; i = i+1)
begin
assign p[(w*(4+(2*(i-1))))-1 : (w*2)*i] = (a[i]?b<<i :0) + p[(w*(4+(2*
(i-2))))-1 :(w*2)*(i-1)];
end
endgenerate
assign y=p[(2*w*w)-1:(2*w)*(w-1)]; //taking last output size bits
endmodule