I am trying to implement a Cyclic Redundancy Check algorithm in Verilog. The algorithm will take the data and then find the modulus with respect to the the quotient polynomial. My problem is that in the following code both the shift
and continue_count
signals remain high and low respectively. When I want it to change their conditions depending on the state of the FSM. I am attaching my code below.
This is the main body of the code:
module CRC(data,poly,clk,rst,final_code,temp,load,shift,l_rem,s_shift,finale,continue_count,t_count,r_count,hold);
input [20:0]data,poly;
input clk,rst;
wire [10:0]n_count,m_count,shiftby;
output wire [10:0]t_count,r_count;
wire [20:0]fin_remainder;
wire [32:0]mod_data;
output wire[41:0]final_code;
output wire load,shift,l_rem,s_shift,finale,continue_count;
output wire hold;
wire [20:0]rem;
output wire [20:0]temp;
n_bit_count m_nbitcount(.data(poly),
.bit_count(n_count));
assign mod_data=data<<(n_count-1);
fsm_CRC m_CRC( .clk(clk),
.rst(rst),
.shift(shift),
.load(load),
.l_rem(l_rem),
.s_shift(s_shift),
.finale(finale),
.continue_count(continue_count),
.hold(hold));
CRC_datapath2 m_data( .data(mod_data),
.poly(poly),
.hold(hold),
.load(load),
.l_rem(l_rem),
.n_count(n_count),
.srem(rem),
.rem(rem),
.m_count(m_count),
.shift(shift),
.t_count(t_count),
.r_count(r_count),
.tr_count(r_count),
.fin_result(fin_remainder),
.temp(temp));
n_bit_count m_mbitcount(.data(rem),
.bit_count(m_count));
n_bit_count m_tbitcount(.data(mod_data),
.bit_count(t_count));
assign final_code={data,fin_remainder};
endmodule
This is the FSM Control unit portion
module fsm_CRC(clk,rst,shift,load,l_rem,s_shift,finale,continue_count,hold);
input clk,rst,shift,continue_count;
output reg load,l_rem,s_shift,finale,hold;
reg [2:0]pres_state,next_state;
parameter [2:0]LOAD=3'b 000;
parameter [2:0]XOR= 3'b 001;
parameter [2:0]REM= 3'b 010;
parameter [2:0]SHIFT= 3'b 011;
parameter [2:0]FINAL= 3'b 100;
always @(posedge clk)begin
if(rst)pres_state<=LOAD;
else pres_state<=next_state;
end
always @(pres_state or shift or continue_count)begin
case(pres_state)
LOAD: begin
load = 1;
hold=0;
l_rem=0;
s_shift=0;
finale=0;
next_state = XOR;
end
XOR: begin
load = 0;
hold=1;
l_rem=0;
s_shift=0;
finale=0;
if(~continue_count)next_state<=FINAL;
else if(shift)next_state<=SHIFT;
else next_state<=REM;
end
REM: begin
load=0;
hold=0;
l_rem=1;
s_shift=0;
finale=0;
next_state<=XOR;
end
SHIFT: begin
load=0;
hold=0;
l_rem=0;
s_shift=1;
finale=0;
next_state<=XOR;
end
FINAL: begin
load=0;
hold=0;
l_rem=0;
s_shift=0;
finale=1;
next_state<=FINAL;
end
endcase
end
endmodule
This is the datapath portion:
module CRC_datapath2(data,poly,rem,load,n_count,srem,hold,m_count,t_count,shift,finale,continue_count,l_rem,s_shift,r_count,tr_count,fin_result,temp);
input [32:0]data;
input [20:0]poly,srem;
input [10:0]n_count,m_count,t_count,tr_count;
input load,hold,l_rem,s_shift,finale;
output wire [20:0]rem,fin_result;
output reg [20:0]temp;
output reg shift,continue_count;
output reg[10:0]r_count;
reg [10:0]shiftby;
reg [20:0]shiftdata,data_reg;
reg [41:0]shiftdata_reg;
always @(load or s_shift or l_rem or hold or n_count or m_count or t_count or tr_count or srem or data)begin
if(load)begin
temp=data>>(t_count-n_count);
r_count=n_count;
end
else if(hold)begin
if(t_count>tr_count)begin
if(n_count>m_count)shift=1;
else shift=0;
continue_count=1;
end
else continue_count=0;
end
else if(l_rem)begin
temp=srem;
r_count=tr_count;
end
else if(s_shift)begin
shiftby= n_count-m_count;
r_count=tr_count+shiftby;
data_reg=(((data<<(33 - t_count + tr_count))>>12)>>(21 - shiftby))<<(21-shiftby);
shiftdata_reg={srem,data_reg};
shiftdata=shiftdata_reg>>(21-shiftby);
temp=shiftdata;
end
end
assign rem=temp^poly;
assign fin_result=(finale)? rem:0;
endmodule
There are two warnings, I am concerned about. First is the latch warning:
The other is the shift unsafe behavior. I believe this is the contributing reason
The University waveform output is attached below:
-
\$\begingroup\$ I want to use latches. But my shift latch is showing wrong behaviour alongside the continue_count \$\endgroup\$Rezef– Rezef2023年09月12日 10:32:29 +00:00Commented Sep 12, 2023 at 10:32
-
1\$\begingroup\$ If you now have working code and you are interested in having it reviewed, you could post it on CodeReview Make sure to read the policy first. \$\endgroup\$toolic– toolic2023年09月13日 13:30:33 +00:00Commented Sep 13, 2023 at 13:30
1 Answer 1
You have connection issues in the Verilog code. The simulators I used generate compile warnings. If your simulator did not generate any warnings, you can try your code on the free simulators on EDAPlayground.
CRC_datapath2 m_data( .data(mod_data),
|
xmelab: *W,CUVWSP : 1 output port was not connected:
xmelab: continue_count
CRC_datapath2 m_data( .data(mod_data),
|
xmelab: *W,CUVWSI : 2 input ports were not connected:
xmelab: finale
xmelab: s_shift
Sometimes output ports can be left unconnected, but all input ports should be driven.
Since you did not post a complete code example, it is not possible for us to run a simulation. I recommend you break your problem down into smaller pieces for further debug if you continue to have simulation problems.
Unintended latches arise when you attempt to describe combinational logic with an always
block, but you neglect to make assignments to a signal in all branches of logic.
For example, in the CRC_datapath2
module, the continue_count
signal is only assigned when hold
=1. continue_count
must be assigned under all conditions. You could either add assignments to all if/else
clauses, or add a default assignment at the start of the always
block.