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:
105
hw/fpga/crc7.sv
Normal file
105
hw/fpga/crc7.sv
Normal 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
|
||||
@@ -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
|
||||
|
||||
Reference in New Issue
Block a user