1
\$\begingroup\$

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:

latch warning

The other is the shift unsafe behavior. I believe this is the contributing reason

shift unsafe Behavior

The University waveform output is attached below:

Wrong Output

\$\endgroup\$
2
  • \$\begingroup\$ I want to use latches. But my shift latch is showing wrong behaviour alongside the continue_count \$\endgroup\$
    – Rezef
    Commented 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
    Commented Sep 13, 2023 at 13:30

1 Answer 1

1
\$\begingroup\$

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.

\$\endgroup\$
0

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Not the answer you're looking for? Browse other questions tagged or ask your own question.