mirror of
https://github.com/Polprzewodnikowy/SummerCart64.git
synced 2024-12-24 12:01:56 +01:00
flashram fully working
This commit is contained in:
parent
93f7ef54c4
commit
30ff67139b
@ -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 = 03:59:09 August 28, 2021
|
# Date created = 17:57:25 August 28, 2021
|
||||||
#
|
#
|
||||||
# -------------------------------------------------------------------------- #
|
# -------------------------------------------------------------------------- #
|
||||||
#
|
#
|
||||||
@ -58,6 +58,7 @@ set_global_assignment -name SYSTEMVERILOG_FILE picorv32/picorv32.v
|
|||||||
set_global_assignment -name SYSTEMVERILOG_FILE rtl/cpu/cpu_bus.sv
|
set_global_assignment -name SYSTEMVERILOG_FILE rtl/cpu/cpu_bus.sv
|
||||||
set_global_assignment -name SYSTEMVERILOG_FILE rtl/cpu/cpu_cfg.sv
|
set_global_assignment -name SYSTEMVERILOG_FILE rtl/cpu/cpu_cfg.sv
|
||||||
set_global_assignment -name SYSTEMVERILOG_FILE rtl/cpu/cpu_dma.sv
|
set_global_assignment -name SYSTEMVERILOG_FILE rtl/cpu/cpu_dma.sv
|
||||||
|
set_global_assignment -name SYSTEMVERILOG_FILE rtl/cpu/cpu_flashram.sv
|
||||||
set_global_assignment -name SYSTEMVERILOG_FILE rtl/cpu/cpu_gpio.sv
|
set_global_assignment -name SYSTEMVERILOG_FILE rtl/cpu/cpu_gpio.sv
|
||||||
set_global_assignment -name SYSTEMVERILOG_FILE rtl/cpu/cpu_i2c.sv
|
set_global_assignment -name SYSTEMVERILOG_FILE rtl/cpu/cpu_i2c.sv
|
||||||
set_global_assignment -name SYSTEMVERILOG_FILE rtl/cpu/cpu_ram.sv
|
set_global_assignment -name SYSTEMVERILOG_FILE rtl/cpu/cpu_ram.sv
|
||||||
@ -71,6 +72,7 @@ set_global_assignment -name SYSTEMVERILOG_FILE rtl/memory/memory_sdram.sv
|
|||||||
set_global_assignment -name SYSTEMVERILOG_FILE rtl/n64/n64_bootloader.sv
|
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_flashram.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_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
|
||||||
@ -186,7 +188,7 @@ set_global_assignment -name TIMING_ANALYZER_MULTICORNER_ANALYSIS ON
|
|||||||
|
|
||||||
# Compiler Assignments
|
# Compiler Assignments
|
||||||
# ====================
|
# ====================
|
||||||
set_global_assignment -name OPTIMIZATION_MODE BALANCED
|
set_global_assignment -name OPTIMIZATION_MODE "HIGH PERFORMANCE EFFORT"
|
||||||
|
|
||||||
# Analysis & Synthesis Assignments
|
# Analysis & Synthesis Assignments
|
||||||
# ================================
|
# ================================
|
||||||
@ -200,6 +202,7 @@ set_global_assignment -name VHDL_INPUT_VERSION VHDL_2008
|
|||||||
set_global_assignment -name VHDL_SHOW_LMF_MAPPING_MESSAGES OFF
|
set_global_assignment -name VHDL_SHOW_LMF_MAPPING_MESSAGES OFF
|
||||||
set_global_assignment -name VERILOG_INPUT_VERSION SYSTEMVERILOG_2005
|
set_global_assignment -name VERILOG_INPUT_VERSION SYSTEMVERILOG_2005
|
||||||
set_global_assignment -name VERILOG_SHOW_LMF_MAPPING_MESSAGES OFF
|
set_global_assignment -name VERILOG_SHOW_LMF_MAPPING_MESSAGES OFF
|
||||||
|
set_global_assignment -name TOP_LEVEL_ENTITY SummerCart64
|
||||||
|
|
||||||
# Fitter Assignments
|
# Fitter Assignments
|
||||||
# ==================
|
# ==================
|
||||||
|
@ -8,7 +8,7 @@ static const uint8_t err_token[3] = { 'E', 'R', 'R' };
|
|||||||
static uint8_t save_type = 0;
|
static uint8_t save_type = 0;
|
||||||
static uint16_t cic_type = 0xFFFF;
|
static uint16_t cic_type = 0xFFFF;
|
||||||
static uint8_t tv_type = 0xFF;
|
static uint8_t tv_type = 0xFF;
|
||||||
static volatile uint32_t *save_pointer = &SDRAM + DEFAULT_SAVE_OFFSET;
|
static uint32_t *save_pointer = (uint32_t *) (SDRAM_BASE + DEFAULT_SAVE_OFFSET);
|
||||||
|
|
||||||
void process_usb (void);
|
void process_usb (void);
|
||||||
void process_cfg (void);
|
void process_cfg (void);
|
||||||
@ -16,9 +16,13 @@ void process_dd (void);
|
|||||||
void process_si (void);
|
void process_si (void);
|
||||||
void process_uart (void);
|
void process_uart (void);
|
||||||
void process_rtc (void);
|
void process_rtc (void);
|
||||||
|
void process_flashram (void);
|
||||||
void cfg_set_save_type (uint8_t type);
|
void cfg_set_save_type (uint8_t type);
|
||||||
void cfg_update_config (uint32_t *args);
|
void cfg_update_config (uint32_t *args);
|
||||||
|
|
||||||
|
// void print (const char *text);
|
||||||
|
// void print_02hex (unsigned char number);
|
||||||
|
|
||||||
void process (void) {
|
void process (void) {
|
||||||
while (1) {
|
while (1) {
|
||||||
process_usb();
|
process_usb();
|
||||||
@ -27,6 +31,7 @@ void process (void) {
|
|||||||
process_si();
|
process_si();
|
||||||
process_uart();
|
process_uart();
|
||||||
process_rtc();
|
process_rtc();
|
||||||
|
process_flashram();
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -189,6 +194,32 @@ void process_rtc (void) {
|
|||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
|
void process_flashram (void) {
|
||||||
|
uint32_t scr = FLASHRAM->SCR;
|
||||||
|
volatile uint32_t *offset_pointer = save_pointer;
|
||||||
|
size_t length;
|
||||||
|
|
||||||
|
if (scr & FLASHRAM_OPERATION_PENDING) {
|
||||||
|
if (scr & FLASHRAM_WRITE_OR_ERASE) {
|
||||||
|
if (scr & FLASHRAM_SECTOR_OR_ALL) {
|
||||||
|
length = 128 * 1024;
|
||||||
|
} else {
|
||||||
|
offset_pointer += 32 * (scr >> FLASHRAM_SECTOR_BIT);
|
||||||
|
length = 16 * 1024;
|
||||||
|
}
|
||||||
|
for (size_t i = 0; i < (length / 4); i++) {
|
||||||
|
offset_pointer[i] = 0xFFFFFFFF;
|
||||||
|
}
|
||||||
|
} else {
|
||||||
|
offset_pointer += 32 * (scr >> FLASHRAM_SECTOR_BIT);
|
||||||
|
for (size_t i = 0; i < 32; i++) {
|
||||||
|
offset_pointer[i] &= FLASHRAM->BUFFER[i];
|
||||||
|
}
|
||||||
|
}
|
||||||
|
FLASHRAM->SCR = FLASHRAM_OPERATION_DONE;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
void cfg_update_config (uint32_t *args) {
|
void cfg_update_config (uint32_t *args) {
|
||||||
switch (args[0]) {
|
switch (args[0]) {
|
||||||
case 0: {
|
case 0: {
|
||||||
@ -232,36 +263,37 @@ void cfg_update_config (uint32_t *args) {
|
|||||||
|
|
||||||
void cfg_set_save_type (uint8_t type) {
|
void cfg_set_save_type (uint8_t type) {
|
||||||
CFG->SCR &= ~(CFG_SCR_FLASHRAM_EN | CFG_SCR_SRAM_BANKED | CFG_SCR_SRAM_EN);
|
CFG->SCR &= ~(CFG_SCR_FLASHRAM_EN | CFG_SCR_SRAM_BANKED | CFG_SCR_SRAM_EN);
|
||||||
|
uint32_t save_offset = 0;
|
||||||
|
|
||||||
switch (type) {
|
switch (type) {
|
||||||
case 0: {
|
case 0: {
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
case 1: {
|
case 1: {
|
||||||
CFG->SAVE_OFFSET = SDRAM_SIZE - 512;
|
save_offset = SDRAM_SIZE - 512;
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
case 2: {
|
case 2: {
|
||||||
CFG->SAVE_OFFSET = SDRAM_SIZE - 2048;
|
save_offset = SDRAM_SIZE - 2048;
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
case 3: {
|
case 3: {
|
||||||
CFG->SAVE_OFFSET = SDRAM_SIZE - (32 * 1024);
|
save_offset = SDRAM_SIZE - (32 * 1024);
|
||||||
CFG->SCR |= CFG_SCR_SRAM_EN;
|
CFG->SCR |= CFG_SCR_SRAM_EN;
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
case 4: {
|
case 4: {
|
||||||
CFG->SAVE_OFFSET = SDRAM_SIZE - (256 * 1024);
|
save_offset = SDRAM_SIZE - (256 * 1024);
|
||||||
CFG->SCR |= CFG_SCR_FLASHRAM_EN;
|
CFG->SCR |= CFG_SCR_FLASHRAM_EN;
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
case 5: {
|
case 5: {
|
||||||
CFG->SAVE_OFFSET = SDRAM_SIZE - (3 * 32 * 1024);
|
save_offset = SDRAM_SIZE - (3 * 32 * 1024);
|
||||||
CFG->SCR |= CFG_SCR_SRAM_BANKED | CFG_SCR_SRAM_EN;
|
CFG->SCR |= CFG_SCR_SRAM_BANKED | CFG_SCR_SRAM_EN;
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
case 6: {
|
case 6: {
|
||||||
CFG->SAVE_OFFSET = 0x01618000;
|
save_offset = 0x01608000;
|
||||||
CFG->SCR |= CFG_SCR_FLASHRAM_EN;
|
CFG->SCR |= CFG_SCR_FLASHRAM_EN;
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
@ -270,8 +302,10 @@ void cfg_set_save_type (uint8_t type) {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
save_pointer = &SDRAM + CFG->SAVE_OFFSET;
|
save_pointer = (uint32_t *) (SDRAM_BASE + save_offset);
|
||||||
save_type = type;
|
save_type = type;
|
||||||
|
|
||||||
|
CFG->SAVE_OFFSET = save_offset;
|
||||||
}
|
}
|
||||||
|
|
||||||
// void print (const char *text) {
|
// void print (const char *text) {
|
||||||
|
@ -6,19 +6,19 @@
|
|||||||
#include <stdint.h>
|
#include <stdint.h>
|
||||||
|
|
||||||
|
|
||||||
#define DEFAULT_SAVE_OFFSET (0x03FE0000)
|
#define DEFAULT_SAVE_OFFSET (0x03FE0000UL)
|
||||||
#define DEFAULT_DD_OFFSET (0x03BE0000)
|
#define DEFAULT_DD_OFFSET (0x03BE0000UL)
|
||||||
|
|
||||||
|
|
||||||
typedef volatile uint8_t io8_t;
|
typedef volatile uint8_t io8_t;
|
||||||
typedef volatile uint32_t io32_t;
|
typedef volatile uint32_t io32_t;
|
||||||
|
|
||||||
|
|
||||||
#define RAM_BASE (0x00000000)
|
#define RAM_BASE (0x00000000UL)
|
||||||
#define RAM (*((io32_t *) RAM_BASE))
|
#define RAM (*((io32_t *) RAM_BASE))
|
||||||
|
|
||||||
|
|
||||||
#define BOOTLOADER_BASE (0x10000000)
|
#define BOOTLOADER_BASE (0x10000000UL)
|
||||||
#define BOOTLOADER (*((io32_t *) BOOTLOADER_BASE))
|
#define BOOTLOADER (*((io32_t *) BOOTLOADER_BASE))
|
||||||
|
|
||||||
|
|
||||||
@ -29,7 +29,7 @@ typedef volatile struct gpio_regs {
|
|||||||
io8_t __padding;
|
io8_t __padding;
|
||||||
} gpio_regs_t;
|
} gpio_regs_t;
|
||||||
|
|
||||||
#define GPIO_BASE (0x20000000)
|
#define GPIO_BASE (0x20000000UL)
|
||||||
#define GPIO ((gpio_regs_t *) GPIO_BASE)
|
#define GPIO ((gpio_regs_t *) GPIO_BASE)
|
||||||
|
|
||||||
|
|
||||||
@ -38,7 +38,7 @@ typedef volatile struct i2c_regs {
|
|||||||
io32_t DR;
|
io32_t DR;
|
||||||
} i2c_regs_t;
|
} i2c_regs_t;
|
||||||
|
|
||||||
#define I2C_BASE (0x30000000)
|
#define I2C_BASE (0x30000000UL)
|
||||||
#define I2C ((i2c_regs_t *) I2C_BASE)
|
#define I2C ((i2c_regs_t *) I2C_BASE)
|
||||||
|
|
||||||
#define I2C_SCR_START (1 << 0)
|
#define I2C_SCR_START (1 << 0)
|
||||||
@ -55,7 +55,7 @@ typedef volatile struct usb_regs {
|
|||||||
io8_t __padding[3];
|
io8_t __padding[3];
|
||||||
} usb_regs_t;
|
} usb_regs_t;
|
||||||
|
|
||||||
#define USB_BASE (0x40000000)
|
#define USB_BASE (0x40000000UL)
|
||||||
#define USB ((usb_regs_t *) USB_BASE)
|
#define USB ((usb_regs_t *) USB_BASE)
|
||||||
|
|
||||||
#define USB_SCR_RXNE (1 << 0)
|
#define USB_SCR_RXNE (1 << 0)
|
||||||
@ -70,7 +70,7 @@ typedef volatile struct uart_regs {
|
|||||||
io8_t __padding[3];
|
io8_t __padding[3];
|
||||||
} uart_regs_t;
|
} uart_regs_t;
|
||||||
|
|
||||||
#define UART_BASE (0x50000000)
|
#define UART_BASE (0x50000000UL)
|
||||||
#define UART ((uart_regs_t *) UART_BASE)
|
#define UART ((uart_regs_t *) UART_BASE)
|
||||||
|
|
||||||
#define UART_SCR_RXNE (1 << 0)
|
#define UART_SCR_RXNE (1 << 0)
|
||||||
@ -83,7 +83,7 @@ typedef volatile struct dma_regs {
|
|||||||
io32_t ID_LEN;
|
io32_t ID_LEN;
|
||||||
} dma_regs_t;
|
} dma_regs_t;
|
||||||
|
|
||||||
#define DMA_BASE (0x60000000)
|
#define DMA_BASE (0x60000000UL)
|
||||||
#define DMA ((dma_regs_t *) DMA_BASE)
|
#define DMA ((dma_regs_t *) DMA_BASE)
|
||||||
|
|
||||||
#define DMA_SCR_START (1 << 0)
|
#define DMA_SCR_START (1 << 0)
|
||||||
@ -101,7 +101,7 @@ typedef volatile struct cfg_regs {
|
|||||||
io32_t DATA[3];
|
io32_t DATA[3];
|
||||||
} cfg_regs_t;
|
} cfg_regs_t;
|
||||||
|
|
||||||
#define CFG_BASE (0x70000000)
|
#define CFG_BASE (0x70000000UL)
|
||||||
#define CFG ((cfg_regs_t *) CFG_BASE)
|
#define CFG ((cfg_regs_t *) CFG_BASE)
|
||||||
|
|
||||||
#define CFG_SCR_SDRAM_SWITCH (1 << 0)
|
#define CFG_SCR_SDRAM_SWITCH (1 << 0)
|
||||||
@ -114,9 +114,25 @@ typedef volatile struct cfg_regs {
|
|||||||
#define CFG_SCR_CPU_READY (1 << 31)
|
#define CFG_SCR_CPU_READY (1 << 31)
|
||||||
|
|
||||||
|
|
||||||
#define SDRAM_BASE (0x80000000)
|
#define SDRAM_BASE (0x80000000UL)
|
||||||
#define SDRAM (*((io32_t *) SDRAM_BASE))
|
#define SDRAM (*((io32_t *) SDRAM_BASE))
|
||||||
#define SDRAM_SIZE (64 * 1024 * 1024)
|
#define SDRAM_SIZE (64 * 1024 * 1024)
|
||||||
|
|
||||||
|
|
||||||
|
typedef volatile struct flashram_regs {
|
||||||
|
io32_t SCR;
|
||||||
|
io32_t __padding[31];
|
||||||
|
io32_t BUFFER[32];
|
||||||
|
} flashram_regs_t;
|
||||||
|
|
||||||
|
#define FLASHRAM_BASE (0x90000000UL)
|
||||||
|
#define FLASHRAM ((flashram_regs_t *) FLASHRAM_BASE)
|
||||||
|
|
||||||
|
#define FLASHRAM_OPERATION_PENDING (1 << 0)
|
||||||
|
#define FLASHRAM_OPERATION_DONE (1 << 1)
|
||||||
|
#define FLASHRAM_WRITE_OR_ERASE (1 << 2)
|
||||||
|
#define FLASHRAM_SECTOR_OR_ALL (1 << 3)
|
||||||
|
#define FLASHRAM_SECTOR_BIT (8)
|
||||||
|
|
||||||
|
|
||||||
#endif
|
#endif
|
||||||
|
@ -60,6 +60,8 @@ module SummerCart64 (
|
|||||||
|
|
||||||
if_sdram sdram ();
|
if_sdram sdram ();
|
||||||
|
|
||||||
|
if_flashram flashram ();
|
||||||
|
|
||||||
system system_inst (
|
system system_inst (
|
||||||
.sys(sys)
|
.sys(sys)
|
||||||
);
|
);
|
||||||
@ -75,6 +77,7 @@ module SummerCart64 (
|
|||||||
.cfg(cfg),
|
.cfg(cfg),
|
||||||
.dma(dma),
|
.dma(dma),
|
||||||
.sdram(sdram),
|
.sdram(sdram),
|
||||||
|
.flashram(flashram),
|
||||||
|
|
||||||
.n64_pi_alel(i_n64_pi_alel),
|
.n64_pi_alel(i_n64_pi_alel),
|
||||||
.n64_pi_aleh(i_n64_pi_aleh),
|
.n64_pi_aleh(i_n64_pi_aleh),
|
||||||
@ -99,6 +102,7 @@ module SummerCart64 (
|
|||||||
.cfg(cfg),
|
.cfg(cfg),
|
||||||
.dma(dma),
|
.dma(dma),
|
||||||
.sdram(sdram),
|
.sdram(sdram),
|
||||||
|
.flashram(flashram),
|
||||||
|
|
||||||
.gpio_o(gpio_o),
|
.gpio_o(gpio_o),
|
||||||
.gpio_i(gpio_i),
|
.gpio_i(gpio_i),
|
||||||
|
77
fw/rtl/cpu/cpu_flashram.sv
Normal file
77
fw/rtl/cpu/cpu_flashram.sv
Normal file
@ -0,0 +1,77 @@
|
|||||||
|
interface if_flashram ();
|
||||||
|
|
||||||
|
logic [4:0] address;
|
||||||
|
logic [31:0] rdata;
|
||||||
|
logic [9:0] sector;
|
||||||
|
logic operation_pending;
|
||||||
|
logic write_or_erase;
|
||||||
|
logic sector_or_all;
|
||||||
|
logic operation_done;
|
||||||
|
|
||||||
|
modport cpu (
|
||||||
|
output address,
|
||||||
|
input rdata,
|
||||||
|
input sector,
|
||||||
|
input operation_pending,
|
||||||
|
input write_or_erase,
|
||||||
|
input sector_or_all,
|
||||||
|
output operation_done
|
||||||
|
);
|
||||||
|
|
||||||
|
modport flashram (
|
||||||
|
input address,
|
||||||
|
output rdata,
|
||||||
|
output sector,
|
||||||
|
output operation_pending,
|
||||||
|
output write_or_erase,
|
||||||
|
output sector_or_all,
|
||||||
|
input operation_done
|
||||||
|
);
|
||||||
|
|
||||||
|
endinterface
|
||||||
|
|
||||||
|
|
||||||
|
module cpu_flashram (
|
||||||
|
if_system.sys sys,
|
||||||
|
if_cpu_bus bus,
|
||||||
|
if_flashram.cpu flashram
|
||||||
|
);
|
||||||
|
|
||||||
|
always_ff @(posedge sys.clk) begin
|
||||||
|
bus.ack <= 1'b0;
|
||||||
|
if (bus.request) begin
|
||||||
|
bus.ack <= 1'b1;
|
||||||
|
end
|
||||||
|
end
|
||||||
|
|
||||||
|
always_comb begin
|
||||||
|
bus.rdata = 32'd0;
|
||||||
|
if (bus.ack) begin
|
||||||
|
bus.rdata = {
|
||||||
|
14'd0,
|
||||||
|
flashram.sector,
|
||||||
|
4'd0,
|
||||||
|
flashram.sector_or_all,
|
||||||
|
flashram.write_or_erase,
|
||||||
|
1'b0,
|
||||||
|
flashram.operation_pending
|
||||||
|
};
|
||||||
|
if (bus.address[7]) begin
|
||||||
|
bus.rdata = flashram.rdata;
|
||||||
|
end
|
||||||
|
end
|
||||||
|
|
||||||
|
flashram.address = bus.address[6:2];
|
||||||
|
end
|
||||||
|
|
||||||
|
always_ff @(posedge sys.clk) begin
|
||||||
|
flashram.operation_done <= 1'b0;
|
||||||
|
|
||||||
|
if (bus.request) begin
|
||||||
|
if (!bus.address[5] && bus.wmask[0]) begin
|
||||||
|
flashram.operation_done <= bus.wdata[1];
|
||||||
|
end
|
||||||
|
end
|
||||||
|
end
|
||||||
|
|
||||||
|
endmodule
|
@ -46,7 +46,7 @@ module cpu_sdram (
|
|||||||
|
|
||||||
sdram.write = current_word ? &bus.wmask[3:2] : &bus.wmask[1:0];
|
sdram.write = current_word ? &bus.wmask[3:2] : &bus.wmask[1:0];
|
||||||
sdram.address = {1'b0, bus.address[30:2], current_word, 1'b0};
|
sdram.address = {1'b0, bus.address[30:2], current_word, 1'b0};
|
||||||
sdram.wdata = current_word ? bus.wdata[31:16] : bus.wdata[15:0];
|
sdram.wdata = current_word ? bus.wdata[15:0] : bus.wdata[31:16];
|
||||||
end
|
end
|
||||||
|
|
||||||
always_ff @(posedge sys.clk) begin
|
always_ff @(posedge sys.clk) begin
|
||||||
|
@ -3,6 +3,7 @@ module cpu_soc (
|
|||||||
if_config.cpu cfg,
|
if_config.cpu cfg,
|
||||||
if_dma dma,
|
if_dma dma,
|
||||||
if_sdram.cpu sdram,
|
if_sdram.cpu sdram,
|
||||||
|
if_flashram.cpu flashram,
|
||||||
|
|
||||||
input [7:0] gpio_i,
|
input [7:0] gpio_i,
|
||||||
output [7:0] gpio_o,
|
output [7:0] gpio_o,
|
||||||
@ -97,4 +98,10 @@ module cpu_soc (
|
|||||||
.sdram(sdram)
|
.sdram(sdram)
|
||||||
);
|
);
|
||||||
|
|
||||||
|
cpu_flashram cpu_flashram_inst (
|
||||||
|
.sys(sys),
|
||||||
|
.bus(bus.at[sc64::ID_CPU_FLASHRAM].device),
|
||||||
|
.flashram(flashram)
|
||||||
|
);
|
||||||
|
|
||||||
endmodule
|
endmodule
|
||||||
|
@ -114,20 +114,20 @@ module memory_sdram (
|
|||||||
end
|
end
|
||||||
end
|
end
|
||||||
|
|
||||||
logic [15:0] wait_counter;
|
logic [13:0] wait_counter;
|
||||||
logic [15:0] refresh_counter;
|
logic [9:0] refresh_counter;
|
||||||
logic pending_refresh;
|
logic pending_refresh;
|
||||||
|
|
||||||
always_ff @(posedge sys.clk) begin
|
always_ff @(posedge sys.clk) begin
|
||||||
if (sys.reset || state != next_state) begin
|
if (sys.reset || state != next_state) begin
|
||||||
wait_counter <= 16'd0;
|
wait_counter <= 14'd0;
|
||||||
end else begin
|
end else begin
|
||||||
wait_counter <= wait_counter + 1'd1;
|
wait_counter <= wait_counter + 1'd1;
|
||||||
end
|
end
|
||||||
|
|
||||||
if (sdram_next_cmd == CMD_REF) begin
|
if (sdram_next_cmd == CMD_REF) begin
|
||||||
refresh_counter <= 16'd0;
|
refresh_counter <= 10'd0;
|
||||||
end else begin
|
end else if (refresh_counter < 10'h3FF) begin
|
||||||
refresh_counter <= refresh_counter + 1'd1;
|
refresh_counter <= refresh_counter + 1'd1;
|
||||||
end
|
end
|
||||||
end
|
end
|
||||||
|
185
fw/rtl/n64/n64_flashram.sv
Normal file
185
fw/rtl/n64/n64_flashram.sv
Normal file
@ -0,0 +1,185 @@
|
|||||||
|
module n64_flashram (
|
||||||
|
if_system.sys sys,
|
||||||
|
if_n64_bus bus,
|
||||||
|
if_config.flashram cfg,
|
||||||
|
if_flashram.flashram flashram
|
||||||
|
);
|
||||||
|
|
||||||
|
localparam [31:0] FLASH_TYPE_ID = 32'h1111_8001;
|
||||||
|
localparam [31:0] FLASH_MODEL_ID = 32'h00C2_001D;
|
||||||
|
|
||||||
|
typedef enum bit [7:0] {
|
||||||
|
CMD_STATUS_MODE = 8'hD2,
|
||||||
|
CMD_READID_MODE = 8'hE1,
|
||||||
|
CMD_READ_MODE = 8'hF0,
|
||||||
|
CMD_ERASE_SECTOR = 8'h4B,
|
||||||
|
CMD_ERASE_CHIP = 8'h3C,
|
||||||
|
CMD_BUFFER_MODE = 8'hB4,
|
||||||
|
CMD_ERASE_START = 8'h78,
|
||||||
|
CMD_WRITE_START = 8'hA5
|
||||||
|
} e_cmd;
|
||||||
|
|
||||||
|
typedef enum bit [0:0] {
|
||||||
|
S_IDLE,
|
||||||
|
S_WAIT
|
||||||
|
} e_bus_state;
|
||||||
|
|
||||||
|
typedef enum bit [1:0] {
|
||||||
|
FS_STATUS,
|
||||||
|
FS_ID,
|
||||||
|
FS_READ,
|
||||||
|
FS_BUFFER
|
||||||
|
} e_flashram_state;
|
||||||
|
|
||||||
|
typedef enum bit [1:0] {
|
||||||
|
B_WRITE_BUSY,
|
||||||
|
B_ERASE_BUSY,
|
||||||
|
B_WRITE_DONE,
|
||||||
|
B_ERASE_DONE
|
||||||
|
} e_flashram_status;
|
||||||
|
|
||||||
|
e_bus_state bus_state;
|
||||||
|
e_flashram_state flashram_state;
|
||||||
|
logic [3:0] flashram_status;
|
||||||
|
logic [7:0] flashram_command;
|
||||||
|
logic flashram_erase_enabled;
|
||||||
|
|
||||||
|
logic [1:0][15:0] write_buffer [0:31];
|
||||||
|
logic [1:0] write_buffer_wmask;
|
||||||
|
|
||||||
|
always_comb begin
|
||||||
|
write_buffer_wmask = 2'b00;
|
||||||
|
if (bus.request && bus.write && !bus.address[16] && flashram_state == FS_BUFFER) begin
|
||||||
|
write_buffer_wmask[0] = bus.address[1];
|
||||||
|
write_buffer_wmask[1] = !bus.address[1];
|
||||||
|
end
|
||||||
|
end
|
||||||
|
|
||||||
|
always @(posedge sys.clk) begin
|
||||||
|
flashram.rdata <= {write_buffer[flashram.address][1], write_buffer[flashram.address][0]};
|
||||||
|
if (write_buffer_wmask[0]) write_buffer[bus.address[6:2]][0] <= bus.wdata;
|
||||||
|
if (write_buffer_wmask[1]) write_buffer[bus.address[6:2]][1] <= bus.wdata;
|
||||||
|
end
|
||||||
|
|
||||||
|
always_comb begin
|
||||||
|
bus.rdata = 16'd0;
|
||||||
|
if (bus.ack) begin
|
||||||
|
if (bus.address[1]) begin
|
||||||
|
bus.rdata = {12'd0, flashram_status};
|
||||||
|
end
|
||||||
|
if (flashram_state == FS_ID) begin
|
||||||
|
case (bus.address[2:1])
|
||||||
|
0: bus.rdata = FLASH_TYPE_ID[31:16];
|
||||||
|
1: bus.rdata = FLASH_TYPE_ID[15:0];
|
||||||
|
2: bus.rdata = FLASH_MODEL_ID[31:16];
|
||||||
|
3: bus.rdata = FLASH_MODEL_ID[15:0];
|
||||||
|
endcase
|
||||||
|
end
|
||||||
|
end
|
||||||
|
|
||||||
|
cfg.flashram_read_mode = flashram_state == FS_READ;
|
||||||
|
end
|
||||||
|
|
||||||
|
always_ff @(posedge sys.clk) begin
|
||||||
|
bus.ack <= 1'b0;
|
||||||
|
|
||||||
|
if (sys.reset) begin
|
||||||
|
bus_state <= S_IDLE;
|
||||||
|
flashram_state <= FS_STATUS;
|
||||||
|
flashram_status <= 4'b0000;
|
||||||
|
flashram_erase_enabled <= 1'b0;
|
||||||
|
flashram.operation_pending <= 1'b0;
|
||||||
|
end else begin
|
||||||
|
if (flashram.operation_done) begin
|
||||||
|
flashram.operation_pending <= 1'b0;
|
||||||
|
if (flashram.write_or_erase) begin
|
||||||
|
flashram_status[B_ERASE_BUSY] <= 1'b0;
|
||||||
|
flashram_status[B_ERASE_DONE] <= 1'b1;
|
||||||
|
end else begin
|
||||||
|
flashram_status[B_WRITE_BUSY] <= 1'b0;
|
||||||
|
flashram_status[B_WRITE_DONE] <= 1'b1;
|
||||||
|
end
|
||||||
|
end
|
||||||
|
|
||||||
|
case (bus_state)
|
||||||
|
S_IDLE: begin
|
||||||
|
if (bus.request) begin
|
||||||
|
bus_state <= S_WAIT;
|
||||||
|
bus.ack <= 1'b1;
|
||||||
|
if (bus.write && !flashram.operation_pending) begin
|
||||||
|
if (bus.address[16]) begin
|
||||||
|
if (!bus.address[1]) begin
|
||||||
|
flashram_command <= bus.wdata[15:8];
|
||||||
|
end else begin
|
||||||
|
flashram_erase_enabled <= 1'b0;
|
||||||
|
|
||||||
|
case (flashram_command)
|
||||||
|
CMD_STATUS_MODE: begin
|
||||||
|
flashram_state <= FS_STATUS;
|
||||||
|
end
|
||||||
|
|
||||||
|
CMD_READID_MODE: begin
|
||||||
|
flashram_state <= FS_ID;
|
||||||
|
end
|
||||||
|
|
||||||
|
CMD_READ_MODE: begin
|
||||||
|
flashram_state <= FS_READ;
|
||||||
|
end
|
||||||
|
|
||||||
|
CMD_ERASE_SECTOR: begin
|
||||||
|
flashram_state <= FS_STATUS;
|
||||||
|
flashram_erase_enabled <= 1'b1;
|
||||||
|
flashram.sector <= bus.wdata[9:0];
|
||||||
|
flashram.sector_or_all <= 1'b0;
|
||||||
|
end
|
||||||
|
|
||||||
|
CMD_ERASE_CHIP: begin
|
||||||
|
flashram_state <= FS_STATUS;
|
||||||
|
flashram_erase_enabled <= 1'b1;
|
||||||
|
flashram.sector <= 10'd0;
|
||||||
|
flashram.sector_or_all <= 1'b1;
|
||||||
|
end
|
||||||
|
|
||||||
|
CMD_BUFFER_MODE: begin
|
||||||
|
flashram_state <= FS_BUFFER;
|
||||||
|
end
|
||||||
|
|
||||||
|
CMD_ERASE_START: begin
|
||||||
|
flashram_state <= FS_STATUS;
|
||||||
|
if (flashram_erase_enabled) begin
|
||||||
|
flashram_status[B_ERASE_BUSY] <= 1'b1;
|
||||||
|
flashram_status[B_ERASE_DONE] <= 1'b0;
|
||||||
|
flashram.operation_pending <= 1'b1;
|
||||||
|
flashram.write_or_erase <= 1'b1;
|
||||||
|
end
|
||||||
|
end
|
||||||
|
|
||||||
|
CMD_WRITE_START: begin
|
||||||
|
flashram_state <= FS_STATUS;
|
||||||
|
flashram_status[B_WRITE_BUSY] <= 1'b1;
|
||||||
|
flashram_status[B_WRITE_DONE] <= 1'b0;
|
||||||
|
flashram.sector <= bus.wdata[9:0];
|
||||||
|
flashram.operation_pending <= 1'b1;
|
||||||
|
flashram.write_or_erase <= 1'b0;
|
||||||
|
flashram.sector_or_all <= 1'b0;
|
||||||
|
end
|
||||||
|
endcase
|
||||||
|
end
|
||||||
|
end else begin
|
||||||
|
if (flashram_state == FS_STATUS) begin
|
||||||
|
flashram_status[B_ERASE_DONE] <= bus.wdata[B_ERASE_DONE];
|
||||||
|
flashram_status[B_WRITE_DONE] <= bus.wdata[B_WRITE_DONE];
|
||||||
|
end
|
||||||
|
end
|
||||||
|
end
|
||||||
|
end
|
||||||
|
end
|
||||||
|
|
||||||
|
S_WAIT: begin
|
||||||
|
bus_state <= S_IDLE;
|
||||||
|
end
|
||||||
|
endcase
|
||||||
|
end
|
||||||
|
end
|
||||||
|
|
||||||
|
endmodule
|
@ -3,6 +3,7 @@ module n64_soc (
|
|||||||
if_config cfg,
|
if_config cfg,
|
||||||
if_dma.memory dma,
|
if_dma.memory dma,
|
||||||
if_sdram.memory sdram,
|
if_sdram.memory sdram,
|
||||||
|
if_flashram.flashram flashram,
|
||||||
|
|
||||||
input n64_pi_alel,
|
input n64_pi_alel,
|
||||||
input n64_pi_aleh,
|
input n64_pi_aleh,
|
||||||
@ -56,9 +57,11 @@ module n64_soc (
|
|||||||
.bus(bus.at[sc64::ID_N64_BOOTLOADER].device)
|
.bus(bus.at[sc64::ID_N64_BOOTLOADER].device)
|
||||||
);
|
);
|
||||||
|
|
||||||
n64_dummy n64_flashram_inst (
|
n64_flashram n64_flashram_inst (
|
||||||
.sys(sys),
|
.sys(sys),
|
||||||
.bus(bus.at[sc64::ID_N64_FLASHRAM].device)
|
.bus(bus.at[sc64::ID_N64_FLASHRAM].device),
|
||||||
|
.cfg(cfg),
|
||||||
|
.flashram(flashram)
|
||||||
);
|
);
|
||||||
|
|
||||||
n64_dummy n64_ddregs_inst (
|
n64_dummy n64_ddregs_inst (
|
||||||
|
@ -19,6 +19,7 @@ package sc64;
|
|||||||
ID_CPU_DMA,
|
ID_CPU_DMA,
|
||||||
ID_CPU_CFG,
|
ID_CPU_CFG,
|
||||||
ID_CPU_SDRAM,
|
ID_CPU_SDRAM,
|
||||||
|
ID_CPU_FLASHRAM,
|
||||||
__ID_CPU_END
|
__ID_CPU_END
|
||||||
} e_cpu_id;
|
} e_cpu_id;
|
||||||
|
|
||||||
|
Loading…
Reference in New Issue
Block a user