CRC32 code does not work - verilog

I just started to work with CRC32.So when I wanted to check the code I wrote and I get xxxxxx as the output.I am not sure if the code is right though
module last_time(input [127:0]finalinput,output [31:0]crcout1
,input clk);
wire [31:0]poly;
assign poly=32'h04c11db7;
reg [7:0]lsb;
reg [3:0]i;
reg [7:0]ans;
reg [31:0]nextcrc;
reg [31:0]newcrc;
reg [31:0]crcout;
reg [7:0] lut [255:0];
always#(posedge clk)
begin
crcout=32'hffffffff;
lsb=finalinput;
for(i=0;i<16;i=i+1)
begin
ans=(8'hff^(lsb));
newcrc = lut[ans];
$readmemh("table.txt",lut); // to fill lut
nextcrc=(newcrc)^(crcout>>8);
lsb=lsb>>8;
end
end
assign crcout1=nextcrc^32'hffffffff;
endmodule

The issue was with the input to the LUT, it should be an integer and not a reg value.
The LUT size was not the correct size
module bit32(input [31:0]msg,input [31:0]crcinitial,output reg[31:0]tableout,output [23:0]crcshifted,
output[31:0]newcrc,output reg [7:0]xor1);
wire [7:0]msglsb;
assign msglsb=msg;
wire [7:0]crclsb;
assign crclsb=crcinitial;
integer k;
reg [31:0]lut[0:255];
initial
begin
assign xor1=(crclsb^msglsb)&8'hff;
assign k=xor1;
assign tableout=lut[xor1];
$readmemh("table.txt",lut);
end
assign crcshifted=crcinitial>>8;
assign newcrc=(tableout^crcshifted)^32'hffffffff;
endmodule

Related

trying to do shift left every cycle time Verilog [closed]

Closed. This question needs debugging details. It is not currently accepting answers.
Edit the question to include desired behavior, a specific problem or error, and the shortest code necessary to reproduce the problem. This will help others answer the question.
Closed yesterday.
Improve this question
i tried to do it in two ways, and each time i got stuck by the same problem Error (10031): Net "copy_data_in[183]" at RotateText.sv(16) is already driven by input port "data_in[183]", and cannot be driven by another signal.
Hi , i have input of 23 elements that each one is 8 bits.i have output of 6 elements that each one is 8 bits.The input should get change each time. in the end it should be like circular printing. Excuse me but ENABLE should be CLK.
i tried to do it in two ways, and each time i got stuck by the same problem Error (10031): Net "copy_data_in[183]" at RotateText.sv(16) is already driven by input port "data_in[183]", and cannot be driven by another signal.
This first try :
module RotateText( data_in,HEX0S,HEX1S,HEX2S,HEX3S,HEX4S,HEX5S,ENABLE);
input [7:0] data_in [22:0];
input ENABLE;
output reg [7:0] HEX0S;
output reg [7:0] HEX1S;
output reg [7:0] HEX2S;
output reg [7:0] HEX3S;
output reg [7:0] HEX4S;
output reg [7:0] HEX5S;
reg [7:0] tmp;
reg [7:0] copy_data_in [22:0];
reg [7:0] tmp2;
integer i;
integer j=0;
always#(posedge ENABLE)begin
if(j==0)begin
for(i = 0; i < 23; i=i+1) begin
copy_data_in[i] <= data_in[i];
end
end
HEX5S<=copy_data_in[22];
HEX4S<=copy_data_in[21];
HEX3S<=copy_data_in[20];
HEX2S<=copy_data_in[19];
HEX1S<=copy_data_in[18];
HEX0S<=copy_data_in[17];
tmp<= copy_data_in[22];
copy_data_in[22:1]<=copy_data_in[21:0];
copy_data_in[0]<=tmp;
j=j+1;
end
endmodule
This is another approch :
module RotateText( data_in,HEX0S,HEX1S,HEX2S,HEX3S,HEX4S,HEX5S,ENABLE);
input [183:0] data_in ;
input ENABLE;
output reg [7:0] HEX0S;
output reg [7:0] HEX1S;
output reg [7:0] HEX2S;
output reg [7:0] HEX3S;
output reg [7:0] HEX4S;
output reg [7:0] HEX5S;
reg [7:0] tmp;
reg [183:0] copy_data_in;
integer i;
integer j=0;
integer index;
assign copy_data_in=data_in;
always#(posedge ENABLE)begin
HEX5S<=copy_data_in[183:176];
HEX4S<=copy_data_in[175:168];
HEX3S<=copy_data_in[167:160];
HEX2S<=copy_data_in[159:152];
HEX1S<=copy_data_in[151:144];
HEX0S<=copy_data_in[143:136];
tmp<=data_in[183:176];
copy_data_in<=copy_data_in<<8;
copy_data_in[7:0]<=tmp;
end
endmodule
glad to get help .
The post has a circular shift register (sr).
An sr accepts input from the previous stage or from a module input for loading; not both at the same time. Loading & shifting are mutually exclusive behaviors in the same clock clock cycle. The design needs a input control signal to decide load or shift.
The posted code errors out, because its trying to drive the sr internally, and from inputs at the same time.
Here is a solution based on the posted code.
Variable load_shiftn determines load or shift .
module rot(
input logic clk,
input [7:0] data_in [22:0],
input logic load_shiftn,
output reg [7:0] HEX0S,
output reg [7:0] HEX1S,
output reg [7:0] HEX2S,
output reg [7:0] HEX3S,
output reg [7:0] HEX4S,
output reg [7:0] HEX5S
);
// internal
reg [7:0] sr [22:0];
always#(posedge clk)begin
if(load_shiftn)
sr <= data_in;
else begin
sr[22:1] <= sr[21:0];
sr[0] <= sr[22];
end
end
always # * begin
HEX5S =sr[22];
HEX4S =sr[21];
HEX3S =sr[20];
HEX2S =sr[19];
HEX1S =sr[18];
HEX0S =sr[17];
end
endmodule
Testbench
module tb ();
bit clk;
logic [7:0] data_in [22:0];
bit load_shiftn;
logic [7:0] HEX0S;
logic [7:0] HEX1S;
logic [7:0] HEX2S;
logic [7:0] HEX3S;
logic [7:0] HEX4S;
logic [7:0] HEX5S;
always #5 clk = !clk;
initial begin
#270;
$finish;
end
rot u1 (.*);
initial begin
$dumpfile("dump.vcd");
$dumpvars;
end
initial begin
foreach(data_in[i])
data_in[i] = i;
end
initial begin
#(posedge clk)
load_shiftn <= 1;
repeat(2) #(posedge clk);
load_shiftn <= 0;
end
endmodule
Waves

Why is iverilog complaining about my testbench module?

I'm writing a verilog module for my CompSci class and this module specifically is the data memory module. Structurally and analytically, I'm looking at it and it should work based off of the other files that I have, but I'm not sure why this one specifically is acting up and giving me all x's. Hoping a fresh set of eyes can help find the error I missed. Thanks in advance.
datamem.v:
module datamem(Ina, Inb, enable, readwrite, dataOut, clk, rst);
input wire [31:0] Ina;
input wire [31:0] Inb;
input wire enable;
input wire readwrite;
input wire clk;
input wire rst;
reg [31:0] memory[0:65535];
output reg [31:0] dataOut;
always #(memory[Ina]) begin
dataOut = memory[Ina];
end
always #(posedge clk) begin
if(1'b1 == readwrite) begin
memory[Ina] = Inb;
end
end
endmodule
datamem_tb.v:
module datamem_tb();
reg [31:0] Ina;
reg [31:0] Inb;
reg enable;
reg readwrite;
reg clk;
reg rst;
wire [31:0] dataOut;
datamem DUT (Ina, Inb, enable, readwrite, dataOut, clk, rst);
initial
begin
Ina <= 32'd0;
Inb <= 32'd0;
enable <= 0;
readwrite <= 0;
#20 Ina <= 32'd1234;
#20 Inb <= 32'd1234;
#20 Ina <= 32'd0517;
#20 Inb <= 32'd10259;
end
always #(Ina or Inb)
#1 $display("| Ina = %d | Inb = %d | dataOut = %d |", Ina, Inb, dataOut);
endmodule
A few things as to why you are getting all 'x:
You never run the clock, you need to add something like the following to have the clock toggle:
initial begin
clk = 1'b0;
forever #5 clk = ~clk;
end
You never assert readwrite which is required to write to your memory module (you set it to 0 on line 20 and never change it). Without being written to, memory will retain its original value of 'x for every element
Aside from that, there are a few other issues with your module:
Use implicit sensitive lists (instead of always #(memory[inA]) use always #(*))
Use non-blocking assignment for your memory write (memory[inA] <= inB)
Consider using $monitor instead of $display for your print statements to avoid timing issues, and you only need call it at the beginning of your initial block in your testbench (http://referencedesigner.com/tutorials/verilog/verilog_09.php)
Your rst and enable arent connected to anything.
Another example of a memory unit implementation can be found here:
Data memory unit

Verilog HDL error: Illegal left-hand side assignment

I am learning CPU Design and basic Verilog HDL. I have a processor running in tkgate on Fedora 29 and I have designed a hardware RAM disk. I can't test the RAM but have decided to replace it with an HDL RAM disk. Whenever I try to simulate the circuit, I get the error:
RAM_HDL, line 17: Illegal use of 'w7' in left-hand-side assignment.
Here is my code for the RAM:
module RAM_HDL(RAM, Data_In, Data_Out, Address, RW);
reg [15:0] RAM [127:0];
wire [15:0] Data_In;
wire [15:0] Data_Out;
wire [7:0] Address;
wire RW;
initial
$readmemb("RAM_DATA.BIN", RAM);
always #(*)
begin
if (RW)
RAM[Address] <= Data_In;
Data_Out <= Address;
end
endmodule
The error is on line 17:
Data_Out <= Address;
I believe one of your problems is trying to assign to a wire type in an always block. Try changing the declaration of Data_Out to reg instead of wire. The 2 following examples compiled for me:
module RAM_HDL(Data_In, Data_Out, Address, RW);
reg [15:0] RAM [127:0];
input wire [15:0] Data_In;
output reg [15:0] Data_Out;
input wire [7:0] Address;
input wire RW;
initial
$readmemb("RAM_DATA.BIN", RAM);
always #(*)
begin
if (RW)
RAM[Address] <= Data_In;
Data_Out <= Address;
end
endmodule
note the changes. input and output are declared on the ports. The ram array is not one of the ports and the data_out is a reg.
another option would be to move the assignment of data out outside the always block and keep it as a wire:
module RAM_HDL(Data_In, Data_Out, Address, RW);
reg [15:0] RAM [127:0];
input wire [15:0] Data_In;
output wire [15:0] Data_Out;
input wire [7:0] Address;
input wire RW;
initial
$readmemb("RAM_DATA.BIN", RAM);
always #(*)
begin
if (RW)
RAM[Address] <= Data_In;
end
assign Data_Out = Address;
endmodule
the changes are mostly the same. the input output declarations and the ram array is removed from the port list. Data_Out however is now assigned outside the always block so it can stay a wire.
The following code compiles at least:
module RAM_HDL(Data_In, Data_Out, Address, RW);
reg [15:0] RAM [127:0];
input [15:0] Data_In;
output [15:0] Data_Out;
input [7:0] Address;
input RW;
initial
$readmemb("RAM_DATA.BIN", RAM);
always #(*)
begin
if (RW)
RAM[Address] <= Data_In;
end
assign Data_Out = RAM[Address];
endmodule

How to add clock in Xilinx/Verilog

I am new in Xilinx.
Here's my code,and i want to add clock in it.
Please tell me how to add clock. Thanks
code
module Traffic(
output reg red1,
output reg red2,
output reg red3,
output reg red4,
output reg yel1,
output reg yel2,
output reg yel3,
output reg yel4,
output reg gr1,
output reg gr2,
output reg gr3,
output reg gr4,
input [1:0] c1,
input [1:0] c2
);
always #(c1,c2,red1,red2,red3,red4,yel1,yel2,yel3,yel4,gr1,gr2,gr3,gr4)
begin
case({c1,c2})
4'b0000:begin red1=0;red2=1;red3=1;red4=0; yel1=1;yel2=0;yel3=0;yel4=1; gr1=0;gr2=0;gr3=0;gr4=0; end
4'b0001:begin red1=1;red2=1;red3=1;red4=0; yel1=0;yel2=0;yel3=0;yel4=0; gr1=0;gr2=0;gr3=0;gr4=1; end
4'b0010:begin red1=0;red2=1;red3=1;red4=0; yel1=1;yel2=1;yel3=0;yel4=0; gr1=0;gr2=0;gr3=0;gr4=0; end
4'b0011:begin red1=1;red2=1;red3=1;red4=1; yel1=0;yel2=0;yel3=0;yel4=0; gr1=0;gr2=1;gr3=0;gr4=0; end
4'b0100:begin red1=1;red2=0;red3=0;red4=1; yel1=0;yel2=1;yel3=1;yel4=0; gr1=0;gr2=0;gr3=0;gr4=0; end
4'b0101:begin red1=1;red2=1;red3=0;red4=1; yel1=0;yel2=0;yel3=0;yel4=0; gr1=0;gr2=0;gr3=1;gr4=0; end
4'b0110:begin red1=1;red2=1;red3=0;red4=0; yel1=0;yel2=0;yel3=1;yel4=1; gr1=0;gr2=0;gr3=0;gr4=0; end
4'b0111:begin red1=1;red2=1;red3=1;red4=0; yel1=0;yel2=0;yel3=0;yel4=0; gr1=0;gr2=0;gr3=0;gr4=1; end
endcase
end
endmodule
-------------
Text Fixture
-------------
module tf;
// Inputs
reg [1:0] c1;
reg [1:0] c2;
// Outputs
wire red1;
wire red2;
wire red3;
wire red4;
wire yel1;
wire yel2;
wire yel3;
wire yel4;
wire gr1;
wire gr2;
wire gr3;
wire gr4;
// Instantiate the Unit Under Test (UUT)
Traffic uut (
.red1(red1),
.red2(red2),
.red3(red3),
.red4(red4),
.yel1(yel1),
.yel2(yel2),
.yel3(yel3),
.yel4(yel4),
.gr1(gr1),
.gr2(gr2),
.gr3(gr3),
.gr4(gr4),
.c1(c1),
.c2(c2)
);
initial begin
c1 = 2'b00;c2 = 2'b00;
#100 c1 = 2'b00;c2 = 2'b01;
#100 c1 = 2'b00;c2 = 2'b10;
#100 c1 = 2'b00;c2 = 2'b11;
#100 c1 = 2'b01;c2 = 2'b00;
#100 c1 = 2'b01;c2 = 2'b01;
#100 c1 = 2'b01;c2 = 2'b10;
#100 c1 = 2'b01;c2 = 2'b11;
end
If I understand your question correctly, you would like the outputs of your module to be synchronous to a clock. you need to declare the clock as in input wire, and alter the always block to use the posedge clk. It's also good to add a reset -- you can have a synchronous reset or an asynchronous reset. Here's how such a block would be structured, with an asynchronous reset:
module Traffic(
input wire clk,
input wire resetb, // negative edge asynchronous reset
output reg red1,
output reg red2,
output reg red3,
output reg red4,
output reg yel1,
output reg yel2,
output reg yel3,
output reg yel4,
output reg gr1,
output reg gr2,
output reg gr3,
output reg gr4,
input [1:0] c1,
input [1:0] c2
);
always #(posedge clk or negedge resetb)
begin
if (!resetb) begin
red1 <= 'd0;
// etc....
end else begin
case({c1,c2})
4'b0000:begin
red1<=0;red2<=1;red3<=1;red4<=0;
yel1<=1;yel2<=0;yel3<=0;yel4<=1;
gr1<=0;gr2<=0;gr3<=0;gr4<=0;
end
4'b0001:begin
red1<=1;red2<=1;red3<=1;red4<=0;
yel1<=0;yel2<=0;yel3<=0;yel4<=0;
gr1<=0;gr2<=0;gr3<=0;gr4<=1;
end
// etc...
endcase
end
end
endmodule

Verilog logical error

module ocircuit (ooutp,s0,s1 ,clk,write,raddA,raddB,wadd,wdata);
output [3:0] ooutp;
input clk, write,s0,s1;
input [2:0] raddA;
input [2:0] wadd;
input [2:0] raddB;
input [3:0] wdata;
reg [9:0] ooutp;
wire [3:0] dataA;
wire [3:0] dataB;
reg [9:0] inner;
regfile y (dataA,dataB,clk,write,raddA,raddB,wadd,wdata);
always #(posedge clk) begin
if (s0==0) begin
assign inner = dataA [3:0]*dataB [3:0];
end
else begin
assign inner = ((dataA [3:0]*dataB [3:0])+inner [9:0]);
end
//inner=inner1;
ooutp =s1?inner [9:0]:10'd0;
end
endmodule
This is the code. regfile is a simple register file. In the testbench, s0 = 0 during the first cycle and s0 = 1.
For subsequent cycles, this code should return the value of A*B+C*D by using one adder and one multiplier. In the first cycle, when c0 = 0, the answer that is saved in inner (a register) is right but in the second cycle, when c0 = 1 the answer is wrong.
Por example: A=1; B=2; C=1; D=1;
First cycle: x=A*B=2
Second cycle (C*D)+x=5
I think there is something wrong with this statement
assign inner = ((dataA [3:0]*dataB [3:0])+inner [9:0]);
Any help or hint will be appreciated.
Although assign can be used from within an always block, I think you just wanted to store a value into inner depending upon the value of s0. To do that, use non-blocking assignments ( <= ).
Also, you can directly output to ooutp instead of saving the final result in inner, avoiding a possible glitch in the multiplexer you instantiate here:
ooutp =s1?inner [9:0]:10'd0;
Which, by the way, it should be outside the always block, in an assign line:
assign ooutp = s1? inner [9:0]:10'd0;
module ocircuit (ooutp,s0,s1 ,clk,write,raddA,raddB,wadd,wdata);
output [3:0] ooutp;
input clk, write,s0,s1;
input [2:0] raddA;
input [2:0] wadd;
input [2:0] raddB;
input [3:0] wdata;
reg [9:0] ooutp;
wire [3:0] dataA;
wire [3:0] dataB;
reg [9:0] inner;
regfile y (dataA,dataB,clk,write,raddA,raddB,wadd,wdata);
always #(posedge clk) begin
if (s0==0) begin
inner <= dataA [3:0]*dataB [3:0];
end
else begin
ooutp <= ((dataA [3:0]*dataB [3:0])+inner [9:0]);
end
end
endmodule

Resources