mirror of
https://github.com/Polprzewodnikowy/SummerCart64.git
synced 2024-12-24 03:51:57 +01:00
horrible
This commit is contained in:
parent
d550d9c184
commit
1722b3cd3f
@ -19,7 +19,7 @@
|
||||
#
|
||||
# Quartus Prime
|
||||
# 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 QSYS_FILE rtl/intel/flash/intel_flash.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/gpio/intel_gpio_ddro.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 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_cfg.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_soc.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)
|
||||
# ------------------------
|
||||
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
|
@ -67,6 +67,10 @@ __NAKED__ int main (void) {
|
||||
GPIO_OE = (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;
|
||||
USB_SCR = USB_SCR_FLUSH_TX | USB_SCR_FLUSH_TX;
|
||||
|
||||
@ -156,6 +160,19 @@ __NAKED__ int main (void) {
|
||||
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;
|
||||
}
|
||||
}
|
||||
|
@ -14,7 +14,7 @@ static const uint8_t rtc_bit_mask[7] = {
|
||||
|
||||
|
||||
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) {
|
||||
@ -22,22 +22,22 @@ static void i2c_wait_busy (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) {
|
||||
i2c_wait_busy();
|
||||
I2C_SR = I2C_SR_START;
|
||||
I2C_SCR = I2C_SCR_START;
|
||||
}
|
||||
|
||||
static void i2c_stop (void) {
|
||||
i2c_wait_busy();
|
||||
I2C_SR = I2C_SR_STOP;
|
||||
I2C_SCR = I2C_SCR_STOP;
|
||||
}
|
||||
|
||||
static uint8_t i2c_write (uint8_t data) {
|
||||
i2c_wait_busy();
|
||||
I2C_SR = 0;
|
||||
I2C_SCR = 0;
|
||||
I2C_DR = data;
|
||||
i2c_wait_busy();
|
||||
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) {
|
||||
i2c_wait_busy();
|
||||
I2C_SR = cfg;
|
||||
I2C_SCR = cfg;
|
||||
I2C_DR = 0xFF;
|
||||
i2c_wait_busy();
|
||||
*data = I2C_DR;
|
||||
@ -74,7 +74,7 @@ static uint8_t i2c_rx (uint8_t address, uint8_t *data, size_t length) {
|
||||
i2c_start();
|
||||
result |= i2c_write(RTC_ADDR | I2C_ADDR_READ);
|
||||
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();
|
||||
|
||||
|
@ -6,60 +6,78 @@
|
||||
#include <stdint.h>
|
||||
|
||||
|
||||
#define __NAKED__ __attribute__((naked))
|
||||
#define __NAKED__ __attribute__((naked))
|
||||
|
||||
typedef volatile uint8_t * io8_t;
|
||||
typedef volatile uint32_t * io32_t;
|
||||
typedef volatile uint8_t * io8_t;
|
||||
typedef volatile uint32_t * io32_t;
|
||||
|
||||
#define RAM (*((io32_t) 0x00000000))
|
||||
#define BOOTLOADER (*((io32_t) 0x10000000))
|
||||
#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 USB_SCR (*((io8_t) 0x40000000))
|
||||
#define USB_DR (*((io8_t) 0x40000004))
|
||||
#define UART_SCR (*((io8_t) 0x50000000))
|
||||
#define UART_DR (*((io8_t) 0x50000004))
|
||||
#define DMA_SCR (*((io8_t) 0x60000000))
|
||||
#define DMA_MADDR (*((io32_t) 0x60000004))
|
||||
#define DMA_ID_LEN (*((io32_t) 0x60000008))
|
||||
#define SDRAM (*((io32_t) 0x68000000))
|
||||
#define CFG_SCR (*((io32_t) 0x70000000))
|
||||
#define CFG_DD_OFFSET (*((io32_t) 0x70000004))
|
||||
#define CFG_SAVE_OFFSET (*((io32_t) 0x70000008))
|
||||
#define CFG_COMMAND (*((io8_t) 0x7000000C))
|
||||
#define CFG_ARG_1 (*((io32_t) 0x70000010))
|
||||
#define CFG_ARG_2 (*((io32_t) 0x70000014))
|
||||
#define CFG_RESPONSE (*((io32_t) 0x70000018))
|
||||
#define RAM (*((io32_t) 0x00000000))
|
||||
|
||||
#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 BOOTLOADER (*((io32_t) 0x10000000))
|
||||
|
||||
#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 GPIO (*((io32_t) 0x20000000))
|
||||
#define GPIO_O (*((io8_t) 0x20000000))
|
||||
#define GPIO_I (*((io8_t) 0x20000001))
|
||||
#define GPIO_OE (*((io8_t) 0x20000002))
|
||||
|
||||
#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 I2C_SCR (*((io8_t) 0x30000000))
|
||||
#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_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_DR (*((io8_t) 0x50000004))
|
||||
|
||||
#define UART_SCR_RXNE (1 << 0)
|
||||
#define UART_SCR_TXE (1 << 1)
|
||||
|
||||
|
||||
#define DMA_SCR (*((io8_t) 0x60000000))
|
||||
#define DMA_MADDR (*((io32_t) 0x60000004))
|
||||
#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 CFG_SCR (*((io32_t) 0x70000000))
|
||||
#define CFG_DD_OFFSET (*((io32_t) 0x70000004))
|
||||
#define CFG_SAVE_OFFSET (*((io32_t) 0x70000008))
|
||||
#define CFG_COMMAND (*((io8_t) 0x7000000C))
|
||||
#define CFG_ARG_1 (*((io32_t) 0x70000010))
|
||||
#define CFG_ARG_2 (*((io32_t) 0x70000014))
|
||||
#define CFG_RESPONSE (*((io32_t) 0x70000018))
|
||||
|
||||
#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
|
||||
|
@ -42,6 +42,7 @@ module n64_cfg (
|
||||
S_IDLE: begin
|
||||
if (bus.request) begin
|
||||
state <= S_WAIT;
|
||||
bus.ack <= 1'b1;
|
||||
if (bus.write) begin
|
||||
case (bus.address[4:1])
|
||||
// ...
|
||||
@ -65,7 +66,6 @@ module n64_cfg (
|
||||
end
|
||||
|
||||
S_WAIT: begin
|
||||
bus.ack <= 1'b1;
|
||||
state <= S_IDLE;
|
||||
end
|
||||
endcase
|
||||
|
@ -10,6 +10,57 @@ module n64_pi (
|
||||
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
|
||||
|
||||
logic [2:0] n64_pi_alel_ff;
|
||||
@ -28,7 +79,6 @@ module n64_pi (
|
||||
logic pi_aleh;
|
||||
logic pi_alel;
|
||||
logic pi_read;
|
||||
logic pi_read_delayed;
|
||||
logic pi_write;
|
||||
|
||||
always_comb begin
|
||||
@ -36,10 +86,10 @@ module n64_pi (
|
||||
pi_aleh = n64_pi_aleh_ff[2];
|
||||
pi_alel = n64_pi_alel_ff[2];
|
||||
pi_read = n64_pi_read_ff[1];
|
||||
pi_read_delayed = n64_pi_read_ff[2];
|
||||
pi_write = n64_pi_write_ff[2];
|
||||
end
|
||||
|
||||
|
||||
// PI bus state and event generator
|
||||
|
||||
typedef enum bit [1:0] {
|
||||
@ -68,20 +118,22 @@ module n64_pi (
|
||||
logic alel_op;
|
||||
logic read_op;
|
||||
logic write_op;
|
||||
logic end_op;
|
||||
|
||||
always_comb begin
|
||||
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;
|
||||
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;
|
||||
end_op = !pi_reset && last_pi_mode == PI_MODE_VALID && pi_mode != PI_MODE_VALID;
|
||||
end
|
||||
|
||||
|
||||
// Input and output data sampling
|
||||
|
||||
logic [15:0] n64_pi_ad_input;
|
||||
logic [15:0] n64_pi_ad_output;
|
||||
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_data;
|
||||
|
||||
@ -91,38 +143,65 @@ module n64_pi (
|
||||
|
||||
always_comb begin
|
||||
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
|
||||
|
||||
always_ff @(posedge sys.clk) begin
|
||||
n64_pi_ad_input <= n64_pi_ad;
|
||||
n64_pi_ad_output <= n64_pi_ad_output_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
|
||||
if (pending_operation && bus.ack) begin
|
||||
n64_pi_ad_output_data <= bus.rdata;
|
||||
end
|
||||
|
||||
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
|
||||
|
||||
// Internal bus controller
|
||||
|
||||
typedef enum bit [0:0] {
|
||||
S_IDLE,
|
||||
S_WAIT
|
||||
} e_state;
|
||||
|
||||
e_state state;
|
||||
logic first_operation;
|
||||
// Address decoding
|
||||
|
||||
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
|
||||
if (aleh_op) begin
|
||||
n64_pi_address_valid <= 1'b0;
|
||||
next_offset <= 32'd0;
|
||||
sram_selected <= 1'b0;
|
||||
if (cfg.dd_enabled) begin
|
||||
if (n64_pi_ad_input == 16'h0500) begin
|
||||
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
|
||||
n64_pi_address_valid <= 1'b1;
|
||||
next_id <= sc64::ID_N64_SDRAM;
|
||||
next_offset <= cfg.dd_offset;
|
||||
next_offset <= cfg.dd_offset + 32'h0A00_0000;
|
||||
end
|
||||
end
|
||||
if (n64_pi_ad_input >= 16'h0800 && n64_pi_ad_input < 16'h0802) begin
|
||||
if (cfg.sram_enabled) begin
|
||||
n64_pi_address_valid <= 1'b1;
|
||||
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
|
||||
n64_pi_address_valid <= 1'b1;
|
||||
next_id <= sc64::ID_N64_FLASHRAM;
|
||||
if (cfg.flashram_read_mode) begin
|
||||
next_id <= sc64::ID_N64_SDRAM;
|
||||
next_offset <= cfg.save_offset;
|
||||
next_offset <= cfg.save_offset + 32'h0800_0000;
|
||||
end
|
||||
end
|
||||
end
|
||||
@ -159,46 +238,81 @@ module n64_pi (
|
||||
end
|
||||
end
|
||||
|
||||
always_ff @(posedge sys.clk) begin
|
||||
if (sys.reset || sys.n64_hard_reset || sys.n64_soft_reset) begin
|
||||
state <= S_IDLE;
|
||||
bus.request <= 1'b0;
|
||||
pending_operation <= 1'b0;
|
||||
end else begin
|
||||
case (state)
|
||||
S_IDLE: begin
|
||||
if (aleh_op) begin
|
||||
bus.address[31:16] <= n64_pi_ad_input;
|
||||
end
|
||||
if (alel_op) begin
|
||||
bus.address <= {bus.address[31:16], n64_pi_ad_input[15:1], 1'b0} + next_offset;
|
||||
end
|
||||
if (n64_pi_address_valid && (alel_op || read_op || write_op || pending_operation)) begin
|
||||
state <= S_WAIT;
|
||||
bus.id <= next_id;
|
||||
bus.request <= 1'b1;
|
||||
bus.write <= write_op || (pending_operation && pending_write);
|
||||
if (!alel_op && !(first_operation && write_op)) begin
|
||||
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
|
||||
|
||||
S_WAIT: begin
|
||||
if (bus.ack) begin
|
||||
state <= S_IDLE;
|
||||
bus.request <= 1'b0;
|
||||
n64_pi_ad_output_data_buffer <= bus.rdata;
|
||||
// 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
|
||||
read_fifo_flush <= 1'b0;
|
||||
|
||||
write_fifo_read <= 1'b0;
|
||||
|
||||
if (sys.reset || sys.n64_hard_reset) begin
|
||||
bus.request <= 1'b0;
|
||||
read_fifo_flush <= 1'b1;
|
||||
write_fifo_flush <= 1'b1;
|
||||
end else begin
|
||||
write_fifo_flush <= starting_id == sc64::ID_N64_SDRAM && !cfg.sdram_writable && !sram_selected;
|
||||
|
||||
if (aleh_op) begin
|
||||
starting_address[31:16] <= n64_pi_ad_input;
|
||||
end
|
||||
|
||||
if (alel_op) begin
|
||||
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
|
||||
|
||||
if (write_op) begin
|
||||
can_read <= 1'b0;
|
||||
if (first_write_op) begin
|
||||
first_write_op <= 1'b0;
|
||||
load_starting_address <= 1'b1;
|
||||
end
|
||||
end
|
||||
|
||||
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
|
||||
if (read_op || write_op) begin
|
||||
pending_operation <= 1'b1;
|
||||
pending_write <= write_op;
|
||||
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
|
||||
endcase
|
||||
end else begin
|
||||
if (bus.ack) begin
|
||||
bus.request <= 1'b0;
|
||||
bus.address <= bus.address + 2'd2;
|
||||
end
|
||||
end
|
||||
|
||||
if (end_op) begin
|
||||
can_read <= 1'b0;
|
||||
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)
|
||||
);
|
||||
|
||||
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 (
|
||||
.sys(sys),
|
||||
.bus(bus.at[sc64::ID_N64_CFG].device),
|
||||
@ -61,3 +71,46 @@ module n64_soc (
|
||||
);
|
||||
|
||||
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 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));
|
||||
|
||||
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_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__ (
|
||||
".set noat \n\t"
|
||||
".set noreorder \n\t"
|
||||
|
@ -16,6 +16,19 @@ typedef struct sc64_cart_registers {
|
||||
#define SC64_CFG_SCR_CPU_BUSY (1 << 30)
|
||||
|
||||
#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) {
|
||||
OS_BOOT_CONFIG->tv_type = TV_NTSC;
|
||||
@ -41,5 +54,7 @@ int main(void) {
|
||||
uint16_t cic_seed = boot_get_cic_seed(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);
|
||||
}
|
||||
|
Loading…
Reference in New Issue
Block a user