This commit is contained in:
Polprzewodnikowy 2021-08-15 21:49:02 +02:00
parent 494707a60b
commit 0db5e5c59f
29 changed files with 829 additions and 834 deletions

View File

@ -19,7 +19,7 @@
#
# Quartus Prime
# Version 20.1.1 Build 720 11/11/2020 SJ Lite Edition
# Date created = 20:28:54 August 10, 2021
# Date created = 18:00:40 August 15, 2021
#
# -------------------------------------------------------------------------- #
#
@ -59,11 +59,14 @@ set_global_assignment -name SYSTEMVERILOG_FILE rtl/cpu/cpu_ram.sv
set_global_assignment -name SYSTEMVERILOG_FILE rtl/cpu/cpu_soc.sv
set_global_assignment -name SYSTEMVERILOG_FILE rtl/cpu/cpu_uart.sv
set_global_assignment -name SYSTEMVERILOG_FILE rtl/cpu/cpu_usb.sv
set_global_assignment -name SYSTEMVERILOG_FILE rtl/cpu/cpu_wrapper.sv
set_global_assignment -name SYSTEMVERILOG_FILE rtl/usb/usb_fifo.sv
set_global_assignment -name SYSTEMVERILOG_FILE rtl/usb/usb_ft1248.sv
set_global_assignment -name SYSTEMVERILOG_FILE rtl/SummerCart64.sv
set_global_assignment -name SYSTEMVERILOG_FILE rtl/system/system.sv
set_global_assignment -name SYSTEMVERILOG_FILE rtl/old/usb_ftdi_fsi.sv
set_global_assignment -name SOURCE_FILE sfp.spf
set_global_assignment -name QIP_FILE rtl/intel/fifo/fifo8.qip
# Pin & Location Assignments
# ==========================
@ -222,104 +225,34 @@ set_global_assignment -name OUTPUT_IO_TIMING_FAR_END_VMEAS "HALF SIGNAL SWING" -
# Fitter Assignments
# ==================
set_instance_assignment -name WEAK_PULL_UP_RESISTOR ON -to i_n64_nmi
set_instance_assignment -name WEAK_PULL_UP_RESISTOR ON -to i_n64_pi_aleh
set_instance_assignment -name WEAK_PULL_UP_RESISTOR ON -to i_n64_pi_alel
set_instance_assignment -name WEAK_PULL_UP_RESISTOR ON -to i_n64_pi_read
set_instance_assignment -name WEAK_PULL_UP_RESISTOR ON -to i_n64_pi_write
set_instance_assignment -name WEAK_PULL_UP_RESISTOR ON -to i_n64_reset
set_instance_assignment -name WEAK_PULL_UP_RESISTOR ON -to i_n64_si_clk
set_instance_assignment -name WEAK_PULL_UP_RESISTOR ON -to io_n64_si_dq
set_instance_assignment -name WEAK_PULL_UP_RESISTOR ON -to o_n64_irq
set_instance_assignment -name WEAK_PULL_UP_RESISTOR ON -to o_usb_cs
set_instance_assignment -name WEAK_PULL_UP_RESISTOR ON -to o_usb_miosi[0]
set_instance_assignment -name WEAK_PULL_UP_RESISTOR ON -to o_usb_miosi[1]
set_instance_assignment -name WEAK_PULL_UP_RESISTOR ON -to o_usb_miosi[2]
set_instance_assignment -name WEAK_PULL_UP_RESISTOR ON -to o_usb_miosi[3]
set_instance_assignment -name WEAK_PULL_UP_RESISTOR ON -to i_n64_nmi
set_instance_assignment -name WEAK_PULL_UP_RESISTOR ON -to i_n64_pi_aleh
set_instance_assignment -name WEAK_PULL_UP_RESISTOR ON -to i_n64_pi_alel
set_instance_assignment -name WEAK_PULL_UP_RESISTOR ON -to i_n64_pi_read
set_instance_assignment -name WEAK_PULL_UP_RESISTOR ON -to i_n64_pi_write
set_instance_assignment -name WEAK_PULL_UP_RESISTOR ON -to i_n64_reset
set_instance_assignment -name WEAK_PULL_UP_RESISTOR ON -to i_n64_si_clk
set_instance_assignment -name WEAK_PULL_UP_RESISTOR ON -to io_n64_si_dq
set_instance_assignment -name WEAK_PULL_UP_RESISTOR ON -to o_n64_irq
set_instance_assignment -name WEAK_PULL_UP_RESISTOR ON -to o_usb_cs
set_instance_assignment -name WEAK_PULL_UP_RESISTOR ON -to o_usb_miosi[0]
set_instance_assignment -name WEAK_PULL_UP_RESISTOR ON -to o_usb_miosi[1]
set_instance_assignment -name WEAK_PULL_UP_RESISTOR ON -to o_usb_miosi[2]
set_instance_assignment -name WEAK_PULL_UP_RESISTOR ON -to o_usb_miosi[3]
# start DESIGN_PARTITION(Top)
# ---------------------------
# Incremental Compilation Assignments
# ===================================
set_global_assignment -name PARTITION_NETLIST_TYPE SOURCE -section_id Top
set_global_assignment -name PARTITION_FITTER_PRESERVATION_LEVEL PLACEMENT_AND_ROUTING -section_id Top
set_global_assignment -name PARTITION_COLOR 16764057 -section_id Top
set_global_assignment -name PARTITION_NETLIST_TYPE SOURCE -section_id Top
set_global_assignment -name PARTITION_FITTER_PRESERVATION_LEVEL PLACEMENT_AND_ROUTING -section_id Top
set_global_assignment -name PARTITION_COLOR 16764057 -section_id Top
# end DESIGN_PARTITION(Top)
# -------------------------
# end ENTITY(SummerCart64)
# ------------------------
set_global_assignment -name SLD_NODE_CREATOR_ID 110 -section_id auto_signaltap_0
set_global_assignment -name SLD_NODE_ENTITY_NAME sld_signaltap -section_id auto_signaltap_0
set_instance_assignment -name CONNECT_TO_SLD_NODE_ENTITY_PORT acq_trigger_in[0] -to i_n64_reset -section_id auto_signaltap_0
set_instance_assignment -name CONNECT_TO_SLD_NODE_ENTITY_PORT acq_trigger_in[1] -to i_n64_si_clk -section_id auto_signaltap_0
set_instance_assignment -name CONNECT_TO_SLD_NODE_ENTITY_PORT acq_data_in[0] -to i_n64_reset -section_id auto_signaltap_0
set_instance_assignment -name CONNECT_TO_SLD_NODE_ENTITY_PORT acq_data_in[1] -to i_n64_si_clk -section_id auto_signaltap_0
set_global_assignment -name SLD_NODE_PARAMETER_ASSIGNMENT "SLD_RAM_BLOCK_TYPE=AUTO" -section_id auto_signaltap_0
set_global_assignment -name SLD_NODE_PARAMETER_ASSIGNMENT "SLD_STORAGE_QUALIFIER_BITS=42" -section_id auto_signaltap_0
set_global_assignment -name SLD_NODE_PARAMETER_ASSIGNMENT "SLD_NODE_INFO=805334528" -section_id auto_signaltap_0
set_global_assignment -name SLD_NODE_PARAMETER_ASSIGNMENT "SLD_POWER_UP_TRIGGER=0" -section_id auto_signaltap_0
set_global_assignment -name SLD_NODE_PARAMETER_ASSIGNMENT "SLD_STORAGE_QUALIFIER_INVERSION_MASK_LENGTH=0" -section_id auto_signaltap_0
set_global_assignment -name SLD_NODE_PARAMETER_ASSIGNMENT "SLD_ATTRIBUTE_MEM_MODE=OFF" -section_id auto_signaltap_0
set_global_assignment -name SLD_NODE_PARAMETER_ASSIGNMENT "SLD_STATE_FLOW_USE_GENERATED=0" -section_id auto_signaltap_0
set_global_assignment -name SLD_NODE_PARAMETER_ASSIGNMENT "SLD_STATE_BITS=11" -section_id auto_signaltap_0
set_global_assignment -name SLD_NODE_PARAMETER_ASSIGNMENT "SLD_BUFFER_FULL_STOP=1" -section_id auto_signaltap_0
set_global_assignment -name SLD_NODE_PARAMETER_ASSIGNMENT "SLD_CURRENT_RESOURCE_WIDTH=1" -section_id auto_signaltap_0
set_global_assignment -name SLD_NODE_PARAMETER_ASSIGNMENT "SLD_INCREMENTAL_ROUTING=1" -section_id auto_signaltap_0
set_instance_assignment -name POST_FIT_CONNECT_TO_SLD_NODE_ENTITY_PORT crc[0] -to auto_signaltap_0|gnd -section_id auto_signaltap_0
set_instance_assignment -name POST_FIT_CONNECT_TO_SLD_NODE_ENTITY_PORT crc[2] -to auto_signaltap_0|gnd -section_id auto_signaltap_0
set_instance_assignment -name POST_FIT_CONNECT_TO_SLD_NODE_ENTITY_PORT crc[3] -to auto_signaltap_0|vcc -section_id auto_signaltap_0
set_instance_assignment -name POST_FIT_CONNECT_TO_SLD_NODE_ENTITY_PORT crc[8] -to auto_signaltap_0|vcc -section_id auto_signaltap_0
set_instance_assignment -name POST_FIT_CONNECT_TO_SLD_NODE_ENTITY_PORT crc[9] -to auto_signaltap_0|gnd -section_id auto_signaltap_0
set_instance_assignment -name POST_FIT_CONNECT_TO_SLD_NODE_ENTITY_PORT crc[10] -to auto_signaltap_0|gnd -section_id auto_signaltap_0
set_instance_assignment -name POST_FIT_CONNECT_TO_SLD_NODE_ENTITY_PORT crc[13] -to auto_signaltap_0|gnd -section_id auto_signaltap_0
set_instance_assignment -name POST_FIT_CONNECT_TO_SLD_NODE_ENTITY_PORT crc[14] -to auto_signaltap_0|gnd -section_id auto_signaltap_0
set_instance_assignment -name POST_FIT_CONNECT_TO_SLD_NODE_ENTITY_PORT crc[15] -to auto_signaltap_0|vcc -section_id auto_signaltap_0
set_instance_assignment -name POST_FIT_CONNECT_TO_SLD_NODE_ENTITY_PORT crc[17] -to auto_signaltap_0|vcc -section_id auto_signaltap_0
set_instance_assignment -name POST_FIT_CONNECT_TO_SLD_NODE_ENTITY_PORT crc[23] -to auto_signaltap_0|gnd -section_id auto_signaltap_0
set_instance_assignment -name POST_FIT_CONNECT_TO_SLD_NODE_ENTITY_PORT crc[25] -to auto_signaltap_0|vcc -section_id auto_signaltap_0
set_instance_assignment -name POST_FIT_CONNECT_TO_SLD_NODE_ENTITY_PORT crc[28] -to auto_signaltap_0|gnd -section_id auto_signaltap_0
set_instance_assignment -name POST_FIT_CONNECT_TO_SLD_NODE_ENTITY_PORT crc[31] -to auto_signaltap_0|gnd -section_id auto_signaltap_0
set_global_assignment -name SLD_NODE_PARAMETER_ASSIGNMENT "SLD_TRIGGER_LEVEL=1" -section_id auto_signaltap_0
set_global_assignment -name SLD_NODE_PARAMETER_ASSIGNMENT "SLD_TRIGGER_IN_ENABLED=0" -section_id auto_signaltap_0
set_global_assignment -name SLD_NODE_PARAMETER_ASSIGNMENT "SLD_TRIGGER_PIPELINE=0" -section_id auto_signaltap_0
set_global_assignment -name SLD_NODE_PARAMETER_ASSIGNMENT "SLD_RAM_PIPELINE=0" -section_id auto_signaltap_0
set_global_assignment -name SLD_NODE_PARAMETER_ASSIGNMENT "SLD_COUNTER_PIPELINE=0" -section_id auto_signaltap_0
set_global_assignment -name SLD_NODE_PARAMETER_ASSIGNMENT "SLD_ADVANCED_TRIGGER_ENTITY=basic,1," -section_id auto_signaltap_0
set_global_assignment -name SLD_NODE_PARAMETER_ASSIGNMENT "SLD_TRIGGER_LEVEL_PIPELINE=1" -section_id auto_signaltap_0
set_global_assignment -name SLD_NODE_PARAMETER_ASSIGNMENT "SLD_ENABLE_ADVANCED_TRIGGER=0" -section_id auto_signaltap_0
set_instance_assignment -name POST_FIT_CONNECT_TO_SLD_NODE_ENTITY_PORT crc[30] -to auto_signaltap_0|vcc -section_id auto_signaltap_0
set_global_assignment -name SLD_NODE_PARAMETER_ASSIGNMENT "SLD_SEGMENT_SIZE=65536" -section_id auto_signaltap_0
set_instance_assignment -name POST_FIT_CONNECT_TO_SLD_NODE_ENTITY_PORT crc[20] -to auto_signaltap_0|vcc -section_id auto_signaltap_0
set_instance_assignment -name POST_FIT_CONNECT_TO_SLD_NODE_ENTITY_PORT crc[22] -to auto_signaltap_0|vcc -section_id auto_signaltap_0
set_global_assignment -name SLD_NODE_PARAMETER_ASSIGNMENT "SLD_SAMPLE_DEPTH=65536" -section_id auto_signaltap_0
set_instance_assignment -name CONNECT_TO_SLD_NODE_ENTITY_PORT acq_clk -to i_clk -section_id auto_signaltap_0
set_instance_assignment -name POST_FIT_CONNECT_TO_SLD_NODE_ENTITY_PORT crc[5] -to auto_signaltap_0|gnd -section_id auto_signaltap_0
set_instance_assignment -name POST_FIT_CONNECT_TO_SLD_NODE_ENTITY_PORT crc[12] -to auto_signaltap_0|vcc -section_id auto_signaltap_0
set_instance_assignment -name CONNECT_TO_SLD_NODE_ENTITY_PORT acq_trigger_in[2] -to io_avr_mosi -section_id auto_signaltap_0
set_instance_assignment -name CONNECT_TO_SLD_NODE_ENTITY_PORT acq_trigger_in[3] -to io_n64_cic_clk -section_id auto_signaltap_0
set_instance_assignment -name CONNECT_TO_SLD_NODE_ENTITY_PORT acq_trigger_in[4] -to io_n64_cic_dq -section_id auto_signaltap_0
set_instance_assignment -name CONNECT_TO_SLD_NODE_ENTITY_PORT acq_data_in[2] -to io_avr_mosi -section_id auto_signaltap_0
set_instance_assignment -name CONNECT_TO_SLD_NODE_ENTITY_PORT acq_data_in[3] -to io_n64_cic_clk -section_id auto_signaltap_0
set_instance_assignment -name CONNECT_TO_SLD_NODE_ENTITY_PORT acq_data_in[4] -to io_n64_cic_dq -section_id auto_signaltap_0
set_global_assignment -name SLD_NODE_PARAMETER_ASSIGNMENT "SLD_DATA_BITS=5" -section_id auto_signaltap_0
set_global_assignment -name SLD_NODE_PARAMETER_ASSIGNMENT "SLD_TRIGGER_BITS=5" -section_id auto_signaltap_0
set_global_assignment -name SLD_NODE_PARAMETER_ASSIGNMENT "SLD_INVERSION_MASK=000000000000000000000000000000000000000000000" -section_id auto_signaltap_0
set_global_assignment -name SLD_NODE_PARAMETER_ASSIGNMENT "SLD_INVERSION_MASK_LENGTH=45" -section_id auto_signaltap_0
set_instance_assignment -name POST_FIT_CONNECT_TO_SLD_NODE_ENTITY_PORT crc[1] -to auto_signaltap_0|gnd -section_id auto_signaltap_0
set_instance_assignment -name POST_FIT_CONNECT_TO_SLD_NODE_ENTITY_PORT crc[4] -to auto_signaltap_0|vcc -section_id auto_signaltap_0
set_instance_assignment -name POST_FIT_CONNECT_TO_SLD_NODE_ENTITY_PORT crc[6] -to auto_signaltap_0|vcc -section_id auto_signaltap_0
set_instance_assignment -name POST_FIT_CONNECT_TO_SLD_NODE_ENTITY_PORT crc[7] -to auto_signaltap_0|vcc -section_id auto_signaltap_0
set_instance_assignment -name POST_FIT_CONNECT_TO_SLD_NODE_ENTITY_PORT crc[11] -to auto_signaltap_0|vcc -section_id auto_signaltap_0
set_instance_assignment -name POST_FIT_CONNECT_TO_SLD_NODE_ENTITY_PORT crc[16] -to auto_signaltap_0|vcc -section_id auto_signaltap_0
set_instance_assignment -name POST_FIT_CONNECT_TO_SLD_NODE_ENTITY_PORT crc[18] -to auto_signaltap_0|gnd -section_id auto_signaltap_0
set_instance_assignment -name POST_FIT_CONNECT_TO_SLD_NODE_ENTITY_PORT crc[19] -to auto_signaltap_0|vcc -section_id auto_signaltap_0
set_instance_assignment -name POST_FIT_CONNECT_TO_SLD_NODE_ENTITY_PORT crc[21] -to auto_signaltap_0|vcc -section_id auto_signaltap_0
set_instance_assignment -name POST_FIT_CONNECT_TO_SLD_NODE_ENTITY_PORT crc[24] -to auto_signaltap_0|gnd -section_id auto_signaltap_0
set_instance_assignment -name POST_FIT_CONNECT_TO_SLD_NODE_ENTITY_PORT crc[26] -to auto_signaltap_0|vcc -section_id auto_signaltap_0
set_instance_assignment -name POST_FIT_CONNECT_TO_SLD_NODE_ENTITY_PORT crc[27] -to auto_signaltap_0|gnd -section_id auto_signaltap_0
set_instance_assignment -name POST_FIT_CONNECT_TO_SLD_NODE_ENTITY_PORT crc[29] -to auto_signaltap_0|gnd -section_id auto_signaltap_0
set_global_assignment -name SLD_FILE db/stp_auto_stripped.stp
set_instance_assignment -name PARTITION_HIERARCHY root_partition -to | -section_id Top

View File

@ -23,7 +23,7 @@ try:
if (not line):
break
value = format(struct.unpack('<I', line)[0], '08x')
rom_formatted += f'\n {index}: {var_name} = 32\'h{value};'
rom_formatted += f'\n {index}: {var_name} = 32\'h{value};'
index += 1
sv_code.write(sv_template.read().format(rom_formatted=rom_formatted))

Binary file not shown.

View File

@ -3,12 +3,12 @@
int reset_handler (void) {
io8_t pointer = &RAM;
while (!(UART_SR & UART_SR_TXE));
UART_TX = '>';
while (!(USB_SR & USB_SR_TXE));
USB_DR = '>';
while (1) {
if (UART_SR & UART_SR_RXNE) {
*pointer++ = UART_RX;
if (USB_SR & USB_SR_RXNE) {
*pointer++ = USB_DR;
}
if ((uint32_t)pointer == (24 * 1024)) {
__asm__("call 0");

Binary file not shown.

View File

@ -9,16 +9,15 @@ typedef volatile uint8_t * io8_t;
typedef volatile uint32_t * io32_t;
#define RAM (*((io8_t) 0x00000000))
#define UART_SR (*((io8_t) 0xB0000000))
#define UART_RX (*((io8_t) 0xB0000004))
#define UART_TX (*((io8_t) 0xB0000008))
#define GPIO (*((io32_t) 0xE0000000))
#define GPIO_O (*((io8_t) 0xE0000000))
#define GPIO_I (*((io8_t) 0xE0000001))
#define GPIO_OE (*((io8_t) 0xE0000002))
#define GPIO (*((io32_t) 0x20000000))
#define GPIO_O (*((io8_t) 0x20000000))
#define GPIO_I (*((io8_t) 0x20000001))
#define GPIO_OE (*((io8_t) 0x20000002))
#define USB_SR (*((io8_t) 0x40000000))
#define USB_DR (*((io8_t) 0x40000004))
#define UART_SR_RXNE (1 << 0)
#define UART_SR_TXE (1 << 1)
#define USB_SR_RXNE (1 << 0)
#define USB_SR_TXE (1 << 1)
#endif

View File

@ -1,7 +1,7 @@
MEMORY
{
ram (rwx) : org = 0x00000000, len = 24k
rom (rx) : org = 0xF0000000, len = 1k
rom (rx) : org = 0x10000000, len = 1k
}
__stack_pointer = ORIGIN(ram) + LENGTH(ram) - 16;

View File

@ -1,43 +1,39 @@
module cpu_bootloader (
if_system.sys system_if,
if_cpu_bus_out cpu_bus_if,
if_cpu_bus_in cpu_bootloader_if
);
module cpu_bootloader (if_cpu_bus bus);
wire request;
wire [31:0] rdata;
cpu_bus_glue #(.ADDRESS(4'hF)) cpu_bus_glue_bootloader_inst (
.*,
.cpu_peripheral_if(cpu_bootloader_if),
.request(request),
.rdata(rdata)
);
always_ff @(posedge bus.clk) begin
bus.ack <= 1'b0;
if (bus.request) begin
bus.ack <= 1'b1;
end
end
always_comb begin
case (cpu_bus_if.address[6:2])
0: rdata = 32'hb0000737;
1: rdata = 32'h00074783;
2: rdata = 32'h0027f793;
3: rdata = 32'hfe078ce3;
4: rdata = 32'h03e00793;
5: rdata = 32'h00f70423;
6: rdata = 32'hb00006b7;
7: rdata = 32'h00000793;
8: rdata = 32'h00006637;
9: rdata = 32'h0006c703;
10: rdata = 32'h00177713;
11: rdata = 32'h00070a63;
12: rdata = 32'h0046c703;
13: rdata = 32'h00178793;
14: rdata = 32'h0ff77713;
15: rdata = 32'hfee78fa3;
16: rdata = 32'hfec792e3;
17: rdata = 32'h10000097;
18: rdata = 32'hfbc080e7;
19: rdata = 32'hfd9ff06f;
default: rdata = 32'h0000_0000;
endcase
bus.rdata = 32'd0;
if (bus.ack) begin
case (bus.address[6:2])
0: bus.rdata = 32'h40000737;
1: bus.rdata = 32'h00074783;
2: bus.rdata = 32'h0027f793;
3: bus.rdata = 32'hfe078ce3;
4: bus.rdata = 32'h03e00793;
5: bus.rdata = 32'h00f70223;
6: bus.rdata = 32'h400006b7;
7: bus.rdata = 32'h00000793;
8: bus.rdata = 32'h00006637;
9: bus.rdata = 32'h0006c703;
10: bus.rdata = 32'h00177713;
11: bus.rdata = 32'h00070a63;
12: bus.rdata = 32'h0046c703;
13: bus.rdata = 32'h00178793;
14: bus.rdata = 32'h0ff77713;
15: bus.rdata = 32'hfee78fa3;
16: bus.rdata = 32'hfec792e3;
17: bus.rdata = 32'hf0000097;
18: bus.rdata = 32'hfbc080e7;
19: bus.rdata = 32'hfd9ff06f;
default: bus.rdata = 32'd0;
endcase
end
end
endmodule

View File

@ -1,24 +1,22 @@
rdata
module cpu_bootloader (
if_system.sys system_if,
if_cpu_bus_out cpu_bus_if,
if_cpu_bus_in cpu_bootloader_if
);
bus.rdata
module cpu_bootloader (if_cpu_bus bus);
wire request;
wire [31:0] rdata;
cpu_bus_glue #(.ADDRESS(4'hF)) cpu_bus_glue_bootloader_inst (
.*,
.cpu_peripheral_if(cpu_bootloader_if),
.request(request),
.rdata(rdata)
);
always_ff @(posedge bus.clk) begin
bus.ack <= 1'b0;
if (bus.request) begin
bus.ack <= 1'b1;
end
end
always_comb begin
case (cpu_bus_if.address[6:2]){rom_formatted}
default: rdata = 32'h0000_0000;
endcase
bus.rdata = 32'd0;
if (bus.ack) begin
case (bus.address[6:2]){rom_formatted}
default: bus.rdata = 32'd0;
endcase
end
end
endmodule

Binary file not shown.

Binary file not shown.

View File

@ -7,8 +7,8 @@ volatile int counter = 0;
void print (const char *text) {
while (*text != '\0') {
while (!(UART_SR & UART_SR_TXE) && (!(UART_SR & UART_SR_RXNE)));
UART_TX = *text++;
while (!(UART_SR & UART_SR_TXE));
UART_DR = *text++;
}
}
@ -77,7 +77,7 @@ __NAKED__ int main (void) {
counter = 0;
if (UART_SR & UART_SR_RXNE) {
rtc_new_data[index++] = UART_RX;
rtc_new_data[index++] = UART_DR;
if (index == 7) {
index = 0;
rtc_set_time(rtc_new_data);

View File

@ -11,15 +11,14 @@
typedef volatile uint8_t * io8_t;
typedef volatile uint32_t * io32_t;
#define I2C_SR (*((io8_t) 0xC0000000))
#define I2C_DR (*((io8_t) 0xC0000004))
#define UART_SR (*((io8_t) 0xD0000000))
#define UART_RX (*((io8_t) 0xD0000004))
#define UART_TX (*((io8_t) 0xD0000008))
#define GPIO (*((io32_t) 0xE0000000))
#define GPIO_O (*((io8_t) 0xE0000000))
#define GPIO_I (*((io8_t) 0xE0000001))
#define GPIO_OE (*((io8_t) 0xE0000002))
#define GPIO (*((io32_t) 0x20000000))
#define GPIO_O (*((io8_t) 0x20000000))
#define GPIO_I (*((io8_t) 0x20000001))
#define GPIO_OE (*((io8_t) 0x20000002))
#define I2C_SR (*((io8_t) 0x30000000))
#define I2C_DR (*((io8_t) 0x30000004))
#define UART_SR (*((io8_t) 0x40000000))
#define UART_DR (*((io8_t) 0x40000004))
#define I2C_SR_START (1 << 0)
#define I2C_SR_STOP (1 << 1)

Binary file not shown.

View File

@ -6,10 +6,10 @@ module SummerCart64 (
input i_usb_miso,
inout [3:0] io_usb_miosi,
output o_ftdi_clk,
output o_ftdi_si,
input i_ftdi_so,
input i_ftdi_cts,
// output o_ftdi_clk,
// output o_ftdi_si,
// input i_ftdi_so,
// input i_ftdi_cts,
input i_n64_reset,
input i_n64_nmi,
@ -37,9 +37,9 @@ module SummerCart64 (
inout io_sd_cmd,
inout [3:0] io_sd_dat,
output o_flash_clk,
output o_flash_cs,
inout io_flash_dq[3:0],
// output o_flash_clk,
// output o_flash_cs,
// inout io_flash_dq[3:0],
inout io_rtc_scl,
inout io_rtc_sda,
@ -58,10 +58,10 @@ module SummerCart64 (
assign o_led = gpio_oe[0] ? gpio_o[0] : 1'bZ;
assign o_n64_irq = gpio_oe[1] ? gpio_o[1] : 1'bZ;
assign gpio_i = {4'd0, i_n64_nmi, i_n64_reset, o_n64_irq, o_led};
assign gpio_i = {io_pmod[0], 3'b000, i_n64_nmi, i_n64_reset, o_n64_irq, o_led};
cpu_soc cpu_soc_inst (
.*,
.system_if(system_if),
.gpio_o(gpio_o),
.gpio_i(gpio_i),
.gpio_oe(gpio_oe),
@ -69,12 +69,8 @@ module SummerCart64 (
.usb_cs(o_usb_cs),
.usb_miso(i_usb_miso),
.usb_miosi(io_usb_miosi),
.ftdi_clk(o_ftdi_clk),
.ftdi_si(o_ftdi_si),
.ftdi_so(i_ftdi_so),
.ftdi_cts(i_ftdi_cts),
.scl(io_rtc_scl),
.sda(io_rtc_sda)
.i2c_scl(io_rtc_scl),
.i2c_sda(io_rtc_sda)
);
endmodule

View File

@ -1,41 +1,57 @@
interface if_cpu_bus_out ();
interface if_cpu_bus #(
parameter NUM_DEVICES = 1
) (
input clk,
input reset
);
logic req;
logic [3:0] wstrb;
logic request;
logic ack;
logic [3:0] wmask;
logic [31:0] address;
logic [31:0] wdata;
endinterface
interface if_cpu_bus_in ();
logic ack;
logic [31:0] rdata;
endinterface
logic device_ack [(NUM_DEVICES - 1):0];
logic [31:0] device_rdata [(NUM_DEVICES - 1):0];
module cpu_bus_glue #(
parameter [3:0] ADDRESS = 4'h0
) (
if_system.sys system_if,
if_cpu_bus_out cpu_bus_if,
if_cpu_bus_in cpu_peripheral_if,
always_comb begin
ack = 1'b0;
rdata = 32'd0;
output request,
input [31:0] rdata
);
reg ack;
assign request = (cpu_bus_if.address[31:28] == ADDRESS) && cpu_bus_if.req;
assign cpu_peripheral_if.ack = ack & request;
assign cpu_peripheral_if.rdata = cpu_peripheral_if.ack ? rdata : 32'd0;
always_ff @(posedge system_if.clk) begin
ack <= 1'b0;
if (!system_if.reset && request) begin
ack <= 1'b1;
for (integer i = 0; i < NUM_DEVICES; i++) begin
ack = ack | device_ack[i];
rdata = rdata | device_rdata[i];
end
end
endmodule
modport cpu (
input clk,
input reset,
output request,
input ack,
output wmask,
output address,
output wdata,
input rdata
);
genvar n;
generate
for (n = 0; n < NUM_DEVICES; n++) begin : at
wire device_request = request && address[31:28] == n[3:0];
modport device (
input .clk(clk),
input .reset(reset),
input .request(device_request),
output .ack(device_ack[n]),
input .wmask(wmask),
input .address(address),
input .wdata(wdata),
output .rdata(device_rdata[n])
);
end
endgenerate
endinterface

View File

@ -1,40 +1,38 @@
module cpu_gpio (
if_system.sys system_if,
if_cpu_bus_out cpu_bus_if,
if_cpu_bus_in cpu_gpio_if,
if_cpu_bus bus,
input [7:0] gpio_i,
output reg [7:0] gpio_o,
output reg [7:0] gpio_oe
);
wire request;
wire [31:0] rdata;
cpu_bus_glue #(.ADDRESS(4'hE)) cpu_bus_glue_gpio_inst (
.*,
.cpu_peripheral_if(cpu_gpio_if),
.request(request),
.rdata(rdata)
);
reg [7:0] gpio_i_ff1, gpio_i_ff2;
reg [7:0] gpio_o_value;
reg [7:0] gpio_oe_value;
assign rdata = {8'd0, gpio_oe_value, gpio_i_ff2, gpio_o_value};
always_comb begin
bus.rdata = 32'd0;
if (bus.ack) begin
bus.rdata = {8'd0, gpio_oe_value, gpio_i_ff2, gpio_o_value};
end
end
always_ff @(posedge system_if.clk) begin
always_ff @(posedge bus.clk) begin
{gpio_i_ff2, gpio_i_ff1} <= {gpio_i_ff1, gpio_i};
gpio_o <= gpio_o_value;
gpio_oe <= gpio_oe_value;
if (system_if.reset) begin
bus.ack <= 1'b0;
if (bus.request) begin
bus.ack <= 1'b1;
end
if (bus.reset) begin
gpio_o_value <= 8'd0;
gpio_oe_value <= 8'd0;
end else if (request) begin
if (cpu_bus_if.wstrb[0]) gpio_o_value <= cpu_bus_if.wdata[7:0];
if (cpu_bus_if.wstrb[2]) gpio_oe_value <= cpu_bus_if.wdata[23:16];
end else if (bus.request) begin
if (bus.wmask[0]) gpio_o_value <= bus.wdata[7:0];
if (bus.wmask[2]) gpio_oe_value <= bus.wdata[23:16];
end
end

View File

@ -1,39 +1,35 @@
module cpu_i2c (
if_system.sys system_if,
if_cpu_bus_out cpu_bus_if,
if_cpu_bus_in cpu_i2c_if,
if_cpu_bus bus,
inout scl,
inout sda
inout i2c_scl,
inout i2c_sda
);
wire request;
wire [31:0] rdata;
cpu_bus_glue #(.ADDRESS(4'hC)) cpu_bus_glue_i2c_inst (
.*,
.cpu_peripheral_if(cpu_i2c_if),
.request(request),
.rdata(rdata)
);
reg [1:0] state;
reg mack;
reg [8:0] trx_data;
always_comb begin
case (cpu_bus_if.address[2])
0: rdata = {27'd0, |state, ~trx_data[0], mack, 2'b00};
1: rdata = {23'd0, trx_data[0], trx_data[8:1]};
default: rdata = 32'd0;
endcase
bus.rdata = 32'd0;
if (bus.ack) begin
case (bus.address[2])
0: bus.rdata = {27'd0, |state, ~trx_data[0], mack, 2'b00};
1: bus.rdata = {23'd0, trx_data[0], trx_data[8:1]};
default: bus.rdata = 32'd0;
endcase
end
end
always_ff @(posedge system_if.clk) begin
if (system_if.reset) begin
always_ff @(posedge bus.clk) begin
bus.ack <= 1'b0;
if (bus.request) begin
bus.ack <= 1'b1;
end
if (bus.reset) begin
mack <= 1'b0;
end else if (request && cpu_bus_if.wstrb[0] && !cpu_bus_if.address[2]) begin
mack <= cpu_bus_if.wdata[2];
end else if (bus.request && bus.wmask[0] && !bus.address[2]) begin
mack <= bus.wdata[2];
end
end
@ -43,14 +39,14 @@ module cpu_i2c (
wire clock_tick = &clock_div;
wire [3:0] clock_phase = {4{clock_tick}} & clock_phase_gen;
always_ff @(posedge system_if.clk) begin
if (system_if.reset) begin
always_ff @(posedge bus.clk) begin
if (bus.reset) begin
clock_div <= 6'd0;
end else begin
clock_div <= clock_div + 1'd1;
end
if (system_if.reset || state == 2'd0) begin
if (bus.reset || state == 2'd0) begin
clock_phase_gen <= 4'b0001;
end else if (clock_tick) begin
clock_phase_gen <= {clock_phase_gen[2:0], clock_phase_gen[3]};
@ -63,13 +59,13 @@ module cpu_i2c (
reg scl_o;
reg sda_o;
assign scl = scl_o ? 1'bZ : 1'b0;
assign sda = sda_o ? 1'bZ : 1'b0;
assign i2c_scl = scl_o ? 1'bZ : 1'b0;
assign i2c_sda = sda_o ? 1'bZ : 1'b0;
always_ff @(posedge system_if.clk) begin
{sda_i_ff2, sda_i_ff1} <= {sda_i_ff1, sda};
always_ff @(posedge bus.clk) begin
{sda_i_ff2, sda_i_ff1} <= {sda_i_ff1, i2c_sda};
if (system_if.reset) begin
if (bus.reset) begin
state <= 2'd0;
scl_o <= 1'b1;
sda_o <= 1'b1;
@ -78,16 +74,16 @@ module cpu_i2c (
2'd0: begin
bit_counter <= 4'd0;
if (request && cpu_bus_if.wstrb[0]) begin
case (cpu_bus_if.address[2])
if (bus.request && bus.wmask[0]) begin
case (bus.address[2])
0: begin
if (cpu_bus_if.wdata[1]) state <= 2'd2;
if (cpu_bus_if.wdata[0]) state <= 2'd1;
if (bus.wdata[1]) state <= 2'd2;
if (bus.wdata[0]) state <= 2'd1;
end
1: begin
state <= 2'd3;
trx_data <= {cpu_bus_if.wdata[7:0], ~mack};
trx_data <= {bus.wdata[7:0], ~mack};
end
endcase
end

View File

@ -1,18 +1,4 @@
module cpu_ram (
if_system.sys system_if,
if_cpu_bus_out cpu_bus_if,
if_cpu_bus_in cpu_ram_if
);
wire request;
wire [31:0] rdata;
cpu_bus_glue #(.ADDRESS(4'h0)) cpu_bus_glue_ram_inst (
.*,
.cpu_peripheral_if(cpu_ram_if),
.request(request),
.rdata(rdata)
);
module cpu_ram(if_cpu_bus bus);
wire bank;
reg [3:0][7:0] ram_1 [0:4095];
@ -20,24 +6,38 @@ module cpu_ram (
reg [31:0] q_1, q_2;
wire [31:0] q;
assign bank = cpu_bus_if.address[14];
assign rdata = bank ? q_2 : q_1;
assign bank = bus.address[14];
always_ff @(posedge system_if.clk) begin
q_1 <= ram_1[cpu_bus_if.address[13:2]];
if (request & !bank) begin
if (cpu_bus_if.wstrb[0]) ram_1[cpu_bus_if.address[13:2]][0] <= cpu_bus_if.wdata[7:0];
if (cpu_bus_if.wstrb[1]) ram_1[cpu_bus_if.address[13:2]][1] <= cpu_bus_if.wdata[15:8];
if (cpu_bus_if.wstrb[2]) ram_1[cpu_bus_if.address[13:2]][2] <= cpu_bus_if.wdata[23:16];
if (cpu_bus_if.wstrb[3]) ram_1[cpu_bus_if.address[13:2]][3] <= cpu_bus_if.wdata[31:24];
always_comb begin
bus.rdata = 32'd0;
if (bus.ack) begin
bus.rdata = q_1;
if (bank) bus.rdata = q_2;
end
end
always_ff @(posedge bus.clk) begin
bus.ack <= 1'b0;
if (bus.request) begin
bus.ack <= 1'b1;
end
end
always_ff @(posedge bus.clk) begin
q_1 <= ram_1[bus.address[13:2]];
if (bus.request & !bank) begin
if (bus.wmask[0]) ram_1[bus.address[13:2]][0] <= bus.wdata[7:0];
if (bus.wmask[1]) ram_1[bus.address[13:2]][1] <= bus.wdata[15:8];
if (bus.wmask[2]) ram_1[bus.address[13:2]][2] <= bus.wdata[23:16];
if (bus.wmask[3]) ram_1[bus.address[13:2]][3] <= bus.wdata[31:24];
end
q_2 <= ram_2[cpu_bus_if.address[12:2]];
if (request & bank) begin
if (cpu_bus_if.wstrb[0]) ram_2[cpu_bus_if.address[12:2]][0] <= cpu_bus_if.wdata[7:0];
if (cpu_bus_if.wstrb[1]) ram_2[cpu_bus_if.address[12:2]][1] <= cpu_bus_if.wdata[15:8];
if (cpu_bus_if.wstrb[2]) ram_2[cpu_bus_if.address[12:2]][2] <= cpu_bus_if.wdata[23:16];
if (cpu_bus_if.wstrb[3]) ram_2[cpu_bus_if.address[12:2]][3] <= cpu_bus_if.wdata[31:24];
q_2 <= ram_2[bus.address[12:2]];
if (bus.request & bank) begin
if (bus.wmask[0]) ram_2[bus.address[12:2]][0] <= bus.wdata[7:0];
if (bus.wmask[1]) ram_2[bus.address[12:2]][1] <= bus.wdata[15:8];
if (bus.wmask[2]) ram_2[bus.address[12:2]][2] <= bus.wdata[23:16];
if (bus.wmask[3]) ram_2[bus.address[12:2]][3] <= bus.wdata[31:24];
end
end

View File

@ -10,114 +10,60 @@ module cpu_soc (
input usb_miso,
inout [3:0] usb_miosi,
output ftdi_clk,
output ftdi_si,
input ftdi_so,
input ftdi_cts,
inout scl,
inout sda
inout i2c_scl,
inout i2c_sda
);
if_cpu_bus_out cpu_bus_if ();
enum bit [3:0] {
RAM,
BOOTLOADER,
GPIO,
I2C,
USB,
__NUM_DEVICES
} e_address_map;
wire cpu_ack;
wire [31:0] cpu_rdata;
picorv32 #(
.ENABLE_COUNTERS(0),
.ENABLE_COUNTERS64(0),
.ENABLE_REGS_16_31(1),
.ENABLE_REGS_DUALPORT(1),
.LATCHED_MEM_RDATA(0),
.TWO_STAGE_SHIFT(0),
.BARREL_SHIFTER(0),
.TWO_CYCLE_COMPARE(0),
.TWO_CYCLE_ALU(0),
.COMPRESSED_ISA(0),
.CATCH_MISALIGN(0),
.CATCH_ILLINSN(0),
.ENABLE_PCPI(0),
.ENABLE_MUL(0),
.ENABLE_FAST_MUL(0),
.ENABLE_DIV(0),
.ENABLE_IRQ(0),
.ENABLE_IRQ_QREGS(0),
.ENABLE_IRQ_TIMER(0),
.ENABLE_TRACE(0),
.REGS_INIT_ZERO(0),
.MASKED_IRQ(32'h0000_0000),
.LATCHED_IRQ(32'hFFFF_FFFF),
.PROGADDR_RESET(32'hF000_0000),
.PROGADDR_IRQ(32'h0000_0010),
.STACKADDR(32'hFFFF_FFFF)
) cpu_inst (
if_cpu_bus #(
.NUM_DEVICES(__NUM_DEVICES)
) bus (
.clk(system_if.clk),
.resetn(~system_if.reset),
.mem_valid(cpu_bus_if.req),
.mem_ready(cpu_ack),
.mem_addr(cpu_bus_if.address),
.mem_wdata(cpu_bus_if.wdata),
.mem_wstrb(cpu_bus_if.wstrb),
.mem_rdata(cpu_rdata)
.reset(system_if.reset)
);
cpu_wrapper # (
.ENTRY_DEVICE(BOOTLOADER)
) cpu_wrapper_inst (
.bus(bus)
);
if_cpu_bus_in cpu_ram_if ();
cpu_ram cpu_ram_inst (.*);
cpu_ram cpu_ram_inst (
.bus(bus.at[RAM].device)
);
if_cpu_bus_in cpu_bootloader_if ();
cpu_bootloader cpu_bootloader_inst (.*);
cpu_bootloader cpu_bootloader_inst (
.bus(bus.at[BOOTLOADER].device)
);
if_cpu_bus_in cpu_gpio_if ();
cpu_gpio cpu_gpio_inst (
.*,
.bus(bus.at[GPIO].device),
.gpio_i(gpio_i),
.gpio_o(gpio_o),
.gpio_oe(gpio_oe)
);
if_cpu_bus_in cpu_uart_if ();
cpu_uart cpu_uart_inst (
.*,
.ftdi_clk(ftdi_clk),
.ftdi_si(ftdi_si),
.ftdi_so(ftdi_so),
.ftdi_cts(ftdi_cts)
);
if_cpu_bus_in cpu_i2c_if ();
cpu_i2c cpu_i2c_inst (
.*,
.scl(scl),
.sda(sda)
.bus(bus.at[I2C].device),
.i2c_scl(i2c_scl),
.i2c_sda(i2c_sda)
);
if_cpu_bus_in cpu_usb_if ();
cpu_usb cpu_usb_inst (
.*,
.system_if(system_if),
.bus(bus.at[USB].device),
.usb_clk(usb_clk),
.usb_cs(usb_cs),
.usb_miso(usb_miso),
.usb_miosi(usb_miosi)
);
assign cpu_ack = (
cpu_ram_if.ack |
cpu_bootloader_if.ack |
cpu_gpio_if.ack |
cpu_uart_if.ack |
cpu_i2c_if.ack |
cpu_usb_if.ack
);
assign cpu_rdata = (
cpu_ram_if.rdata |
cpu_bootloader_if.rdata |
cpu_gpio_if.rdata |
cpu_uart_if.rdata |
cpu_i2c_if.rdata |
cpu_usb_if.rdata
);
endmodule

View File

@ -1,81 +1,81 @@
module cpu_uart (
if_system.sys system_if,
if_cpu_bus_out cpu_bus_if,
if_cpu_bus_in cpu_uart_if,
// module cpu_uart (
// if_system.sys system_if,
// if_cpu_bus_out cpu_bus_if,
// if_cpu_bus_in cpu_uart_if,
output ftdi_clk,
output ftdi_si,
input ftdi_so,
input ftdi_cts
);
// output ftdi_clk,
// output ftdi_si,
// input ftdi_so,
// input ftdi_cts
// );
wire request;
wire [31:0] rdata;
// wire request;
// wire [31:0] rdata;
cpu_bus_glue #(.ADDRESS(4'hD)) cpu_bus_glue_uart_inst (
.*,
.cpu_peripheral_if(cpu_uart_if),
.request(request),
.rdata(rdata)
);
// cpu_bus_glue #(.ADDRESS(4'hD)) cpu_bus_glue_uart_inst (
// .*,
// .cpu_peripheral_if(cpu_uart_if),
// .request(request),
// .rdata(rdata)
// );
reg rx_ready;
wire tx_busy;
reg [7:0] rx_data;
reg [7:0] tx_data;
// reg rx_ready;
// wire tx_busy;
// reg [7:0] rx_data;
// reg [7:0] tx_data;
always_comb begin
case (cpu_bus_if.address[3:2])
0: rdata = {30'd0, ~tx_busy, ~rx_ready};
1: rdata = {24'd0, rx_data};
2: rdata = {24'd0, tx_data};
default: rdata = 32'd0;
endcase
end
// always_comb begin
// case (cpu_bus_if.address[3:2])
// 0: rdata = {30'd0, ~tx_busy, ~rx_ready};
// 1: rdata = {24'd0, rx_data};
// 2: rdata = {24'd0, tx_data};
// default: rdata = 32'd0;
// endcase
// end
wire rx_valid;
reg tx_valid;
wire [7:0] f_rx_data;
// wire rx_valid;
// reg tx_valid;
// wire [7:0] f_rx_data;
always_ff @(posedge system_if.clk) begin
tx_valid <= 1'b0;
// always_ff @(posedge system_if.clk) begin
// tx_valid <= 1'b0;
if (rx_valid) begin
rx_ready <= 1'b0;
rx_data <= f_rx_data;
end
// if (rx_valid) begin
// rx_ready <= 1'b0;
// rx_data <= f_rx_data;
// end
if (system_if.reset) begin
rx_ready <= 1'b1;
end else if (request) begin
if (cpu_bus_if.wstrb[0] && cpu_bus_if.address[3:2] == 2'd2 && !tx_busy) begin
tx_valid <= 1'b1;
tx_data <= cpu_bus_if.wdata[7:0];
end
if (cpu_bus_if.address[3:2] == 2'd1) begin
rx_ready <= 1'b1;
end
end
end
// if (system_if.reset) begin
// rx_ready <= 1'b1;
// end else if (request) begin
// if (cpu_bus_if.wstrb[0] && cpu_bus_if.address[3:2] == 2'd2 && !tx_busy) begin
// tx_valid <= 1'b1;
// tx_data <= cpu_bus_if.wdata[7:0];
// end
// if (cpu_bus_if.address[3:2] == 2'd1) begin
// rx_ready <= 1'b1;
// end
// end
// end
usb_ftdi_fsi usb_ftdi_fsi_inst (
.i_clk(system_if.clk),
.i_reset(system_if.reset),
// usb_ftdi_fsi usb_ftdi_fsi_inst (
// .i_clk(system_if.clk),
// .i_reset(system_if.reset),
.o_ftdi_clk(ftdi_clk),
.o_ftdi_si(ftdi_si),
.i_ftdi_so(ftdi_so),
.i_ftdi_cts(ftdi_cts),
// .o_ftdi_clk(ftdi_clk),
// .o_ftdi_si(ftdi_si),
// .i_ftdi_so(ftdi_so),
// .i_ftdi_cts(ftdi_cts),
.i_rx_ready(rx_ready),
.o_rx_valid(rx_valid),
// .o_rx_channel(1'bX),
.o_rx_data(f_rx_data),
// .i_rx_ready(rx_ready),
// .o_rx_valid(rx_valid),
// // .o_rx_channel(1'bX),
// .o_rx_data(f_rx_data),
.o_tx_busy(tx_busy),
.i_tx_valid(tx_valid),
.i_tx_channel(1'b1),
.i_tx_data(tx_data)
);
// .o_tx_busy(tx_busy),
// .i_tx_valid(tx_valid),
// .i_tx_channel(1'b1),
// .i_tx_data(tx_data)
// );
endmodule
// endmodule

View File

@ -1,7 +1,6 @@
module cpu_usb (
if_system.sys system_if,
if_cpu_bus_out cpu_bus_if,
if_cpu_bus_in cpu_usb_if,
if_system system_if,
if_cpu_bus bus,
output usb_clk,
output usb_cs,
@ -9,70 +8,54 @@ module cpu_usb (
inout [3:0] usb_miosi
);
wire request;
wire [31:0] rdata;
reg rx_flush;
wire rx_empty;
reg rx_read;
wire [7:0] rx_rdata;
cpu_bus_glue #(.ADDRESS(4'hB)) cpu_bus_glue_usb_inst (
.*,
.cpu_peripheral_if(cpu_usb_if),
.request(request),
.rdata(rdata)
);
reg rx_ready;
wire tx_busy;
reg [7:0] rx_data;
reg [7:0] tx_data;
reg tx_flush;
wire tx_full;
reg tx_write;
reg [7:0] tx_wdata;
always_comb begin
case (cpu_bus_if.address[3:2])
0: rdata = {30'd0, ~tx_busy, ~rx_ready};
1: rdata = {24'd0, rx_data};
2: rdata = {24'd0, tx_data};
default: rdata = 32'd0;
endcase
bus.rdata = 32'd0;
if (bus.ack) begin
case (bus.address[2:2])
0: bus.rdata = {30'd0, ~tx_full, ~rx_empty};
1: bus.rdata = {24'd0, rx_rdata};
default: bus.rdata = 32'd0;
endcase
end
end
reg usb_request;
reg usb_write;
wire usb_busy;
wire usb_ack;
wire [7:0] usb_wdata;
wire [7:0] usb_rdata;
wire usb_rx_available;
wire usb_tx_available;
always_ff @(posedge bus.clk) begin
rx_flush <= 1'b0;
rx_read <= 1'b0;
assign tx_busy = usb_busy || !usb_tx_available;
assign usb_wdata = tx_data;
tx_flush <= 1'b0;
tx_write <= 1'b0;
// wire rx_valid;
// reg tx_valid;
// wire [7:0] f_rx_data;
always_ff @(posedge system_if.clk) begin
// tx_valid <= 1'b0;
usb_request <= 1'b0;
if (usb_ack) begin
rx_ready <= 1'b0;
rx_data <= usb_rdata;
bus.ack <= 1'b0;
if (bus.request) begin
bus.ack <= 1'b1;
end
if (system_if.reset) begin
rx_ready <= 1'b1;
end else if (request) begin
if (cpu_bus_if.wstrb[0] && cpu_bus_if.address[3:2] == 2'd2 && !tx_busy) begin
// tx_valid <= 1'b1;
usb_request <= 1'b1;
usb_write <= 1'b1;
tx_data <= cpu_bus_if.wdata[7:0];
end
if (cpu_bus_if.address[3:2] == 2'd1) begin
rx_ready <= 1'b1;
end
end else if (usb_rx_available && rx_ready) begin
usb_request <= 1'b1;
usb_write <= 1'b0;
if (bus.request) begin
case (bus.address[2:2])
2'd0: if (bus.wmask[0]) begin
{tx_flush, rx_flush} <= bus.wdata[3:2];
end
2'd1: if (bus.wmask[0]) begin
if (!tx_full) begin
tx_write <= 1'b1;
tx_wdata <= bus.wdata[7:0];
end
end else begin
rx_read <= 1'b1;
end
endcase
end
end
@ -84,14 +67,15 @@ module cpu_usb (
.usb_miso(usb_miso),
.usb_miosi(usb_miosi),
.request(usb_request),
.write(usb_write),
.busy(usb_busy),
.ack(usb_ack),
.wdata(usb_wdata),
.rdata(usb_rdata),
.rx_available(usb_rx_available),
.tx_available(usb_tx_available)
.rx_flush(rx_flush),
.rx_empty(rx_empty),
.rx_read(rx_read),
.rx_rdata(rx_rdata),
.tx_flush(tx_flush),
.tx_full(tx_full),
.tx_write(tx_write),
.tx_wdata(tx_wdata)
);
endmodule

49
fw/rtl/cpu/cpu_wrapper.sv Normal file
View File

@ -0,0 +1,49 @@
module cpu_wrapper #(
parameter [3:0] ENTRY_DEVICE = 4'h0
) (
if_cpu_bus.cpu bus
);
typedef enum bit {S_IDLE, S_WAITING} e_bus_state;
e_bus_state state;
wire mem_la_read;
wire mem_la_write;
always_ff @(posedge bus.clk) begin
bus.request <= 1'b0;
if (bus.reset) begin
state <= S_IDLE;
end else begin
if (state == S_IDLE && (mem_la_read || mem_la_write)) begin
state <= S_WAITING;
bus.request <= 1'b1;
end
if (state == S_WAITING && bus.ack) begin
state <= S_IDLE;
end
end
end
picorv32 #(
.ENABLE_COUNTERS(0),
.ENABLE_COUNTERS64(0),
.TWO_STAGE_SHIFT(0),
.CATCH_MISALIGN(0),
.CATCH_ILLINSN(0),
.PROGADDR_RESET({ENTRY_DEVICE, 28'h000_0000})
) cpu_inst (
.clk(bus.clk),
.resetn(~bus.reset),
.mem_addr(bus.address),
.mem_wdata(bus.wdata),
.mem_wstrb(bus.wmask),
.mem_ready(bus.ack),
.mem_rdata(bus.rdata),
.mem_la_read(mem_la_read),
.mem_la_write(mem_la_write)
);
endmodule

View File

@ -0,0 +1,4 @@
set_global_assignment -name IP_TOOL_NAME "FIFO"
set_global_assignment -name IP_TOOL_VERSION "20.1"
set_global_assignment -name IP_GENERATED_DEVICE_FAMILY "{MAX 10}"
set_global_assignment -name VERILOG_FILE [file join $::quartus(qip_path) "fifo8.v"]

179
fw/rtl/intel/fifo/fifo8.v Normal file
View File

@ -0,0 +1,179 @@
// megafunction wizard: %FIFO%
// GENERATION: STANDARD
// VERSION: WM1.0
// MODULE: scfifo
// ============================================================
// File Name: fifo8.v
// Megafunction Name(s):
// scfifo
//
// Simulation Library Files(s):
// altera_mf
// ============================================================
// ************************************************************
// THIS IS A WIZARD-GENERATED FILE. DO NOT EDIT THIS FILE!
//
// 20.1.1 Build 720 11/11/2020 SJ Lite Edition
// ************************************************************
//Copyright (C) 2020 Intel Corporation. All rights reserved.
//Your use of Intel Corporation's design tools, logic functions
//and other software and tools, and any partner logic
//functions, and any output files from any of the foregoing
//(including device programming or simulation files), and any
//associated documentation or information are expressly subject
//to the terms and conditions of the Intel Program License
//Subscription Agreement, the Intel Quartus Prime License Agreement,
//the Intel FPGA IP License Agreement, or other applicable license
//agreement, including, without limitation, that your use is for
//the sole purpose of programming logic devices manufactured by
//Intel and sold by Intel or its authorized distributors. Please
//refer to the applicable agreement for further details, at
//https://fpgasoftware.intel.com/eula.
// synopsys translate_off
`timescale 1 ps / 1 ps
// synopsys translate_on
module fifo8 (
clock,
data,
rdreq,
sclr,
wrreq,
almost_empty,
almost_full,
empty,
full,
q);
input clock;
input [7:0] data;
input rdreq;
input sclr;
input wrreq;
output almost_empty;
output almost_full;
output empty;
output full;
output [7:0] q;
wire sub_wire0;
wire sub_wire1;
wire sub_wire2;
wire sub_wire3;
wire [7:0] sub_wire4;
wire almost_empty = sub_wire0;
wire almost_full = sub_wire1;
wire empty = sub_wire2;
wire full = sub_wire3;
wire [7:0] q = sub_wire4[7:0];
scfifo scfifo_component (
.clock (clock),
.data (data),
.rdreq (rdreq),
.sclr (sclr),
.wrreq (wrreq),
.almost_empty (sub_wire0),
.almost_full (sub_wire1),
.empty (sub_wire2),
.full (sub_wire3),
.q (sub_wire4),
.aclr (),
.eccstatus (),
.usedw ());
defparam
scfifo_component.add_ram_output_register = "ON",
scfifo_component.almost_empty_value = 2,
scfifo_component.almost_full_value = 1023,
scfifo_component.intended_device_family = "MAX 10",
scfifo_component.lpm_numwords = 1024,
scfifo_component.lpm_showahead = "ON",
scfifo_component.lpm_type = "scfifo",
scfifo_component.lpm_width = 8,
scfifo_component.lpm_widthu = 10,
scfifo_component.overflow_checking = "ON",
scfifo_component.underflow_checking = "ON",
scfifo_component.use_eab = "ON";
endmodule
// ============================================================
// CNX file retrieval info
// ============================================================
// Retrieval info: PRIVATE: AlmostEmpty NUMERIC "1"
// Retrieval info: PRIVATE: AlmostEmptyThr NUMERIC "2"
// Retrieval info: PRIVATE: AlmostFull NUMERIC "1"
// Retrieval info: PRIVATE: AlmostFullThr NUMERIC "1023"
// Retrieval info: PRIVATE: CLOCKS_ARE_SYNCHRONIZED NUMERIC "1"
// Retrieval info: PRIVATE: Clock NUMERIC "0"
// Retrieval info: PRIVATE: Depth NUMERIC "1024"
// Retrieval info: PRIVATE: Empty NUMERIC "1"
// Retrieval info: PRIVATE: Full NUMERIC "1"
// Retrieval info: PRIVATE: INTENDED_DEVICE_FAMILY STRING "MAX 10"
// Retrieval info: PRIVATE: LE_BasedFIFO NUMERIC "0"
// Retrieval info: PRIVATE: LegacyRREQ NUMERIC "0"
// Retrieval info: PRIVATE: MAX_DEPTH_BY_9 NUMERIC "0"
// Retrieval info: PRIVATE: OVERFLOW_CHECKING NUMERIC "0"
// Retrieval info: PRIVATE: Optimize NUMERIC "1"
// Retrieval info: PRIVATE: RAM_BLOCK_TYPE NUMERIC "0"
// Retrieval info: PRIVATE: SYNTH_WRAPPER_GEN_POSTFIX STRING "0"
// Retrieval info: PRIVATE: UNDERFLOW_CHECKING NUMERIC "0"
// Retrieval info: PRIVATE: UsedW NUMERIC "0"
// Retrieval info: PRIVATE: Width NUMERIC "8"
// Retrieval info: PRIVATE: dc_aclr NUMERIC "0"
// Retrieval info: PRIVATE: diff_widths NUMERIC "0"
// Retrieval info: PRIVATE: msb_usedw NUMERIC "0"
// Retrieval info: PRIVATE: output_width NUMERIC "8"
// Retrieval info: PRIVATE: rsEmpty NUMERIC "1"
// Retrieval info: PRIVATE: rsFull NUMERIC "0"
// Retrieval info: PRIVATE: rsUsedW NUMERIC "0"
// Retrieval info: PRIVATE: sc_aclr NUMERIC "0"
// Retrieval info: PRIVATE: sc_sclr NUMERIC "1"
// Retrieval info: PRIVATE: wsEmpty NUMERIC "0"
// Retrieval info: PRIVATE: wsFull NUMERIC "1"
// Retrieval info: PRIVATE: wsUsedW NUMERIC "0"
// Retrieval info: LIBRARY: altera_mf altera_mf.altera_mf_components.all
// Retrieval info: CONSTANT: ADD_RAM_OUTPUT_REGISTER STRING "ON"
// Retrieval info: CONSTANT: ALMOST_EMPTY_VALUE NUMERIC "2"
// Retrieval info: CONSTANT: ALMOST_FULL_VALUE NUMERIC "1023"
// Retrieval info: CONSTANT: INTENDED_DEVICE_FAMILY STRING "MAX 10"
// Retrieval info: CONSTANT: LPM_NUMWORDS NUMERIC "1024"
// Retrieval info: CONSTANT: LPM_SHOWAHEAD STRING "ON"
// Retrieval info: CONSTANT: LPM_TYPE STRING "scfifo"
// Retrieval info: CONSTANT: LPM_WIDTH NUMERIC "8"
// Retrieval info: CONSTANT: LPM_WIDTHU NUMERIC "10"
// Retrieval info: CONSTANT: OVERFLOW_CHECKING STRING "ON"
// Retrieval info: CONSTANT: UNDERFLOW_CHECKING STRING "ON"
// Retrieval info: CONSTANT: USE_EAB STRING "ON"
// Retrieval info: USED_PORT: almost_empty 0 0 0 0 OUTPUT NODEFVAL "almost_empty"
// Retrieval info: USED_PORT: almost_full 0 0 0 0 OUTPUT NODEFVAL "almost_full"
// Retrieval info: USED_PORT: clock 0 0 0 0 INPUT NODEFVAL "clock"
// Retrieval info: USED_PORT: data 0 0 8 0 INPUT NODEFVAL "data[7..0]"
// Retrieval info: USED_PORT: empty 0 0 0 0 OUTPUT NODEFVAL "empty"
// Retrieval info: USED_PORT: full 0 0 0 0 OUTPUT NODEFVAL "full"
// Retrieval info: USED_PORT: q 0 0 8 0 OUTPUT NODEFVAL "q[7..0]"
// Retrieval info: USED_PORT: rdreq 0 0 0 0 INPUT NODEFVAL "rdreq"
// Retrieval info: USED_PORT: sclr 0 0 0 0 INPUT NODEFVAL "sclr"
// Retrieval info: USED_PORT: wrreq 0 0 0 0 INPUT NODEFVAL "wrreq"
// Retrieval info: CONNECT: @clock 0 0 0 0 clock 0 0 0 0
// Retrieval info: CONNECT: @data 0 0 8 0 data 0 0 8 0
// Retrieval info: CONNECT: @rdreq 0 0 0 0 rdreq 0 0 0 0
// Retrieval info: CONNECT: @sclr 0 0 0 0 sclr 0 0 0 0
// Retrieval info: CONNECT: @wrreq 0 0 0 0 wrreq 0 0 0 0
// Retrieval info: CONNECT: almost_empty 0 0 0 0 @almost_empty 0 0 0 0
// Retrieval info: CONNECT: almost_full 0 0 0 0 @almost_full 0 0 0 0
// Retrieval info: CONNECT: empty 0 0 0 0 @empty 0 0 0 0
// Retrieval info: CONNECT: full 0 0 0 0 @full 0 0 0 0
// Retrieval info: CONNECT: q 0 0 8 0 @q 0 0 8 0
// Retrieval info: GEN_FILE: TYPE_NORMAL fifo8.v TRUE
// Retrieval info: GEN_FILE: TYPE_NORMAL fifo8.inc FALSE
// Retrieval info: GEN_FILE: TYPE_NORMAL fifo8.cmp FALSE
// Retrieval info: GEN_FILE: TYPE_NORMAL fifo8.bsf FALSE
// Retrieval info: GEN_FILE: TYPE_NORMAL fifo8_inst.v FALSE
// Retrieval info: GEN_FILE: TYPE_NORMAL fifo8_bb.v FALSE
// Retrieval info: LIB_FILE: altera_mf

View File

@ -37,9 +37,9 @@ module system (if_system.pll system_if);
.locked(locked)
);
intel_snp intel_snp_inst (
.source(external_reset),
.source_clk(system_if.clk)
);
// intel_snp intel_snp_inst (
// .source(external_reset),
// .source_clk(system_if.clk)
// );
endmodule

46
fw/rtl/usb/usb_fifo.sv Normal file
View File

@ -0,0 +1,46 @@
module usb_fifo #(
parameter FIFO_LENGTH = 1024,
parameter FIFO_WIDTH = 8
) (
if_system.sys system_if,
input flush,
output full,
input write,
input [(FIFO_WIDTH - 1):0] wdata,
output empty,
input read,
output reg [(FIFO_WIDTH - 1):0] rdata
);
localparam FIFO_ADDRESS_WIDTH = $clog2(FIFO_LENGTH);
reg [(FIFO_WIDTH - 1):0] r_fifo_mem [0:(FIFO_LENGTH - 1)];
reg [FIFO_ADDRESS_WIDTH:0] r_fifo_wrptr;
reg [FIFO_ADDRESS_WIDTH:0] r_fifo_rdptr;
wire w_full_or_empty = r_fifo_wrptr[(FIFO_ADDRESS_WIDTH - 1):0] == r_fifo_rdptr[(FIFO_ADDRESS_WIDTH - 1):0];
assign empty = r_fifo_wrptr == r_fifo_rdptr;
assign full = !empty && w_full_or_empty;
always_ff @(posedge system_if.clk) begin
rdata <= r_fifo_mem[r_fifo_rdptr[(FIFO_ADDRESS_WIDTH - 1):0]];
if (system_if.reset || flush) begin
r_fifo_wrptr <= {(FIFO_ADDRESS_WIDTH + 1){1'b0}};
r_fifo_rdptr <= {(FIFO_ADDRESS_WIDTH + 1){1'b0}};
end else begin
if (write) begin
r_fifo_mem[r_fifo_wrptr[(FIFO_ADDRESS_WIDTH - 1):0]] <= wdata;
r_fifo_wrptr <= r_fifo_wrptr + 1'd1;
end
if (read) begin
r_fifo_rdptr <= r_fifo_rdptr + 1'd1;
end
end
end
endmodule

View File

@ -6,22 +6,70 @@ module usb_ft1248 (
input usb_miso,
inout [3:0] usb_miosi,
input request,
input write,
output busy,
output reg ack,
input [7:0] wdata,
output reg [7:0] rdata,
input rx_flush,
output rx_empty,
output rx_almost_empty,
input rx_read,
output [7:0] rx_rdata,
output reg rx_available,
output reg tx_available
input tx_flush,
output tx_full,
output tx_almost_full,
input tx_write,
input [7:0] tx_wdata
);
// FIFOs
wire rx_full;
wire rx_almost_full;
reg rx_write;
reg [7:0] rx_wdata;
wire tx_empty;
reg tx_read;
wire [7:0] tx_rdata;
fifo8 fifo_8_rx_inst (
.clock(system_if.clk),
.sclr(rx_flush),
.empty(rx_empty),
.almost_empty(rx_almost_empty),
.rdreq(rx_read),
.q(rx_rdata),
.full(rx_full),
.almost_full(rx_almost_full),
.wrreq(rx_write),
.data(rx_wdata)
);
fifo8 fifo_8_tx_inst (
.clock(system_if.clk),
.sclr(tx_flush),
.empty(tx_empty),
.rdreq(tx_read),
.q(tx_rdata),
.full(tx_full),
.almost_full(tx_almost_full),
.wrreq(tx_write),
.data(tx_wdata)
);
// FT1248 interface controller
// Constants definition
typedef enum bit [2:0] {
S_IDLE = 3'b000,
S_TRY_RX = 3'b000,
S_TRY_TX = 3'b001,
S_COMMAND = 3'b100,
S_DATA = 3'b101,
S_END = 3'b110
S_END = 3'b111
} e_state;
typedef enum bit [7:0] {
@ -29,126 +77,154 @@ module usb_ft1248 (
C_READ = 8'h04
} e_command;
// FSM state
e_state state;
assign busy = state[2];
// Clock divider and generator
reg [3:0] clock_divider;
wire rising_edge;
wire falling_edge;
assign rising_edge = clock_divider[1];
assign falling_edge = clock_divider[3];
wire rising_edge = clock_divider[1];
always_ff @(posedge system_if.clk) begin
if (system_if.reset || state == S_IDLE) begin
if (system_if.reset || state == S_TRY_RX || state == S_TRY_TX) begin
clock_divider <= 4'b0001;
usb_clk <= 1'b0;
end else begin
clock_divider <= {clock_divider[2:0], clock_divider[3]};
if (state != S_END) begin
if (rising_edge) usb_clk <= 1'b1;
if (falling_edge) usb_clk <= 1'b0;
end
end
end
reg miosi_ff_1, miosi_ff_2;
reg miso_ff_1, miso_ff_2;
reg mode;
// Output chip select and data register behavior
reg [1:0] bit_counter;
reg [7:0] tx_buffer;
reg output_enable;
wire clk_data;
reg cs_data;
wire [3:0] miosi_data;
reg miosi_output_enable_data;
reg [7:0] tx_data;
reg [3:0] miosi;
reg clk_output;
reg cs_output;
reg [3:0] miosi_input;
reg [3:0] miosi_output;
reg miosi_output_enable;
reg miso_input;
reg [7:0] command;
assign usb_miosi = output_enable ? miosi : 4'bZZZZ;
always_comb begin
clk_data = 1'b0;
if (state == S_COMMAND || state == S_DATA) clk_data = (clock_divider[2] | clock_divider[3]);
usb_clk = clk_output;
usb_cs = cs_output;
miosi_data = bit_counter[0] ? tx_buffer[3:0] : tx_buffer[7:4];
usb_miosi = miosi_output_enable ? miosi_output : 4'bZZZZ;
end
always_ff @(posedge system_if.clk) begin
{miosi_ff_2, miosi_ff_1} <= {miosi_ff_1, usb_miosi[0]};
{miso_ff_2, miso_ff_1} <= {miso_ff_1, usb_miso};
rx_available <= 1'b0;
tx_available <= 1'b0;
ack <= 1'b0;
clk_output <= clk_data;
cs_output <= cs_data;
miosi_input <= usb_miosi;
miosi_output <= miosi_data;
miosi_output_enable <= miosi_output_enable_data;
miso_input <= usb_miso;
end
// FSM
reg is_write;
always_ff @(posedge system_if.clk) begin
rx_write <= 1'b0;
tx_read <= 1'b0;
if (system_if.reset) begin
state <= S_IDLE;
usb_cs <= 1'b1;
output_enable <= 1'b0;
state <= S_TRY_RX;
cs_data <= 1'b1;
miosi_output_enable_data <= 1'b0;
end else begin
case (state)
S_IDLE: begin
rx_available <= ~miso_ff_2;
tx_available <= ~miosi_ff_2;
bit_counter <= 1'b0;
usb_cs <= 1'b1;
output_enable <= 1'b0;
if (request) begin
mode <= write;
if (rx_available || (write && tx_available)) begin
state <= S_COMMAND;
command <= write ? C_WRITE : C_READ;
usb_cs <= 1'b0;
rx_available <= 1'b0;
tx_available <= 1'b0;
tx_data <= {wdata[3:0], wdata[7:4]};
end
S_TRY_RX: begin
if (!rx_full) begin
state <= S_COMMAND;
tx_buffer <= C_READ;
bit_counter <= 2'b11;
is_write <= 1'b0;
end else begin
state <= S_TRY_TX;
end
end
S_TRY_TX: begin
if (!tx_empty) begin
state <= S_COMMAND;
tx_buffer <= C_WRITE;
bit_counter <= 2'b11;
is_write <= 1'b1;
end else begin
state <= S_TRY_RX;
end
end
S_COMMAND: begin
cs_data <= 1'b0;
if (rising_edge) begin
output_enable <= 1'b1;
bit_counter <= bit_counter + 1'd1;
{miosi, command} <= {command, 4'bXXXX};
if (bit_counter == 2'd2) begin
output_enable <= 1'b0;
miosi_output_enable_data <= 1'b1;
if (bit_counter == 2'd1) begin
miosi_output_enable_data <= 1'b0;
end
if (bit_counter == 2'd2) begin
if (!miso_input) begin
state <= S_DATA;
bit_counter <= 2'b11;
tx_buffer <= tx_rdata;
miosi_output_enable_data <= is_write;
end else begin
state <= S_END;
miosi_output_enable_data <= 1'b0;
end
end
end
if (falling_edge && (bit_counter == 2'd3)) begin
state <= S_DATA;
bit_counter <= 2'd0;
end
end
S_DATA: begin
if (rising_edge) begin
output_enable <= mode;
bit_counter[0] <= ~bit_counter[0];
{miosi, tx_data} <= {tx_data, 4'bXXXX};
end
if (falling_edge) begin
rdata <= {usb_miosi, rdata[7:4]};
if (!bit_counter[0]) begin
bit_counter <= {1'b0, ~bit_counter[0]};
miosi_output_enable_data <= is_write;
rx_wdata <= {miosi_input, rx_wdata[7:4]};
if (bit_counter == 1'd1) begin
tx_buffer <= tx_rdata;
end
if (!is_write && (bit_counter[0] == 1'd0)) begin
rx_write <= 1'b1;
end
if (is_write && (bit_counter[0] == 1'd1)) begin
tx_read <= 1'b1;
end
if (
(bit_counter[0] == 1'd1 && miso_input) ||
(bit_counter[0] == 1'd0 && (
(is_write && tx_empty) ||
(!is_write && rx_almost_full)
))) begin
state <= S_END;
output_enable <= 1'b0;
ack <= 1'b1;
miosi_output_enable_data <= 1'b0;
end
end
end
S_END: begin
if (rising_edge) begin
bit_counter <= bit_counter + 1'd1;
if (bit_counter == 2'd3) begin
state <= S_IDLE;
end
usb_cs <= 1'b1;
end
cs_data <= 1'b1;
state <= is_write ? S_TRY_RX : S_TRY_TX;
end
default: begin
state <= S_IDLE;
state <= S_TRY_RX;
cs_data <= 1'b1;
miosi_output_enable_data <= 1'b0;
end
endcase
end
end
endmodule

File diff suppressed because one or more lines are too long