Previously the crc would be reset after 1 clock cycle while the valid signal was still high. Now the data is preserved in the valid state until the load signal is asserted.
107 lines
2.2 KiB
Systemverilog
107 lines
2.2 KiB
Systemverilog
module crc7 #(parameter POLYNOMIAL = 8'h89)
|
|
(
|
|
input clk,
|
|
input rst,
|
|
|
|
input load,
|
|
input [39:0] data_in,
|
|
|
|
output logic [6:0] crc_out,
|
|
output logic valid
|
|
);
|
|
|
|
logic [46:0] data;
|
|
logic [46:0] next_data;
|
|
logic [46:0] polyshift;
|
|
|
|
typedef enum bit [1:0] {IDLE, WORKING, VALID} macro_t;
|
|
struct packed {
|
|
macro_t macro;
|
|
logic [5:0] count;
|
|
} state, next_state;
|
|
|
|
always_ff @(posedge clk) begin
|
|
if (rst) begin
|
|
polyshift <= {POLYNOMIAL, 39'b0}; //start all the way at the left
|
|
data <= '0;
|
|
state.macro <= IDLE;
|
|
state.count <= '0;
|
|
end else begin
|
|
if (load) begin
|
|
data <= {data_in, 7'b0};
|
|
end else begin
|
|
data <= next_data;
|
|
end
|
|
state <= next_state;
|
|
|
|
if (state.macro == WORKING) begin
|
|
polyshift <= polyshift >> 1;
|
|
end
|
|
|
|
if (state.macro == VALID) begin
|
|
polyshift <= {POLYNOMIAL, 39'b0};
|
|
end
|
|
end
|
|
end
|
|
|
|
always_comb begin
|
|
next_state = state;
|
|
|
|
case (state.macro)
|
|
IDLE: begin
|
|
if (load) begin
|
|
next_state.macro = WORKING;
|
|
next_state.count = '0;
|
|
end
|
|
end
|
|
|
|
WORKING: begin
|
|
if (state.count < 39) begin
|
|
next_state.count = state.count + 6'b1;
|
|
end else begin
|
|
next_state.macro = VALID;
|
|
next_state.count = '0;
|
|
end
|
|
end
|
|
|
|
VALID: begin // Same as IDLE, but IDLE is just for reset.
|
|
if (load) begin
|
|
next_state.macro = WORKING;
|
|
next_state.count = '0;
|
|
end
|
|
end
|
|
|
|
default:;
|
|
endcase
|
|
end
|
|
|
|
always_comb begin
|
|
valid = 0;
|
|
next_data = '0;
|
|
crc_out = '0;
|
|
|
|
case (state.macro)
|
|
IDLE: begin
|
|
valid = 0;
|
|
end
|
|
|
|
WORKING: begin
|
|
if (data[6'd46 - state.count]) begin
|
|
next_data = data ^ polyshift;
|
|
end else begin
|
|
next_data = data;
|
|
end
|
|
end
|
|
|
|
VALID: begin
|
|
valid = ~load;
|
|
next_data = data;
|
|
crc_out = data[6:0];
|
|
end
|
|
|
|
default:;
|
|
endcase
|
|
end
|
|
|
|
endmodule
|