mirror of
https://github.com/Polprzewodnikowy/SummerCart64.git
synced 2024-11-25 15:16:53 +01:00
flashram working
This commit is contained in:
parent
aa74831511
commit
c4c101b6d3
@ -19,7 +19,7 @@
|
||||
#
|
||||
# Quartus Prime
|
||||
# Version 20.1.1 Build 720 11/11/2020 SJ Lite Edition
|
||||
# Date created = 01:35:54 February 19, 2021
|
||||
# Date created = 15:52:44 February 27, 2021
|
||||
#
|
||||
# -------------------------------------------------------------------------- #
|
||||
#
|
||||
@ -51,6 +51,7 @@ set_global_assignment -name QIP_FILE rtl/intel/fifo/fifo_sd.qip
|
||||
set_global_assignment -name QIP_FILE rtl/intel/fifo/fifo_usb.qip
|
||||
set_global_assignment -name QIP_FILE rtl/intel/gpio/gpio_ddro.qip
|
||||
set_global_assignment -name QIP_FILE rtl/intel/pll/pll.qip
|
||||
set_global_assignment -name QIP_FILE rtl/intel/ram/ram_flashram_write_buffer.qip
|
||||
set_global_assignment -name QIP_FILE rtl/intel/ram/ram_n64_eeprom.qip
|
||||
set_global_assignment -name QSYS_FILE rtl/intel/flash/onchip_flash.qsys
|
||||
set_global_assignment -name SDC_FILE constraints.sdc
|
||||
@ -58,6 +59,7 @@ set_global_assignment -name SIGNALTAP_FILE output_files/signal_tap_logic_analyze
|
||||
set_global_assignment -name SYSTEMVERILOG_FILE rtl/intel/gpio/gpio_ddro/altera_gpio_lite.sv -library gpio_ddro
|
||||
set_global_assignment -name VERILOG_FILE rtl/cart/cart_control.v
|
||||
set_global_assignment -name VERILOG_FILE rtl/cart/cart_led.v
|
||||
set_global_assignment -name VERILOG_FILE rtl/flashram/flashram_controller.v
|
||||
set_global_assignment -name VERILOG_FILE rtl/glue/device_arbiter.v
|
||||
set_global_assignment -name VERILOG_FILE rtl/memory/memory_embedded_flash.v
|
||||
set_global_assignment -name VERILOG_FILE rtl/memory/memory_sdram.v
|
||||
@ -160,12 +162,6 @@ set_location_assignment PIN_114 -to o_sd_clk
|
||||
set_location_assignment PIN_118 -to io_sd_cmd
|
||||
set_location_assignment PIN_119 -to io_sd_dat[3]
|
||||
set_location_assignment PIN_120 -to io_sd_dat[2]
|
||||
set_location_assignment PIN_121 -to io_sram_dq[0]
|
||||
set_location_assignment PIN_122 -to o_sram_clk
|
||||
set_location_assignment PIN_123 -to io_sram_dq[3]
|
||||
set_location_assignment PIN_124 -to o_sram_cs
|
||||
set_location_assignment PIN_126 -to io_sram_dq[1]
|
||||
set_location_assignment PIN_127 -to io_sram_dq[2]
|
||||
set_location_assignment PIN_138 -to io_pmod[0]
|
||||
set_location_assignment PIN_140 -to io_pmod[1]
|
||||
set_location_assignment PIN_141 -to io_pmod[2]
|
||||
|
@ -17,7 +17,6 @@ module cart_control (
|
||||
output reg o_rom_switch,
|
||||
output reg o_ddipl_enable,
|
||||
output reg o_sram_enable,
|
||||
output reg o_sram_768k_mode,
|
||||
output reg o_flashram_enable,
|
||||
output reg o_sd_enable,
|
||||
output reg o_eeprom_pi_enable,
|
||||
@ -40,7 +39,7 @@ module cart_control (
|
||||
input [31:0] i_debug_fifo_data,
|
||||
|
||||
output reg [23:0] o_ddipl_address,
|
||||
output reg [23:0] o_sram_address
|
||||
output reg [23:0] o_save_address
|
||||
);
|
||||
|
||||
// Module parameters
|
||||
@ -100,17 +99,16 @@ module cart_control (
|
||||
o_rom_switch <= 1'b0;
|
||||
o_ddipl_enable <= 1'b0;
|
||||
o_sram_enable <= 1'b0;
|
||||
o_sram_768k_mode <= 1'b0;
|
||||
o_flashram_enable <= 1'b0;
|
||||
o_sd_enable <= 1'b0;
|
||||
o_eeprom_pi_enable <= 1'b0;
|
||||
o_eeprom_enable <= 1'b0;
|
||||
o_eeprom_16k_mode <= 1'b0;
|
||||
o_n64_reset_btn <= 1'b1;
|
||||
o_ddipl_address <= 24'hF0_0000;
|
||||
o_sram_address <= 24'hFF_E000;
|
||||
o_ddipl_address <= 24'hEF_8000;
|
||||
o_save_address <= 24'hFF_8000;
|
||||
o_debug_dma_bank <= 4'd1;
|
||||
o_debug_dma_address <= 24'hFC_0000;
|
||||
o_debug_dma_address <= 24'hCF_8000;
|
||||
o_debug_dma_length <= 20'd0;
|
||||
r_bootloader <= 16'h0000;
|
||||
r_skip_bootloader <= 1'b0;
|
||||
@ -121,7 +119,6 @@ module cart_control (
|
||||
{
|
||||
r_skip_bootloader,
|
||||
o_flashram_enable,
|
||||
o_sram_768k_mode,
|
||||
o_sram_enable,
|
||||
o_sd_enable,
|
||||
o_eeprom_pi_enable,
|
||||
@ -130,31 +127,38 @@ module cart_control (
|
||||
o_ddipl_enable,
|
||||
o_rom_switch,
|
||||
o_sdram_writable
|
||||
} <= i_data[10:0];
|
||||
} <= {i_data[10:9], i_data[7:0]};
|
||||
end
|
||||
|
||||
REG_BOOT: begin
|
||||
r_bootloader <= i_data[15:0];
|
||||
end
|
||||
|
||||
REG_GPIO: begin
|
||||
o_n64_reset_btn <= ~i_data[0];
|
||||
end
|
||||
|
||||
REG_USB_SCR: begin
|
||||
{o_debug_fifo_flush, o_debug_dma_start} <= {i_data[2], i_data[0]};
|
||||
end
|
||||
|
||||
REG_USB_DMA_ADDR: begin
|
||||
{o_debug_dma_bank, o_debug_dma_address} <= {i_data[31:28], i_data[25:2]};
|
||||
end
|
||||
|
||||
REG_USB_DMA_LEN: begin
|
||||
o_debug_dma_length <= i_data[19:0];
|
||||
end
|
||||
|
||||
REG_DDIPL_ADDR: begin
|
||||
o_ddipl_address <= i_data[25:2];
|
||||
end
|
||||
|
||||
REG_SRAM_ADDR: begin
|
||||
o_sram_address <= i_data[25:2];
|
||||
end
|
||||
default: begin
|
||||
o_save_address <= i_data[25:2];
|
||||
end
|
||||
|
||||
default: begin end
|
||||
endcase
|
||||
end
|
||||
|
||||
@ -182,7 +186,7 @@ module cart_control (
|
||||
o_data[10:0] <= {
|
||||
r_skip_bootloader,
|
||||
o_flashram_enable,
|
||||
o_sram_768k_mode,
|
||||
1'b0,
|
||||
o_sram_enable,
|
||||
o_sd_enable,
|
||||
o_eeprom_pi_enable,
|
||||
@ -193,26 +197,32 @@ module cart_control (
|
||||
o_sdram_writable
|
||||
};
|
||||
end
|
||||
|
||||
REG_BOOT: begin
|
||||
o_data[15:0] <= r_bootloader;
|
||||
end
|
||||
|
||||
REG_VERSION: begin
|
||||
o_data <= {"S", "6", "4", VERSION};
|
||||
end
|
||||
|
||||
REG_GPIO: begin
|
||||
o_data[2:0] <= {r_nmi_ff2, r_reset_ff2, ~o_n64_reset_btn};
|
||||
end
|
||||
|
||||
REG_USB_SCR: begin
|
||||
{o_data[13:3], o_data[1:0]} <= {i_debug_fifo_items, i_debug_ready, i_debug_dma_busy};
|
||||
end
|
||||
|
||||
REG_DDIPL_ADDR: begin
|
||||
o_data[25:0] <= {o_ddipl_address, 2'b00};
|
||||
end
|
||||
|
||||
REG_SRAM_ADDR: begin
|
||||
o_data[25:0] <= {o_sram_address, 2'b00};
|
||||
end
|
||||
default: begin
|
||||
o_data[25:0] <= {o_save_address, 2'b00};
|
||||
end
|
||||
|
||||
default: begin end
|
||||
endcase
|
||||
end else begin
|
||||
o_data <= i_debug_fifo_data;
|
||||
|
@ -4,5 +4,4 @@
|
||||
`define BANK_SDRAM 4'd1
|
||||
`define BANK_CART 4'd2
|
||||
`define BANK_EEPROM 4'd3
|
||||
`define BANK_FLASHRAM 4'd4
|
||||
`define BANK_SD 4'd5
|
||||
`define BANK_SD 4'd4
|
||||
|
301
fw/rtl/flashram/flashram_controller.v
Normal file
301
fw/rtl/flashram/flashram_controller.v
Normal file
@ -0,0 +1,301 @@
|
||||
`include "../constants.vh"
|
||||
|
||||
module flashram_controller (
|
||||
input i_clk,
|
||||
input i_reset,
|
||||
|
||||
input [23:0] i_save_address,
|
||||
|
||||
output o_flashram_read_mode,
|
||||
|
||||
input i_request,
|
||||
input i_write,
|
||||
output o_busy,
|
||||
output reg o_ack,
|
||||
input [14:0] i_address,
|
||||
output reg [31:0] o_data,
|
||||
input [31:0] i_data,
|
||||
|
||||
output reg o_mem_request,
|
||||
output reg o_mem_write,
|
||||
input i_mem_busy,
|
||||
input i_mem_ack,
|
||||
output reg [3:0] o_mem_bank,
|
||||
output reg [23:0] o_mem_address,
|
||||
output reg [31:0] o_mem_data,
|
||||
input [31:0] i_mem_data
|
||||
);
|
||||
|
||||
// State machine and command decoder
|
||||
|
||||
localparam [31:0] FLASH_TYPE_ID = 32'h1111_8001;
|
||||
localparam [31:0] FLASH_MODEL_ID = 32'h00C2_001D;
|
||||
|
||||
localparam [7:0] CMD_STATUS_MODE = 8'hD2;
|
||||
localparam [7:0] CMD_READID_MODE = 8'hE1;
|
||||
localparam [7:0] CMD_READ_MODE = 8'hF0;
|
||||
localparam [7:0] CMD_ERASE_SECTOR = 8'h4B;
|
||||
localparam [7:0] CMD_ERASE_CHIP = 8'h3C;
|
||||
localparam [7:0] CMD_WRITE_MODE = 8'hB4;
|
||||
localparam [7:0] CMD_ERASE_START = 8'h78;
|
||||
localparam [7:0] CMD_WRITE_START = 8'hA5;
|
||||
|
||||
localparam STATE_STATUS = 0;
|
||||
localparam STATE_ID = 1;
|
||||
localparam STATE_READ = 2;
|
||||
localparam STATE_ERASE = 3;
|
||||
localparam STATE_WRITE = 4;
|
||||
localparam STATE_EXECUTE = 5;
|
||||
|
||||
localparam [1:0] EXECUTE_WRITE = 2'b00;
|
||||
localparam [1:0] EXECUTE_ERASE_SECTOR = 2'b10;
|
||||
localparam [1:0] EXECUTE_ERASE_CHIP = 2'b11;
|
||||
|
||||
reg [5:0] r_flashram_state;
|
||||
reg [9:0] r_sector_offset;
|
||||
reg [1:0] r_execute_mode;
|
||||
reg r_execute_start;
|
||||
reg r_execute_done;
|
||||
|
||||
assign o_flashram_read_mode = r_flashram_state[STATE_READ];
|
||||
|
||||
wire w_cmd_request = i_request && i_write && i_address[14] && !r_flashram_state[STATE_EXECUTE];
|
||||
wire [7:0] w_cmd_op = i_data[31:24];
|
||||
|
||||
always @(posedge i_clk) begin
|
||||
r_execute_start <= 1'b0;
|
||||
|
||||
if (i_reset || r_execute_done) begin
|
||||
r_flashram_state <= (1'b1 << STATE_STATUS);
|
||||
end else begin
|
||||
if (w_cmd_request) begin
|
||||
r_flashram_state <= 6'b000000;
|
||||
|
||||
if (w_cmd_op == CMD_STATUS_MODE) begin
|
||||
r_flashram_state[STATE_STATUS] <= 1'b1;
|
||||
end
|
||||
|
||||
if (w_cmd_op == CMD_READID_MODE) begin
|
||||
r_flashram_state[STATE_ID] <= 1'b1;
|
||||
end
|
||||
|
||||
if (w_cmd_op == CMD_READ_MODE) begin
|
||||
r_flashram_state[STATE_READ] <= 1'b1;
|
||||
end
|
||||
|
||||
if (w_cmd_op == CMD_ERASE_SECTOR) begin
|
||||
r_flashram_state[STATE_ERASE] <= 1'b1;
|
||||
r_sector_offset <= {i_data[9:7], 7'd0};
|
||||
r_execute_mode <= EXECUTE_ERASE_SECTOR;
|
||||
end
|
||||
|
||||
if (w_cmd_op == CMD_ERASE_CHIP) begin
|
||||
r_flashram_state[STATE_ERASE] <= 1'b1;
|
||||
r_sector_offset <= 10'd0;
|
||||
r_execute_mode <= EXECUTE_ERASE_CHIP;
|
||||
end
|
||||
|
||||
if (w_cmd_op == CMD_WRITE_MODE) begin
|
||||
r_flashram_state[STATE_WRITE] <= 1'b1;
|
||||
end
|
||||
|
||||
if (w_cmd_op == CMD_ERASE_START) begin
|
||||
if (r_flashram_state[STATE_ERASE]) begin
|
||||
r_flashram_state[STATE_EXECUTE] <= 1'b1;
|
||||
r_execute_start <= 1'b1;
|
||||
end
|
||||
end
|
||||
|
||||
if (w_cmd_op == CMD_WRITE_START) begin
|
||||
r_flashram_state[STATE_EXECUTE] <= 1'b1;
|
||||
r_sector_offset <= i_data[9:0];
|
||||
r_execute_mode <= EXECUTE_WRITE;
|
||||
r_execute_start <= 1'b1;
|
||||
end
|
||||
end
|
||||
end
|
||||
end
|
||||
|
||||
|
||||
// Status controller
|
||||
|
||||
reg r_erase_busy;
|
||||
reg r_erase_done;
|
||||
|
||||
reg r_write_busy;
|
||||
reg r_write_done;
|
||||
|
||||
wire [3:0] w_status = {r_erase_done, r_write_done, r_erase_busy, r_write_busy};
|
||||
|
||||
wire w_status_write_request = i_request && i_write && !i_address[14] && r_flashram_state[STATE_STATUS];
|
||||
|
||||
always @(posedge i_clk) begin
|
||||
if (i_reset) begin
|
||||
r_erase_busy <= 1'b0;
|
||||
r_write_busy <= 1'b0;
|
||||
r_erase_done <= 1'b0;
|
||||
r_write_done <= 1'b0;
|
||||
end else begin
|
||||
if (w_status_write_request) begin
|
||||
r_erase_done <= r_erase_done & i_data[3];
|
||||
r_write_done <= r_write_done & i_data[1];
|
||||
end
|
||||
|
||||
if (r_execute_start) begin
|
||||
if (r_execute_mode == EXECUTE_WRITE) begin
|
||||
r_write_busy <= 1'b1;
|
||||
r_write_done <= 1'b0;
|
||||
end else begin
|
||||
r_erase_busy <= 1'b1;
|
||||
r_erase_done <= 1'b0;
|
||||
end
|
||||
end
|
||||
|
||||
if (r_execute_done) begin
|
||||
if (r_execute_mode == EXECUTE_WRITE) begin
|
||||
r_write_busy <= 1'b0;
|
||||
r_write_done <= 1'b1;
|
||||
end else begin
|
||||
r_erase_busy <= 1'b0;
|
||||
r_erase_done <= 1'b1;
|
||||
end
|
||||
end
|
||||
end
|
||||
end
|
||||
|
||||
|
||||
// Bus controller
|
||||
|
||||
assign o_busy = 1'b0;
|
||||
|
||||
wire [31:0] w_write_buffer_o_data;
|
||||
|
||||
wire w_flashram_controller_read_request = i_request && !i_write && !o_busy && !r_flashram_state[STATE_READ];
|
||||
|
||||
always @(posedge i_clk) begin
|
||||
o_ack <= 1'b0;
|
||||
|
||||
if (w_flashram_controller_read_request) begin
|
||||
o_ack <= 1'b1;
|
||||
o_data <= {12'h000, w_status, 12'h000, w_status};
|
||||
|
||||
if (r_flashram_state[STATE_ID]) begin
|
||||
o_data <= i_address[0] ? FLASH_MODEL_ID : FLASH_TYPE_ID;
|
||||
end
|
||||
|
||||
if (r_flashram_state[STATE_WRITE]) begin
|
||||
o_data <= w_write_buffer_o_data;
|
||||
end
|
||||
end
|
||||
end
|
||||
|
||||
|
||||
// Page write buffer
|
||||
|
||||
reg [4:0] r_write_buffer_address;
|
||||
|
||||
wire [31:0] w_write_buffer_o_mem_data;
|
||||
|
||||
wire w_write_buffer_request = i_request && i_write && !o_busy && !i_address[14] && r_flashram_state[STATE_WRITE];
|
||||
|
||||
ram_flashram_write_buffer ram_flashram_write_buffer_inst (
|
||||
.clock(i_clk),
|
||||
|
||||
.wren_a(w_write_buffer_request),
|
||||
.address_a(i_address[4:0]),
|
||||
.data_a(i_data),
|
||||
.q_a(w_write_buffer_o_data),
|
||||
|
||||
.wren_b(i_mem_ack),
|
||||
.address_b(r_write_buffer_address),
|
||||
.data_b(i_mem_data & w_write_buffer_o_mem_data),
|
||||
.q_b(w_write_buffer_o_mem_data)
|
||||
);
|
||||
|
||||
|
||||
// Memory controller
|
||||
|
||||
reg [15:0] r_items_left;
|
||||
|
||||
wire w_execute_done = !r_execute_start && (r_items_left == 16'd0) && r_flashram_state[STATE_EXECUTE];
|
||||
wire w_read_phase_done = w_execute_done && !o_mem_write && i_mem_ack;
|
||||
wire w_write_phase_done = w_execute_done && o_mem_write;
|
||||
|
||||
wire w_mem_request_successful = o_mem_request && !i_mem_busy;
|
||||
wire w_address_reset = r_execute_start || w_read_phase_done;
|
||||
wire w_write_buffer_address_increment = o_mem_write ? w_mem_request_successful : i_mem_ack;
|
||||
|
||||
always @(posedge i_clk) begin
|
||||
r_execute_done <= w_write_phase_done;
|
||||
end
|
||||
|
||||
always @(posedge i_clk) begin
|
||||
if (w_address_reset) begin
|
||||
case (r_execute_mode)
|
||||
EXECUTE_WRITE: r_items_left <= 16'h20;
|
||||
EXECUTE_ERASE_SECTOR: r_items_left <= 16'h1000;
|
||||
EXECUTE_ERASE_CHIP: r_items_left <= 16'h8000;
|
||||
default: r_items_left <= 16'd0;
|
||||
endcase
|
||||
end
|
||||
|
||||
if (w_mem_request_successful) begin
|
||||
r_items_left <= r_items_left - 1'd1;
|
||||
end
|
||||
end
|
||||
|
||||
always @(posedge i_clk) begin
|
||||
if (i_reset) begin
|
||||
o_mem_request <= 1'b0;
|
||||
end else begin
|
||||
if (r_items_left > 16'd0) begin
|
||||
o_mem_request <= 1'b1;
|
||||
end
|
||||
|
||||
if (w_mem_request_successful) begin
|
||||
o_mem_request <= 1'b0;
|
||||
end
|
||||
end
|
||||
end
|
||||
|
||||
always @(posedge i_clk) begin
|
||||
if (r_execute_start) begin
|
||||
if (r_execute_mode == EXECUTE_WRITE) begin
|
||||
o_mem_write <= 1'b0;
|
||||
end else begin
|
||||
o_mem_write <= 1'b1;
|
||||
end
|
||||
end
|
||||
|
||||
if (w_read_phase_done) begin
|
||||
o_mem_write <= 1'b1;
|
||||
end
|
||||
end
|
||||
|
||||
always @(posedge i_clk) begin
|
||||
o_mem_bank <= `BANK_SDRAM;
|
||||
end
|
||||
|
||||
always @(posedge i_clk) begin
|
||||
if (w_address_reset) begin
|
||||
o_mem_address <= i_save_address + {9'd0, r_sector_offset, 5'd0};
|
||||
r_write_buffer_address <= 5'd0;
|
||||
end else begin
|
||||
if (w_mem_request_successful) begin
|
||||
o_mem_address <= o_mem_address + 1'd1;
|
||||
end
|
||||
|
||||
if (w_write_buffer_address_increment) begin
|
||||
r_write_buffer_address <= r_write_buffer_address + 1'd1;
|
||||
end
|
||||
end
|
||||
end
|
||||
|
||||
always @(*) begin
|
||||
o_mem_data = 32'hFFFF_FFFF;
|
||||
if (r_execute_mode == EXECUTE_WRITE) begin
|
||||
o_mem_data = w_write_buffer_o_mem_data;
|
||||
end
|
||||
end
|
||||
|
||||
endmodule
|
4
fw/rtl/intel/ram/ram_flashram_write_buffer.qip
Normal file
4
fw/rtl/intel/ram/ram_flashram_write_buffer.qip
Normal file
@ -0,0 +1,4 @@
|
||||
set_global_assignment -name IP_TOOL_NAME "RAM: 2-PORT"
|
||||
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) "ram_flashram_write_buffer.v"]
|
243
fw/rtl/intel/ram/ram_flashram_write_buffer.v
Normal file
243
fw/rtl/intel/ram/ram_flashram_write_buffer.v
Normal file
@ -0,0 +1,243 @@
|
||||
// megafunction wizard: %RAM: 2-PORT%
|
||||
// GENERATION: STANDARD
|
||||
// VERSION: WM1.0
|
||||
// MODULE: altsyncram
|
||||
|
||||
// ============================================================
|
||||
// File Name: ram_flashram_write_buffer.v
|
||||
// Megafunction Name(s):
|
||||
// altsyncram
|
||||
//
|
||||
// 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 ram_flashram_write_buffer (
|
||||
address_a,
|
||||
address_b,
|
||||
clock,
|
||||
data_a,
|
||||
data_b,
|
||||
wren_a,
|
||||
wren_b,
|
||||
q_a,
|
||||
q_b);
|
||||
|
||||
input [4:0] address_a;
|
||||
input [4:0] address_b;
|
||||
input clock;
|
||||
input [31:0] data_a;
|
||||
input [31:0] data_b;
|
||||
input wren_a;
|
||||
input wren_b;
|
||||
output [31:0] q_a;
|
||||
output [31:0] q_b;
|
||||
`ifndef ALTERA_RESERVED_QIS
|
||||
// synopsys translate_off
|
||||
`endif
|
||||
tri1 clock;
|
||||
tri0 wren_a;
|
||||
tri0 wren_b;
|
||||
`ifndef ALTERA_RESERVED_QIS
|
||||
// synopsys translate_on
|
||||
`endif
|
||||
|
||||
wire [31:0] sub_wire0;
|
||||
wire [31:0] sub_wire1;
|
||||
wire [31:0] q_a = sub_wire0[31:0];
|
||||
wire [31:0] q_b = sub_wire1[31:0];
|
||||
|
||||
altsyncram altsyncram_component (
|
||||
.address_a (address_a),
|
||||
.address_b (address_b),
|
||||
.clock0 (clock),
|
||||
.data_a (data_a),
|
||||
.data_b (data_b),
|
||||
.wren_a (wren_a),
|
||||
.wren_b (wren_b),
|
||||
.q_a (sub_wire0),
|
||||
.q_b (sub_wire1),
|
||||
.aclr0 (1'b0),
|
||||
.aclr1 (1'b0),
|
||||
.addressstall_a (1'b0),
|
||||
.addressstall_b (1'b0),
|
||||
.byteena_a (1'b1),
|
||||
.byteena_b (1'b1),
|
||||
.clock1 (1'b1),
|
||||
.clocken0 (1'b1),
|
||||
.clocken1 (1'b1),
|
||||
.clocken2 (1'b1),
|
||||
.clocken3 (1'b1),
|
||||
.eccstatus (),
|
||||
.rden_a (1'b1),
|
||||
.rden_b (1'b1));
|
||||
defparam
|
||||
altsyncram_component.address_reg_b = "CLOCK0",
|
||||
altsyncram_component.clock_enable_input_a = "BYPASS",
|
||||
altsyncram_component.clock_enable_input_b = "BYPASS",
|
||||
altsyncram_component.clock_enable_output_a = "BYPASS",
|
||||
altsyncram_component.clock_enable_output_b = "BYPASS",
|
||||
altsyncram_component.indata_reg_b = "CLOCK0",
|
||||
altsyncram_component.intended_device_family = "MAX 10",
|
||||
altsyncram_component.lpm_type = "altsyncram",
|
||||
altsyncram_component.numwords_a = 32,
|
||||
altsyncram_component.numwords_b = 32,
|
||||
altsyncram_component.operation_mode = "BIDIR_DUAL_PORT",
|
||||
altsyncram_component.outdata_aclr_a = "NONE",
|
||||
altsyncram_component.outdata_aclr_b = "NONE",
|
||||
altsyncram_component.outdata_reg_a = "UNREGISTERED",
|
||||
altsyncram_component.outdata_reg_b = "UNREGISTERED",
|
||||
altsyncram_component.power_up_uninitialized = "FALSE",
|
||||
altsyncram_component.read_during_write_mode_mixed_ports = "DONT_CARE",
|
||||
altsyncram_component.read_during_write_mode_port_a = "NEW_DATA_WITH_NBE_READ",
|
||||
altsyncram_component.read_during_write_mode_port_b = "NEW_DATA_WITH_NBE_READ",
|
||||
altsyncram_component.widthad_a = 5,
|
||||
altsyncram_component.widthad_b = 5,
|
||||
altsyncram_component.width_a = 32,
|
||||
altsyncram_component.width_b = 32,
|
||||
altsyncram_component.width_byteena_a = 1,
|
||||
altsyncram_component.width_byteena_b = 1,
|
||||
altsyncram_component.wrcontrol_wraddress_reg_b = "CLOCK0";
|
||||
|
||||
|
||||
endmodule
|
||||
|
||||
// ============================================================
|
||||
// CNX file retrieval info
|
||||
// ============================================================
|
||||
// Retrieval info: PRIVATE: ADDRESSSTALL_A NUMERIC "0"
|
||||
// Retrieval info: PRIVATE: ADDRESSSTALL_B NUMERIC "0"
|
||||
// Retrieval info: PRIVATE: BYTEENA_ACLR_A NUMERIC "0"
|
||||
// Retrieval info: PRIVATE: BYTEENA_ACLR_B NUMERIC "0"
|
||||
// Retrieval info: PRIVATE: BYTE_ENABLE_A NUMERIC "0"
|
||||
// Retrieval info: PRIVATE: BYTE_ENABLE_B NUMERIC "0"
|
||||
// Retrieval info: PRIVATE: BYTE_SIZE NUMERIC "8"
|
||||
// Retrieval info: PRIVATE: BlankMemory NUMERIC "1"
|
||||
// Retrieval info: PRIVATE: CLOCK_ENABLE_INPUT_A NUMERIC "0"
|
||||
// Retrieval info: PRIVATE: CLOCK_ENABLE_INPUT_B NUMERIC "0"
|
||||
// Retrieval info: PRIVATE: CLOCK_ENABLE_OUTPUT_A NUMERIC "0"
|
||||
// Retrieval info: PRIVATE: CLOCK_ENABLE_OUTPUT_B NUMERIC "0"
|
||||
// Retrieval info: PRIVATE: CLRdata NUMERIC "0"
|
||||
// Retrieval info: PRIVATE: CLRq NUMERIC "0"
|
||||
// Retrieval info: PRIVATE: CLRrdaddress NUMERIC "0"
|
||||
// Retrieval info: PRIVATE: CLRrren NUMERIC "0"
|
||||
// Retrieval info: PRIVATE: CLRwraddress NUMERIC "0"
|
||||
// Retrieval info: PRIVATE: CLRwren NUMERIC "0"
|
||||
// Retrieval info: PRIVATE: Clock NUMERIC "0"
|
||||
// Retrieval info: PRIVATE: Clock_A NUMERIC "0"
|
||||
// Retrieval info: PRIVATE: Clock_B NUMERIC "0"
|
||||
// Retrieval info: PRIVATE: IMPLEMENT_IN_LES NUMERIC "0"
|
||||
// Retrieval info: PRIVATE: INDATA_ACLR_B NUMERIC "0"
|
||||
// Retrieval info: PRIVATE: INDATA_REG_B NUMERIC "1"
|
||||
// Retrieval info: PRIVATE: INIT_FILE_LAYOUT STRING "PORT_A"
|
||||
// Retrieval info: PRIVATE: INIT_TO_SIM_X NUMERIC "0"
|
||||
// Retrieval info: PRIVATE: INTENDED_DEVICE_FAMILY STRING "MAX 10"
|
||||
// Retrieval info: PRIVATE: JTAG_ENABLED NUMERIC "0"
|
||||
// Retrieval info: PRIVATE: JTAG_ID STRING "NONE"
|
||||
// Retrieval info: PRIVATE: MAXIMUM_DEPTH NUMERIC "0"
|
||||
// Retrieval info: PRIVATE: MEMSIZE NUMERIC "1024"
|
||||
// Retrieval info: PRIVATE: MEM_IN_BITS NUMERIC "0"
|
||||
// Retrieval info: PRIVATE: MIFfilename STRING ""
|
||||
// Retrieval info: PRIVATE: OPERATION_MODE NUMERIC "3"
|
||||
// Retrieval info: PRIVATE: OUTDATA_ACLR_B NUMERIC "0"
|
||||
// Retrieval info: PRIVATE: OUTDATA_REG_B NUMERIC "0"
|
||||
// Retrieval info: PRIVATE: RAM_BLOCK_TYPE NUMERIC "0"
|
||||
// Retrieval info: PRIVATE: READ_DURING_WRITE_MODE_MIXED_PORTS NUMERIC "2"
|
||||
// Retrieval info: PRIVATE: READ_DURING_WRITE_MODE_PORT_A NUMERIC "4"
|
||||
// Retrieval info: PRIVATE: READ_DURING_WRITE_MODE_PORT_B NUMERIC "4"
|
||||
// Retrieval info: PRIVATE: REGdata NUMERIC "1"
|
||||
// Retrieval info: PRIVATE: REGq NUMERIC "0"
|
||||
// Retrieval info: PRIVATE: REGrdaddress NUMERIC "0"
|
||||
// Retrieval info: PRIVATE: REGrren NUMERIC "0"
|
||||
// Retrieval info: PRIVATE: REGwraddress NUMERIC "1"
|
||||
// Retrieval info: PRIVATE: REGwren NUMERIC "1"
|
||||
// Retrieval info: PRIVATE: SYNTH_WRAPPER_GEN_POSTFIX STRING "0"
|
||||
// Retrieval info: PRIVATE: USE_DIFF_CLKEN NUMERIC "0"
|
||||
// Retrieval info: PRIVATE: UseDPRAM NUMERIC "1"
|
||||
// Retrieval info: PRIVATE: VarWidth NUMERIC "0"
|
||||
// Retrieval info: PRIVATE: WIDTH_READ_A NUMERIC "32"
|
||||
// Retrieval info: PRIVATE: WIDTH_READ_B NUMERIC "32"
|
||||
// Retrieval info: PRIVATE: WIDTH_WRITE_A NUMERIC "32"
|
||||
// Retrieval info: PRIVATE: WIDTH_WRITE_B NUMERIC "32"
|
||||
// Retrieval info: PRIVATE: WRADDR_ACLR_B NUMERIC "0"
|
||||
// Retrieval info: PRIVATE: WRADDR_REG_B NUMERIC "1"
|
||||
// Retrieval info: PRIVATE: WRCTRL_ACLR_B NUMERIC "0"
|
||||
// Retrieval info: PRIVATE: enable NUMERIC "0"
|
||||
// Retrieval info: PRIVATE: rden NUMERIC "0"
|
||||
// Retrieval info: LIBRARY: altera_mf altera_mf.altera_mf_components.all
|
||||
// Retrieval info: CONSTANT: ADDRESS_REG_B STRING "CLOCK0"
|
||||
// Retrieval info: CONSTANT: CLOCK_ENABLE_INPUT_A STRING "BYPASS"
|
||||
// Retrieval info: CONSTANT: CLOCK_ENABLE_INPUT_B STRING "BYPASS"
|
||||
// Retrieval info: CONSTANT: CLOCK_ENABLE_OUTPUT_A STRING "BYPASS"
|
||||
// Retrieval info: CONSTANT: CLOCK_ENABLE_OUTPUT_B STRING "BYPASS"
|
||||
// Retrieval info: CONSTANT: INDATA_REG_B STRING "CLOCK0"
|
||||
// Retrieval info: CONSTANT: INTENDED_DEVICE_FAMILY STRING "MAX 10"
|
||||
// Retrieval info: CONSTANT: LPM_TYPE STRING "altsyncram"
|
||||
// Retrieval info: CONSTANT: NUMWORDS_A NUMERIC "32"
|
||||
// Retrieval info: CONSTANT: NUMWORDS_B NUMERIC "32"
|
||||
// Retrieval info: CONSTANT: OPERATION_MODE STRING "BIDIR_DUAL_PORT"
|
||||
// Retrieval info: CONSTANT: OUTDATA_ACLR_A STRING "NONE"
|
||||
// Retrieval info: CONSTANT: OUTDATA_ACLR_B STRING "NONE"
|
||||
// Retrieval info: CONSTANT: OUTDATA_REG_A STRING "UNREGISTERED"
|
||||
// Retrieval info: CONSTANT: OUTDATA_REG_B STRING "UNREGISTERED"
|
||||
// Retrieval info: CONSTANT: POWER_UP_UNINITIALIZED STRING "FALSE"
|
||||
// Retrieval info: CONSTANT: READ_DURING_WRITE_MODE_MIXED_PORTS STRING "DONT_CARE"
|
||||
// Retrieval info: CONSTANT: READ_DURING_WRITE_MODE_PORT_A STRING "NEW_DATA_WITH_NBE_READ"
|
||||
// Retrieval info: CONSTANT: READ_DURING_WRITE_MODE_PORT_B STRING "NEW_DATA_WITH_NBE_READ"
|
||||
// Retrieval info: CONSTANT: WIDTHAD_A NUMERIC "5"
|
||||
// Retrieval info: CONSTANT: WIDTHAD_B NUMERIC "5"
|
||||
// Retrieval info: CONSTANT: WIDTH_A NUMERIC "32"
|
||||
// Retrieval info: CONSTANT: WIDTH_B NUMERIC "32"
|
||||
// Retrieval info: CONSTANT: WIDTH_BYTEENA_A NUMERIC "1"
|
||||
// Retrieval info: CONSTANT: WIDTH_BYTEENA_B NUMERIC "1"
|
||||
// Retrieval info: CONSTANT: WRCONTROL_WRADDRESS_REG_B STRING "CLOCK0"
|
||||
// Retrieval info: USED_PORT: address_a 0 0 5 0 INPUT NODEFVAL "address_a[4..0]"
|
||||
// Retrieval info: USED_PORT: address_b 0 0 5 0 INPUT NODEFVAL "address_b[4..0]"
|
||||
// Retrieval info: USED_PORT: clock 0 0 0 0 INPUT VCC "clock"
|
||||
// Retrieval info: USED_PORT: data_a 0 0 32 0 INPUT NODEFVAL "data_a[31..0]"
|
||||
// Retrieval info: USED_PORT: data_b 0 0 32 0 INPUT NODEFVAL "data_b[31..0]"
|
||||
// Retrieval info: USED_PORT: q_a 0 0 32 0 OUTPUT NODEFVAL "q_a[31..0]"
|
||||
// Retrieval info: USED_PORT: q_b 0 0 32 0 OUTPUT NODEFVAL "q_b[31..0]"
|
||||
// Retrieval info: USED_PORT: wren_a 0 0 0 0 INPUT GND "wren_a"
|
||||
// Retrieval info: USED_PORT: wren_b 0 0 0 0 INPUT GND "wren_b"
|
||||
// Retrieval info: CONNECT: @address_a 0 0 5 0 address_a 0 0 5 0
|
||||
// Retrieval info: CONNECT: @address_b 0 0 5 0 address_b 0 0 5 0
|
||||
// Retrieval info: CONNECT: @clock0 0 0 0 0 clock 0 0 0 0
|
||||
// Retrieval info: CONNECT: @data_a 0 0 32 0 data_a 0 0 32 0
|
||||
// Retrieval info: CONNECT: @data_b 0 0 32 0 data_b 0 0 32 0
|
||||
// Retrieval info: CONNECT: @wren_a 0 0 0 0 wren_a 0 0 0 0
|
||||
// Retrieval info: CONNECT: @wren_b 0 0 0 0 wren_b 0 0 0 0
|
||||
// Retrieval info: CONNECT: q_a 0 0 32 0 @q_a 0 0 32 0
|
||||
// Retrieval info: CONNECT: q_b 0 0 32 0 @q_b 0 0 32 0
|
||||
// Retrieval info: GEN_FILE: TYPE_NORMAL ram_flashram_write_buffer.v TRUE
|
||||
// Retrieval info: GEN_FILE: TYPE_NORMAL ram_flashram_write_buffer.inc FALSE
|
||||
// Retrieval info: GEN_FILE: TYPE_NORMAL ram_flashram_write_buffer.cmp FALSE
|
||||
// Retrieval info: GEN_FILE: TYPE_NORMAL ram_flashram_write_buffer.bsf FALSE
|
||||
// Retrieval info: GEN_FILE: TYPE_NORMAL ram_flashram_write_buffer_inst.v FALSE
|
||||
// Retrieval info: GEN_FILE: TYPE_NORMAL ram_flashram_write_buffer_bb.v FALSE
|
||||
// Retrieval info: LIB_FILE: altera_mf
|
@ -4,46 +4,44 @@ module n64_bank_decoder (
|
||||
input i_clk,
|
||||
|
||||
input i_address_high_op,
|
||||
input i_address_low_op,
|
||||
input [15:0] i_n64_pi_ad,
|
||||
|
||||
output reg [3:0] o_bank,
|
||||
output reg o_prefetch,
|
||||
output reg o_ddipl_request,
|
||||
output reg o_sram_request,
|
||||
output reg o_ddipl_pi_request,
|
||||
output reg o_sram_pi_request,
|
||||
output reg o_flashram_pi_request,
|
||||
|
||||
input i_ddipl_enable,
|
||||
input i_sram_enable,
|
||||
input i_sram_768k_mode,
|
||||
input i_flashram_enable,
|
||||
input i_eeprom_enable,
|
||||
input i_eeprom_pi_enable,
|
||||
input i_sd_enable
|
||||
);
|
||||
|
||||
reg r_address_high_lsb;
|
||||
|
||||
always @(posedge i_clk) begin
|
||||
if (i_address_high_op) begin
|
||||
o_bank <= `BANK_INVALID;
|
||||
o_prefetch <= 1'b1;
|
||||
o_ddipl_request <= 1'b0;
|
||||
o_sram_request <= 1'b0;
|
||||
o_ddipl_pi_request <= 1'b0;
|
||||
o_sram_pi_request <= 1'b0;
|
||||
o_flashram_pi_request <= 1'b0;
|
||||
|
||||
casez (i_n64_pi_ad)
|
||||
16'b0000011000??????: begin // DDIPL
|
||||
if (i_ddipl_enable) begin
|
||||
o_bank <= `BANK_SDRAM;
|
||||
o_ddipl_request <= 1'b1;
|
||||
o_ddipl_pi_request <= 1'b1;
|
||||
end
|
||||
end
|
||||
|
||||
16'b000010000000000?: begin // SRAM / FlashRAM
|
||||
r_address_high_lsb <= i_n64_pi_ad[0];
|
||||
if (i_flashram_enable && !i_n64_pi_ad[0]) begin
|
||||
o_bank <= `BANK_FLASHRAM;
|
||||
if (i_flashram_enable) begin
|
||||
o_bank <= `BANK_SDRAM;
|
||||
o_flashram_pi_request <= 1'b1;
|
||||
end else if (i_sram_enable) begin
|
||||
o_bank <= `BANK_SDRAM;
|
||||
o_sram_request <= 1'b1;
|
||||
o_sram_pi_request <= 1'b1;
|
||||
end
|
||||
end
|
||||
|
||||
@ -57,7 +55,7 @@ module n64_bank_decoder (
|
||||
end
|
||||
|
||||
16'b0001111000000001: begin // EEPROM
|
||||
if (i_eeprom_enable) begin
|
||||
if (i_eeprom_pi_enable) begin
|
||||
o_bank <= `BANK_EEPROM;
|
||||
end
|
||||
end
|
||||
@ -68,49 +66,6 @@ module n64_bank_decoder (
|
||||
o_prefetch <= 1'b0;
|
||||
end
|
||||
end
|
||||
default: begin end
|
||||
endcase
|
||||
end
|
||||
|
||||
if (i_address_low_op) begin
|
||||
case (o_bank)
|
||||
`BANK_SDRAM: begin
|
||||
if (o_sram_request) begin
|
||||
if (i_sram_768k_mode) begin
|
||||
if (r_address_high_lsb && i_n64_pi_ad[1]) begin
|
||||
o_bank <= `BANK_INVALID;
|
||||
end
|
||||
end else begin
|
||||
if (i_n64_pi_ad[1]) begin
|
||||
o_bank <= `BANK_INVALID;
|
||||
end
|
||||
end
|
||||
end
|
||||
end
|
||||
|
||||
`BANK_CART: begin
|
||||
if (i_n64_pi_ad[15:14] != 2'b00) begin
|
||||
o_bank <= `BANK_INVALID;
|
||||
end
|
||||
end
|
||||
|
||||
`BANK_EEPROM: begin
|
||||
if (i_n64_pi_ad[15:11] != 5'b00000) begin
|
||||
o_bank <= `BANK_INVALID;
|
||||
end
|
||||
end
|
||||
|
||||
`BANK_FLASHRAM: begin
|
||||
if (r_address_high_lsb) begin
|
||||
o_bank <= `BANK_INVALID;
|
||||
end
|
||||
end
|
||||
|
||||
`BANK_SD: begin
|
||||
if (i_n64_pi_ad[15:10] != 6'b000000) begin
|
||||
o_bank <= `BANK_INVALID;
|
||||
end
|
||||
end
|
||||
|
||||
default: begin end
|
||||
endcase
|
||||
|
@ -20,17 +20,19 @@ module n64_pi (
|
||||
input [31:0] i_data,
|
||||
output reg [31:0] o_data,
|
||||
|
||||
output o_sram_request,
|
||||
output o_sram_pi_request,
|
||||
output o_flashram_pi_request,
|
||||
|
||||
input i_ddipl_enable,
|
||||
input i_sram_enable,
|
||||
input i_sram_768k_mode,
|
||||
input i_flashram_enable,
|
||||
input i_sd_enable,
|
||||
input i_eeprom_enable,
|
||||
input i_eeprom_pi_enable,
|
||||
|
||||
input [23:0] i_ddipl_address,
|
||||
input [23:0] i_sram_address
|
||||
input [23:0] i_save_address,
|
||||
|
||||
input i_flashram_read_mode
|
||||
);
|
||||
|
||||
// Parameters
|
||||
@ -88,7 +90,7 @@ module n64_pi (
|
||||
// Bank decoder, address translator and prefetch signal
|
||||
|
||||
wire w_bank_prefetch;
|
||||
wire w_ddipl_request;
|
||||
wire w_ddipl_pi_request;
|
||||
|
||||
wire w_prefetch = !PREFETCH_DISABLE && w_bank_prefetch;
|
||||
|
||||
@ -96,19 +98,18 @@ module n64_pi (
|
||||
.i_clk(i_clk),
|
||||
|
||||
.i_address_high_op(w_address_high_op),
|
||||
.i_address_low_op(w_address_low_op),
|
||||
.i_n64_pi_ad(io_n64_pi_ad),
|
||||
|
||||
.o_bank(o_bank),
|
||||
.o_prefetch(w_bank_prefetch),
|
||||
.o_ddipl_request(w_ddipl_request),
|
||||
.o_sram_request(o_sram_request),
|
||||
.o_ddipl_pi_request(w_ddipl_pi_request),
|
||||
.o_sram_pi_request(o_sram_pi_request),
|
||||
.o_flashram_pi_request(o_flashram_pi_request),
|
||||
|
||||
.i_ddipl_enable(i_ddipl_enable),
|
||||
.i_sram_enable(i_sram_enable),
|
||||
.i_sram_768k_mode(i_sram_768k_mode),
|
||||
.i_flashram_enable(i_flashram_enable),
|
||||
.i_eeprom_enable(i_eeprom_enable),
|
||||
.i_eeprom_pi_enable(i_eeprom_pi_enable),
|
||||
.i_sd_enable(i_sd_enable)
|
||||
);
|
||||
|
||||
@ -124,6 +125,7 @@ module n64_pi (
|
||||
if (r_address_valid_op) begin
|
||||
r_word_counter <= 1'b0;
|
||||
end
|
||||
|
||||
if (w_read_op || w_write_op) begin
|
||||
r_word_counter <= ~r_word_counter;
|
||||
end
|
||||
@ -153,11 +155,13 @@ module n64_pi (
|
||||
end
|
||||
if (i_ack) begin
|
||||
r_prefetch_read <= 1'b0;
|
||||
|
||||
if (w_prefetch) begin
|
||||
r_pi_read_buffer <= i_data;
|
||||
end else begin
|
||||
r_pi_output_data <= i_data;
|
||||
end
|
||||
|
||||
if (r_prefetch_read) begin
|
||||
r_pi_output_data <= i_data;
|
||||
end
|
||||
@ -201,6 +205,7 @@ module n64_pi (
|
||||
o_request <= 1'b0;
|
||||
o_write <= 1'b0;
|
||||
end
|
||||
|
||||
if (w_bus_request_op) begin
|
||||
if (o_request) begin
|
||||
r_pending_request <= 1'b1;
|
||||
@ -210,6 +215,7 @@ module n64_pi (
|
||||
o_write <= w_bus_write_op;
|
||||
end
|
||||
end
|
||||
|
||||
if (r_pending_request && !i_busy) begin
|
||||
o_request <= 1'b1;
|
||||
o_write <= r_pending_request_write;
|
||||
@ -224,7 +230,7 @@ module n64_pi (
|
||||
wire [9:0] w_pi_high_address = io_n64_pi_ad[9:0];
|
||||
wire [15:0] w_pi_low_address = {io_n64_pi_ad[15:1], 1'b0};
|
||||
wire [25:0] w_ddipl_translated_address = o_address + {i_ddipl_address, 2'b00};
|
||||
wire [25:0] w_sram_translated_address = o_address + {i_sram_address, 2'b00};
|
||||
wire [25:0] w_save_translated_address = o_address + {i_save_address, 2'b00};
|
||||
|
||||
reg r_first_transfer;
|
||||
reg [14:0] r_address_low_buffer;
|
||||
@ -241,13 +247,19 @@ module n64_pi (
|
||||
if (r_address_valid_op) begin
|
||||
r_first_transfer <= w_prefetch;
|
||||
r_address_low_buffer <= o_address[15:1];
|
||||
if (w_ddipl_request) begin
|
||||
|
||||
if (w_ddipl_pi_request) begin
|
||||
o_address <= w_ddipl_translated_address;
|
||||
r_address_low_buffer <= w_ddipl_translated_address[15:1];
|
||||
end
|
||||
if (o_sram_request) begin
|
||||
o_address <= w_sram_translated_address;
|
||||
r_address_low_buffer <= w_sram_translated_address[15:1];
|
||||
|
||||
if (o_sram_pi_request) begin
|
||||
o_address <= w_save_translated_address;
|
||||
r_address_low_buffer <= w_save_translated_address[15:1];
|
||||
end
|
||||
|
||||
if (o_flashram_pi_request && i_flashram_read_mode) begin
|
||||
o_address <= w_save_translated_address;
|
||||
end
|
||||
end
|
||||
|
||||
|
@ -20,8 +20,8 @@ module sd_interface (
|
||||
input i_dma_ack,
|
||||
output [3:0] o_dma_bank,
|
||||
output [23:0] o_dma_address,
|
||||
input [31:0] i_dma_data,
|
||||
output [31:0] o_dma_data
|
||||
output [31:0] o_dma_data,
|
||||
input [31:0] i_dma_data
|
||||
);
|
||||
|
||||
// Clock generator
|
||||
|
183
fw/rtl/top.v
183
fw/rtl/top.v
@ -33,10 +33,6 @@ module top (
|
||||
inout io_sd_cmd,
|
||||
inout [3:0] io_sd_dat,
|
||||
|
||||
output o_sram_clk,
|
||||
output o_sram_cs,
|
||||
inout [3:0] io_sram_dq,
|
||||
|
||||
output o_rtc_scl,
|
||||
inout io_rtc_sda,
|
||||
|
||||
@ -57,7 +53,6 @@ module top (
|
||||
|
||||
wire w_n64_reset_btn;
|
||||
|
||||
assign {o_sram_clk, o_sram_cs, io_sram_dq} = 6'bZZZZZZ;
|
||||
assign {o_rtc_scl, io_rtc_sda} = 2'bZZ;
|
||||
assign io_pmod[3] = w_n64_reset_btn ? 1'bZ : 1'b0;
|
||||
assign {io_pmod[7:4], io_pmod[2:0]} = 7'bZZZZZZZ;
|
||||
@ -110,42 +105,63 @@ module top (
|
||||
wire w_n64_ack_cart_control;
|
||||
wire [31:0] w_n64_i_data_cart_control;
|
||||
|
||||
wire w_n64_busy_sdram;
|
||||
wire w_n64_ack_sdram;
|
||||
wire [31:0] w_n64_i_data_sdram;
|
||||
|
||||
wire w_n64_busy_embedded_flash;
|
||||
wire w_n64_ack_embedded_flash;
|
||||
wire [31:0] w_n64_i_data_embedded_flash;
|
||||
|
||||
wire w_n64_busy_sdram;
|
||||
wire w_n64_ack_sdram;
|
||||
wire [31:0] w_n64_i_data_sdram;
|
||||
|
||||
wire w_n64_busy_eeprom;
|
||||
wire w_n64_ack_eeprom;
|
||||
wire [31:0] w_n64_i_data_eeprom;
|
||||
|
||||
wire w_n64_busy_flashram;
|
||||
wire w_n64_ack_flashram;
|
||||
wire [31:0] w_n64_i_data_flashram;
|
||||
|
||||
wire w_n64_busy_sd;
|
||||
wire w_n64_ack_sd;
|
||||
wire [31:0] w_n64_i_data_sd;
|
||||
|
||||
wire w_sram_request;
|
||||
wire w_sram_pi_request;
|
||||
wire w_flashram_pi_request;
|
||||
|
||||
wire w_ddipl_enable;
|
||||
wire w_sram_enable;
|
||||
wire w_sram_768k_mode;
|
||||
wire w_flashram_enable;
|
||||
wire w_sd_enable;
|
||||
wire w_eeprom_pi_enable;
|
||||
|
||||
wire [23:0] w_ddipl_address;
|
||||
wire [23:0] w_sram_address;
|
||||
wire [23:0] w_save_address;
|
||||
|
||||
wire w_flashram_read_mode;
|
||||
|
||||
always @(*) begin
|
||||
w_n64_busy = w_n64_busy_cart_control || w_n64_busy_sdram || w_n64_busy_embedded_flash || w_n64_busy_eeprom || w_n64_busy_sd;
|
||||
w_n64_ack = w_n64_ack_cart_control || w_n64_ack_sdram || w_n64_ack_embedded_flash || w_n64_ack_eeprom || w_n64_ack_sd;
|
||||
w_n64_busy = (
|
||||
w_n64_busy_cart_control ||
|
||||
w_n64_busy_embedded_flash ||
|
||||
w_n64_busy_sdram ||
|
||||
w_n64_busy_eeprom ||
|
||||
w_n64_busy_flashram ||
|
||||
w_n64_busy_sd
|
||||
);
|
||||
w_n64_ack = (
|
||||
w_n64_ack_cart_control ||
|
||||
w_n64_ack_embedded_flash ||
|
||||
w_n64_ack_sdram ||
|
||||
w_n64_ack_eeprom ||
|
||||
w_n64_ack_flashram ||
|
||||
w_n64_ack_sd
|
||||
);
|
||||
w_n64_i_data = 32'h0000_0000;
|
||||
if (w_n64_ack_cart_control) w_n64_i_data = w_n64_i_data_cart_control;
|
||||
if (w_n64_ack_sdram) w_n64_i_data = w_n64_i_data_sdram;
|
||||
if (w_n64_ack_embedded_flash) w_n64_i_data = w_n64_i_data_embedded_flash;
|
||||
if (w_n64_ack_sdram) w_n64_i_data = w_n64_i_data_sdram;
|
||||
if (w_n64_ack_eeprom) w_n64_i_data = w_n64_i_data_eeprom;
|
||||
if (w_n64_ack_flashram) w_n64_i_data = w_n64_i_data_flashram;
|
||||
if (w_n64_ack_sd) w_n64_i_data = w_n64_i_data_sd;
|
||||
end
|
||||
|
||||
@ -169,17 +185,19 @@ module top (
|
||||
.i_data(w_n64_i_data),
|
||||
.o_data(w_n64_o_data),
|
||||
|
||||
.o_sram_request(w_sram_request),
|
||||
.o_sram_pi_request(w_sram_pi_request),
|
||||
.o_flashram_pi_request(w_flashram_pi_request),
|
||||
|
||||
.i_ddipl_enable(w_ddipl_enable),
|
||||
.i_sram_enable(w_sram_enable),
|
||||
.i_sram_768k_mode(w_sram_768k_mode),
|
||||
.i_flashram_enable(w_flashram_enable),
|
||||
.i_sd_enable(w_sd_enable),
|
||||
.i_eeprom_enable(w_eeprom_pi_enable),
|
||||
.i_eeprom_pi_enable(w_eeprom_pi_enable),
|
||||
|
||||
.i_ddipl_address(w_ddipl_address),
|
||||
.i_sram_address(w_sram_address)
|
||||
.i_save_address(w_save_address),
|
||||
|
||||
.i_flashram_read_mode(w_flashram_read_mode)
|
||||
);
|
||||
|
||||
|
||||
@ -321,7 +339,6 @@ module top (
|
||||
.o_rom_switch(w_rom_switch),
|
||||
.o_ddipl_enable(w_ddipl_enable),
|
||||
.o_sram_enable(w_sram_enable),
|
||||
.o_sram_768k_mode(w_sram_768k_mode),
|
||||
.o_flashram_enable(w_flashram_enable),
|
||||
.o_sd_enable(w_sd_enable),
|
||||
.o_eeprom_pi_enable(w_eeprom_pi_enable),
|
||||
@ -330,7 +347,7 @@ module top (
|
||||
|
||||
.o_n64_reset_btn(w_n64_reset_btn),
|
||||
|
||||
.i_debug_ready(1'b1),
|
||||
.i_debug_ready(1'b1), // TODO: Detect USB cable insertion
|
||||
|
||||
.o_debug_dma_start(w_debug_dma_start),
|
||||
.i_debug_dma_busy(w_debug_dma_busy),
|
||||
@ -344,29 +361,16 @@ module top (
|
||||
.i_debug_fifo_data(w_debug_fifo_data),
|
||||
|
||||
.o_ddipl_address(w_ddipl_address),
|
||||
.o_sram_address(w_sram_address)
|
||||
);
|
||||
|
||||
|
||||
// Embedded flash
|
||||
|
||||
wire w_embedded_flash_request_n64 = w_n64_request && !w_rom_switch && !w_n64_write && w_n64_bank == `BANK_SDRAM;
|
||||
|
||||
memory_embedded_flash memory_embedded_flash_inst (
|
||||
.i_clk(w_sys_clk),
|
||||
.i_reset(w_sys_reset),
|
||||
|
||||
.i_request(w_embedded_flash_request_n64),
|
||||
.o_busy(w_n64_busy_embedded_flash),
|
||||
.o_ack(w_n64_ack_embedded_flash),
|
||||
.i_address(w_n64_address[20:2]),
|
||||
.o_data(w_n64_i_data_embedded_flash)
|
||||
.o_save_address(w_save_address)
|
||||
);
|
||||
|
||||
|
||||
// SD card
|
||||
|
||||
wire w_n64_request_sd = w_n64_request && w_n64_bank == `BANK_SD;
|
||||
wire w_n64_request_sd = (
|
||||
w_n64_request &&
|
||||
w_n64_bank == `BANK_SD
|
||||
);
|
||||
|
||||
wire w_sd_dma_request;
|
||||
wire w_sd_dma_write;
|
||||
@ -415,14 +419,83 @@ module top (
|
||||
.i_dma_ack(w_sd_dma_ack),
|
||||
.o_dma_bank(w_sd_dma_bank),
|
||||
.o_dma_address(w_sd_dma_address),
|
||||
.i_dma_data(w_sd_dma_i_data),
|
||||
.o_dma_data(w_sd_dma_o_data)
|
||||
.o_dma_data(w_sd_dma_o_data),
|
||||
.i_dma_data(w_sd_dma_i_data)
|
||||
);
|
||||
|
||||
|
||||
// FlashRAM
|
||||
|
||||
wire w_flashram_request_n64 = (
|
||||
w_n64_request &&
|
||||
w_flashram_pi_request &&
|
||||
w_n64_bank == `BANK_SDRAM
|
||||
);
|
||||
|
||||
wire w_flashram_dma_request;
|
||||
wire w_flashram_dma_write;
|
||||
wire w_flashram_dma_busy;
|
||||
wire w_flashram_dma_ack;
|
||||
wire [3:0] w_flashram_dma_bank;
|
||||
wire [23:0] w_flashram_dma_address;
|
||||
wire [31:0] w_flashram_dma_i_data;
|
||||
wire [31:0] w_flashram_dma_o_data;
|
||||
|
||||
flashram_controller flashram_controller_inst (
|
||||
.i_clk(w_sys_clk),
|
||||
.i_reset(w_sys_reset),
|
||||
|
||||
.i_save_address(w_save_address),
|
||||
|
||||
.o_flashram_read_mode(w_flashram_read_mode),
|
||||
|
||||
.i_request(w_flashram_request_n64),
|
||||
.i_write(w_n64_write),
|
||||
.o_busy(w_n64_busy_flashram),
|
||||
.o_ack(w_n64_ack_flashram),
|
||||
.i_address(w_n64_address[16:2]),
|
||||
.o_data(w_n64_i_data_flashram),
|
||||
.i_data(w_n64_o_data),
|
||||
|
||||
.o_mem_request(w_flashram_dma_request),
|
||||
.o_mem_write(w_flashram_dma_write),
|
||||
.i_mem_busy(w_flashram_dma_busy),
|
||||
.i_mem_ack(w_flashram_dma_ack),
|
||||
.o_mem_bank(w_flashram_dma_bank),
|
||||
.o_mem_address(w_flashram_dma_address),
|
||||
.o_mem_data(w_flashram_dma_o_data),
|
||||
.i_mem_data(w_flashram_dma_i_data)
|
||||
);
|
||||
|
||||
|
||||
// Embedded flash in FPGA
|
||||
|
||||
wire w_embedded_flash_request_n64 = (
|
||||
w_n64_request &&
|
||||
!w_rom_switch &&
|
||||
!w_n64_write &&
|
||||
w_n64_bank == `BANK_SDRAM
|
||||
);
|
||||
|
||||
memory_embedded_flash memory_embedded_flash_inst (
|
||||
.i_clk(w_sys_clk),
|
||||
.i_reset(w_sys_reset),
|
||||
|
||||
.i_request(w_embedded_flash_request_n64),
|
||||
.o_busy(w_n64_busy_embedded_flash),
|
||||
.o_ack(w_n64_ack_embedded_flash),
|
||||
.i_address(w_n64_address[20:2]),
|
||||
.o_data(w_n64_i_data_embedded_flash)
|
||||
);
|
||||
|
||||
|
||||
// SDRAM
|
||||
|
||||
wire w_sdram_request_n64 = w_n64_request && w_rom_switch && (!w_n64_write || (w_n64_write && (w_sdram_writable || w_sram_request)));
|
||||
wire w_sdram_request_n64 = w_n64_request && (
|
||||
(w_rom_switch && (w_sdram_writable || !w_n64_write) && !w_flashram_pi_request) ||
|
||||
w_sram_pi_request ||
|
||||
(w_flashram_pi_request && w_flashram_read_mode && !w_n64_write)
|
||||
);
|
||||
|
||||
wire w_sdram_request;
|
||||
wire w_sdram_write;
|
||||
@ -433,21 +506,21 @@ module top (
|
||||
wire [31:0] w_sdram_i_data;
|
||||
|
||||
device_arbiter #(
|
||||
.NUM_CONTROLLERS(3),
|
||||
.NUM_CONTROLLERS(4),
|
||||
.ADDRESS_WIDTH(25),
|
||||
.DEVICE_BANK(`BANK_SDRAM)
|
||||
) device_arbiter_sdram_inst (
|
||||
.i_clk(w_sys_clk),
|
||||
.i_reset(w_sys_reset),
|
||||
|
||||
.i_request({w_sd_dma_request, w_pc_request, w_sdram_request_n64}),
|
||||
.i_write({w_sd_dma_write, w_pc_write, w_n64_write}),
|
||||
.o_busy({w_sd_dma_busy_sdram, w_pc_busy_sdram, w_n64_busy_sdram}),
|
||||
.o_ack({w_sd_dma_ack_sdram, w_pc_ack_sdram, w_n64_ack_sdram}),
|
||||
.i_bank({w_sd_dma_bank, w_pc_bank, w_n64_bank}),
|
||||
.i_address({{w_sd_dma_address, 1'b0}, w_pc_address[25:1], w_n64_address[25:1]}),
|
||||
.o_data({w_sd_dma_i_data_sdram, w_pc_i_data_sdram, w_n64_i_data_sdram}),
|
||||
.i_data({w_sd_dma_o_data, w_pc_o_data, w_n64_o_data}),
|
||||
.i_request({w_flashram_dma_request, w_sd_dma_request, w_pc_request, w_sdram_request_n64}),
|
||||
.i_write({w_flashram_dma_write, w_sd_dma_write, w_pc_write, w_n64_write}),
|
||||
.o_busy({w_flashram_dma_busy, w_sd_dma_busy_sdram, w_pc_busy_sdram, w_n64_busy_sdram}),
|
||||
.o_ack({w_flashram_dma_ack, w_sd_dma_ack_sdram, w_pc_ack_sdram, w_n64_ack_sdram}),
|
||||
.i_bank({w_flashram_dma_bank, w_sd_dma_bank, w_pc_bank, w_n64_bank}),
|
||||
.i_address({{w_flashram_dma_address, 1'b0}, {w_sd_dma_address, 1'b0}, w_pc_address[25:1], w_n64_address[25:1]}),
|
||||
.o_data({w_flashram_dma_i_data, w_sd_dma_i_data_sdram, w_pc_i_data_sdram, w_n64_i_data_sdram}),
|
||||
.i_data({w_flashram_dma_o_data, w_sd_dma_o_data, w_pc_o_data, w_n64_o_data}),
|
||||
|
||||
.o_device_request(w_sdram_request),
|
||||
.o_device_write(w_sdram_write),
|
||||
@ -480,7 +553,7 @@ module top (
|
||||
);
|
||||
|
||||
|
||||
// EEPROM 4/16k
|
||||
// N64 SI (EEPROM 4/16k and RTC)
|
||||
|
||||
wire w_eeprom_request;
|
||||
wire w_eeprom_write;
|
||||
@ -539,7 +612,11 @@ module top (
|
||||
|
||||
// LED
|
||||
|
||||
wire w_led_trigger = (w_n64_request && !w_n64_busy) || (w_pc_request && !w_pc_busy) || (w_sd_dma_request && !w_sd_dma_busy);
|
||||
wire w_led_trigger = (
|
||||
(w_n64_request && !w_n64_busy) ||
|
||||
(w_pc_request && !w_pc_busy) ||
|
||||
(w_sd_dma_request && !w_sd_dma_busy)
|
||||
);
|
||||
|
||||
cart_led cart_led_inst (
|
||||
.i_clk(w_sys_clk),
|
||||
|
@ -93,15 +93,16 @@ int main(void) {
|
||||
switch (config.save_type) {
|
||||
case 1: sc64_enable_eeprom(false); break;
|
||||
case 2: sc64_enable_eeprom(true); break;
|
||||
case 3: sc64_enable_sram(false); break;
|
||||
case 4: sc64_enable_sram(true); break;
|
||||
case 5: sc64_enable_flashram(); break;
|
||||
case 3:
|
||||
case 4: sc64_enable_sram(); break;
|
||||
case 5:
|
||||
case 6: sc64_enable_flashram(); break;
|
||||
}
|
||||
|
||||
if (config.save_type == 3) {
|
||||
sc64_set_sram_address(SC64_SDRAM_SIZE - (32 * 1024));
|
||||
} else if (config.save_type == 4) {
|
||||
sc64_set_sram_address(SC64_SDRAM_SIZE - (3 * 32 * 1024));
|
||||
if (config.save_type >= 3 || config.save_type <= 5) {
|
||||
sc64_set_save_address(SC64_SDRAM_SIZE - (128 * 1024));
|
||||
} else if (config.save_type == 6) {
|
||||
sc64_set_save_address(0x01618000);
|
||||
}
|
||||
|
||||
if (rom_loaded && (config.save[0] != '\0') && config.save_writeback) {
|
||||
|
@ -41,13 +41,8 @@ void sc64_disable_flashram(void) {
|
||||
sc64_disable_peripheral(SC64_CART_SCR_FLASHRAM_ENABLE);
|
||||
}
|
||||
|
||||
void sc64_enable_sram(bool mode_768k) {
|
||||
void sc64_enable_sram(void) {
|
||||
sc64_enable_peripheral(SC64_CART_SCR_SRAM_ENABLE);
|
||||
if (mode_768k) {
|
||||
sc64_enable_peripheral(SC64_CART_SCR_SRAM_768K_MODE);
|
||||
} else {
|
||||
sc64_disable_peripheral(SC64_CART_SCR_SRAM_768K_MODE);
|
||||
}
|
||||
}
|
||||
|
||||
void sc64_disable_sram(void) {
|
||||
@ -127,10 +122,10 @@ void sc64_set_ddipl_address(uint32_t address) {
|
||||
platform_pi_io_write(&SC64_CART->DDIPL_ADDR, address & SC64_CART_DDIPL_ADDR_ADDRESS_MASK);
|
||||
}
|
||||
|
||||
uint32_t sc64_get_sram_address(void) {
|
||||
uint32_t sc64_get_save_address(void) {
|
||||
return platform_pi_io_read(&SC64_CART->SRAM_ADDR) & SC64_CART_SRAM_ADDR_ADDRESS_MASK;
|
||||
}
|
||||
|
||||
void sc64_set_sram_address(uint32_t address) {
|
||||
void sc64_set_save_address(uint32_t address) {
|
||||
platform_pi_io_write(&SC64_CART->SRAM_ADDR, address & SC64_CART_SRAM_ADDR_ADDRESS_MASK);
|
||||
}
|
||||
|
@ -14,7 +14,7 @@ void sc64_enable_skip_bootloader(void);
|
||||
void sc64_disable_skip_bootloader(void);
|
||||
void sc64_enable_flashram(void);
|
||||
void sc64_disable_flashram(void);
|
||||
void sc64_enable_sram(bool mode_768k);
|
||||
void sc64_enable_sram(void);
|
||||
void sc64_disable_sram(void);
|
||||
void sc64_enable_sd(void);
|
||||
void sc64_disable_sd(void);
|
||||
@ -33,8 +33,8 @@ void sc64_set_boot_mode(uint32_t boot);
|
||||
uint32_t sc64_get_version(void);
|
||||
uint32_t sc64_get_ddipl_address(void);
|
||||
void sc64_set_ddipl_address(uint32_t address);
|
||||
uint32_t sc64_get_sram_address(void);
|
||||
void sc64_set_sram_address(uint32_t address);
|
||||
uint32_t sc64_get_save_address(void);
|
||||
void sc64_set_save_address(uint32_t address);
|
||||
|
||||
|
||||
#endif
|
||||
|
@ -11,8 +11,7 @@
|
||||
#define SC64_BANK_SDRAM (1)
|
||||
#define SC64_BANK_CART (2)
|
||||
#define SC64_BANK_EEPROM (3)
|
||||
#define SC64_BANK_FLASHRAM (4)
|
||||
#define SC64_BANK_SD (5)
|
||||
#define SC64_BANK_SD (4)
|
||||
|
||||
|
||||
// Cart Interface Registers
|
||||
|
@ -156,14 +156,10 @@ sc64_sd_fs_error_t sc64_sd_fs_load_save(const char *path) {
|
||||
length = (scr & SC64_CART_SCR_EEPROM_16K_MODE) ? 2048 : 512;
|
||||
current_bank = SC64_BANK_EEPROM;
|
||||
current_offset = 0;
|
||||
} else if (scr & SC64_CART_SCR_SRAM_ENABLE) {
|
||||
length = ((scr & SC64_CART_SCR_SRAM_768K_MODE) ? 3 : 1) * (32 * 1024);
|
||||
} else if (scr & (SC64_CART_SCR_SRAM_ENABLE | SC64_CART_SCR_FLASHRAM_ENABLE)) {
|
||||
length = 128 * 1024;
|
||||
current_bank = SC64_BANK_SDRAM;
|
||||
current_offset = sc64_get_sram_address();
|
||||
} else if (scr & SC64_CART_SCR_FLASHRAM_ENABLE) { // TODO: FlashRAM
|
||||
length = 0;
|
||||
current_bank = SC64_BANK_FLASHRAM;
|
||||
current_offset = 0;
|
||||
current_offset = sc64_get_save_address();
|
||||
}
|
||||
|
||||
if ((length == 0) || (path == NULL)) {
|
||||
@ -203,14 +199,10 @@ sc64_sd_fs_error_t sc64_sd_fs_store_save(const char *path) {
|
||||
platform_pi_dma_read(save_buffer, &SC64_EEPROM->MEM, length);
|
||||
platform_cache_invalidate(save_buffer, length);
|
||||
sc64_disable_eeprom_pi();
|
||||
} else if (scr & SC64_CART_SCR_SRAM_ENABLE) {
|
||||
length = ((scr & SC64_CART_SCR_SRAM_768K_MODE) ? 3 : 1) * (32 * 1024);
|
||||
platform_pi_dma_read(save_buffer, sc64_get_sram_address(), length);
|
||||
} else if (scr & (SC64_CART_SCR_SRAM_ENABLE | SC64_CART_SCR_FLASHRAM_ENABLE)) {
|
||||
length = 128 * 1024;
|
||||
platform_pi_dma_read(save_buffer, sc64_get_save_address(), length);
|
||||
platform_cache_invalidate(save_buffer, length);
|
||||
} else if (scr & SC64_CART_SCR_FLASHRAM_ENABLE) { // TODO: FlashRAM
|
||||
length = 0;
|
||||
// platform_pi_dma_read(save_buffer, 0, length);
|
||||
// platform_cache_invalidate(save_buffer, length);
|
||||
}
|
||||
|
||||
if ((length == 0) || (path == NULL)) {
|
||||
|
Loading…
Reference in New Issue
Block a user