Add crc7 module

This module takes in a 40 bit word and generates the 7 bit crc7
appropriate for an SD card.

It does not use any fancy parallel algorithm, it does it 1 bit at a
time.
This commit is contained in:
Byron Lathi
2022-04-08 00:50:28 -05:00
parent f276c5469e
commit e828df0807
2 changed files with 106 additions and 0 deletions

105
hw/fpga/crc7.sv Normal file
View File

@@ -0,0 +1,105 @@
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;
crc_out = data[6:0];
end
default:;
endcase
end
endmodule

View File

@@ -350,6 +350,7 @@ set_location_assignment PIN_V22 -to DRAM_LDQM
set_location_assignment PIN_U22 -to DRAM_RAS_N
set_location_assignment PIN_J21 -to DRAM_UDQM
set_location_assignment PIN_V20 -to DRAM_WE_N
set_global_assignment -name SYSTEMVERILOG_FILE crc7.sv
set_global_assignment -name SYSTEMVERILOG_FILE memory_mapper.sv
set_global_assignment -name SYSTEMVERILOG_FILE board_io.sv
set_global_assignment -name SYSTEMVERILOG_FILE sdram.sv