Add files from previous version
This commit is contained in:
@@ -8,6 +8,7 @@ module addr_decode
|
||||
output o_multiplier_cs,
|
||||
output o_divider_cs,
|
||||
output o_uart_cs,
|
||||
output o_sdcard_cs,
|
||||
output o_sdram_cs
|
||||
);
|
||||
|
||||
@@ -16,6 +17,7 @@ assign o_timer_cs = i_addr >= 16'heff8 && i_addr <= 16'heffb;
|
||||
assign o_multiplier_cs = i_addr >= 16'heff0 && i_addr <= 16'heff7;
|
||||
assign o_divider_cs = i_addr >= 16'hefe8 && i_addr <= 16'hefef;
|
||||
assign o_uart_cs = i_addr >= 16'hefe6 && i_addr <= 16'hefe7;
|
||||
assign o_sdcard_cs = i_addr >= 16'hefd8 && i_addr <= 16'hefdf;
|
||||
assign o_leds_cs = i_addr == 16'hefff;
|
||||
assign o_sdram_cs = i_addr < 16'h8000;
|
||||
|
||||
|
||||
106
hw/efinix_fpga/crc7.sv
Normal file
106
hw/efinix_fpga/crc7.sv
Normal file
@@ -0,0 +1,106 @@
|
||||
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
|
||||
@@ -3,7 +3,7 @@
|
||||
{
|
||||
"name": "la0",
|
||||
"type": "la",
|
||||
"uuid": "44caec2ec3a74324b8ff7cb201ab080b",
|
||||
"uuid": "cb44f83ddf674d66b2dd550675cad77d",
|
||||
"trigin_en": false,
|
||||
"trigout_en": false,
|
||||
"auto_inserted": true,
|
||||
@@ -12,127 +12,37 @@
|
||||
"input_pipeline": 1,
|
||||
"probes": [
|
||||
{
|
||||
"name": "u_uart/addr",
|
||||
"name": "sd_data_OUT",
|
||||
"width": 1,
|
||||
"probe_type": 1
|
||||
},
|
||||
{
|
||||
"name": "u_uart/baud_rate",
|
||||
"name": "sd_cmd_IN",
|
||||
"width": 1,
|
||||
"probe_type": 1
|
||||
},
|
||||
{
|
||||
"name": "u_uart/baud_x16_ce",
|
||||
"name": "sd_data_OE",
|
||||
"width": 1,
|
||||
"probe_type": 1
|
||||
},
|
||||
{
|
||||
"name": "u_uart/clk",
|
||||
"name": "sd_data_IN",
|
||||
"width": 1,
|
||||
"probe_type": 1
|
||||
},
|
||||
{
|
||||
"name": "u_uart/clk_50",
|
||||
"name": "sd_cmd_OE",
|
||||
"width": 1,
|
||||
"probe_type": 1
|
||||
},
|
||||
{
|
||||
"name": "u_uart/control",
|
||||
"width": 8,
|
||||
"probe_type": 1
|
||||
},
|
||||
{
|
||||
"name": "u_uart/cs",
|
||||
"name": "sd_cmd_OUT",
|
||||
"width": 1,
|
||||
"probe_type": 1
|
||||
},
|
||||
{
|
||||
"name": "u_uart/irqb",
|
||||
"width": 1,
|
||||
"probe_type": 1
|
||||
},
|
||||
{
|
||||
"name": "u_uart/i_data",
|
||||
"width": 8,
|
||||
"probe_type": 1
|
||||
},
|
||||
{
|
||||
"name": "u_uart/next_state",
|
||||
"width": 2,
|
||||
"probe_type": 1
|
||||
},
|
||||
{
|
||||
"name": "u_uart/o_data",
|
||||
"width": 8,
|
||||
"probe_type": 1
|
||||
},
|
||||
{
|
||||
"name": "u_uart/reset",
|
||||
"width": 1,
|
||||
"probe_type": 1
|
||||
},
|
||||
{
|
||||
"name": "u_uart/rwb",
|
||||
"width": 1,
|
||||
"probe_type": 1
|
||||
},
|
||||
{
|
||||
"name": "u_uart/rx_busy",
|
||||
"width": 1,
|
||||
"probe_type": 1
|
||||
},
|
||||
{
|
||||
"name": "u_uart/rx_data",
|
||||
"width": 8,
|
||||
"probe_type": 1
|
||||
},
|
||||
{
|
||||
"name": "u_uart/rx_data_valid",
|
||||
"width": 1,
|
||||
"probe_type": 1
|
||||
},
|
||||
{
|
||||
"name": "u_uart/rx_error",
|
||||
"width": 1,
|
||||
"probe_type": 1
|
||||
},
|
||||
{
|
||||
"name": "u_uart/rx_i",
|
||||
"width": 1,
|
||||
"probe_type": 1
|
||||
},
|
||||
{
|
||||
"name": "u_uart/rx_parity_error",
|
||||
"width": 1,
|
||||
"probe_type": 1
|
||||
},
|
||||
{
|
||||
"name": "u_uart/state",
|
||||
"width": 2,
|
||||
"probe_type": 1
|
||||
},
|
||||
{
|
||||
"name": "u_uart/status",
|
||||
"width": 8,
|
||||
"probe_type": 1
|
||||
},
|
||||
{
|
||||
"name": "u_uart/tx_busy",
|
||||
"width": 1,
|
||||
"probe_type": 1
|
||||
},
|
||||
{
|
||||
"name": "u_uart/tx_data",
|
||||
"width": 8,
|
||||
"probe_type": 1
|
||||
},
|
||||
{
|
||||
"name": "u_uart/tx_en",
|
||||
"width": 1,
|
||||
"probe_type": 1
|
||||
},
|
||||
{
|
||||
"name": "u_uart/tx_o",
|
||||
"name": "w_sdcard_cs",
|
||||
"width": 1,
|
||||
"probe_type": 1
|
||||
}
|
||||
@@ -267,486 +177,38 @@
|
||||
},
|
||||
{
|
||||
"name": "la0_probe0",
|
||||
"net": "addr",
|
||||
"path": [
|
||||
"u_uart"
|
||||
]
|
||||
"net": "sd_data_OUT",
|
||||
"path": []
|
||||
},
|
||||
{
|
||||
"name": "la0_probe1",
|
||||
"net": "baud_rate",
|
||||
"path": [
|
||||
"u_uart"
|
||||
]
|
||||
"net": "sd_cmd_IN",
|
||||
"path": []
|
||||
},
|
||||
{
|
||||
"name": "la0_probe2",
|
||||
"net": "baud_x16_ce",
|
||||
"path": [
|
||||
"u_uart"
|
||||
]
|
||||
"net": "sd_data_OE",
|
||||
"path": []
|
||||
},
|
||||
{
|
||||
"name": "la0_probe3",
|
||||
"net": "clk",
|
||||
"path": [
|
||||
"u_uart"
|
||||
]
|
||||
"net": "sd_data_IN",
|
||||
"path": []
|
||||
},
|
||||
{
|
||||
"name": "la0_probe4",
|
||||
"net": "clk_50",
|
||||
"path": [
|
||||
"u_uart"
|
||||
]
|
||||
"net": "sd_cmd_OE",
|
||||
"path": []
|
||||
},
|
||||
{
|
||||
"name": "la0_probe5[0]",
|
||||
"net": "control[0]",
|
||||
"path": [
|
||||
"u_uart"
|
||||
]
|
||||
},
|
||||
{
|
||||
"name": "la0_probe5[1]",
|
||||
"net": "control[1]",
|
||||
"path": [
|
||||
"u_uart"
|
||||
]
|
||||
},
|
||||
{
|
||||
"name": "la0_probe5[2]",
|
||||
"net": "control[2]",
|
||||
"path": [
|
||||
"u_uart"
|
||||
]
|
||||
},
|
||||
{
|
||||
"name": "la0_probe5[3]",
|
||||
"net": "control[3]",
|
||||
"path": [
|
||||
"u_uart"
|
||||
]
|
||||
},
|
||||
{
|
||||
"name": "la0_probe5[4]",
|
||||
"net": "control[4]",
|
||||
"path": [
|
||||
"u_uart"
|
||||
]
|
||||
},
|
||||
{
|
||||
"name": "la0_probe5[5]",
|
||||
"net": "control[5]",
|
||||
"path": [
|
||||
"u_uart"
|
||||
]
|
||||
},
|
||||
{
|
||||
"name": "la0_probe5[6]",
|
||||
"net": "control[6]",
|
||||
"path": [
|
||||
"u_uart"
|
||||
]
|
||||
},
|
||||
{
|
||||
"name": "la0_probe5[7]",
|
||||
"net": "control[7]",
|
||||
"path": [
|
||||
"u_uart"
|
||||
]
|
||||
"name": "la0_probe5",
|
||||
"net": "sd_cmd_OUT",
|
||||
"path": []
|
||||
},
|
||||
{
|
||||
"name": "la0_probe6",
|
||||
"net": "cs",
|
||||
"path": [
|
||||
"u_uart"
|
||||
]
|
||||
},
|
||||
{
|
||||
"name": "la0_probe7",
|
||||
"net": "irqb",
|
||||
"path": [
|
||||
"u_uart"
|
||||
]
|
||||
},
|
||||
{
|
||||
"name": "la0_probe8[0]",
|
||||
"net": "i_data[0]",
|
||||
"path": [
|
||||
"u_uart"
|
||||
]
|
||||
},
|
||||
{
|
||||
"name": "la0_probe8[1]",
|
||||
"net": "i_data[1]",
|
||||
"path": [
|
||||
"u_uart"
|
||||
]
|
||||
},
|
||||
{
|
||||
"name": "la0_probe8[2]",
|
||||
"net": "i_data[2]",
|
||||
"path": [
|
||||
"u_uart"
|
||||
]
|
||||
},
|
||||
{
|
||||
"name": "la0_probe8[3]",
|
||||
"net": "i_data[3]",
|
||||
"path": [
|
||||
"u_uart"
|
||||
]
|
||||
},
|
||||
{
|
||||
"name": "la0_probe8[4]",
|
||||
"net": "i_data[4]",
|
||||
"path": [
|
||||
"u_uart"
|
||||
]
|
||||
},
|
||||
{
|
||||
"name": "la0_probe8[5]",
|
||||
"net": "i_data[5]",
|
||||
"path": [
|
||||
"u_uart"
|
||||
]
|
||||
},
|
||||
{
|
||||
"name": "la0_probe8[6]",
|
||||
"net": "i_data[6]",
|
||||
"path": [
|
||||
"u_uart"
|
||||
]
|
||||
},
|
||||
{
|
||||
"name": "la0_probe8[7]",
|
||||
"net": "i_data[7]",
|
||||
"path": [
|
||||
"u_uart"
|
||||
]
|
||||
},
|
||||
{
|
||||
"name": "la0_probe9[0]",
|
||||
"net": "next_state[0]",
|
||||
"path": [
|
||||
"u_uart"
|
||||
]
|
||||
},
|
||||
{
|
||||
"name": "la0_probe9[1]",
|
||||
"net": "next_state[1]",
|
||||
"path": [
|
||||
"u_uart"
|
||||
]
|
||||
},
|
||||
{
|
||||
"name": "la0_probe10[0]",
|
||||
"net": "o_data[0]",
|
||||
"path": [
|
||||
"u_uart"
|
||||
]
|
||||
},
|
||||
{
|
||||
"name": "la0_probe10[1]",
|
||||
"net": "o_data[1]",
|
||||
"path": [
|
||||
"u_uart"
|
||||
]
|
||||
},
|
||||
{
|
||||
"name": "la0_probe10[2]",
|
||||
"net": "o_data[2]",
|
||||
"path": [
|
||||
"u_uart"
|
||||
]
|
||||
},
|
||||
{
|
||||
"name": "la0_probe10[3]",
|
||||
"net": "o_data[3]",
|
||||
"path": [
|
||||
"u_uart"
|
||||
]
|
||||
},
|
||||
{
|
||||
"name": "la0_probe10[4]",
|
||||
"net": "o_data[4]",
|
||||
"path": [
|
||||
"u_uart"
|
||||
]
|
||||
},
|
||||
{
|
||||
"name": "la0_probe10[5]",
|
||||
"net": "o_data[5]",
|
||||
"path": [
|
||||
"u_uart"
|
||||
]
|
||||
},
|
||||
{
|
||||
"name": "la0_probe10[6]",
|
||||
"net": "o_data[6]",
|
||||
"path": [
|
||||
"u_uart"
|
||||
]
|
||||
},
|
||||
{
|
||||
"name": "la0_probe10[7]",
|
||||
"net": "o_data[7]",
|
||||
"path": [
|
||||
"u_uart"
|
||||
]
|
||||
},
|
||||
{
|
||||
"name": "la0_probe11",
|
||||
"net": "reset",
|
||||
"path": [
|
||||
"u_uart"
|
||||
]
|
||||
},
|
||||
{
|
||||
"name": "la0_probe12",
|
||||
"net": "rwb",
|
||||
"path": [
|
||||
"u_uart"
|
||||
]
|
||||
},
|
||||
{
|
||||
"name": "la0_probe13",
|
||||
"net": "rx_busy",
|
||||
"path": [
|
||||
"u_uart"
|
||||
]
|
||||
},
|
||||
{
|
||||
"name": "la0_probe14[0]",
|
||||
"net": "rx_data[0]",
|
||||
"path": [
|
||||
"u_uart"
|
||||
]
|
||||
},
|
||||
{
|
||||
"name": "la0_probe14[1]",
|
||||
"net": "rx_data[1]",
|
||||
"path": [
|
||||
"u_uart"
|
||||
]
|
||||
},
|
||||
{
|
||||
"name": "la0_probe14[2]",
|
||||
"net": "rx_data[2]",
|
||||
"path": [
|
||||
"u_uart"
|
||||
]
|
||||
},
|
||||
{
|
||||
"name": "la0_probe14[3]",
|
||||
"net": "rx_data[3]",
|
||||
"path": [
|
||||
"u_uart"
|
||||
]
|
||||
},
|
||||
{
|
||||
"name": "la0_probe14[4]",
|
||||
"net": "rx_data[4]",
|
||||
"path": [
|
||||
"u_uart"
|
||||
]
|
||||
},
|
||||
{
|
||||
"name": "la0_probe14[5]",
|
||||
"net": "rx_data[5]",
|
||||
"path": [
|
||||
"u_uart"
|
||||
]
|
||||
},
|
||||
{
|
||||
"name": "la0_probe14[6]",
|
||||
"net": "rx_data[6]",
|
||||
"path": [
|
||||
"u_uart"
|
||||
]
|
||||
},
|
||||
{
|
||||
"name": "la0_probe14[7]",
|
||||
"net": "rx_data[7]",
|
||||
"path": [
|
||||
"u_uart"
|
||||
]
|
||||
},
|
||||
{
|
||||
"name": "la0_probe15",
|
||||
"net": "rx_data_valid",
|
||||
"path": [
|
||||
"u_uart"
|
||||
]
|
||||
},
|
||||
{
|
||||
"name": "la0_probe16",
|
||||
"net": "rx_error",
|
||||
"path": [
|
||||
"u_uart"
|
||||
]
|
||||
},
|
||||
{
|
||||
"name": "la0_probe17",
|
||||
"net": "rx_i",
|
||||
"path": [
|
||||
"u_uart"
|
||||
]
|
||||
},
|
||||
{
|
||||
"name": "la0_probe18",
|
||||
"net": "rx_parity_error",
|
||||
"path": [
|
||||
"u_uart"
|
||||
]
|
||||
},
|
||||
{
|
||||
"name": "la0_probe19[0]",
|
||||
"net": "state[0]",
|
||||
"path": [
|
||||
"u_uart"
|
||||
]
|
||||
},
|
||||
{
|
||||
"name": "la0_probe19[1]",
|
||||
"net": "state[1]",
|
||||
"path": [
|
||||
"u_uart"
|
||||
]
|
||||
},
|
||||
{
|
||||
"name": "la0_probe20[0]",
|
||||
"net": "status[0]",
|
||||
"path": [
|
||||
"u_uart"
|
||||
]
|
||||
},
|
||||
{
|
||||
"name": "la0_probe20[1]",
|
||||
"net": "status[1]",
|
||||
"path": [
|
||||
"u_uart"
|
||||
]
|
||||
},
|
||||
{
|
||||
"name": "la0_probe20[2]",
|
||||
"net": "status[2]",
|
||||
"path": [
|
||||
"u_uart"
|
||||
]
|
||||
},
|
||||
{
|
||||
"name": "la0_probe20[3]",
|
||||
"net": "status[3]",
|
||||
"path": [
|
||||
"u_uart"
|
||||
]
|
||||
},
|
||||
{
|
||||
"name": "la0_probe20[4]",
|
||||
"net": "status[4]",
|
||||
"path": [
|
||||
"u_uart"
|
||||
]
|
||||
},
|
||||
{
|
||||
"name": "la0_probe20[5]",
|
||||
"net": "status[5]",
|
||||
"path": [
|
||||
"u_uart"
|
||||
]
|
||||
},
|
||||
{
|
||||
"name": "la0_probe20[6]",
|
||||
"net": "status[6]",
|
||||
"path": [
|
||||
"u_uart"
|
||||
]
|
||||
},
|
||||
{
|
||||
"name": "la0_probe20[7]",
|
||||
"net": "status[7]",
|
||||
"path": [
|
||||
"u_uart"
|
||||
]
|
||||
},
|
||||
{
|
||||
"name": "la0_probe21",
|
||||
"net": "tx_busy",
|
||||
"path": [
|
||||
"u_uart"
|
||||
]
|
||||
},
|
||||
{
|
||||
"name": "la0_probe22[0]",
|
||||
"net": "tx_data[0]",
|
||||
"path": [
|
||||
"u_uart"
|
||||
]
|
||||
},
|
||||
{
|
||||
"name": "la0_probe22[1]",
|
||||
"net": "tx_data[1]",
|
||||
"path": [
|
||||
"u_uart"
|
||||
]
|
||||
},
|
||||
{
|
||||
"name": "la0_probe22[2]",
|
||||
"net": "tx_data[2]",
|
||||
"path": [
|
||||
"u_uart"
|
||||
]
|
||||
},
|
||||
{
|
||||
"name": "la0_probe22[3]",
|
||||
"net": "tx_data[3]",
|
||||
"path": [
|
||||
"u_uart"
|
||||
]
|
||||
},
|
||||
{
|
||||
"name": "la0_probe22[4]",
|
||||
"net": "tx_data[4]",
|
||||
"path": [
|
||||
"u_uart"
|
||||
]
|
||||
},
|
||||
{
|
||||
"name": "la0_probe22[5]",
|
||||
"net": "tx_data[5]",
|
||||
"path": [
|
||||
"u_uart"
|
||||
]
|
||||
},
|
||||
{
|
||||
"name": "la0_probe22[6]",
|
||||
"net": "tx_data[6]",
|
||||
"path": [
|
||||
"u_uart"
|
||||
]
|
||||
},
|
||||
{
|
||||
"name": "la0_probe22[7]",
|
||||
"net": "tx_data[7]",
|
||||
"path": [
|
||||
"u_uart"
|
||||
]
|
||||
},
|
||||
{
|
||||
"name": "la0_probe23",
|
||||
"net": "tx_en",
|
||||
"path": [
|
||||
"u_uart"
|
||||
]
|
||||
},
|
||||
{
|
||||
"name": "la0_probe24",
|
||||
"net": "tx_o",
|
||||
"path": [
|
||||
"u_uart"
|
||||
]
|
||||
"net": "w_sdcard_cs",
|
||||
"path": []
|
||||
}
|
||||
]
|
||||
}
|
||||
@@ -764,270 +226,60 @@
|
||||
"capture_control": false,
|
||||
"selected_nets": [
|
||||
{
|
||||
"name": "addr",
|
||||
"name": "sd_data_OUT",
|
||||
"width": 1,
|
||||
"clk_domain": "clk_2",
|
||||
"selected_probe_type": "DATA AND TRIGGER",
|
||||
"child": [],
|
||||
"path": [
|
||||
"u_uart"
|
||||
]
|
||||
"path": []
|
||||
},
|
||||
{
|
||||
"name": "baud_rate",
|
||||
"name": "sd_cmd_IN",
|
||||
"width": 1,
|
||||
"clk_domain": "clk_2",
|
||||
"selected_probe_type": "DATA AND TRIGGER",
|
||||
"child": [],
|
||||
"path": [
|
||||
"u_uart"
|
||||
]
|
||||
"path": []
|
||||
},
|
||||
{
|
||||
"name": "baud_x16_ce",
|
||||
"name": "sd_data_OE",
|
||||
"width": 1,
|
||||
"clk_domain": "clk_2",
|
||||
"selected_probe_type": "DATA AND TRIGGER",
|
||||
"child": [],
|
||||
"path": [
|
||||
"u_uart"
|
||||
]
|
||||
"path": []
|
||||
},
|
||||
{
|
||||
"name": "clk",
|
||||
"name": "sd_data_IN",
|
||||
"width": 1,
|
||||
"clk_domain": "clk_2",
|
||||
"selected_probe_type": "DATA AND TRIGGER",
|
||||
"child": [],
|
||||
"path": [
|
||||
"u_uart"
|
||||
]
|
||||
"path": []
|
||||
},
|
||||
{
|
||||
"name": "clk_50",
|
||||
"name": "sd_cmd_OE",
|
||||
"width": 1,
|
||||
"clk_domain": "clk_2",
|
||||
"selected_probe_type": "DATA AND TRIGGER",
|
||||
"child": [],
|
||||
"path": [
|
||||
"u_uart"
|
||||
]
|
||||
"path": []
|
||||
},
|
||||
{
|
||||
"name": "control",
|
||||
"width": 8,
|
||||
"clk_domain": "clk_2",
|
||||
"selected_probe_type": "DATA AND TRIGGER",
|
||||
"child": [],
|
||||
"path": [
|
||||
"u_uart"
|
||||
],
|
||||
"net_idx_left": 7,
|
||||
"net_idx_right": 0
|
||||
},
|
||||
{
|
||||
"name": "cs",
|
||||
"name": "sd_cmd_OUT",
|
||||
"width": 1,
|
||||
"clk_domain": "clk_2",
|
||||
"selected_probe_type": "DATA AND TRIGGER",
|
||||
"child": [],
|
||||
"path": [
|
||||
"u_uart"
|
||||
]
|
||||
"path": []
|
||||
},
|
||||
{
|
||||
"name": "irqb",
|
||||
"name": "w_sdcard_cs",
|
||||
"width": 1,
|
||||
"clk_domain": "clk_2",
|
||||
"selected_probe_type": "DATA AND TRIGGER",
|
||||
"child": [],
|
||||
"path": [
|
||||
"u_uart"
|
||||
]
|
||||
},
|
||||
{
|
||||
"name": "i_data",
|
||||
"width": 8,
|
||||
"clk_domain": "clk_2",
|
||||
"selected_probe_type": "DATA AND TRIGGER",
|
||||
"child": [],
|
||||
"path": [
|
||||
"u_uart"
|
||||
],
|
||||
"net_idx_left": 7,
|
||||
"net_idx_right": 0
|
||||
},
|
||||
{
|
||||
"name": "next_state",
|
||||
"width": 2,
|
||||
"clk_domain": "clk_2",
|
||||
"selected_probe_type": "DATA AND TRIGGER",
|
||||
"child": [],
|
||||
"path": [
|
||||
"u_uart"
|
||||
],
|
||||
"net_idx_left": 1,
|
||||
"net_idx_right": 0
|
||||
},
|
||||
{
|
||||
"name": "o_data",
|
||||
"width": 8,
|
||||
"clk_domain": "clk_2",
|
||||
"selected_probe_type": "DATA AND TRIGGER",
|
||||
"child": [],
|
||||
"path": [
|
||||
"u_uart"
|
||||
],
|
||||
"net_idx_left": 7,
|
||||
"net_idx_right": 0
|
||||
},
|
||||
{
|
||||
"name": "reset",
|
||||
"width": 1,
|
||||
"clk_domain": "clk_2",
|
||||
"selected_probe_type": "DATA AND TRIGGER",
|
||||
"child": [],
|
||||
"path": [
|
||||
"u_uart"
|
||||
]
|
||||
},
|
||||
{
|
||||
"name": "rwb",
|
||||
"width": 1,
|
||||
"clk_domain": "clk_2",
|
||||
"selected_probe_type": "DATA AND TRIGGER",
|
||||
"child": [],
|
||||
"path": [
|
||||
"u_uart"
|
||||
]
|
||||
},
|
||||
{
|
||||
"name": "rx_busy",
|
||||
"width": 1,
|
||||
"clk_domain": "clk_2",
|
||||
"selected_probe_type": "DATA AND TRIGGER",
|
||||
"child": [],
|
||||
"path": [
|
||||
"u_uart"
|
||||
]
|
||||
},
|
||||
{
|
||||
"name": "rx_data",
|
||||
"width": 8,
|
||||
"clk_domain": "clk_2",
|
||||
"selected_probe_type": "DATA AND TRIGGER",
|
||||
"child": [],
|
||||
"path": [
|
||||
"u_uart"
|
||||
],
|
||||
"net_idx_left": 7,
|
||||
"net_idx_right": 0
|
||||
},
|
||||
{
|
||||
"name": "rx_data_valid",
|
||||
"width": 1,
|
||||
"clk_domain": "clk_2",
|
||||
"selected_probe_type": "DATA AND TRIGGER",
|
||||
"child": [],
|
||||
"path": [
|
||||
"u_uart"
|
||||
]
|
||||
},
|
||||
{
|
||||
"name": "rx_error",
|
||||
"width": 1,
|
||||
"clk_domain": "clk_2",
|
||||
"selected_probe_type": "DATA AND TRIGGER",
|
||||
"child": [],
|
||||
"path": [
|
||||
"u_uart"
|
||||
]
|
||||
},
|
||||
{
|
||||
"name": "rx_i",
|
||||
"width": 1,
|
||||
"clk_domain": "clk_2",
|
||||
"selected_probe_type": "DATA AND TRIGGER",
|
||||
"child": [],
|
||||
"path": [
|
||||
"u_uart"
|
||||
]
|
||||
},
|
||||
{
|
||||
"name": "rx_parity_error",
|
||||
"width": 1,
|
||||
"clk_domain": "clk_2",
|
||||
"selected_probe_type": "DATA AND TRIGGER",
|
||||
"child": [],
|
||||
"path": [
|
||||
"u_uart"
|
||||
]
|
||||
},
|
||||
{
|
||||
"name": "state",
|
||||
"width": 2,
|
||||
"clk_domain": "clk_2",
|
||||
"selected_probe_type": "DATA AND TRIGGER",
|
||||
"child": [],
|
||||
"path": [
|
||||
"u_uart"
|
||||
],
|
||||
"net_idx_left": 1,
|
||||
"net_idx_right": 0
|
||||
},
|
||||
{
|
||||
"name": "status",
|
||||
"width": 8,
|
||||
"clk_domain": "clk_2",
|
||||
"selected_probe_type": "DATA AND TRIGGER",
|
||||
"child": [],
|
||||
"path": [
|
||||
"u_uart"
|
||||
],
|
||||
"net_idx_left": 7,
|
||||
"net_idx_right": 0
|
||||
},
|
||||
{
|
||||
"name": "tx_busy",
|
||||
"width": 1,
|
||||
"clk_domain": "clk_2",
|
||||
"selected_probe_type": "DATA AND TRIGGER",
|
||||
"child": [],
|
||||
"path": [
|
||||
"u_uart"
|
||||
]
|
||||
},
|
||||
{
|
||||
"name": "tx_data",
|
||||
"width": 8,
|
||||
"clk_domain": "clk_2",
|
||||
"selected_probe_type": "DATA AND TRIGGER",
|
||||
"child": [],
|
||||
"path": [
|
||||
"u_uart"
|
||||
],
|
||||
"net_idx_left": 7,
|
||||
"net_idx_right": 0
|
||||
},
|
||||
{
|
||||
"name": "tx_en",
|
||||
"width": 1,
|
||||
"clk_domain": "clk_2",
|
||||
"selected_probe_type": "DATA AND TRIGGER",
|
||||
"child": [],
|
||||
"path": [
|
||||
"u_uart"
|
||||
]
|
||||
},
|
||||
{
|
||||
"name": "tx_o",
|
||||
"width": 1,
|
||||
"clk_domain": "clk_2",
|
||||
"selected_probe_type": "DATA AND TRIGGER",
|
||||
"child": [],
|
||||
"path": [
|
||||
"u_uart"
|
||||
]
|
||||
"path": []
|
||||
}
|
||||
],
|
||||
"top_module": "super6502",
|
||||
|
||||
@@ -4,25 +4,25 @@ input integer index;//Mode type
|
||||
input integer val_; //Port A index, Port B Index, Number of Items in Loop, Port A Start, Port B Start, reserved
|
||||
case (index)
|
||||
0: bram_ini_table=
|
||||
(val_== 0)?256'h008d000ef000e6000ad000f9000f00000100089000ef000e7000ad00000000a2:
|
||||
(val_== 1)?256'h0000000000000000000000000000000000000000000000f100080000ef000e60:
|
||||
(val_== 2)?256'h0000000000000000000000000000000000000000000000000000000000000000:
|
||||
(val_== 3)?256'h0000000000000000000000000000000000000000000000000000000000000000:
|
||||
(val_== 4)?256'h0000000000000000000000000000000000000000000000000000000000000000:
|
||||
(val_== 5)?256'h0000000000000000000000000000000000000000000000000000000000000000:
|
||||
(val_== 6)?256'h0000000000000000000000000000000000000000000000000000000000000000:
|
||||
(val_== 7)?256'h0000000000000000000000000000000000000000000000000000000000000000:
|
||||
(val_== 8)?256'h0000000000000000000000000000000000000000000000000000000000000000:
|
||||
(val_== 9)?256'h0000000000000000000000000000000000000000000000000000000000000000:
|
||||
(val_==10)?256'h0000000000000000000000000000000000000000000000000000000000000000:
|
||||
(val_==11)?256'h0000000000000000000000000000000000000000000000000000000000000000:
|
||||
(val_==12)?256'h0000000000000000000000000000000000000000000000000000000000000000:
|
||||
(val_==13)?256'h0000000000000000000000000000000000000000000000000000000000000000:
|
||||
(val_==14)?256'h0000000000000000000000000000000000000000000000000000000000000000:
|
||||
(val_==15)?256'h0000000000000000000000000000000000000000000000000000000000000000:
|
||||
(val_==16)?256'h0000000000000000000000000000000000000000000000000000000000000000:
|
||||
(val_==17)?256'h0000000000000000000000000000000000000000000000000000000000000000:
|
||||
(val_==18)?256'h0000000000000000000000000000000000000000000000000000000000000000:
|
||||
(val_== 0)?256'h001000085000aa000a9000ea000ff0002b0002000000000a9000ff0002200020:
|
||||
(val_== 1)?256'h07b0002000000000a200010000a9000ff0002b0002000008000a900011000e60:
|
||||
(val_== 2)?256'h6400011000640001000064000fd00080000cb000ea000f000010000a5000ff00:
|
||||
(val_== 3)?256'h90008e000ef000d80008d000ff000d3000200004800060000130006400012000:
|
||||
(val_== 4)?256'h00068000ef000db0008d00003000a5000ef000da0008d00002000a5000ef000d:
|
||||
(val_== 5)?256'h0029000ef000dc000ad000090008600008000850005a00060000ef000dc0008d:
|
||||
(val_== 6)?256'h0ef000d9000ad000080009100000000a0000ef000d8000ad000f9000f0000010:
|
||||
(val_== 7)?256'hc8000ef000db000ad0000800091000c8000ef000da000ad0000800091000c800:
|
||||
(val_== 8)?256'hc000ad000480006000000000a2000ef000dd000ad000600007a0000800091000:
|
||||
(val_== 9)?256'h000090008600008000850005a0006000068000f9000f00000200029000ef000d:
|
||||
(val_==10)?256'h00c80000800091000c80000800091000c8000080009100000000a000000000a9:
|
||||
(val_==11)?256'h0f00000100029000ef000dc000ad00026000f00008800009000a000008000910:
|
||||
(val_==12)?256'h91000c8000ef000d9000ad000080009100000000a0000ef000d8000ad000f600:
|
||||
(val_==13)?256'h800091000c8000ef000db000ad0000800091000c8000ef000da000ad00008000:
|
||||
(val_==14)?256'h00060000ff000a2000ff000a90007a0006000000000a200000000a90007a0000:
|
||||
(val_==15)?256'h006800001000e6000020009000000000850000000065000980001800048000c8:
|
||||
(val_==16)?256'h088000030008500000000b100003000a0000ff000c10004c00004000a0000600:
|
||||
(val_==17)?256'hce0004c00000000b100088000aa00000000b100088000020008500000000b100:
|
||||
(val_==18)?256'h00000000000000000000000000000000000000000000000000000000000ff000:
|
||||
(val_==19)?256'h000ff00000000ff00000000ff000000000000000000000000000000000000000:
|
||||
(val_==20)?256'h0000000000000000000000000000000000000000000000000000000000000000:
|
||||
(val_==21)?256'h0000000000000000000000000000000000000000000000000000000000000000:
|
||||
|
||||
@@ -1,235 +1,235 @@
|
||||
20
|
||||
22
|
||||
ff
|
||||
a9
|
||||
00
|
||||
20
|
||||
2b
|
||||
ff
|
||||
ea
|
||||
a9
|
||||
aa
|
||||
85
|
||||
10
|
||||
e6
|
||||
11
|
||||
a9
|
||||
08
|
||||
20
|
||||
2b
|
||||
ff
|
||||
a9
|
||||
10
|
||||
a2
|
||||
00
|
||||
ad
|
||||
e7
|
||||
20
|
||||
7b
|
||||
ff
|
||||
a5
|
||||
10
|
||||
f0
|
||||
ea
|
||||
cb
|
||||
80
|
||||
fd
|
||||
64
|
||||
10
|
||||
64
|
||||
11
|
||||
64
|
||||
12
|
||||
64
|
||||
13
|
||||
60
|
||||
48
|
||||
20
|
||||
d3
|
||||
ff
|
||||
8d
|
||||
d8
|
||||
ef
|
||||
89
|
||||
8e
|
||||
d9
|
||||
ef
|
||||
a5
|
||||
02
|
||||
8d
|
||||
da
|
||||
ef
|
||||
a5
|
||||
03
|
||||
8d
|
||||
db
|
||||
ef
|
||||
68
|
||||
8d
|
||||
dc
|
||||
ef
|
||||
60
|
||||
5a
|
||||
85
|
||||
08
|
||||
86
|
||||
09
|
||||
ad
|
||||
dc
|
||||
ef
|
||||
29
|
||||
01
|
||||
f0
|
||||
f9
|
||||
ad
|
||||
e6
|
||||
d8
|
||||
ef
|
||||
8d
|
||||
e6
|
||||
a0
|
||||
00
|
||||
91
|
||||
08
|
||||
ad
|
||||
d9
|
||||
ef
|
||||
80
|
||||
f1
|
||||
00
|
||||
00
|
||||
00
|
||||
00
|
||||
00
|
||||
00
|
||||
00
|
||||
00
|
||||
00
|
||||
00
|
||||
00
|
||||
00
|
||||
00
|
||||
00
|
||||
00
|
||||
00
|
||||
00
|
||||
00
|
||||
00
|
||||
00
|
||||
00
|
||||
00
|
||||
00
|
||||
00
|
||||
00
|
||||
00
|
||||
00
|
||||
00
|
||||
00
|
||||
00
|
||||
00
|
||||
00
|
||||
00
|
||||
00
|
||||
00
|
||||
00
|
||||
00
|
||||
00
|
||||
00
|
||||
00
|
||||
00
|
||||
00
|
||||
00
|
||||
00
|
||||
00
|
||||
00
|
||||
00
|
||||
00
|
||||
00
|
||||
00
|
||||
00
|
||||
00
|
||||
00
|
||||
00
|
||||
00
|
||||
00
|
||||
00
|
||||
00
|
||||
00
|
||||
00
|
||||
00
|
||||
00
|
||||
00
|
||||
00
|
||||
00
|
||||
00
|
||||
00
|
||||
00
|
||||
00
|
||||
00
|
||||
00
|
||||
00
|
||||
00
|
||||
00
|
||||
00
|
||||
00
|
||||
00
|
||||
00
|
||||
00
|
||||
00
|
||||
00
|
||||
00
|
||||
00
|
||||
00
|
||||
00
|
||||
00
|
||||
00
|
||||
00
|
||||
00
|
||||
00
|
||||
00
|
||||
00
|
||||
00
|
||||
00
|
||||
00
|
||||
00
|
||||
00
|
||||
00
|
||||
00
|
||||
00
|
||||
00
|
||||
00
|
||||
00
|
||||
00
|
||||
00
|
||||
00
|
||||
00
|
||||
00
|
||||
00
|
||||
00
|
||||
00
|
||||
00
|
||||
00
|
||||
00
|
||||
00
|
||||
00
|
||||
00
|
||||
00
|
||||
00
|
||||
00
|
||||
00
|
||||
00
|
||||
00
|
||||
00
|
||||
00
|
||||
00
|
||||
00
|
||||
00
|
||||
00
|
||||
00
|
||||
00
|
||||
00
|
||||
00
|
||||
00
|
||||
00
|
||||
00
|
||||
00
|
||||
00
|
||||
00
|
||||
00
|
||||
00
|
||||
00
|
||||
00
|
||||
00
|
||||
00
|
||||
00
|
||||
00
|
||||
00
|
||||
00
|
||||
00
|
||||
00
|
||||
00
|
||||
00
|
||||
00
|
||||
00
|
||||
00
|
||||
00
|
||||
00
|
||||
00
|
||||
00
|
||||
00
|
||||
00
|
||||
00
|
||||
00
|
||||
00
|
||||
00
|
||||
00
|
||||
00
|
||||
00
|
||||
00
|
||||
00
|
||||
00
|
||||
00
|
||||
00
|
||||
00
|
||||
00
|
||||
00
|
||||
00
|
||||
00
|
||||
00
|
||||
00
|
||||
00
|
||||
00
|
||||
00
|
||||
00
|
||||
00
|
||||
00
|
||||
00
|
||||
00
|
||||
00
|
||||
00
|
||||
00
|
||||
00
|
||||
00
|
||||
00
|
||||
00
|
||||
00
|
||||
00
|
||||
00
|
||||
00
|
||||
00
|
||||
00
|
||||
00
|
||||
00
|
||||
00
|
||||
00
|
||||
00
|
||||
00
|
||||
00
|
||||
00
|
||||
00
|
||||
00
|
||||
00
|
||||
00
|
||||
00
|
||||
c8
|
||||
91
|
||||
08
|
||||
ad
|
||||
da
|
||||
ef
|
||||
c8
|
||||
91
|
||||
08
|
||||
ad
|
||||
db
|
||||
ef
|
||||
c8
|
||||
91
|
||||
08
|
||||
7a
|
||||
60
|
||||
ad
|
||||
dd
|
||||
ef
|
||||
a2
|
||||
00
|
||||
60
|
||||
48
|
||||
ad
|
||||
dc
|
||||
ef
|
||||
29
|
||||
02
|
||||
f0
|
||||
f9
|
||||
68
|
||||
60
|
||||
5a
|
||||
85
|
||||
08
|
||||
86
|
||||
09
|
||||
a9
|
||||
00
|
||||
a0
|
||||
00
|
||||
91
|
||||
08
|
||||
c8
|
||||
91
|
||||
08
|
||||
c8
|
||||
91
|
||||
08
|
||||
c8
|
||||
91
|
||||
08
|
||||
a0
|
||||
09
|
||||
88
|
||||
f0
|
||||
26
|
||||
ad
|
||||
dc
|
||||
ef
|
||||
29
|
||||
01
|
||||
f0
|
||||
f6
|
||||
ad
|
||||
d8
|
||||
ef
|
||||
a0
|
||||
00
|
||||
91
|
||||
08
|
||||
ad
|
||||
d9
|
||||
ef
|
||||
c8
|
||||
91
|
||||
08
|
||||
ad
|
||||
da
|
||||
ef
|
||||
c8
|
||||
91
|
||||
08
|
||||
ad
|
||||
db
|
||||
ef
|
||||
c8
|
||||
91
|
||||
08
|
||||
7a
|
||||
a9
|
||||
00
|
||||
a2
|
||||
00
|
||||
60
|
||||
7a
|
||||
a9
|
||||
ff
|
||||
a2
|
||||
ff
|
||||
60
|
||||
c8
|
||||
48
|
||||
18
|
||||
98
|
||||
65
|
||||
00
|
||||
85
|
||||
00
|
||||
90
|
||||
02
|
||||
e6
|
||||
01
|
||||
68
|
||||
60
|
||||
a0
|
||||
04
|
||||
4c
|
||||
c1
|
||||
ff
|
||||
a0
|
||||
03
|
||||
b1
|
||||
00
|
||||
85
|
||||
03
|
||||
88
|
||||
b1
|
||||
00
|
||||
85
|
||||
02
|
||||
88
|
||||
b1
|
||||
00
|
||||
aa
|
||||
88
|
||||
b1
|
||||
00
|
||||
4c
|
||||
ce
|
||||
ff
|
||||
00
|
||||
00
|
||||
00
|
||||
|
||||
235
hw/efinix_fpga/sd_controller.sv
Normal file
235
hw/efinix_fpga/sd_controller.sv
Normal file
@@ -0,0 +1,235 @@
|
||||
module sd_controller(
|
||||
input clk,
|
||||
input sd_clk,
|
||||
input rst,
|
||||
|
||||
input [2:0] addr,
|
||||
input [7:0] data,
|
||||
input cs,
|
||||
input rw,
|
||||
|
||||
input i_sd_cmd,
|
||||
output logic o_sd_cmd,
|
||||
|
||||
input i_sd_data,
|
||||
output logic o_sd_data,
|
||||
|
||||
output logic [7:0] data_out
|
||||
);
|
||||
|
||||
logic [31:0] arg;
|
||||
logic [5:0] cmd;
|
||||
|
||||
logic [47:0] rxcmd_buf;
|
||||
logic [31:0] rx_val;
|
||||
|
||||
logic [7:0] rxdata_buf [512];
|
||||
logic [8:0] data_count;
|
||||
|
||||
logic [15:0] data_crc;
|
||||
|
||||
|
||||
assign rx_val = rxcmd_buf[39:8];
|
||||
|
||||
always_comb begin
|
||||
data_out = 'x;
|
||||
|
||||
if (addr < 4'h4) begin
|
||||
data_out = rx_val[8 * addr +: 8];
|
||||
end else if (addr == 4'h4) begin
|
||||
data_out = {data_flag, read_flag};
|
||||
end else if (addr == 4'h5) begin
|
||||
data_out = rxdata_buf[data_count];
|
||||
end
|
||||
end
|
||||
|
||||
logic read_flag, next_read_flag;
|
||||
logic data_flag, next_data_flag;
|
||||
|
||||
typedef enum bit [2:0] {IDLE, LOAD, CRC, TXCMD, RXCMD, TXDATA, RXDATA, RXDCRC} macro_t;
|
||||
struct packed {
|
||||
macro_t macro;
|
||||
logic [8:0] count;
|
||||
logic [2:0] d_bit_count;
|
||||
} state, next_state;
|
||||
|
||||
always_ff @(negedge clk) begin
|
||||
if (rst) begin
|
||||
state.macro <= IDLE;
|
||||
state.count <= '0;
|
||||
state.d_bit_count <= '1;
|
||||
read_flag <= '0;
|
||||
data_flag <= '0;
|
||||
data_count <= '0;
|
||||
end else begin
|
||||
if (state.macro == TXCMD || state.macro == CRC) begin
|
||||
if (sd_clk) begin
|
||||
state <= next_state;
|
||||
end
|
||||
end else if (state.macro == RXCMD || state.macro == RXDATA || state.macro == RXDCRC) begin
|
||||
if (~sd_clk) begin
|
||||
state <= next_state;
|
||||
end
|
||||
end else begin
|
||||
state <= next_state;
|
||||
end
|
||||
end
|
||||
|
||||
if (sd_clk) begin
|
||||
read_flag <= next_read_flag;
|
||||
data_flag <= next_data_flag;
|
||||
end
|
||||
|
||||
if (cs & ~rw) begin
|
||||
if (addr < 4'h4) begin
|
||||
arg[8 * addr +: 8] <= data;
|
||||
end else if (addr == 4'h4) begin
|
||||
cmd <= data[6:0];
|
||||
end
|
||||
end
|
||||
|
||||
if (cs & addr == 4'h5 && sd_clk) begin
|
||||
data_count <= data_count + 8'b1;
|
||||
end
|
||||
|
||||
if (state.macro == RXCMD) begin
|
||||
rxcmd_buf[6'd46-state.count] <= i_sd_cmd; //we probabily missed bit 47
|
||||
end
|
||||
|
||||
if (state.macro == RXDATA && ~sd_clk) begin
|
||||
rxdata_buf[state.count][state.d_bit_count] <= i_sd_data;
|
||||
end
|
||||
|
||||
if (state.macro == RXDCRC && ~sd_clk) begin
|
||||
data_crc[4'd15-state.count] <= i_sd_data;
|
||||
data_count <= '0;
|
||||
end
|
||||
|
||||
end
|
||||
|
||||
logic [6:0] crc;
|
||||
logic load_crc;
|
||||
logic crc_valid;
|
||||
logic [39:0] _packet;
|
||||
assign _packet = {1'b0, 1'b1, cmd, arg};
|
||||
logic [47:0] packet_crc;
|
||||
assign packet_crc = {_packet, crc, 1'b1};
|
||||
|
||||
crc7 u_crc7(
|
||||
.clk(clk),
|
||||
.rst(rst),
|
||||
.load(load_crc),
|
||||
.data_in(_packet),
|
||||
.crc_out(crc),
|
||||
.valid(crc_valid)
|
||||
);
|
||||
|
||||
always_comb begin
|
||||
next_state = state;
|
||||
next_read_flag = read_flag;
|
||||
next_data_flag = data_flag;
|
||||
|
||||
case (state.macro)
|
||||
IDLE: begin
|
||||
if (~i_sd_cmd) begin // receive data if sd pulls cmd low
|
||||
next_state.macro = RXCMD;
|
||||
end
|
||||
|
||||
if (~i_sd_data) begin
|
||||
next_state.d_bit_count = '1;
|
||||
next_state.macro = RXDATA;
|
||||
end
|
||||
|
||||
if (addr == 4'h4 & cs & ~rw) begin // transmit if cpu writes to cmd
|
||||
next_state.macro = LOAD;
|
||||
end
|
||||
|
||||
if (addr == 4'h4 & cs & rw) begin
|
||||
next_read_flag = '0;
|
||||
end
|
||||
|
||||
if (addr == 4'h5 & cs) begin
|
||||
next_data_flag = '0;
|
||||
end
|
||||
end
|
||||
|
||||
LOAD: begin
|
||||
next_state.macro = CRC;
|
||||
end
|
||||
|
||||
CRC: begin
|
||||
next_state.macro = TXCMD;
|
||||
end
|
||||
|
||||
TXCMD: begin
|
||||
if (state.count < 47) begin
|
||||
next_state.count = state.count + 6'b1;
|
||||
end else begin
|
||||
next_state.macro = IDLE;
|
||||
next_state.count = '0;
|
||||
end
|
||||
end
|
||||
|
||||
RXCMD: begin
|
||||
if (state.count < 47) begin
|
||||
next_state.count = state.count + 6'b1;
|
||||
end else begin
|
||||
next_read_flag = '1;
|
||||
next_state.macro = IDLE;
|
||||
next_state.count = '0;
|
||||
end
|
||||
end
|
||||
|
||||
RXDATA: begin
|
||||
if (state.count < 511 || (state.count == 511 && state.d_bit_count > 0)) begin
|
||||
if (state.d_bit_count == 8'h0) begin
|
||||
next_state.count = state.count + 9'b1;
|
||||
end
|
||||
next_state.d_bit_count = state.d_bit_count - 3'h1;
|
||||
end else begin
|
||||
next_data_flag = '1;
|
||||
next_state.macro = RXDCRC;
|
||||
next_state.count = '0;
|
||||
end
|
||||
end
|
||||
|
||||
RXDCRC: begin
|
||||
if (state.count < 16) begin
|
||||
next_state.count = state.count + 9'b1;
|
||||
end else begin
|
||||
next_state.macro = IDLE;
|
||||
next_state.count = '0;
|
||||
end
|
||||
end
|
||||
|
||||
default: begin
|
||||
next_state.macro = IDLE;
|
||||
next_state.count = '0;
|
||||
end
|
||||
endcase
|
||||
end
|
||||
|
||||
always_comb begin
|
||||
o_sd_cmd = '1; //default to 1
|
||||
o_sd_data = '1;
|
||||
|
||||
load_crc = '0;
|
||||
|
||||
case (state.macro)
|
||||
IDLE:;
|
||||
|
||||
CRC: begin
|
||||
load_crc = '1;
|
||||
end
|
||||
|
||||
TXCMD: begin
|
||||
o_sd_cmd = packet_crc[6'd47 - state.count];
|
||||
end
|
||||
|
||||
RXCMD:;
|
||||
|
||||
default:;
|
||||
endcase
|
||||
end
|
||||
|
||||
endmodule
|
||||
@@ -38,10 +38,33 @@ module super6502
|
||||
output logic [1:0] o_sdr_DQM,
|
||||
|
||||
input uart_rx,
|
||||
output uart_tx
|
||||
output uart_tx,
|
||||
|
||||
output sd_cs,
|
||||
output sd_clk,
|
||||
|
||||
input sd_cmd_IN,
|
||||
output sd_cmd_OUT,
|
||||
output sd_cmd_OE,
|
||||
|
||||
input sd_data_IN,
|
||||
output sd_data_OUT,
|
||||
output sd_data_OE
|
||||
);
|
||||
|
||||
assign sd_cs = '1;
|
||||
|
||||
logic o_sd_cmd, i_sd_cmd;
|
||||
logic o_sd_data, i_sd_data;
|
||||
|
||||
assign i_sd_cmd = sd_cmd_IN;
|
||||
assign sd_cmd_OUT = '0;
|
||||
assign sd_cmd_OE = ~o_sd_cmd;
|
||||
|
||||
assign i_sd_data = sd_data_IN;
|
||||
assign sd_data_OUT = '0;
|
||||
assign sd_data_OE = ~o_sd_data;
|
||||
|
||||
assign pll_cpu_reset = '1;
|
||||
assign o_pll_reset = '1;
|
||||
|
||||
@@ -72,6 +95,7 @@ logic w_timer_cs;
|
||||
logic w_multiplier_cs;
|
||||
logic w_divider_cs;
|
||||
logic w_uart_cs;
|
||||
logic w_sdcard_cs;
|
||||
|
||||
addr_decode u_addr_decode(
|
||||
.i_addr(cpu_addr),
|
||||
@@ -81,6 +105,7 @@ addr_decode u_addr_decode(
|
||||
.o_multiplier_cs(w_multiplier_cs),
|
||||
.o_divider_cs(w_divider_cs),
|
||||
.o_uart_cs(w_uart_cs),
|
||||
.o_sdcard_cs(w_sdcard_cs),
|
||||
.o_sdram_cs(w_sdram_cs)
|
||||
);
|
||||
|
||||
@@ -90,6 +115,7 @@ logic [7:0] w_timer_data_out;
|
||||
logic [7:0] w_multiplier_data_out;
|
||||
logic [7:0] w_divider_data_out;
|
||||
logic [7:0] w_uart_data_out;
|
||||
logic [7:0] w_sdcard_data_out;
|
||||
logic [7:0] w_sdram_data_out;
|
||||
|
||||
always_comb begin
|
||||
@@ -105,6 +131,8 @@ always_comb begin
|
||||
cpu_data_out = w_divider_data_out;
|
||||
else if (w_uart_cs)
|
||||
cpu_data_out = w_uart_data_out;
|
||||
else if (w_sdcard_cs)
|
||||
cpu_data_out = w_sdcard_data_out;
|
||||
else if (w_sdram_cs)
|
||||
cpu_data_out = w_sdram_data_out;
|
||||
else
|
||||
@@ -182,6 +210,31 @@ uart_wrapper u_uart(
|
||||
.irqb(w_uart_irqb)
|
||||
);
|
||||
|
||||
logic sd_clk;
|
||||
always @(posedge clk_2) begin
|
||||
sd_clk <= ~sd_clk;
|
||||
end
|
||||
|
||||
|
||||
sd_controller sd_controller(
|
||||
.clk(clk_2),
|
||||
.sd_clk(sd_clk),
|
||||
.rst(rst),
|
||||
.addr(cpu_addr[2:0]),
|
||||
.data(cpu_data_in),
|
||||
.cs(w_sdcard_cs),
|
||||
.rw(cpu_rwb),
|
||||
|
||||
.i_sd_cmd(i_sd_cmd),
|
||||
.o_sd_cmd(o_sd_cmd),
|
||||
|
||||
.i_sd_data(i_sd_data),
|
||||
.o_sd_data(o_sd_data),
|
||||
|
||||
.data_out(w_sdcard_data_out)
|
||||
);
|
||||
|
||||
|
||||
sdram_adapter u_sdram_adapter(
|
||||
.i_cpuclk(clk_2),
|
||||
.i_arst(~button_reset),
|
||||
|
||||
@@ -1,5 +1,5 @@
|
||||
<?xml version="1.0" encoding="UTF-8"?>
|
||||
<efx:project name="super6502" description="" last_change_date="Thu January 12 2023 14:00:46" location="/home/byron/Projects/super6502/hw/efinix_fpga" sw_version="2022.2.322" last_run_state="pass" last_run_tool="efx_pgm" last_run_flow="bitstream" config_result_in_sync="true" design_ood="sync" place_ood="sync" route_ood="sync" xmlns:efx="http://www.efinixinc.com/enf_proj" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:schemaLocation="http://www.efinixinc.com/enf_proj enf_proj.xsd">
|
||||
<efx:project name="super6502" description="" last_change_date="Thu January 12 2023 16:25:39" location="/home/byron/Projects/super6502/hw/efinix_fpga" sw_version="2022.2.322" last_run_state="pass" last_run_tool="efx_pgm" last_run_flow="bitstream" config_result_in_sync="true" design_ood="sync" place_ood="sync" route_ood="sync" xmlns:efx="http://www.efinixinc.com/enf_proj" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:schemaLocation="http://www.efinixinc.com/enf_proj enf_proj.xsd">
|
||||
<efx:device_info>
|
||||
<efx:family name="Trion"/>
|
||||
<efx:device name="T20F256"/>
|
||||
@@ -21,6 +21,8 @@
|
||||
<efx:design_file name="multiplier.sv" version="default" library="default"/>
|
||||
<efx:design_file name="divider_wrapper.sv" version="default" library="default"/>
|
||||
<efx:design_file name="uart_wrapper.sv" version="default" library="default"/>
|
||||
<efx:design_file name="sd_controller.sv" version="default" library="default"/>
|
||||
<efx:design_file name="crc7.sv" version="default" library="default"/>
|
||||
<efx:top_vhdl_arch name=""/>
|
||||
</efx:design_info>
|
||||
<efx:constraint_info>
|
||||
|
||||
@@ -1,4 +1,4 @@
|
||||
TARGETS=stacktest runram timer timer_irq multiplier divider uart uart2
|
||||
TARGETS=stacktest runram timer timer_irq multiplier divider uart uart2 sdcard
|
||||
SRC=$(wildcard *.s)
|
||||
DIR=../ip/bram
|
||||
|
||||
|
||||
153
hw/efinix_fpga/test_programs/sdcard.s
Normal file
153
hw/efinix_fpga/test_programs/sdcard.s
Normal file
@@ -0,0 +1,153 @@
|
||||
.importzp sp, sreg, ptr1, tmp1, tmp2, tmp3, tmp4
|
||||
|
||||
.export _sd_card_command
|
||||
.export _sd_card_resp
|
||||
.export _sd_card_read_byte
|
||||
.export _sd_card_wait_for_data
|
||||
|
||||
.autoimport on
|
||||
|
||||
.code
|
||||
|
||||
|
||||
SD_ARG = $efd8
|
||||
SD_CMD = $efdc
|
||||
SD_DATA = $efdd
|
||||
|
||||
_resp = $10
|
||||
|
||||
|
||||
main:
|
||||
@cmd0:
|
||||
jsr stztmp ; arg = 0
|
||||
lda #$00 ; cmd = 0
|
||||
jsr _sd_card_command
|
||||
|
||||
nop ; no resp, so need to wait for cmd to finish
|
||||
@cmd8:
|
||||
lda #$aa
|
||||
sta tmp1
|
||||
inc tmp2 ; arg = 000001aa
|
||||
lda #$08 ; cmd = 8
|
||||
jsr _sd_card_command
|
||||
|
||||
lda #<_resp
|
||||
ldx #>_resp
|
||||
jsr _sd_card_resp_timeout
|
||||
|
||||
lda _resp
|
||||
beq @cmd8
|
||||
|
||||
end:
|
||||
wai
|
||||
bra end
|
||||
|
||||
stztmp:
|
||||
stz tmp1
|
||||
stz tmp2
|
||||
stz tmp3
|
||||
stz tmp4
|
||||
rts
|
||||
|
||||
; Send sd card command.
|
||||
; command is in A register, the args are on the stack
|
||||
; I think the order is high byte first?
|
||||
_sd_card_command:
|
||||
pha
|
||||
|
||||
jsr popeax
|
||||
sta SD_ARG
|
||||
stx SD_ARG+1
|
||||
lda sreg
|
||||
sta SD_ARG+2
|
||||
lda sreg+1
|
||||
sta SD_ARG+3
|
||||
|
||||
pla
|
||||
sta SD_CMD
|
||||
rts
|
||||
|
||||
; void sd_card_resp(uint32_t* resp);
|
||||
_sd_card_resp:
|
||||
phy
|
||||
sta ptr1 ; store pointer
|
||||
stx ptr1+1
|
||||
@1: lda SD_CMD ; wait for status flag
|
||||
and #$01
|
||||
beq @1
|
||||
lda SD_ARG
|
||||
ldy #$0
|
||||
sta (ptr1),y
|
||||
lda SD_ARG+1
|
||||
iny
|
||||
sta (ptr1),y
|
||||
lda SD_ARG+2
|
||||
iny
|
||||
sta (ptr1),y
|
||||
lda SD_ARG+3
|
||||
iny
|
||||
sta (ptr1),y
|
||||
ply
|
||||
rts
|
||||
|
||||
_sd_card_read_byte:
|
||||
lda SD_DATA
|
||||
ldx #$00
|
||||
rts
|
||||
|
||||
_sd_card_wait_for_data:
|
||||
pha
|
||||
@1: lda SD_CMD ; wait for status flag
|
||||
and #$02
|
||||
beq @1
|
||||
pla
|
||||
rts
|
||||
|
||||
|
||||
; int sd_card_resp_timeout(uint32_t* resp);
|
||||
_sd_card_resp_timeout:
|
||||
phy
|
||||
sta ptr1 ; store pointer
|
||||
stx ptr1+1
|
||||
lda #$0
|
||||
ldy #$0
|
||||
sta (ptr1),y
|
||||
iny
|
||||
sta (ptr1),y
|
||||
iny
|
||||
sta (ptr1),y
|
||||
iny
|
||||
sta (ptr1),y
|
||||
ldy #$9
|
||||
@1: dey
|
||||
beq @timeout
|
||||
lda SD_CMD ; wait for status flag
|
||||
and #$01
|
||||
beq @1
|
||||
lda SD_ARG
|
||||
ldy #$0
|
||||
sta (ptr1),y
|
||||
lda SD_ARG+1
|
||||
iny
|
||||
sta (ptr1),y
|
||||
lda SD_ARG+2
|
||||
iny
|
||||
sta (ptr1),y
|
||||
lda SD_ARG+3
|
||||
iny
|
||||
sta (ptr1),y
|
||||
ply
|
||||
lda #$00
|
||||
ldx #$00
|
||||
rts
|
||||
@timeout:
|
||||
ply
|
||||
lda #$ff
|
||||
ldx #$ff
|
||||
rts
|
||||
|
||||
.segment "VECTORS"
|
||||
|
||||
.addr main
|
||||
.addr main
|
||||
.addr main
|
||||
Reference in New Issue
Block a user