blob: eb6098c6ca9960e245080425a749a5a71cc57324 [file] [log] [blame]
// File name: CRCcheck.sv
// Created: 11/28/2020
// Author: Zachary Ellis
// Version: 2.0 Extended support
// Description: Check CAN CRC on receiver side
module CRCcheck (
input clk,
input bitstrobe,
input tx_strobe,
input endCRC,
input stopCRC,
input nRST,
input bitstuff,
input [3:0] pkt_size,
input SOF,
input CANRX,
output reg ACK,
output CRCerror
);
typedef enum logic [2:0] {
Idle,
Running,
ENDCRC,
delimeter,
doACK
} state_type;
state_type state, next_state;
reg [14:0] CRC, Next_CRC;
always_ff @(posedge clk, negedge nRST) begin
if(nRST == 0) begin
state <= Idle;
end
else begin
state <= next_state;
end
end
always_comb begin
next_state = state;
ACK = 1'b1;
case(state)
Idle: if(SOF) next_state = Running;
Running: if(endCRC && ~bitstuff) next_state = ENDCRC;
ENDCRC: if(bitstrobe && ~bitstuff) next_state = delimeter;
delimeter: if(tx_strobe && ~bitstuff) next_state = doACK;
doACK: begin
if(tx_strobe) next_state = Idle;
ACK = |CRC;
end
endcase
if(stopCRC) next_state = Idle;
end
wire inv;
wire bit_clk;
assign inv = CANRX ^ CRC[14];
assign bit_clk = (bitstuff) ? 0 : bitstrobe;
always_ff @(posedge bit_clk, negedge nRST) begin
if (nRST == 0) begin
CRC <= '0;
end
else begin
CRC <= Next_CRC;
end
end
always_comb begin
Next_CRC = CRC;
if(state == Idle) Next_CRC = '0; //Next_CRC = 15'b100010110011001;
else if(state == Running) begin
Next_CRC[14] = CRC[13] ^ inv;
Next_CRC[13] = CRC[12];
Next_CRC[12] = CRC[11];
Next_CRC[11] = CRC[10];
Next_CRC[10] = CRC[9] ^ inv;
Next_CRC[9] = CRC[8];
Next_CRC[8] = CRC[7] ^ inv;
Next_CRC[7] = CRC[6] ^ inv;
Next_CRC[6] = CRC[5];
Next_CRC[5] = CRC[4];
Next_CRC[4] = CRC[3] ^ inv;
Next_CRC[3] = CRC[2] ^ inv;
Next_CRC[2] = CRC[1];
Next_CRC[1] = CRC[0];
Next_CRC[0] = inv;
end
end
reg [1:0] CRCerror_delay;
assign CRCerror = CRCerror_delay[1];
always_ff @(posedge bitstrobe, negedge nRST) begin
if(nRST == 0) CRCerror_delay <= '0;
else begin
CRCerror_delay[0] <= (state == doACK) ? ACK : 0;
CRCerror_delay[1] <= CRCerror_delay[0];
end
end
endmodule