mirror of
https://github.com/Polprzewodnikowy/SummerCart64.git
synced 2024-11-22 22:19:14 +01:00
horrible
This commit is contained in:
parent
d550d9c184
commit
1722b3cd3f
@ -19,7 +19,7 @@
|
|||||||
#
|
#
|
||||||
# Quartus Prime
|
# Quartus Prime
|
||||||
# Version 20.1.1 Build 720 11/11/2020 SJ Lite Edition
|
# Version 20.1.1 Build 720 11/11/2020 SJ Lite Edition
|
||||||
# Date created = 16:40:13 August 18, 2021
|
# Date created = 23:35:14 August 23, 2021
|
||||||
#
|
#
|
||||||
# -------------------------------------------------------------------------- #
|
# -------------------------------------------------------------------------- #
|
||||||
#
|
#
|
||||||
@ -48,8 +48,8 @@ set_global_assignment -name NUM_PARALLEL_PROCESSORS ALL
|
|||||||
set_global_assignment -name FLOW_ENABLE_POWER_ANALYZER ON
|
set_global_assignment -name FLOW_ENABLE_POWER_ANALYZER ON
|
||||||
set_global_assignment -name QSYS_FILE rtl/intel/flash/intel_flash.qsys
|
set_global_assignment -name QSYS_FILE rtl/intel/flash/intel_flash.qsys
|
||||||
set_global_assignment -name QSYS_FILE rtl/intel/snp/intel_snp.qsys
|
set_global_assignment -name QSYS_FILE rtl/intel/snp/intel_snp.qsys
|
||||||
# set_global_assignment -name QIP_FILE rtl/intel/fifo/fifo8.qip
|
|
||||||
set_global_assignment -name QIP_FILE rtl/intel/fifo/intel_fifo_8.qip
|
set_global_assignment -name QIP_FILE rtl/intel/fifo/intel_fifo_8.qip
|
||||||
|
set_global_assignment -name QIP_FILE rtl/intel/gpio/intel_gpio_ddro.qip
|
||||||
set_global_assignment -name QIP_FILE rtl/intel/pll/intel_pll.qip
|
set_global_assignment -name QIP_FILE rtl/intel/pll/intel_pll.qip
|
||||||
set_global_assignment -name SDC_FILE SummerCart64.sdc
|
set_global_assignment -name SDC_FILE SummerCart64.sdc
|
||||||
set_global_assignment -name SIGNALTAP_FILE stp.stp
|
set_global_assignment -name SIGNALTAP_FILE stp.stp
|
||||||
@ -71,6 +71,7 @@ set_global_assignment -name SYSTEMVERILOG_FILE rtl/n64/n64_bootloader.sv
|
|||||||
set_global_assignment -name SYSTEMVERILOG_FILE rtl/n64/n64_bus.sv
|
set_global_assignment -name SYSTEMVERILOG_FILE rtl/n64/n64_bus.sv
|
||||||
set_global_assignment -name SYSTEMVERILOG_FILE rtl/n64/n64_cfg.sv
|
set_global_assignment -name SYSTEMVERILOG_FILE rtl/n64/n64_cfg.sv
|
||||||
set_global_assignment -name SYSTEMVERILOG_FILE rtl/n64/n64_pi.sv
|
set_global_assignment -name SYSTEMVERILOG_FILE rtl/n64/n64_pi.sv
|
||||||
|
set_global_assignment -name SYSTEMVERILOG_FILE rtl/n64/n64_pi_fifo.sv
|
||||||
set_global_assignment -name SYSTEMVERILOG_FILE rtl/n64/n64_sdram.sv
|
set_global_assignment -name SYSTEMVERILOG_FILE rtl/n64/n64_sdram.sv
|
||||||
set_global_assignment -name SYSTEMVERILOG_FILE rtl/n64/n64_soc.sv
|
set_global_assignment -name SYSTEMVERILOG_FILE rtl/n64/n64_soc.sv
|
||||||
set_global_assignment -name SYSTEMVERILOG_FILE rtl/SummerCart64.sv
|
set_global_assignment -name SYSTEMVERILOG_FILE rtl/SummerCart64.sv
|
||||||
@ -302,6 +303,23 @@ set_global_assignment -name PARTITION_COLOR 16764057 -section_id Top
|
|||||||
|
|
||||||
# end ENTITY(SummerCart64)
|
# end ENTITY(SummerCart64)
|
||||||
# ------------------------
|
# ------------------------
|
||||||
set_global_assignment -name QIP_FILE rtl/intel/gpio/intel_gpio_ddro.qip
|
|
||||||
|
|
||||||
|
# ------------------------------
|
||||||
|
# start ENTITY(altera_gpio_lite)
|
||||||
|
|
||||||
|
# Project-Wide Assignments
|
||||||
|
# ========================
|
||||||
|
|
||||||
|
# end ENTITY(altera_gpio_lite)
|
||||||
|
# ----------------------------
|
||||||
|
|
||||||
|
# -----------------------------
|
||||||
|
# start ENTITY(intel_gpio_ddro)
|
||||||
|
|
||||||
|
# Project-Wide Assignments
|
||||||
|
# ========================
|
||||||
|
|
||||||
|
# end ENTITY(intel_gpio_ddro)
|
||||||
|
# ---------------------------
|
||||||
|
set_global_assignment -name SIGNALTAP_FILE output_files/signaltap.stp
|
||||||
set_instance_assignment -name PARTITION_HIERARCHY root_partition -to | -section_id Top
|
set_instance_assignment -name PARTITION_HIERARCHY root_partition -to | -section_id Top
|
@ -67,6 +67,10 @@ __NAKED__ int main (void) {
|
|||||||
GPIO_OE = (1 << 0);
|
GPIO_OE = (1 << 0);
|
||||||
GPIO_O = 0; // (1 << 0);
|
GPIO_O = 0; // (1 << 0);
|
||||||
|
|
||||||
|
CFG_SCR |= CFG_SCR_SRAM_EN | CFG_SCR_SDRAM_SWITCH | CFG_SCR_DD_EN;
|
||||||
|
CFG_DD_OFFSET = 0;//0x3BE0000;
|
||||||
|
CFG_SAVE_OFFSET = 0x3FE0000;
|
||||||
|
|
||||||
DMA_SCR = DMA_SCR_STOP;
|
DMA_SCR = DMA_SCR_STOP;
|
||||||
USB_SCR = USB_SCR_FLUSH_TX | USB_SCR_FLUSH_TX;
|
USB_SCR = USB_SCR_FLUSH_TX | USB_SCR_FLUSH_TX;
|
||||||
|
|
||||||
@ -156,6 +160,19 @@ __NAKED__ int main (void) {
|
|||||||
CFG_SCR &= ~CFG_SCR_SDRAM_SWITCH;
|
CFG_SCR &= ~CFG_SCR_SDRAM_SWITCH;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
if (cmd == 'D') {
|
||||||
|
print_02hex(arg1 >> 24);
|
||||||
|
print_02hex(arg1 >> 16);
|
||||||
|
print_02hex(arg1 >> 8);
|
||||||
|
print_02hex(arg1 >> 0);
|
||||||
|
print(" ");
|
||||||
|
print_02hex(arg2 >> 24);
|
||||||
|
print_02hex(arg2 >> 16);
|
||||||
|
print_02hex(arg2 >> 8);
|
||||||
|
print_02hex(arg2 >> 0);
|
||||||
|
print("\r\n");
|
||||||
|
}
|
||||||
|
print("\r\n");
|
||||||
CFG_RESPONSE = 0;
|
CFG_RESPONSE = 0;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -14,7 +14,7 @@ static const uint8_t rtc_bit_mask[7] = {
|
|||||||
|
|
||||||
|
|
||||||
static uint8_t i2c_is_busy (void) {
|
static uint8_t i2c_is_busy (void) {
|
||||||
return (I2C_SR & I2C_SR_BUSY);
|
return (I2C_SCR & I2C_SCR_BUSY);
|
||||||
}
|
}
|
||||||
|
|
||||||
static void i2c_wait_busy (void) {
|
static void i2c_wait_busy (void) {
|
||||||
@ -22,22 +22,22 @@ static void i2c_wait_busy (void) {
|
|||||||
}
|
}
|
||||||
|
|
||||||
static uint8_t i2c_has_ack (void) {
|
static uint8_t i2c_has_ack (void) {
|
||||||
return (I2C_SR & I2C_SR_ACK);
|
return (I2C_SCR & I2C_SCR_ACK);
|
||||||
}
|
}
|
||||||
|
|
||||||
static void i2c_start (void) {
|
static void i2c_start (void) {
|
||||||
i2c_wait_busy();
|
i2c_wait_busy();
|
||||||
I2C_SR = I2C_SR_START;
|
I2C_SCR = I2C_SCR_START;
|
||||||
}
|
}
|
||||||
|
|
||||||
static void i2c_stop (void) {
|
static void i2c_stop (void) {
|
||||||
i2c_wait_busy();
|
i2c_wait_busy();
|
||||||
I2C_SR = I2C_SR_STOP;
|
I2C_SCR = I2C_SCR_STOP;
|
||||||
}
|
}
|
||||||
|
|
||||||
static uint8_t i2c_write (uint8_t data) {
|
static uint8_t i2c_write (uint8_t data) {
|
||||||
i2c_wait_busy();
|
i2c_wait_busy();
|
||||||
I2C_SR = 0;
|
I2C_SCR = 0;
|
||||||
I2C_DR = data;
|
I2C_DR = data;
|
||||||
i2c_wait_busy();
|
i2c_wait_busy();
|
||||||
return i2c_has_ack();
|
return i2c_has_ack();
|
||||||
@ -45,7 +45,7 @@ static uint8_t i2c_write (uint8_t data) {
|
|||||||
|
|
||||||
static void i2c_read (uint8_t *data, uint8_t cfg) {
|
static void i2c_read (uint8_t *data, uint8_t cfg) {
|
||||||
i2c_wait_busy();
|
i2c_wait_busy();
|
||||||
I2C_SR = cfg;
|
I2C_SCR = cfg;
|
||||||
I2C_DR = 0xFF;
|
I2C_DR = 0xFF;
|
||||||
i2c_wait_busy();
|
i2c_wait_busy();
|
||||||
*data = I2C_DR;
|
*data = I2C_DR;
|
||||||
@ -74,7 +74,7 @@ static uint8_t i2c_rx (uint8_t address, uint8_t *data, size_t length) {
|
|||||||
i2c_start();
|
i2c_start();
|
||||||
result |= i2c_write(RTC_ADDR | I2C_ADDR_READ);
|
result |= i2c_write(RTC_ADDR | I2C_ADDR_READ);
|
||||||
for (size_t i = 0; i < length; i++) {
|
for (size_t i = 0; i < length; i++) {
|
||||||
i2c_read(data++, (i == (length - 1)) ? 0 : I2C_SR_MACK);
|
i2c_read(data++, (i == (length - 1)) ? 0 : I2C_SCR_MACK);
|
||||||
}
|
}
|
||||||
i2c_stop();
|
i2c_stop();
|
||||||
|
|
||||||
|
@ -12,21 +12,57 @@ typedef volatile uint8_t * io8_t;
|
|||||||
typedef volatile uint32_t * io32_t;
|
typedef volatile uint32_t * io32_t;
|
||||||
|
|
||||||
#define RAM (*((io32_t) 0x00000000))
|
#define RAM (*((io32_t) 0x00000000))
|
||||||
|
|
||||||
|
|
||||||
#define BOOTLOADER (*((io32_t) 0x10000000))
|
#define BOOTLOADER (*((io32_t) 0x10000000))
|
||||||
|
|
||||||
|
|
||||||
#define GPIO (*((io32_t) 0x20000000))
|
#define GPIO (*((io32_t) 0x20000000))
|
||||||
#define GPIO_O (*((io8_t) 0x20000000))
|
#define GPIO_O (*((io8_t) 0x20000000))
|
||||||
#define GPIO_I (*((io8_t) 0x20000001))
|
#define GPIO_I (*((io8_t) 0x20000001))
|
||||||
#define GPIO_OE (*((io8_t) 0x20000002))
|
#define GPIO_OE (*((io8_t) 0x20000002))
|
||||||
#define I2C_SR (*((io8_t) 0x30000000))
|
|
||||||
|
|
||||||
|
#define I2C_SCR (*((io8_t) 0x30000000))
|
||||||
#define I2C_DR (*((io8_t) 0x30000004))
|
#define I2C_DR (*((io8_t) 0x30000004))
|
||||||
|
|
||||||
|
#define I2C_SCR_START (1 << 0)
|
||||||
|
#define I2C_SCR_STOP (1 << 1)
|
||||||
|
#define I2C_SCR_MACK (1 << 2)
|
||||||
|
#define I2C_SCR_ACK (1 << 3)
|
||||||
|
#define I2C_SCR_BUSY (1 << 4)
|
||||||
|
#define I2C_ADDR_READ (1 << 0)
|
||||||
|
|
||||||
|
|
||||||
#define USB_SCR (*((io8_t) 0x40000000))
|
#define USB_SCR (*((io8_t) 0x40000000))
|
||||||
#define USB_DR (*((io8_t) 0x40000004))
|
#define USB_DR (*((io8_t) 0x40000004))
|
||||||
|
|
||||||
|
#define USB_SCR_RXNE (1 << 0)
|
||||||
|
#define USB_SCR_TXE (1 << 1)
|
||||||
|
#define USB_SCR_FLUSH_RX (1 << 2)
|
||||||
|
#define USB_SCR_FLUSH_TX (1 << 3)
|
||||||
|
|
||||||
|
|
||||||
#define UART_SCR (*((io8_t) 0x50000000))
|
#define UART_SCR (*((io8_t) 0x50000000))
|
||||||
#define UART_DR (*((io8_t) 0x50000004))
|
#define UART_DR (*((io8_t) 0x50000004))
|
||||||
|
|
||||||
|
#define UART_SCR_RXNE (1 << 0)
|
||||||
|
#define UART_SCR_TXE (1 << 1)
|
||||||
|
|
||||||
|
|
||||||
#define DMA_SCR (*((io8_t) 0x60000000))
|
#define DMA_SCR (*((io8_t) 0x60000000))
|
||||||
#define DMA_MADDR (*((io32_t) 0x60000004))
|
#define DMA_MADDR (*((io32_t) 0x60000004))
|
||||||
#define DMA_ID_LEN (*((io32_t) 0x60000008))
|
#define DMA_ID_LEN (*((io32_t) 0x60000008))
|
||||||
|
|
||||||
|
#define DMA_SCR_START (1 << 0)
|
||||||
|
#define DMA_SCR_STOP (1 << 1)
|
||||||
|
#define DMA_SCR_DIR (1 << 2)
|
||||||
|
#define DMA_SCR_BUSY (1 << 3)
|
||||||
|
|
||||||
|
|
||||||
#define SDRAM (*((io32_t) 0x68000000))
|
#define SDRAM (*((io32_t) 0x68000000))
|
||||||
|
|
||||||
|
|
||||||
#define CFG_SCR (*((io32_t) 0x70000000))
|
#define CFG_SCR (*((io32_t) 0x70000000))
|
||||||
#define CFG_DD_OFFSET (*((io32_t) 0x70000004))
|
#define CFG_DD_OFFSET (*((io32_t) 0x70000004))
|
||||||
#define CFG_SAVE_OFFSET (*((io32_t) 0x70000008))
|
#define CFG_SAVE_OFFSET (*((io32_t) 0x70000008))
|
||||||
@ -35,31 +71,13 @@ typedef volatile uint32_t * io32_t;
|
|||||||
#define CFG_ARG_2 (*((io32_t) 0x70000014))
|
#define CFG_ARG_2 (*((io32_t) 0x70000014))
|
||||||
#define CFG_RESPONSE (*((io32_t) 0x70000018))
|
#define CFG_RESPONSE (*((io32_t) 0x70000018))
|
||||||
|
|
||||||
#define I2C_SR_START (1 << 0)
|
|
||||||
#define I2C_SR_STOP (1 << 1)
|
|
||||||
#define I2C_SR_MACK (1 << 2)
|
|
||||||
#define I2C_SR_ACK (1 << 3)
|
|
||||||
#define I2C_SR_BUSY (1 << 4)
|
|
||||||
#define I2C_ADDR_READ (1 << 0)
|
|
||||||
|
|
||||||
#define USB_SCR_RXNE (1 << 0)
|
|
||||||
#define USB_SCR_TXE (1 << 1)
|
|
||||||
#define USB_SCR_FLUSH_RX (1 << 2)
|
|
||||||
#define USB_SCR_FLUSH_TX (1 << 3)
|
|
||||||
|
|
||||||
#define UART_SCR_RXNE (1 << 0)
|
|
||||||
#define UART_SCR_TXE (1 << 1)
|
|
||||||
|
|
||||||
#define DMA_SCR_START (1 << 0)
|
|
||||||
#define DMA_SCR_STOP (1 << 1)
|
|
||||||
#define DMA_SCR_DIR (1 << 2)
|
|
||||||
#define DMA_SCR_BUSY (1 << 3)
|
|
||||||
|
|
||||||
#define DMA_ID_USB (0)
|
|
||||||
#define DMA_ID_SD (1)
|
|
||||||
|
|
||||||
#define CFG_SCR_CPU_BUSY (1 << 30)
|
|
||||||
#define CFG_SCR_SDRAM_SWITCH (1 << 0)
|
#define CFG_SCR_SDRAM_SWITCH (1 << 0)
|
||||||
|
#define CFG_SCR_SDRAM_WRITABLE (1 << 1)
|
||||||
|
#define CFG_SCR_DD_EN (1 << 2)
|
||||||
|
#define CFG_SCR_SRAM_EN (1 << 3)
|
||||||
|
#define CFG_SCR_FLASHRAM_EN (1 << 4)
|
||||||
|
#define CFG_SCR_CPU_BUSY (1 << 30)
|
||||||
|
#define CFG_SCR_CPU_RUNNING (1 << 31)
|
||||||
|
|
||||||
|
|
||||||
#endif
|
#endif
|
||||||
|
@ -42,6 +42,7 @@ module n64_cfg (
|
|||||||
S_IDLE: begin
|
S_IDLE: begin
|
||||||
if (bus.request) begin
|
if (bus.request) begin
|
||||||
state <= S_WAIT;
|
state <= S_WAIT;
|
||||||
|
bus.ack <= 1'b1;
|
||||||
if (bus.write) begin
|
if (bus.write) begin
|
||||||
case (bus.address[4:1])
|
case (bus.address[4:1])
|
||||||
// ...
|
// ...
|
||||||
@ -65,7 +66,6 @@ module n64_cfg (
|
|||||||
end
|
end
|
||||||
|
|
||||||
S_WAIT: begin
|
S_WAIT: begin
|
||||||
bus.ack <= 1'b1;
|
|
||||||
state <= S_IDLE;
|
state <= S_IDLE;
|
||||||
end
|
end
|
||||||
endcase
|
endcase
|
||||||
|
@ -10,6 +10,57 @@ module n64_pi (
|
|||||||
inout [15:0] n64_pi_ad
|
inout [15:0] n64_pi_ad
|
||||||
);
|
);
|
||||||
|
|
||||||
|
// FIFOs
|
||||||
|
|
||||||
|
logic read_fifo_flush;
|
||||||
|
|
||||||
|
logic read_fifo_full;
|
||||||
|
logic read_fifo_write;
|
||||||
|
logic [15:0] read_fifo_wdata;
|
||||||
|
|
||||||
|
logic read_fifo_empty;
|
||||||
|
logic read_fifo_read;
|
||||||
|
logic [15:0] read_fifo_rdata;
|
||||||
|
|
||||||
|
n64_pi_fifo read_fifo_inst (
|
||||||
|
.sys(sys),
|
||||||
|
|
||||||
|
.flush(read_fifo_flush),
|
||||||
|
|
||||||
|
.full(read_fifo_full),
|
||||||
|
.write(read_fifo_write),
|
||||||
|
.wdata(read_fifo_wdata),
|
||||||
|
|
||||||
|
.empty(read_fifo_empty),
|
||||||
|
.read(read_fifo_read),
|
||||||
|
.rdata(read_fifo_rdata)
|
||||||
|
);
|
||||||
|
|
||||||
|
logic write_fifo_flush;
|
||||||
|
|
||||||
|
logic write_fifo_full;
|
||||||
|
logic write_fifo_write;
|
||||||
|
logic [15:0] write_fifo_wdata;
|
||||||
|
|
||||||
|
logic write_fifo_empty;
|
||||||
|
logic write_fifo_read;
|
||||||
|
logic [15:0] write_fifo_rdata;
|
||||||
|
|
||||||
|
n64_pi_fifo write_fifo_inst (
|
||||||
|
.sys(sys),
|
||||||
|
|
||||||
|
.flush(write_fifo_flush),
|
||||||
|
|
||||||
|
.full(write_fifo_full),
|
||||||
|
.write(write_fifo_write),
|
||||||
|
.wdata(write_fifo_wdata),
|
||||||
|
|
||||||
|
.empty(write_fifo_empty),
|
||||||
|
.read(write_fifo_read),
|
||||||
|
.rdata(write_fifo_rdata)
|
||||||
|
);
|
||||||
|
|
||||||
|
|
||||||
// Control signals input synchronization
|
// Control signals input synchronization
|
||||||
|
|
||||||
logic [2:0] n64_pi_alel_ff;
|
logic [2:0] n64_pi_alel_ff;
|
||||||
@ -28,7 +79,6 @@ module n64_pi (
|
|||||||
logic pi_aleh;
|
logic pi_aleh;
|
||||||
logic pi_alel;
|
logic pi_alel;
|
||||||
logic pi_read;
|
logic pi_read;
|
||||||
logic pi_read_delayed;
|
|
||||||
logic pi_write;
|
logic pi_write;
|
||||||
|
|
||||||
always_comb begin
|
always_comb begin
|
||||||
@ -36,10 +86,10 @@ module n64_pi (
|
|||||||
pi_aleh = n64_pi_aleh_ff[2];
|
pi_aleh = n64_pi_aleh_ff[2];
|
||||||
pi_alel = n64_pi_alel_ff[2];
|
pi_alel = n64_pi_alel_ff[2];
|
||||||
pi_read = n64_pi_read_ff[1];
|
pi_read = n64_pi_read_ff[1];
|
||||||
pi_read_delayed = n64_pi_read_ff[2];
|
|
||||||
pi_write = n64_pi_write_ff[2];
|
pi_write = n64_pi_write_ff[2];
|
||||||
end
|
end
|
||||||
|
|
||||||
|
|
||||||
// PI bus state and event generator
|
// PI bus state and event generator
|
||||||
|
|
||||||
typedef enum bit [1:0] {
|
typedef enum bit [1:0] {
|
||||||
@ -68,20 +118,22 @@ module n64_pi (
|
|||||||
logic alel_op;
|
logic alel_op;
|
||||||
logic read_op;
|
logic read_op;
|
||||||
logic write_op;
|
logic write_op;
|
||||||
|
logic end_op;
|
||||||
|
|
||||||
always_comb begin
|
always_comb begin
|
||||||
aleh_op = !pi_reset && last_pi_mode != PI_MODE_HIGH && pi_mode == PI_MODE_HIGH;
|
aleh_op = !pi_reset && last_pi_mode != PI_MODE_HIGH && pi_mode == PI_MODE_HIGH;
|
||||||
alel_op = !pi_reset && last_pi_mode == PI_MODE_HIGH && pi_mode == PI_MODE_LOW;
|
alel_op = !pi_reset && last_pi_mode == PI_MODE_HIGH && pi_mode == PI_MODE_LOW;
|
||||||
read_op = !pi_reset && pi_mode == PI_MODE_VALID && last_read && !pi_read;
|
read_op = !pi_reset && pi_mode == PI_MODE_VALID && last_read && !pi_read;
|
||||||
write_op = !pi_reset && pi_mode == PI_MODE_VALID && last_write && !pi_write;
|
write_op = !pi_reset && pi_mode == PI_MODE_VALID && last_write && !pi_write;
|
||||||
|
end_op = !pi_reset && last_pi_mode == PI_MODE_VALID && pi_mode != PI_MODE_VALID;
|
||||||
end
|
end
|
||||||
|
|
||||||
|
|
||||||
// Input and output data sampling
|
// Input and output data sampling
|
||||||
|
|
||||||
logic [15:0] n64_pi_ad_input;
|
logic [15:0] n64_pi_ad_input;
|
||||||
logic [15:0] n64_pi_ad_output;
|
logic [15:0] n64_pi_ad_output;
|
||||||
logic [15:0] n64_pi_ad_output_data;
|
logic [15:0] n64_pi_ad_output_data;
|
||||||
logic [15:0] n64_pi_ad_output_data_buffer;
|
|
||||||
logic n64_pi_ad_output_enable;
|
logic n64_pi_ad_output_enable;
|
||||||
logic n64_pi_ad_output_enable_data;
|
logic n64_pi_ad_output_enable_data;
|
||||||
|
|
||||||
@ -91,38 +143,65 @@ module n64_pi (
|
|||||||
|
|
||||||
always_comb begin
|
always_comb begin
|
||||||
n64_pi_ad = n64_pi_ad_output_enable ? n64_pi_ad_output : 16'hZZZZ;
|
n64_pi_ad = n64_pi_ad_output_enable ? n64_pi_ad_output : 16'hZZZZ;
|
||||||
n64_pi_ad_output_enable_data = !pi_reset && pi_mode == PI_MODE_VALID && n64_pi_address_valid && !pi_read_delayed;
|
n64_pi_ad_output_enable_data = !pi_reset && pi_mode == PI_MODE_VALID && n64_pi_address_valid && !n64_pi_read_ff[2];
|
||||||
end
|
end
|
||||||
|
|
||||||
always_ff @(posedge sys.clk) begin
|
always_ff @(posedge sys.clk) begin
|
||||||
n64_pi_ad_input <= n64_pi_ad;
|
n64_pi_ad_input <= n64_pi_ad;
|
||||||
n64_pi_ad_output <= n64_pi_ad_output_data;
|
n64_pi_ad_output <= n64_pi_ad_output_data;
|
||||||
n64_pi_ad_output_enable <= n64_pi_ad_output_enable_data;
|
n64_pi_ad_output_enable <= n64_pi_ad_output_enable_data;
|
||||||
if (read_op) begin
|
|
||||||
n64_pi_ad_output_data <= n64_pi_ad_output_data_buffer;
|
|
||||||
end
|
end
|
||||||
if (pending_operation && bus.ack) begin
|
|
||||||
n64_pi_ad_output_data <= bus.rdata;
|
logic wait_for_read_fifo;
|
||||||
|
logic wait_for_write_fifo;
|
||||||
|
|
||||||
|
always_comb begin
|
||||||
|
read_fifo_write = bus.ack && !bus.write;
|
||||||
|
read_fifo_wdata = bus.rdata;
|
||||||
|
|
||||||
|
write_fifo_wdata = n64_pi_ad_input;
|
||||||
|
end
|
||||||
|
|
||||||
|
always_ff @(posedge sys.clk) begin
|
||||||
|
read_fifo_read <= 1'b0;
|
||||||
|
write_fifo_write <= 1'b0;
|
||||||
|
|
||||||
|
if (sys.reset || sys.n64_hard_reset) begin
|
||||||
|
wait_for_read_fifo <= 1'b0;
|
||||||
|
wait_for_write_fifo <= 1'b0;
|
||||||
|
end else begin
|
||||||
|
if (read_op || wait_for_read_fifo) begin
|
||||||
|
if (read_fifo_empty) begin
|
||||||
|
wait_for_read_fifo <= 1'b1;
|
||||||
|
end else begin
|
||||||
|
n64_pi_ad_output_data <= read_fifo_rdata;
|
||||||
|
read_fifo_read <= 1'b1;
|
||||||
|
wait_for_read_fifo <= 1'b0;
|
||||||
|
end
|
||||||
|
end
|
||||||
|
if (write_op || wait_for_write_fifo) begin
|
||||||
|
if (write_fifo_full) begin
|
||||||
|
wait_for_write_fifo <= 1'b1;
|
||||||
|
end else begin
|
||||||
|
write_fifo_write <= 1'b1;
|
||||||
|
wait_for_write_fifo <= 1'b0;
|
||||||
|
end
|
||||||
|
end
|
||||||
end
|
end
|
||||||
end
|
end
|
||||||
|
|
||||||
// Internal bus controller
|
|
||||||
|
|
||||||
typedef enum bit [0:0] {
|
// Address decoding
|
||||||
S_IDLE,
|
|
||||||
S_WAIT
|
|
||||||
} e_state;
|
|
||||||
|
|
||||||
e_state state;
|
|
||||||
logic first_operation;
|
|
||||||
|
|
||||||
sc64::e_n64_id next_id;
|
sc64::e_n64_id next_id;
|
||||||
logic [25:0] next_offset;
|
logic [31:0] next_offset;
|
||||||
|
logic sram_selected;
|
||||||
|
|
||||||
always_ff @(posedge sys.clk) begin
|
always_ff @(posedge sys.clk) begin
|
||||||
if (aleh_op) begin
|
if (aleh_op) begin
|
||||||
n64_pi_address_valid <= 1'b0;
|
n64_pi_address_valid <= 1'b0;
|
||||||
next_offset <= 32'd0;
|
next_offset <= 32'd0;
|
||||||
|
sram_selected <= 1'b0;
|
||||||
if (cfg.dd_enabled) begin
|
if (cfg.dd_enabled) begin
|
||||||
if (n64_pi_ad_input == 16'h0500) begin
|
if (n64_pi_ad_input == 16'h0500) begin
|
||||||
n64_pi_address_valid <= 1'b1;
|
n64_pi_address_valid <= 1'b1;
|
||||||
@ -131,20 +210,20 @@ module n64_pi (
|
|||||||
if (n64_pi_ad_input >= 16'h0600 && n64_pi_ad_input < 16'h0640) begin
|
if (n64_pi_ad_input >= 16'h0600 && n64_pi_ad_input < 16'h0640) begin
|
||||||
n64_pi_address_valid <= 1'b1;
|
n64_pi_address_valid <= 1'b1;
|
||||||
next_id <= sc64::ID_N64_SDRAM;
|
next_id <= sc64::ID_N64_SDRAM;
|
||||||
next_offset <= cfg.dd_offset;
|
next_offset <= cfg.dd_offset + 32'h0A00_0000;
|
||||||
end
|
end
|
||||||
end
|
end
|
||||||
if (n64_pi_ad_input >= 16'h0800 && n64_pi_ad_input < 16'h0802) begin
|
if (n64_pi_ad_input >= 16'h0800 && n64_pi_ad_input < 16'h0802) begin
|
||||||
if (cfg.sram_enabled) begin
|
if (cfg.sram_enabled) begin
|
||||||
n64_pi_address_valid <= 1'b1;
|
n64_pi_address_valid <= 1'b1;
|
||||||
next_id <= sc64::ID_N64_SDRAM;
|
next_id <= sc64::ID_N64_SDRAM;
|
||||||
next_offset <= cfg.save_offset;
|
next_offset <= cfg.save_offset + 32'h0800_0000;
|
||||||
|
sram_selected <= 1'b1;
|
||||||
end else if (cfg.flashram_enabled) begin
|
end else if (cfg.flashram_enabled) begin
|
||||||
n64_pi_address_valid <= 1'b1;
|
n64_pi_address_valid <= 1'b1;
|
||||||
next_id <= sc64::ID_N64_FLASHRAM;
|
next_id <= sc64::ID_N64_FLASHRAM;
|
||||||
if (cfg.flashram_read_mode) begin
|
if (cfg.flashram_read_mode) begin
|
||||||
next_id <= sc64::ID_N64_SDRAM;
|
next_offset <= cfg.save_offset + 32'h0800_0000;
|
||||||
next_offset <= cfg.save_offset;
|
|
||||||
end
|
end
|
||||||
end
|
end
|
||||||
end
|
end
|
||||||
@ -159,46 +238,81 @@ module n64_pi (
|
|||||||
end
|
end
|
||||||
end
|
end
|
||||||
|
|
||||||
|
|
||||||
|
// Bus controller
|
||||||
|
|
||||||
|
logic can_read;
|
||||||
|
logic first_write_op;
|
||||||
|
logic load_starting_address;
|
||||||
|
sc64::e_n64_id starting_id;
|
||||||
|
logic [31:0] starting_address;
|
||||||
|
|
||||||
always_ff @(posedge sys.clk) begin
|
always_ff @(posedge sys.clk) begin
|
||||||
if (sys.reset || sys.n64_hard_reset || sys.n64_soft_reset) begin
|
read_fifo_flush <= 1'b0;
|
||||||
state <= S_IDLE;
|
|
||||||
|
write_fifo_read <= 1'b0;
|
||||||
|
|
||||||
|
if (sys.reset || sys.n64_hard_reset) begin
|
||||||
bus.request <= 1'b0;
|
bus.request <= 1'b0;
|
||||||
pending_operation <= 1'b0;
|
read_fifo_flush <= 1'b1;
|
||||||
|
write_fifo_flush <= 1'b1;
|
||||||
end else begin
|
end else begin
|
||||||
case (state)
|
write_fifo_flush <= starting_id == sc64::ID_N64_SDRAM && !cfg.sdram_writable && !sram_selected;
|
||||||
S_IDLE: begin
|
|
||||||
if (aleh_op) begin
|
if (aleh_op) begin
|
||||||
bus.address[31:16] <= n64_pi_ad_input;
|
starting_address[31:16] <= n64_pi_ad_input;
|
||||||
end
|
end
|
||||||
|
|
||||||
if (alel_op) begin
|
if (alel_op) begin
|
||||||
bus.address <= {bus.address[31:16], n64_pi_ad_input[15:1], 1'b0} + next_offset;
|
read_fifo_flush <= 1'b1;
|
||||||
|
can_read <= 1'b1;
|
||||||
|
first_write_op <= 1'b1;
|
||||||
|
load_starting_address <= 1'b1;
|
||||||
|
starting_id <= next_id;
|
||||||
|
starting_address <= {starting_address[31:16], n64_pi_ad_input[15:1], 1'b0} + next_offset;
|
||||||
end
|
end
|
||||||
if (n64_pi_address_valid && (alel_op || read_op || write_op || pending_operation)) begin
|
|
||||||
state <= S_WAIT;
|
if (write_op) begin
|
||||||
bus.id <= next_id;
|
can_read <= 1'b0;
|
||||||
bus.request <= 1'b1;
|
if (first_write_op) begin
|
||||||
bus.write <= write_op || (pending_operation && pending_write);
|
first_write_op <= 1'b0;
|
||||||
if (!alel_op && !(first_operation && write_op)) begin
|
load_starting_address <= 1'b1;
|
||||||
bus.address[31:1] <= bus.address[31:1] + 1'd1;
|
|
||||||
end
|
|
||||||
bus.wdata <= n64_pi_ad_input;
|
|
||||||
first_operation <= alel_op;
|
|
||||||
pending_operation <= 1'b0;
|
|
||||||
end
|
end
|
||||||
end
|
end
|
||||||
|
|
||||||
S_WAIT: begin
|
if (!bus.request) begin
|
||||||
|
if (!write_fifo_empty) begin
|
||||||
|
bus.request <= 1'b1;
|
||||||
|
bus.write <= 1'b1;
|
||||||
|
if (load_starting_address) begin
|
||||||
|
bus.id <= starting_id;
|
||||||
|
bus.address <= starting_address;
|
||||||
|
load_starting_address <= 1'b0;
|
||||||
|
end
|
||||||
|
bus.wdata <= write_fifo_rdata;
|
||||||
|
write_fifo_read <= 1'b1;
|
||||||
|
end else if (!read_fifo_full && can_read) begin
|
||||||
|
bus.request <= 1'b1;
|
||||||
|
bus.write <= 1'b0;
|
||||||
|
if (load_starting_address) begin
|
||||||
|
bus.id <= starting_id;
|
||||||
|
if (starting_id == sc64::ID_N64_FLASHRAM && cfg.flashram_read_mode) begin
|
||||||
|
bus.id <= sc64::ID_N64_SDRAM;
|
||||||
|
end
|
||||||
|
bus.address <= starting_address;
|
||||||
|
load_starting_address <= 1'b0;
|
||||||
|
end
|
||||||
|
end
|
||||||
|
end else begin
|
||||||
if (bus.ack) begin
|
if (bus.ack) begin
|
||||||
state <= S_IDLE;
|
|
||||||
bus.request <= 1'b0;
|
bus.request <= 1'b0;
|
||||||
n64_pi_ad_output_data_buffer <= bus.rdata;
|
bus.address <= bus.address + 2'd2;
|
||||||
end
|
|
||||||
if (read_op || write_op) begin
|
|
||||||
pending_operation <= 1'b1;
|
|
||||||
pending_write <= write_op;
|
|
||||||
end
|
end
|
||||||
end
|
end
|
||||||
endcase
|
|
||||||
|
if (end_op) begin
|
||||||
|
can_read <= 1'b0;
|
||||||
|
end
|
||||||
end
|
end
|
||||||
end
|
end
|
||||||
|
|
||||||
|
43
fw/rtl/n64/n64_pi_fifo.sv
Normal file
43
fw/rtl/n64/n64_pi_fifo.sv
Normal file
@ -0,0 +1,43 @@
|
|||||||
|
module n64_pi_fifo (
|
||||||
|
if_system.sys sys,
|
||||||
|
|
||||||
|
input flush,
|
||||||
|
|
||||||
|
output full,
|
||||||
|
input write,
|
||||||
|
input [15:0] wdata,
|
||||||
|
|
||||||
|
output empty,
|
||||||
|
input read,
|
||||||
|
output [15:0] rdata
|
||||||
|
);
|
||||||
|
|
||||||
|
logic [15:0] fifo_mem [0:3];
|
||||||
|
logic [2:0] fifo_wr_ptr;
|
||||||
|
logic [2:0] fifo_rd_ptr;
|
||||||
|
|
||||||
|
logic empty_or_full;
|
||||||
|
|
||||||
|
always_comb begin
|
||||||
|
rdata = fifo_mem[fifo_rd_ptr[1:0]];
|
||||||
|
empty_or_full = fifo_wr_ptr[1:0] == fifo_rd_ptr[1:0];
|
||||||
|
empty = empty_or_full && fifo_wr_ptr[2] == fifo_rd_ptr[2];
|
||||||
|
full = empty_or_full && fifo_wr_ptr[2] != fifo_rd_ptr[2];
|
||||||
|
end
|
||||||
|
|
||||||
|
always_ff @(posedge sys.clk) begin
|
||||||
|
if (sys.reset || flush) begin
|
||||||
|
fifo_wr_ptr <= 3'd0;
|
||||||
|
fifo_rd_ptr <= 3'd0;
|
||||||
|
end else begin
|
||||||
|
if (write) begin
|
||||||
|
fifo_mem[fifo_wr_ptr[1:0]] <= wdata;
|
||||||
|
fifo_wr_ptr <= fifo_wr_ptr + 1'd1;
|
||||||
|
end
|
||||||
|
if (read) begin
|
||||||
|
fifo_rd_ptr <= fifo_rd_ptr + 1'd1;
|
||||||
|
end
|
||||||
|
end
|
||||||
|
end
|
||||||
|
|
||||||
|
endmodule
|
@ -54,6 +54,16 @@ module n64_soc (
|
|||||||
.bus(bus.at[sc64::ID_N64_BOOTLOADER].device)
|
.bus(bus.at[sc64::ID_N64_BOOTLOADER].device)
|
||||||
);
|
);
|
||||||
|
|
||||||
|
n64_dummy n64_flashram_inst (
|
||||||
|
.sys(sys),
|
||||||
|
.bus(bus.at[sc64::ID_N64_FLASHRAM].device)
|
||||||
|
);
|
||||||
|
|
||||||
|
n64_dummy n64_ddregs_inst (
|
||||||
|
.sys(sys),
|
||||||
|
.bus(bus.at[sc64::ID_N64_DDREGS].device)
|
||||||
|
);
|
||||||
|
|
||||||
n64_cfg n64_cfg_inst (
|
n64_cfg n64_cfg_inst (
|
||||||
.sys(sys),
|
.sys(sys),
|
||||||
.bus(bus.at[sc64::ID_N64_CFG].device),
|
.bus(bus.at[sc64::ID_N64_CFG].device),
|
||||||
@ -61,3 +71,46 @@ module n64_soc (
|
|||||||
);
|
);
|
||||||
|
|
||||||
endmodule
|
endmodule
|
||||||
|
|
||||||
|
|
||||||
|
module n64_dummy (
|
||||||
|
if_system.sys sys,
|
||||||
|
if_n64_bus bus
|
||||||
|
);
|
||||||
|
|
||||||
|
typedef enum bit [0:0] {
|
||||||
|
S_IDLE,
|
||||||
|
S_WAIT
|
||||||
|
} e_state;
|
||||||
|
|
||||||
|
e_state state;
|
||||||
|
|
||||||
|
always_comb begin
|
||||||
|
bus.rdata = 16'h0000;
|
||||||
|
if (bus.ack) begin
|
||||||
|
bus.rdata = !bus.address[1] ? 16'h0180 : 16'h0000;
|
||||||
|
end
|
||||||
|
end
|
||||||
|
|
||||||
|
always_ff @(posedge sys.clk) begin
|
||||||
|
bus.ack <= 1'b0;
|
||||||
|
|
||||||
|
if (sys.reset) begin
|
||||||
|
state <= S_IDLE;
|
||||||
|
end else begin
|
||||||
|
case (state)
|
||||||
|
S_IDLE: begin
|
||||||
|
if (bus.request) begin
|
||||||
|
state <= S_WAIT;
|
||||||
|
bus.ack <= 1'b1;
|
||||||
|
end
|
||||||
|
end
|
||||||
|
|
||||||
|
S_WAIT: begin
|
||||||
|
state <= S_IDLE;
|
||||||
|
end
|
||||||
|
endcase
|
||||||
|
end
|
||||||
|
end
|
||||||
|
|
||||||
|
endmodule
|
||||||
|
@ -33,7 +33,7 @@ cart_header_t *boot_load_cart_header(void) {
|
|||||||
}
|
}
|
||||||
|
|
||||||
uint16_t boot_get_cic_seed(cart_header_t *cart_header) {
|
uint16_t boot_get_cic_seed(cart_header_t *cart_header) {
|
||||||
uint16_t cic_seed = crc32_to_cic_seed[3].cic_seed;
|
uint16_t cic_seed = crc32_to_cic_seed[7].cic_seed;
|
||||||
uint32_t ipl3_crc32 = crc32_calculate(cart_header->boot_code, sizeof(cart_header->boot_code));
|
uint32_t ipl3_crc32 = crc32_calculate(cart_header->boot_code, sizeof(cart_header->boot_code));
|
||||||
|
|
||||||
for (size_t i = 0; i < ARRAY_ITEMS(crc32_to_cic_seed); i++) {
|
for (size_t i = 0; i < ARRAY_ITEMS(crc32_to_cic_seed); i++) {
|
||||||
@ -140,6 +140,11 @@ void boot(cart_header_t *cart_header, uint16_t cic_seed, tv_type_t tv_type) {
|
|||||||
gpr_regs[CPU_REG_SP] = CPU_ADDRESS_IN_REG(SP_MEM->imem[ARRAY_ITEMS(SP_MEM->imem) - 4]);
|
gpr_regs[CPU_REG_SP] = CPU_ADDRESS_IN_REG(SP_MEM->imem[ARRAY_ITEMS(SP_MEM->imem) - 4]);
|
||||||
gpr_regs[CPU_REG_RA] = CPU_ADDRESS_IN_REG(SP_MEM->imem[(os_tv_type == TV_PAL) ? 341 : 340]);
|
gpr_regs[CPU_REG_RA] = CPU_ADDRESS_IN_REG(SP_MEM->imem[(os_tv_type == TV_PAL) ? 341 : 340]);
|
||||||
|
|
||||||
|
print_debug((uint32_t) gpr_regs[CPU_REG_T3], (uint32_t) gpr_regs[CPU_REG_S3]);
|
||||||
|
print_debug((uint32_t) gpr_regs[CPU_REG_S4], (uint32_t) gpr_regs[CPU_REG_S5]);
|
||||||
|
print_debug((uint32_t) gpr_regs[CPU_REG_S6], (uint32_t) gpr_regs[CPU_REG_S7]);
|
||||||
|
print_debug((uint32_t) gpr_regs[CPU_REG_SP], (uint32_t) gpr_regs[CPU_REG_RA]);
|
||||||
|
|
||||||
__asm__ (
|
__asm__ (
|
||||||
".set noat \n\t"
|
".set noat \n\t"
|
||||||
".set noreorder \n\t"
|
".set noreorder \n\t"
|
||||||
|
@ -16,6 +16,19 @@ typedef struct sc64_cart_registers {
|
|||||||
#define SC64_CFG_SCR_CPU_BUSY (1 << 30)
|
#define SC64_CFG_SCR_CPU_BUSY (1 << 30)
|
||||||
|
|
||||||
#define CMD_SDRAM_SWITCH 'S'
|
#define CMD_SDRAM_SWITCH 'S'
|
||||||
|
#define CMD_DEBUG 'D'
|
||||||
|
|
||||||
|
void print_debug(uint32_t a1, uint32_t a2) {
|
||||||
|
|
||||||
|
uint32_t scr = 0;
|
||||||
|
do {
|
||||||
|
scr = platform_pi_io_read(&SC64_CFG->SCR);
|
||||||
|
} while (scr & SC64_CFG_SCR_CPU_BUSY);
|
||||||
|
|
||||||
|
platform_pi_io_write(&SC64_CFG->ARG[0], a1);
|
||||||
|
platform_pi_io_write(&SC64_CFG->ARG[1], a2);
|
||||||
|
platform_pi_io_write(&SC64_CFG->COMMAND, (uint32_t) CMD_DEBUG);
|
||||||
|
}
|
||||||
|
|
||||||
int main(void) {
|
int main(void) {
|
||||||
OS_BOOT_CONFIG->tv_type = TV_NTSC;
|
OS_BOOT_CONFIG->tv_type = TV_NTSC;
|
||||||
@ -41,5 +54,7 @@ int main(void) {
|
|||||||
uint16_t cic_seed = boot_get_cic_seed(cart_header);
|
uint16_t cic_seed = boot_get_cic_seed(cart_header);
|
||||||
tv_type_t tv_type = boot_get_tv_type(cart_header);
|
tv_type_t tv_type = boot_get_tv_type(cart_header);
|
||||||
|
|
||||||
|
print_debug(cic_seed << 16 | (tv_type & 0x03), cart_header->pi_conf);
|
||||||
|
|
||||||
boot(cart_header, cic_seed, tv_type);
|
boot(cart_header, cic_seed, tv_type);
|
||||||
}
|
}
|
||||||
|
Loading…
Reference in New Issue
Block a user