I have written a shift/add multiplier in Verilog that compiles without error through online compilers, but when i try to compile it with iverilog through the CMD window i receive the following error:
shiftadd.v:1:error: unmatched character (hex U+019E)
(U+019E is the closest unicode character I could find to what it is). What in my code is causing this error? I am not trying to pass any hexadecimal values.
module shiftaddmult(product, multiplicand, multiplier, clk);
input clk;
output reg [63:0] product;
input [63:0] multiplicand;
input [31:0] multiplier;
integer i;
always #(posedge clk) //m or m
begin
if(i< 32)
begin
product[63:32] = 16'b0000_0000_0000_0000;
product[32:16] = multiplier;
if(product[0] == 1)
begin
product[63:32] = product[63:32] + multiplicand;
product [63:0] = product[63:1];
end
else
begin
product [63:0] = product[63:1];
end
i = i + 1;
end
end //end always
endmodule //shift add
module tester(output reg [63:0] product,
output reg [63:0] multiplicand,
output reg [31:0] multiplier,
output reg clk,
output reg i);
initial
begin
i = 0;
clk = 0;
$dumpfile("multdump.dat");
$dumpvars;
#10 multiplier = 16'b0000_0000_0000_0001;
multiplicand = 16'b0000_0000_0000_0010;
//result should = 2
#20 multiplier = 16'b0000_0000_0000_0010;
multiplicand = 16'b0000_0000_0000_0100;
//result should = 'd8
#30 multiplier = 16'b0000_0000_0000_1000;
multiplicand = 16'b0000_0000_0000_1000;
//result should = 'd16
#40 $finish;
end
always begin
#5 clk = ~clk; //clock generator
end
endmodule
module testbench;
wire [63:0] product;
wire [63:0] multiplicand;
wire [31:0] multiplier;
wire i;
wire clk;
tester test(product, multiplicand, multiplier, clk, i);
shiftaddmult mult(product, multiplicand, multiplier, clk);
endmodule
It looks like you are copying code from browser and pasting it in your source code. Copying the code from browser also copies some special characters which cannot be detected by the compiler.
I suggest you write code again do not copy and paste. Just write those lines again using keyboard.
This should work and eliminate unwanted characters.
Related
I'm having an issue with my SV code. I'm attempting to simulate a carry look ahead adder. However, when I look at my timing results
they show result has having an x propagated, as well as SUM.
Here is my SystemVerilog code
module fulladder (input logic i_bit1, i_bit2, i_carry,
output logic o_sum, o_carry);
assign o_sum = i_bit1 ^ i_bit2 ^ i_carry;
assign o_carry = (i_bit1 & i_bit2) | (i_carry & (i_bit1 ^ i_bit2));
endmodule
module carry_lookahead_adder
#(parameter WIDTH)
(input logic [WIDTH-1:0] i_add1,
input logic [WIDTH-1:0] i_add2,
output logic [WIDTH:0] o_result
);
logic [WIDTH:0] w_C;
logic [WIDTH-1:0] w_G, w_P, w_SUM;
//Generate full adders
genvar i;
generate for (i= 1; i<WIDTH; i++)
begin : f_loop
fulladder fi (
.i_bit1(i_add1[i]),
.i_bit2(i_add2[i]),
.i_carry(w_C[i]),
.o_sum(w_SUM[i]),
.o_carry()
);
end
endgenerate
genvar jj;
generate
for (jj=0; jj<WIDTH; jj++)
begin
assign w_G[jj] = i_add1[jj] & i_add2[jj];
assign w_P[jj] = i_add1[jj] | i_add2[jj];
assign w_C[jj+1] = w_G[jj] | (w_P[jj] & w_C[jj]);
end
endgenerate
assign w_C[0] = 1'b0; //No carry input
assign o_result = {w_C[WIDTH], w_SUM};
endmodule
and the testbench
module carry_lookahead_adder_tb (w_RESULT);
parameter WIDTH = 32;
logic [WIDTH-1:0] r_ADD_1 = 0;
logic [WIDTH-1:0] r_ADD_2 = 0;
output logic [WIDTH:0] w_RESULT;
carry_lookahead_adder #(.WIDTH(WIDTH)) carry_lookahead_inst
(
.i_add1(r_ADD_1),
.i_add2(r_ADD_2),
.o_result(w_RESULT)
);
initial
begin
$dumpfile("dump.vcd");
$dumpvars;
#10;
r_ADD_1 = 32'b00000000000000000000000000000000;
r_ADD_2 = 32'b00000000000000000000000000000001;
#10;
r_ADD_1 = 32'b00000000000000000000000000000010;
r_ADD_2 = 32'b00000000000000000000000000000010;
#10;
r_ADD_1 = 32'b00000000000000000000000000000101;
r_ADD_2 = 32'b00000000000000000000000000000110;
#10;
r_ADD_1 = 32'b00000000100000000000000000000101;
r_ADD_2 = 32'b00000000100000000000000000000110;
#10;
r_ADD_1 = 32'b11111111111111111111111111111111;
r_ADD_2 = 32'b11111111111111111111111111111111;
#10;
r_ADD_1 = 32'b00000000000000000000000000000000;
r_ADD_2 = 32'b00000000000000000000000000000001;
#10;
end
endmodule // carry_lookahead_adder_tb
Can anyone clue me into what may be causing this x? Sorry to post my full code; I'm just lost as to where the problem may be coming from.
Bit [0] of w_SUM is unknown because you are not driving it. Change the generate for loop so that the count starts from 0, not 1. Change:
generate for (i= 1; i<WIDTH; i++)
to:
generate for (i= 0; i<WIDTH; i++)
After this change, the x goes away.
The problem was that the for loop was not generating the right number of fulladder instances: you need 32, but you only got 31. There was no fulladder instance for you to connect w_SUM[0], i_add1[0], etc., to.
I'm trying to understanding how the following code works, but struggling to put it together in my head. Could someone give me a more intuitive (visual) explanation of how this pipelined multiplier stage works?
// This is one stage of an 8 stage (9 depending on how you look at it)
// pipelined multiplier that multiplies 2 64-bit integers and returns
// the low 64 bits of the result. This is not an ideal multiplier but
// is sufficient to allow a faster clock period than straight *
module mult_stage(
input clock, reset, start,
input [63:0] product_in, mplier_in, mcand_in,
output logic done,
output logic [63:0] product_out, mplier_out, mcand_out
);
logic [63:0] prod_in_reg, partial_prod_reg;
logic [63:0] partial_product, next_mplier, next_mcand;
assign product_out = prod_in_reg + partial_prod_reg;
assign partial_product = mplier_in[7:0] * mcand_in;
assign next_mplier = {8'b0,mplier_in[63:8]};
assign next_mcand = {mcand_in[55:0],8'b0};
//synopsys sync_set_reset "reset"
always_ff #(posedge clock) begin
prod_in_reg <= #1 product_in;
partial_prod_reg <= #1 partial_product;
mplier_out <= #1 next_mplier;
mcand_out <= #1 next_mcand;
end
// synopsys sync_set_reset "reset"
always_ff #(posedge clock) begin
if(reset)
done <= #1 1'b0;
else
done <= #1 start;
end
endmodule
I am trying to assign value on a specific bit of a 2D array(code[i][k]). This is a net type. But the value not being assigned.reg [3:0] code[0:3] gets unknown logic value 'X'.
Here is the code snippet
for(k=0;k<len;k++) begin
if (tc[k] == 1'b0) begin
code[i][k]= 1'b0;//----> value is not assigning as expected
end else begin
code[i][k]= 1'b1;// ---> value is not assigning as expected
end
end
codeLen[i] = len;
This for loop belongs to always block.Here, code and codeLen is output type.
output [3:0] code[0:3];
output [3:0] codeLen[0:3];
reg [3:0] code[0:3];
reg [3:0] codeLen[0:3];
codeLen[i] is assigned correctly but not the code[i][k]. I was trying to assign k-th bit of i-th byte.
Details
I have created a module which takes 6 inputs and returns two 2-dimensional arrays as output.
Here is the module:
`timescale 1ns / 1ps
module generate_code(CLK,nRST,nodes,nodeCount,characters,charCount,code,codeLen);
input CLK;
input nRST;
input integer nodeCount;//Total nodes in huffman tree
input integer charCount;//Total unique characters
input [6:0] characters[0:3];
input [23:0] nodes[0:6]; // total characters
output [3:0] code[0:3]; //[2:0] max code length <= total characters
output [3:0] codeLen[0:3];
reg [3:0] code[0:3];
reg [3:0] codeLen[0:3];
reg[3:0] tc;//temprary code reg. Holds a single bit in each byte
integer len=0;//code length
reg [23:0] tNode;
function void FindRoot;
reg [23:0] aNode;//local
integer i;
begin
for (i=0; i<nodeCount;i++) begin // For all nodes
aNode= nodes[i]; // aNode is current node
if (tNode[23:16] == aNode[14:7]) begin
tc[len]= tNode[15];//15th bit of nodes is codebit
len++;
//aNode is parent of tNode. Is it root?
if(aNode[23:16]==8'b0000_0000) begin//or frequency==nodeCount or node_id = 8'b1111_1111
return;
end else begin
tNode=aNode;
FindRoot();
end
end
end
end
endfunction
always#(posedge CLK or negedge nRST)
begin
if(!nRST) begin
// init
end
else begin
// Do code generation
integer i,j,k;
for(i= 0;i < charCount;i++) begin // For all character we are going to find codeword
for(j=0; j<nodeCount; j++) begin
tNode= nodes[j];//current node
if (characters[i] == tNode[6:0]) begin
// Got the character. tNode is a leaf nodes. Lets back track to root.
break;
end
end
len=0;
FindRoot();
for(k=0;k<len;k++) begin
if (tc[k] == 1'b0) begin
code[i][k]= 1'b0;
end else begin
code[i][k]= 1'b1;
end
end
//code[i]=2;
codeLen[i]= len;
end
end
end
endmodule
When I am assigning values to code[][], it is expected that following loop is executed. Though not all the bits of code[][] will be set. During debugging, when I come to assignment, I found that value is not being assigned (code[i][k] =1 or 0). Its getting unknown logic value X.
for(k=0;k<len;k++) begin
if (tc[k] == 1'b0) begin
code[i][k]= 1'b0;
end else begin
code[i][k]= 1'b1;
end
end
Testbench:
`timescale 1ns / 1ps
module generate_code_test;
// Inputs
reg CLK;
reg nRST;
integer nodeCount=7;//Total nodes in huffman tree
integer charCount=4;//Total unique characters
reg [6:0] characters[0:3];
reg [23:0] nodes[0:6]; // total characters
// Outputs
wire [3:0] code[0:3]; //[2:0] max code length <= total characters
wire [3:0] codeLen[0:3];
generate_code uut (
.CLK(CLK),
.nRST(nRST),
.nodes(nodes),
.nodeCount(nodeCount),
.characters(characters),
.charCount(charCount),
.code(code),
.codeLen(codeLen)
);
initial begin
// Initialize Inputs
CLK = 0;
nRST = 0;
nodeCount= 7;
charCount= 4;
characters[0]= 7'b110_0001;
characters[1]= 7'b110_0010;
characters[2]= 7'b110_0011;
characters[3]= 7'b110_0100;
nodes[0] = 24'b0000_0011_0_0000_0001_110_0001;
nodes[1] = 24'b0000_0011_1_0000_0010_110_0011;
nodes[2] = 24'b0000_0101_1_0000_0011_111_1111;
nodes[3] = 24'b0000_0101_0_0000_0100_110_0010;
nodes[4] = 24'b1111_1111_1_0000_0101_111_1111;
nodes[5] = 24'b1111_1111_0_0000_0110_110_0100;
nodes[6] = 24'b0000_0000_0_1111_1111_111_1111;
// Wait 10 ns for global reset to finish
#10;
nRST = 1;
end
parameter DELAY = 1;
always
#DELAY CLK = ~CLK;
endmodule
The code has been compiled in ModelSim 2016
I just started learning verilog. So I would really appreciate your help to show my mistakes.
Regards.
I got a fix for my problem. Not all the bits of code[][] has been set. This leads to unknown logic value in code[][] even after setting the bit. It gets solved after initializing all the bits of code[][] in always block.
A couple of days ago I asked about a module (here) I wanted to implement which takes the MSB of input samples, accumulates them (by shifting) and combines them into the output sample when the 32 output bit is "filled".
Thanks to the help there, I got this implementation, which doesn't produce any compilation errors and seemed fine with Xilinx 12.1:
module my_rx_dsp0
#(
//frontend bus width
parameter WIDTH = 24
)
(
//control signals
input clock, //dsp clock
input reset, //active high synchronous reset
input clear, //active high on packet control init
input enable, //active high when streaming enabled
//user settings bus, controlled through user setting regs API
input set_stb, input [7:0] set_addr, input [31:0] set_data,
//full rate inputs directly from the RX frontend
input [WIDTH-1:0] frontend_i,
input [WIDTH-1:0] frontend_q,
//full rate outputs directly to the DDC chain
output [WIDTH-1:0] ddc_in_i,
output [WIDTH-1:0] ddc_in_q,
//strobed samples {I16,Q16} from the RX DDC chain
input [31:0] ddc_out_sample,
input ddc_out_strobe, //high on valid sample
output ddc_out_enable, //enables DDC module
//strobbed baseband samples {I16,Q16} from this module
output reg [31:0] bb_sample,
output reg bb_strobe //high on valid sample
);
reg [3:0] i_msb;
reg [3:0] q_msb;
reg [31:0] temp_buff = 0;
reg [1:0] count = 0;
always #(posedge clock) begin
if(ddc_out_strobe) begin
// bit shifter for MSB
temp_buff <= {i_msb,q_msb,temp_buff[31:8]};
// to avoid if-else condition
count <= (count==2'd3) ? 2'd0 : (count+1);
end
end
always #(*) begin
i_msb = ddc_out_sample[31:28];
q_msb = ddc_out_sample[15:12];
// to avoid if-else condition
bb_strobe = (count==2'd3);
bb_sample = bb_strobe ? temp_buff : 32'd0;
end
assign ddc_in_i = frontend_i;
assign ddc_in_q = frontend_q;
assign ddc_out_enable = enable;
endmodule //my_rx_dsp0_custom
Now I wanted to implement a testbench that tests my_rx_dsp0.v with some examples.
I implemented a my_rx_dsp0_tb_2.v, which reads 32 bit samples from a file named my_input.dat to feed to the module as inputs ddc_out_sample.
They are then compared to the correct values stored at my_output.dat.
Note: I did not write this testbench myself, I adapted it from another testbench from an open-source project.
Here is the implementation:
module my_rx_dsp0_tb ( );
reg clk;
reg reset;
reg enable;
reg ddc_out_strobe; //high on valid sample
reg [31:0] ddc_out_sample;
wire [31:0] bb_sample = 32'd0;
wire bb_strobe;
wire ddc_out_enable = 1'b1; //enables DDC module
parameter WIDTH = 24;
parameter clocks = 2; // number of clocks per input
reg endofsim = 0;
integer number_of_errors;
initial number_of_errors = 0;
wire set_stb = 1;
wire [7:0] set_addr;
wire [31:0] set_data;
wire [WIDTH-1:0] frontend_i;
wire [WIDTH-1:0] frontend_q;
wire [WIDTH-1:0] ddc_in_i;
wire [WIDTH-1:0] ddc_in_q;
reg signed [31:0] compare_out;
// Setup the clock
initial clk = 1'b0;
always #5 clk <= ~clk ;
// Come out of reset after a while
initial reset = 1'b1 ;
initial #1000 reset = 1'b0 ;
// Enable the entire system
initial enable = 1'b1 ;
// Instantiate UUT
my_rx_dsp0 #(.WIDTH(WIDTH)) UUT_rx_dsp0
( .clock(clk), .reset(reset), .clear(clear), .enable(enable),
.set_stb(set_stb), .set_addr(set_addr), .set_data(set_data),
.frontend_i(frontend_i), .frontend_q(frontend_q),
.ddc_in_i(ddc_in_i), .ddc_in_q(ddc_in_q),
.ddc_out_sample(ddc_out_sample), .ddc_out_strobe(ddc_out_strobe), .ddc_out_enable(ddc_out_enable),
.bb_sample(bb_sample), .bb_strobe(bb_strobe) );
//-------Setup file IO-------//
//
integer i, r_in, r_out, infile, outfile;
initial begin
infile = $fopen("my_input.dat","r");
outfile = $fopen("my_output.dat","r");
$timeformat(-9, 2, " ns", 10) ;
// for n=9,p=2 digits after decimal pointer
//min_field_width=10 number of character positions for %t
end
//-------Get sim values and display errors-------//
//
initial begin
// Initialize inputs
ddc_out_strobe <= 1'd0;
ddc_out_sample <= 32'd0;
// Wait for reset to go away
#(negedge reset) #0;
while(!endofsim) begin
// Write the input from the file or 0 if EndOfFile(EOF)
#(posedge clk) begin
#1
ddc_out_strobe <= 1'b1;
if(!$feof(infile))
r_in = $fscanf(infile,"%b\n",ddc_out_sample);
else
ddc_out_sample <= 32'd0;
end
//
// Clocked in; set the strobe to 0 if the # of clocks/sample
// is greater than 1
if( clocks > 1 ) begin
#(posedge clk) begin
ddc_out_strobe <= 1'b0 ;
end
// Wait for the specified # of cycles
for( i = 0 ; i < (clocks-2) ; i = i + 1 ) begin
#(posedge clk) #1 ;
end
end
//
//
// Print out the number of errors that occured
if(number_of_errors) begin
$display("FAILED: %d errors during simulation",number_of_errors) ;
end else begin
$display("PASSED: Simulation successful") ;
end
//
end
end
//-------Comparison btwn simulated values vs known good values-------//
//
always #(posedge clk) begin
if(reset)
endofsim <= 1'b0 ;
else begin
if(!$feof(outfile)) begin
if(bb_strobe) begin
r_out = $fscanf(outfile,"%b\n",compare_out);
if(compare_out != bb_sample) begin
$display("%t: %b != %b",$realtime,bb_sample,compare_out);
number_of_errors = number_of_errors + 1;
end else begin
$display("%t: %b = %b",$realtime,bb_sample,compare_out);
end
end
end else begin
// Signal end of simulation when no more outputs
endofsim <= 1'b1 ;
end
end
end
endmodule // my_rx_dsp0_tb
When simulating with ISim from Xilinx ISE Suite Edition 12.1 I do not get the desired functionality from the module. I am afraid the output contains several x states (unknown states), instead of 1s or 0s as expected.
Question Is this due to:
1) The way the files are being read with $fscanf?
2) Did I wrong by initializing reg [31:0] temp_buff = 0?
3) Or does someone have an idea on what went wrong?
The error prompts from the testbench are (as an example):
xx000x00xxx00x0xx000x0x000000000 != 10000110111001011100010001101100
The X is from having multiple conflicting drivers on bb_sample and ddc_out_enable. The wire type merges the drivers, conflicting bit values of the same strength resolve as X.
UUT_rx_dsp0 is the intended diver. However you added and additional drivers from the way you declared your wires.
...
wire [31:0] bb_sample = 32'd0; // "= 32'd0" is a continuous driver
wire bb_strobe;
wire ddc_out_enable = 1'b1; // "= 1'd1" is a continuous driver
...
What you want is:
...
wire [31:0] bb_sample;
wire bb_strobe;
wire ddc_out_enable;
...
Correcting the above will resolve the X issue. Based on the example error it looks like are data miss matches. With the provided information, it is hard to tell it if it a test-bench or design issue. Could be just clock or propagation skew.
I have written the code below.
My problem:
At index 1
It enters in the for loop with some values. It goes in a 'if' statement and as you can see there the last instruction from every 'if' it is something like 'P=....' .
At index 2 (next step )
It enters in a 'if' statement but the value of P is not from step 1, it is the initial value .
How can I use the last value of 'P' at next step ? (index+1 )
module multiplier(prod, a, b, wireP, wireA, wireS);
output [15:0] prod;
output [16:0] wireA;
output [16:0] wireS;
output [16:0] wireP;
reg [15:0] prod;
input [7:0] a;
input [7:0] b;
reg [16:0] P;
reg [16:0] S;
reg [16:0] A;
wire [16:0] tempshift;
reg [16:0] tempoutshift;
arithmeticShift shiftP(tempshift,P);
wire [16:0] tempPS;
reg [16:0] tempoutPS;
carryForPbooth sumPS(coutPS,tempPS,P,S,0);
wire [16:0]tempPA;
reg [16:0]tempoutPA;
carryForPbooth sumPA(coutPA,tempPA,P,A,0);
reg [16:0] regP;
reg [16:0] regA;
reg [16:0] regS;
integer index;
always #(*) begin
A[16:9] = a[7:0];
A[8:0] = 9'b000000000;
S[16:9] = ~a[7:0]+1'b1;
S[8:0] = 9'b000000000;
P[16:9] = 8'b00000000;
P[8:1] = b[7:0];
P[0] = 1'b0;
#1 tempoutPS = tempPS;
#1 tempoutPA = tempPA;
#1 tempoutshift = tempshift;
for(index = 1; index < 9; index = index + 1) begin
if((P[1:0] == 2'b00) | (P[1:0] == 2'b11)) begin
#1 tempoutshift = tempshift;
#1 P = tempoutshift;
end
if(P[1:0] == 2'b01) begin
#1 tempoutPA = tempPA;
#1 P = tempoutPA;
#1 tempoutshift = tempshift;
#1 P = tempoutshift;
end
if(P[1:0] == 2'b10) begin
#1 tempoutPS = tempPS;
#1 P = tempoutPS;
#1 tempoutshift = tempshift;
#1 P = tempoutshift;
end
end
#1 prod=P[16:1];
end
assign wireP = P;
assign wireS = S;
assign wireA = A;
endmodule
It looks like you are trying to create a synthesizable Shift and Add multiplier architecture where the multiply value is calculated over 9 clock cycles.
Looking through the code and removing some temp variables I have reduced it down to:
module multiplier(
input [7:0] a,
input [7:0] b,
output [15:0] prod,
output reg [16:0] A,
output reg [16:0] S,
output reg [16:0] P
);
wire [16:0] tempshift;
arithmeticShift shiftP(tempshift,P);
wire [16:0] tempPS;
carryForPbooth sumPS(coutPS,tempPS,P,S,0);
wire [16:0] tempPA;
carryForPbooth sumPA(coutPA,tempPA,P,A,0);
reg [3:0] index;
always #(*) begin
A = { a, 9'b000000000};
S = { -a, 9'b000000000} ;// -x => ~x+1
P = {8'b00000000, b, 1'b0};
for(index = 1; index < 9; index = index + 1) begin
if((P[1:0] == 2'b00) | (P[1:0] == 2'b11)) begin
#1 P = tempshift;
end
if(P[1:0] == 2'b01) begin
#1 P = tempPA;
#1 P = tempshift;
end
if(P[1:0] == 2'b10) begin
#1 P = tempPS;
#1 P = tempshift;
end
end
end
assign prod = P[16:1];
endmodule
I think you are faking clock cycles using #1, This will only work in the simulator will either not synthesise or only the last assignment will take effect.
If this is meant to be split over 9 clock cycles the it need to have a counter tied to the shift value, not a for loop. In Verilog for loops are unrolled at compilation time and should be executable in zero time, unless used as part of a testbench.
The sections of code similar to the following appear several times.
#1 P = tempPA;
#1 P = tempshift;
I think you are trying to apply a value to a module then capture its output, using the same variable, this is hard to know as I do not have the interfaces for the blocks you have instantiated. You can not do this in Verilog if you want to synthesize your code. You should be using another intermediate variable to connect things up.
Remember that always #* begin ... end is combinatorial logic, and has no timing except the ripple involved in calculating the answer. For implying a D-Type flip-flop we use:
always #(posedge clk or negedge rst_n) begin
if (~rst_n) begin
// Reset conditions
end
else begin
// Next clock conditions
end
end