输入: 一个[7:0]xxx[0:x]的数组
一个使能信号
clk
rst_n
输出: 输入的数组内容
输出使能
校验通过与否信号
如图,这是crc的输入部分,是一个10字节数组
这是校验的部分
对前8位进行校验,然后输出crc_dout_yorn为1时校验通过,为2时校验不通过
接下来是具体代码
module crc_data(
clk ,
rst_n ,
din ,
din_en ,
crc_dout ,
crc_dout_en ,
crc_dout_yorn
);
parameter WIDTH = 10;
input clk ;
input rst_n ;
input [7:0] din[0:WIDTH-1] ;
input din_en ;
output reg[7:0] crc_dout[0:WIDTH-1] ;
output reg crc_dout_en ;
output reg[1:0] crc_dout_yorn ;
reg[15:0] crc_end ;
reg [3:0] bit_cnt ;
reg [7:0] crc_temp ;
reg [15:0] crc_reg ;
reg [2:0] state_c ;
reg [2:0] state_n ;
reg [2:0] end_cnt ;
reg [4:0] crc_cnt ;
wire [2:0] add_bit_cnt ;
wire [2:0] end_bit_cnt ;
wire idle2crc_xor ;
wire crc_xor2crc_circle ;
wire crc_circle2crg_0reg ;
wire crc_circle2crg_1reg ;
wire crg_0reg2crc_circle ;
wire crg_0reg2crg_done ;
wire crg_1reg2crc_circle ;
wire crg_1reg2crg_done ;
wire crc_done2idle ;
reg crc_en_flag ;
reg crc_allend ;
parameter IDLE = 0 ;
parameter CRC_XOR = 1 ;
parameter CRC_CIRCLE = 2 ;
parameter CRG_0REG = 3 ;
parameter CRG_1REG = 4 ;
parameter CRC_DONE = 5 ;
crc_data_ip your_instance_name (
.clk(clk), // input wire clk
.probe0(din[0]), // input wire [7:0] probe0
.probe1(din[1]), // input wire [7:0] probe1
.probe2(din[2]), // input wire [7:0] probe2
.probe3(din[3]), // input wire [7:0] probe3
.probe4(din[4]), // input wire [7:0] probe4
.probe5(din[5]), // input wire [7:0] probe5
.probe6(din[6]), // input wire [7:0] probe6
.probe7(din[7]), // input wire [7:0] probe7
.probe8(din[8]), // input wire [7:0] probe8
.probe9(din[9]), // input wire [7:0] probe9
.probe10(din_en), // input wire [0:0] probe10
.probe11(crc_dout[0]), // input wire [7:0] probe11
.probe12(crc_dout[1]), // input wire [7:0] probe12
.probe13(crc_dout[2]), // input wire [7:0] probe13
.probe14(crc_dout[3]), // input wire [7:0] probe14
.probe15(crc_dout[4]), // input wire [7:0] probe15
.probe16(crc_dout[5]), // input wire [7:0] probe16
.probe17(crc_dout[6]), // input wire [7:0] probe17
.probe18(crc_dout[7]), // input wire [7:0] probe18
.probe19(crc_dout[8]), // input wire [7:0] probe19
.probe20(crc_dout[9]), // input wire [7:0] probe20
.probe21(crc_dout_en), // input wire [0:0] probe21
.probe22(crc_dout_yorn), // input wire [1:0] probe22
.probe23(crc_end), // input wire [15:0] probe23
.probe24(crc_temp), // input wire [7:0] probe24
.probe25(crc_reg), // input wire [15:0] probe25
.probe26(state_c), // input wire [2:0] probe26
.probe27(crc_cnt), // input wire [4:0] probe27
.probe28(add_bit_cnt ), // input wire [2:0] probe28
.probe29(bit_cnt), // input wire [2:0] probe29
.probe30(idle2crc_xor), // input wire [0:0] probe30
.probe31(crc_done2idle), // input wire [0:0] probe31
.probe32(crc_allend) // input wire [0:0] probe32
);
always@(posedge clk or negedge rst_n)
begin
if(!rst_n)begin
end_cnt<=0;
end
else if(crc_cnt==WIDTH-1)
begin
end_cnt<=end_cnt+1;
end
else if(crc_allend)
begin
end_cnt<=0;
end
end
always@(posedge clk or negedge rst_n)
begin
if(!rst_n)begin
crc_en_flag<=0;
end
else if(din_en)
crc_en_flag<=1;
else if(crc_cnt==WIDTH-2)
crc_en_flag<=0;
else
crc_en_flag<=crc_en_flag;
end
always@(posedge clk or negedge rst_n)
begin
if(!rst_n)
bit_cnt<=0;
else if(add_bit_cnt)
begin
if(end_bit_cnt)
bit_cnt<=0;
else
bit_cnt<=bit_cnt+1;
end
end
assign add_bit_cnt = (state_c==CRG_0REG||state_c==CRG_1REG);
assign end_bit_cnt = add_bit_cnt && bit_cnt==8-1;
always@(posedge clk or negedge rst_n)
begin
if(!rst_n)begin
crc_cnt<=1'b0;
end
else if(end_cnt==3)begin
crc_cnt<=0;
end
else if(din_en)begin
crc_cnt<=crc_cnt+1;
crc_temp<=din[0];
end
else if(state_c==5&&crc_cnt>0&&end_cnt<3)begin
crc_temp<=din[crc_cnt];
crc_cnt<=crc_cnt+1;
end
else if(crc_allend)
crc_temp<=0;
else begin
crc_cnt<=crc_cnt;
end
end
always@(posedge clk or negedge rst_n)
begin
if(!rst_n)
crc_reg<=16'hffff;
else if(state_c==CRC_XOR)
crc_reg[7:0]<=crc_temp^crc_reg[7:0];
else if(state_c==CRC_CIRCLE)
crc_reg<=crc_reg>>1;
else if(state_c==CRG_1REG)
crc_reg<=crc_reg^16'hA001;
else if(crc_allend)
crc_reg<=16'hffff;
end
always@(posedge clk or negedge rst_n)
begin
if(!rst_n)
crc_dout_en<=1'b0;
else if(end_cnt==3)
crc_dout_en<=1'b1;
else
crc_dout_en<=1'b0;
end
always@(posedge clk or negedge rst_n)
begin
if(!rst_n)
crc_allend<=0;
else if(crc_dout_en)
crc_allend<=1;
else
crc_allend<=0;
end
always@(posedge clk or negedge rst_n)
begin
if(!rst_n)begin
crc_end<=16'h0;
crc_dout_yorn<=0;
end
else if(end_cnt==1)
crc_end<={crc_reg[7:0],crc_reg[15:8]};
else if(end_cnt==2)begin
if({din[8],din[9]}==crc_end)
crc_dout_yorn<=1;//无误
else
crc_dout_yorn<=2;//有误
end
else if(crc_allend)begin
crc_dout_yorn<=0;
crc_end<=0;
end
else begin
crc_dout_yorn<=crc_dout_yorn;
crc_end<=crc_end;
end
end
always@(posedge clk or negedge rst_n)
begin
if(!rst_n)
begin
for(int i=0;i<9;i=i+1)
begin
crc_dout[i]<=0;
end
end
else if(crc_dout_yorn)
crc_dout<=din;
end
always@(posedge clk or negedge rst_n)
begin
if(!rst_n)
state_c<=IDLE;
else
state_c<=state_n;
end
always@(*)
begin
case(state_c)
IDLE:begin
if(idle2crc_xor||idle2crc_xor1)
state_n = CRC_XOR;
else
state_n = state_c;
end
CRC_XOR:begin
if(crc_xor2crc_circle)
state_n = CRC_CIRCLE;
else
state_n = state_c;
end
CRC_CIRCLE:begin
if(crc_circle2crg_0reg)
state_n=CRG_0REG;
else if(crc_circle2crg_1reg)
state_n=CRG_1REG;
else
state_n = state_c;
end
CRG_0REG:begin
if(crg_0reg2crc_circle)
state_n = CRC_CIRCLE;
else if(crg_0reg2crg_done)
state_n = CRC_DONE;
else
state_n = state_c;
end
CRG_1REG:begin
if(crg_1reg2crc_circle)
state_n = CRC_CIRCLE;
else if(crg_1reg2crg_done)
state_n = CRC_DONE;
else
state_n = state_c;
end
CRC_DONE:begin
if(crc_done2idle)
state_n = IDLE;
else
state_n = state_c;
end
endcase
end
assign idle2crc_xor =(state_c==IDLE&&din_en ) ;
assign idle2crc_xor1 =(state_c==IDLE&&crc_en_flag ) ;
assign crc_xor2crc_circle =(state_c==CRC_XOR ) ;
assign crc_circle2crg_0reg =(state_c ==CRC_CIRCLE &&crc_reg[0]==1'b0) ;
assign crc_circle2crg_1reg =(state_c ==CRC_CIRCLE &&crc_reg[0]==1'b1) ;
assign crg_0reg2crc_circle =(state_c ==CRG_0REG &&!end_bit_cnt ) ;
assign crg_0reg2crg_done =(state_c ==CRG_0REG &&end_bit_cnt ) ;
assign crg_1reg2crc_circle =(state_c ==CRG_1REG &&!end_bit_cnt ) ;
assign crg_1reg2crg_done =(state_c ==CRG_1REG &&end_bit_cnt ) ;
assign crc_done2idle= state_c==CRC_DONE;
endmodule