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: