mirror of
https://github.com/Polprzewodnikowy/SummerCart64.git
synced 2024-11-21 21:49:15 +01:00
[SC64][FW] EEPROM 4/16K save type implementation
This commit is contained in:
parent
7025f39fcc
commit
160ff68af3
@ -165,7 +165,7 @@ set_location_assignment PIN_11 -to io_pmod[7]
|
||||
set_location_assignment PIN_22 -to io_rtc_sda
|
||||
set_location_assignment PIN_21 -to o_rtc_scl
|
||||
set_location_assignment PIN_17 -to o_led
|
||||
set_global_assignment -name OPTIMIZATION_MODE "HIGH PERFORMANCE EFFORT"
|
||||
set_global_assignment -name OPTIMIZATION_MODE BALANCED
|
||||
set_global_assignment -name ENABLE_SIGNALTAP ON
|
||||
set_global_assignment -name USE_SIGNALTAP_FILE misc/SignalTapLogicAnalyzer.stp
|
||||
set_global_assignment -name RESERVE_ALL_UNUSED_PINS_WEAK_PULLUP "AS INPUT TRI-STATED WITH WEAK PULL-UP"
|
||||
@ -189,6 +189,7 @@ set_global_assignment -name ROUTER_CLOCKING_TOPOLOGY_ANALYSIS ON
|
||||
set_instance_assignment -name GLOBAL_SIGNAL GLOBAL_CLOCK -to "pll:sys_pll|altpll:altpll_component|pll_altpll:auto_generated|wire_pll1_clk[0]"
|
||||
set_instance_assignment -name GLOBAL_SIGNAL GLOBAL_CLOCK -to "pll:sys_pll|altpll:altpll_component|pll_altpll:auto_generated|wire_pll1_clk[1]"
|
||||
set_global_assignment -name FITTER_EFFORT "STANDARD FIT"
|
||||
set_global_assignment -name VERILOG_FILE rtl/n64_si.v
|
||||
set_global_assignment -name VERILOG_FILE rtl/cart_config.v
|
||||
set_global_assignment -name VERILOG_FILE rtl/sdram.v
|
||||
set_global_assignment -name VERILOG_FILE rtl/external/wbsdram.v
|
||||
@ -204,5 +205,6 @@ set_global_assignment -name QIP_FILE rtl/intel/gpio/gpio_ddro.qip
|
||||
set_global_assignment -name QIP_FILE rtl/intel/fifo/fifo_bus_to_pc.qip
|
||||
set_global_assignment -name QIP_FILE rtl/intel/fifo/fifo_pc_to_bus.qip
|
||||
set_global_assignment -name SIGNALTAP_FILE misc/SignalTapLogicAnalyzer.stp
|
||||
set_global_assignment -name QIP_FILE rtl/intel/ram/ram_n64_eeprom.qip
|
||||
set_instance_assignment -name PARTITION_HIERARCHY root_partition -to | -section_id Top
|
||||
set_global_assignment -name SLD_FILE db/SignalTapLogicAnalyzer_auto_stripped.stp
|
File diff suppressed because one or more lines are too long
@ -5,9 +5,11 @@ module address_decoder (
|
||||
output o_flash,
|
||||
output o_flash_cfg,
|
||||
output o_sdram,
|
||||
output o_eeprom,
|
||||
|
||||
input i_flash_enable,
|
||||
input i_sdram_enable,
|
||||
input i_eeprom_pi_enable,
|
||||
|
||||
output o_address_valid
|
||||
);
|
||||
@ -32,6 +34,11 @@ module address_decoder (
|
||||
|
||||
assign o_sdram = i_sdram_enable && (i_address[31:SDRAM_WIDTH] == SDRAM_ADDR[31:SDRAM_WIDTH]);
|
||||
|
||||
assign o_address_valid = (|{o_cart_config, o_flash, o_flash_cfg, o_sdram});
|
||||
localparam EEPROM_ADDR = 32'h1D00_0000;
|
||||
localparam EEPROM_WIDTH = 11;
|
||||
|
||||
assign o_eeprom = i_eeprom_pi_enable && (i_address[31:EEPROM_WIDTH] == EEPROM_ADDR[31:EEPROM_WIDTH]);
|
||||
|
||||
assign o_address_valid = (|{o_cart_config, o_flash, o_flash_cfg, o_sdram, o_eeprom});
|
||||
|
||||
endmodule
|
||||
|
@ -11,61 +11,57 @@ module cart_config (
|
||||
output reg o_ack,
|
||||
input [31:0] i_address,
|
||||
input [31:0] i_data,
|
||||
output [31:0] o_data,
|
||||
output reg [31:0] o_data,
|
||||
|
||||
input i_n64_disabled,
|
||||
|
||||
output o_flash_enable,
|
||||
output o_sdram_enable
|
||||
output o_sdram_enable,
|
||||
output o_eeprom_pi_enable,
|
||||
output o_eeprom_enable,
|
||||
output o_eeprom_16k_enable
|
||||
);
|
||||
|
||||
reg [1:0] r_cart_config;
|
||||
reg [4:0] r_cart_config;
|
||||
reg [7:0] r_cic_type;
|
||||
|
||||
wire [31:0] w_regs [1:0];
|
||||
assign w_regs[0] = {30'd0, r_cart_config};
|
||||
assign w_regs[1] = {24'd0, r_cic_type};
|
||||
always @(*) begin
|
||||
o_data = 32'd0;
|
||||
if (!i_address[2]) o_data = {27'd0, r_cart_config};
|
||||
if (i_address[2]) o_data = {24'd0, r_cic_type};
|
||||
end
|
||||
|
||||
assign o_data = w_regs[i_address[2]];
|
||||
|
||||
assign o_flash_enable = r_cart_config[0];
|
||||
assign o_sdram_enable = r_cart_config[1];
|
||||
assign {
|
||||
o_eeprom_16k_enable,
|
||||
o_eeprom_enable,
|
||||
o_eeprom_pi_enable,
|
||||
o_sdram_enable,
|
||||
o_flash_enable,
|
||||
} = r_cart_config;
|
||||
|
||||
reg r_last_n64_reset;
|
||||
reg r_last_n64_nmi;
|
||||
|
||||
wire w_n64_reset_op = !i_n64_disabled && !r_last_n64_reset && i_n64_reset;
|
||||
wire w_n64_nmi_op = !i_n64_disabled && !r_last_n64_nmi && i_n64_nmi;
|
||||
wire w_n64_reset_op = !i_n64_disabled && ((!r_last_n64_reset && i_n64_reset) || (!r_last_n64_nmi && i_n64_nmi));
|
||||
|
||||
always @(posedge i_clk or posedge i_reset) begin
|
||||
if (i_reset) begin
|
||||
r_last_n64_reset <= 1'b0;
|
||||
r_last_n64_nmi <= 1'b0;
|
||||
end else begin
|
||||
r_last_n64_reset <= i_n64_reset;
|
||||
r_last_n64_nmi <= i_n64_nmi;
|
||||
end
|
||||
end
|
||||
|
||||
always @(posedge i_clk or posedge i_reset or posedge w_n64_reset_op or posedge w_n64_nmi_op) begin
|
||||
if (i_reset || w_n64_reset_op || w_n64_nmi_op) begin
|
||||
r_cart_config <= 2'b01;
|
||||
end else begin
|
||||
if (i_select && i_write_rq && !i_address[2]) r_cart_config <= i_data[1:0];
|
||||
end
|
||||
end
|
||||
|
||||
always @(posedge i_clk or posedge i_reset) begin
|
||||
if (i_reset) begin
|
||||
r_cic_type <= 8'd0;
|
||||
end else begin
|
||||
if (i_select && i_write_rq && i_address[2]) r_cic_type <= i_data[7:0];
|
||||
end
|
||||
always @(posedge i_clk) begin
|
||||
r_last_n64_reset <= i_n64_reset;
|
||||
r_last_n64_nmi <= i_n64_nmi;
|
||||
end
|
||||
|
||||
always @(posedge i_clk) begin
|
||||
o_ack <= 1'b0;
|
||||
if (i_select && (i_read_rq || i_write_rq)) o_ack <= 1'b1;
|
||||
if (i_reset) r_cart_config[4:0] <= 5'b00001;
|
||||
if (w_n64_reset_op) r_cart_config[2:0] <= 3'b001;
|
||||
if (!i_reset && i_select && i_write_rq && !i_address[2]) r_cart_config <= i_data[4:0];
|
||||
end
|
||||
|
||||
always @(posedge i_clk) begin
|
||||
if (i_reset) r_cic_type <= 8'd0;
|
||||
if (!i_reset && i_select && i_write_rq && i_address[2]) r_cic_type <= i_data[7:0];
|
||||
end
|
||||
|
||||
always @(posedge i_clk) begin
|
||||
o_ack <= !i_reset && i_select && (i_read_rq || i_write_rq);
|
||||
end
|
||||
|
||||
endmodule
|
||||
|
4
fw/rtl/intel/ram/ram_n64_eeprom.qip
Normal file
4
fw/rtl/intel/ram/ram_n64_eeprom.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_n64_eeprom.v"]
|
243
fw/rtl/intel/ram/ram_n64_eeprom.v
Normal file
243
fw/rtl/intel/ram/ram_n64_eeprom.v
Normal file
@ -0,0 +1,243 @@
|
||||
// megafunction wizard: %RAM: 2-PORT%
|
||||
// GENERATION: STANDARD
|
||||
// VERSION: WM1.0
|
||||
// MODULE: altsyncram
|
||||
|
||||
// ============================================================
|
||||
// File Name: ram_n64_eeprom.v
|
||||
// Megafunction Name(s):
|
||||
// altsyncram
|
||||
//
|
||||
// Simulation Library Files(s):
|
||||
// altera_mf
|
||||
// ============================================================
|
||||
// ************************************************************
|
||||
// THIS IS A WIZARD-GENERATED FILE. DO NOT EDIT THIS FILE!
|
||||
//
|
||||
// 20.1.0 Build 711 06/05/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_n64_eeprom (
|
||||
address_a,
|
||||
address_b,
|
||||
clock,
|
||||
data_a,
|
||||
data_b,
|
||||
wren_a,
|
||||
wren_b,
|
||||
q_a,
|
||||
q_b);
|
||||
|
||||
input [10:0] address_a;
|
||||
input [8:0] address_b;
|
||||
input clock;
|
||||
input [7:0] data_a;
|
||||
input [31:0] data_b;
|
||||
input wren_a;
|
||||
input wren_b;
|
||||
output [7: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 [7:0] sub_wire0;
|
||||
wire [31:0] sub_wire1;
|
||||
wire [7:0] q_a = sub_wire0[7: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 = 2048,
|
||||
altsyncram_component.numwords_b = 512,
|
||||
altsyncram_component.operation_mode = "BIDIR_DUAL_PORT",
|
||||
altsyncram_component.outdata_aclr_a = "NONE",
|
||||
altsyncram_component.outdata_aclr_b = "NONE",
|
||||
altsyncram_component.outdata_reg_a = "CLOCK0",
|
||||
altsyncram_component.outdata_reg_b = "CLOCK0",
|
||||
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 = 11,
|
||||
altsyncram_component.widthad_b = 9,
|
||||
altsyncram_component.width_a = 8,
|
||||
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 "16384"
|
||||
// Retrieval info: PRIVATE: MEM_IN_BITS NUMERIC "1"
|
||||
// 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 "1"
|
||||
// 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 "1"
|
||||
// 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 "1"
|
||||
// Retrieval info: PRIVATE: WIDTH_READ_A NUMERIC "8"
|
||||
// Retrieval info: PRIVATE: WIDTH_READ_B NUMERIC "32"
|
||||
// Retrieval info: PRIVATE: WIDTH_WRITE_A NUMERIC "8"
|
||||
// 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 "2048"
|
||||
// Retrieval info: CONSTANT: NUMWORDS_B NUMERIC "512"
|
||||
// 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 "CLOCK0"
|
||||
// Retrieval info: CONSTANT: OUTDATA_REG_B STRING "CLOCK0"
|
||||
// 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 "11"
|
||||
// Retrieval info: CONSTANT: WIDTHAD_B NUMERIC "9"
|
||||
// Retrieval info: CONSTANT: WIDTH_A NUMERIC "8"
|
||||
// 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 11 0 INPUT NODEFVAL "address_a[10..0]"
|
||||
// Retrieval info: USED_PORT: address_b 0 0 9 0 INPUT NODEFVAL "address_b[8..0]"
|
||||
// Retrieval info: USED_PORT: clock 0 0 0 0 INPUT VCC "clock"
|
||||
// Retrieval info: USED_PORT: data_a 0 0 8 0 INPUT NODEFVAL "data_a[7..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 8 0 OUTPUT NODEFVAL "q_a[7..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 11 0 address_a 0 0 11 0
|
||||
// Retrieval info: CONNECT: @address_b 0 0 9 0 address_b 0 0 9 0
|
||||
// Retrieval info: CONNECT: @clock0 0 0 0 0 clock 0 0 0 0
|
||||
// Retrieval info: CONNECT: @data_a 0 0 8 0 data_a 0 0 8 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 8 0 @q_a 0 0 8 0
|
||||
// Retrieval info: CONNECT: q_b 0 0 32 0 @q_b 0 0 32 0
|
||||
// Retrieval info: GEN_FILE: TYPE_NORMAL ram_n64_eeprom.v TRUE
|
||||
// Retrieval info: GEN_FILE: TYPE_NORMAL ram_n64_eeprom.inc FALSE
|
||||
// Retrieval info: GEN_FILE: TYPE_NORMAL ram_n64_eeprom.cmp FALSE
|
||||
// Retrieval info: GEN_FILE: TYPE_NORMAL ram_n64_eeprom.bsf FALSE
|
||||
// Retrieval info: GEN_FILE: TYPE_NORMAL ram_n64_eeprom_inst.v FALSE
|
||||
// Retrieval info: GEN_FILE: TYPE_NORMAL ram_n64_eeprom_bb.v FALSE
|
||||
// Retrieval info: LIB_FILE: altera_mf
|
210
fw/rtl/n64_si.v
Normal file
210
fw/rtl/n64_si.v
Normal file
@ -0,0 +1,210 @@
|
||||
module n64_si (
|
||||
input i_clk,
|
||||
input i_reset,
|
||||
|
||||
input i_si_clk,
|
||||
input i_si_reset,
|
||||
input i_si_dq,
|
||||
output reg o_si_dq,
|
||||
|
||||
input i_eeprom_select,
|
||||
input i_read_rq,
|
||||
input i_write_rq,
|
||||
output reg o_ack,
|
||||
input [31:0] i_address,
|
||||
input [31:0] i_data,
|
||||
output [31:0] o_data,
|
||||
|
||||
input i_eeprom_enable,
|
||||
input i_eeprom_16k_enable
|
||||
);
|
||||
|
||||
localparam CMD_EEPROM_STATUS = 8'h00;
|
||||
localparam CMD_EEPROM_READ = 8'h04;
|
||||
localparam CMD_EEPROM_WRITE = 8'h05;
|
||||
|
||||
localparam EEPROM_4K_ID = 8'h80;
|
||||
localparam EEPROM_16K_ID = 8'hC0;
|
||||
|
||||
reg r_last_si_clk;
|
||||
reg r_last_si_dq;
|
||||
|
||||
wire w_si_clk_falling_edge = !i_reset && !i_si_reset && r_last_si_clk && !i_si_clk;
|
||||
wire w_si_clk_rising_edge = !i_reset && !i_si_reset && !r_last_si_clk && i_si_clk;
|
||||
wire w_si_dq_falling_edge = r_last_si_dq && !i_si_dq;
|
||||
wire w_si_dq_rising_edge = !r_last_si_dq && i_si_dq;
|
||||
|
||||
always @(posedge i_clk) begin
|
||||
r_last_si_clk <= i_si_clk;
|
||||
if (w_si_clk_rising_edge) r_last_si_dq <= i_si_dq;
|
||||
end
|
||||
|
||||
// RX module
|
||||
|
||||
reg r_rx_enabled;
|
||||
reg [2:0] r_rx_sub_bit_counter;
|
||||
reg [2:0] r_rx_bit_counter;
|
||||
reg [3:0] r_rx_byte_counter;
|
||||
reg [7:0] r_rx_buffer;
|
||||
reg r_rx_byte_ready;
|
||||
reg r_rx_finished, r_last_rx_finished;
|
||||
|
||||
wire w_rx_sub_bit_counter_timeout = &r_rx_sub_bit_counter;
|
||||
wire w_rx_bit_value = r_rx_sub_bit_counter <= 3'd4;
|
||||
wire w_rx_start = r_last_rx_finished && !r_rx_finished;
|
||||
wire w_rx_finish = !r_last_rx_finished && r_rx_finished;
|
||||
|
||||
always @(posedge i_clk) begin
|
||||
r_rx_byte_ready <= 1'b0;
|
||||
r_last_rx_finished <= r_rx_finished;
|
||||
|
||||
if (r_rx_enabled && w_si_clk_rising_edge) begin
|
||||
if (w_rx_sub_bit_counter_timeout) r_rx_finished <= 1'b1;
|
||||
else r_rx_sub_bit_counter <= r_rx_sub_bit_counter + 3'd1;
|
||||
|
||||
if (w_si_dq_falling_edge) begin
|
||||
r_rx_sub_bit_counter <= 3'd0;
|
||||
if (r_rx_finished) begin
|
||||
r_rx_bit_counter <= 3'd0;
|
||||
r_rx_byte_counter <= 4'b1111;
|
||||
end
|
||||
r_rx_finished <= 1'b0;
|
||||
end
|
||||
|
||||
if (w_si_dq_rising_edge) begin
|
||||
r_rx_bit_counter <= r_rx_bit_counter + 3'd1;
|
||||
r_rx_buffer <= {r_rx_buffer[6:0], w_rx_bit_value};
|
||||
if (&r_rx_bit_counter) begin
|
||||
r_rx_byte_counter <= r_rx_byte_counter + 4'd1;
|
||||
r_rx_byte_ready <= 1'b1;
|
||||
end
|
||||
end
|
||||
end
|
||||
end
|
||||
|
||||
reg r_tx_finished;
|
||||
|
||||
reg r_cmd_eeprom_status;
|
||||
reg r_cmd_eeprom_read;
|
||||
reg r_cmd_eeprom_write;
|
||||
|
||||
wire w_cmd_valid = r_cmd_eeprom_status || r_cmd_eeprom_read || r_cmd_eeprom_write;
|
||||
wire w_cmd_op = r_rx_byte_ready && r_rx_byte_counter == 4'd0;
|
||||
|
||||
always @(posedge i_clk) begin
|
||||
if (i_reset || i_si_reset || w_rx_start || r_tx_finished) begin
|
||||
r_cmd_eeprom_status <= 1'b0;
|
||||
r_cmd_eeprom_read <= 1'b0;
|
||||
r_cmd_eeprom_write <= 1'b0;
|
||||
end else if (w_cmd_op) begin
|
||||
if (i_eeprom_enable) begin
|
||||
r_cmd_eeprom_status <= r_rx_buffer == CMD_EEPROM_STATUS;
|
||||
r_cmd_eeprom_read <= r_rx_buffer == CMD_EEPROM_READ;
|
||||
r_cmd_eeprom_write <= r_rx_buffer == CMD_EEPROM_WRITE;
|
||||
end
|
||||
end
|
||||
end
|
||||
|
||||
reg r_eeprom_read_rq;
|
||||
reg [10:0] r_eeprom_address;
|
||||
|
||||
wire w_eeprom_write_op = r_rx_byte_ready && r_rx_byte_counter >= 4'd2 && r_cmd_eeprom_write;
|
||||
wire w_eeprom_address_op = r_rx_byte_ready && r_rx_byte_counter == 4'd1 && (r_cmd_eeprom_read || r_cmd_eeprom_write);
|
||||
wire w_eeprom_address_next_op = r_eeprom_read_rq || w_eeprom_write_op;
|
||||
|
||||
always @(posedge i_clk) begin
|
||||
if (w_eeprom_address_op) r_eeprom_address <= {r_rx_buffer, 3'b000};
|
||||
if (w_eeprom_address_next_op) r_eeprom_address[2:0] <= r_eeprom_address[2:0] + 3'd1;
|
||||
end
|
||||
|
||||
// TX module
|
||||
|
||||
reg [2:0] r_tx_sub_bit_counter;
|
||||
reg [2:0] r_tx_bit_counter;
|
||||
reg [3:0] r_tx_byte_counter;
|
||||
reg [3:0] r_tx_bytes_to_send;
|
||||
reg [7:0] r_tx_data;
|
||||
|
||||
wire [7:0] w_eeprom_o_data;
|
||||
|
||||
wire w_tx_current_bit = r_tx_data[3'd7 - r_tx_bit_counter];
|
||||
wire w_tx_stop_bit = r_tx_byte_counter == r_tx_bytes_to_send;
|
||||
|
||||
always @(*) begin
|
||||
r_tx_data = 8'h00;
|
||||
if (r_cmd_eeprom_status && r_tx_byte_counter == 4'd1) r_tx_data = i_eeprom_16k_enable ? EEPROM_16K_ID : EEPROM_4K_ID;
|
||||
if (r_cmd_eeprom_read) r_tx_data = w_eeprom_o_data;
|
||||
end
|
||||
|
||||
always @(posedge i_clk) begin
|
||||
if (i_reset || i_si_reset) begin
|
||||
o_si_dq <= 1'b1;
|
||||
r_rx_enabled <= 1'b1;
|
||||
r_tx_finished <= 1'b0;
|
||||
r_eeprom_read_rq <= 1'b0;
|
||||
end else begin
|
||||
r_tx_finished <= 1'b0;
|
||||
r_eeprom_read_rq <= 1'b0;
|
||||
|
||||
if (w_rx_finish && w_cmd_valid) begin
|
||||
r_rx_enabled <= 1'b0;
|
||||
r_tx_sub_bit_counter <= 3'd0;
|
||||
r_tx_bit_counter <= 3'd0;
|
||||
r_tx_byte_counter <= 4'd0;
|
||||
r_tx_bytes_to_send <= 4'd0;
|
||||
if (r_cmd_eeprom_status) r_tx_bytes_to_send <= 4'd3;
|
||||
if (r_cmd_eeprom_read) r_tx_bytes_to_send <= 4'd8;
|
||||
if (r_cmd_eeprom_write) r_tx_bytes_to_send <= 4'd1;
|
||||
end
|
||||
|
||||
if (!r_rx_enabled) begin
|
||||
if (w_si_clk_falling_edge) begin
|
||||
r_tx_sub_bit_counter <= r_tx_sub_bit_counter + 3'd1;
|
||||
|
||||
if (r_tx_sub_bit_counter == 3'd0) o_si_dq <= 1'b0;
|
||||
|
||||
if ((w_tx_current_bit && r_tx_sub_bit_counter == 3'd2) ||
|
||||
(!w_tx_current_bit && r_tx_sub_bit_counter == 3'd6) ||
|
||||
(w_tx_stop_bit && r_tx_sub_bit_counter == 3'd4)) begin
|
||||
o_si_dq <= 1'b1;
|
||||
end
|
||||
|
||||
if (&r_tx_sub_bit_counter) begin
|
||||
if (w_tx_stop_bit) begin
|
||||
r_rx_enabled <= 1'b1;
|
||||
r_tx_finished <= 1'b1;
|
||||
end
|
||||
r_tx_bit_counter <= r_tx_bit_counter + 3'd1;
|
||||
if (&r_tx_bit_counter) begin
|
||||
r_eeprom_read_rq <= 1'b1;
|
||||
r_tx_byte_counter <= r_tx_byte_counter + 4'd1;
|
||||
end
|
||||
end
|
||||
end
|
||||
end
|
||||
end
|
||||
end
|
||||
|
||||
// Block RAM
|
||||
|
||||
ram_n64_eeprom ram_n64_eeprom_inst (
|
||||
.clock(i_clk),
|
||||
|
||||
.address_a(r_eeprom_address),
|
||||
.data_a(r_rx_buffer),
|
||||
.wren_a(w_eeprom_write_op),
|
||||
.q_a(w_eeprom_o_data),
|
||||
|
||||
.address_b(i_address[10:2]),
|
||||
.data_b({i_data[7:0], i_data[15:8], i_data[23:16], i_data[31:24]}),
|
||||
.wren_b(!i_reset && i_eeprom_select && i_write_rq),
|
||||
.q_b({o_data[7:0], o_data[15:8], o_data[23:16], o_data[31:24]})
|
||||
);
|
||||
|
||||
// Bus logic
|
||||
|
||||
always @(posedge i_clk) begin
|
||||
o_ack <= !i_reset && i_eeprom_select && (i_read_rq || i_write_rq);
|
||||
end
|
||||
|
||||
endmodule
|
107
fw/rtl/top.v
107
fw/rtl/top.v
@ -82,47 +82,19 @@ module top (
|
||||
reg r_n64_write_ff1, r_n64_write_ff2;
|
||||
|
||||
reg r_n64_si_clk_ff1, r_n64_si_clk_ff2;
|
||||
reg r_n64_si_dq_ff1, r_n64_si_dq_ff2;
|
||||
|
||||
reg r_n64_cic_clk_ff1, r_n64_cic_clk_ff2;
|
||||
always @(posedge w_sys_clk) begin
|
||||
{r_n64_nmi_ff2, r_n64_nmi_ff1} <= {r_n64_nmi_ff1, i_n64_nmi};
|
||||
{r_n64_reset_ff2, r_n64_reset_ff1} <= {r_n64_reset_ff1, i_n64_reset};
|
||||
|
||||
always @(posedge w_sys_clk or posedge w_sys_reset) begin
|
||||
if (w_sys_reset) begin
|
||||
r_n64_nmi_ff1 <= 1'b0;
|
||||
r_n64_nmi_ff2 <= 1'b0;
|
||||
{r_n64_alel_ff2, r_n64_alel_ff1} <= {r_n64_alel_ff1, i_n64_pi_alel};
|
||||
{r_n64_aleh_ff2, r_n64_aleh_ff1} <= {r_n64_aleh_ff1, i_n64_pi_aleh};
|
||||
{r_n64_read_ff2, r_n64_read_ff1} <= {r_n64_read_ff1, i_n64_pi_read};
|
||||
{r_n64_write_ff2, r_n64_write_ff1} <= {r_n64_write_ff1, i_n64_pi_write};
|
||||
|
||||
r_n64_reset_ff1 <= 1'b0;
|
||||
r_n64_reset_ff2 <= 1'b0;
|
||||
|
||||
r_n64_alel_ff1 <= 1'b0;
|
||||
r_n64_alel_ff2 <= 1'b0;
|
||||
|
||||
r_n64_aleh_ff1 <= 1'b0;
|
||||
r_n64_aleh_ff2 <= 1'b0;
|
||||
|
||||
r_n64_read_ff1 <= 1'b0;
|
||||
r_n64_read_ff2 <= 1'b0;
|
||||
|
||||
r_n64_write_ff1 <= 1'b0;
|
||||
r_n64_write_ff2 <= 1'b0;
|
||||
|
||||
r_n64_si_clk_ff1 <= 1'b0;
|
||||
r_n64_si_clk_ff2 <= 1'b0;
|
||||
|
||||
r_n64_cic_clk_ff1 <= 1'b0;
|
||||
r_n64_cic_clk_ff2 <= 1'b0;
|
||||
end else begin
|
||||
{r_n64_nmi_ff2, r_n64_nmi_ff1} <= {r_n64_nmi_ff1, i_n64_nmi};
|
||||
{r_n64_reset_ff2, r_n64_reset_ff1} <= {r_n64_reset_ff1, i_n64_reset};
|
||||
|
||||
{r_n64_alel_ff2, r_n64_alel_ff1} <= {r_n64_alel_ff1, i_n64_pi_alel};
|
||||
{r_n64_aleh_ff2, r_n64_aleh_ff1} <= {r_n64_aleh_ff1, i_n64_pi_aleh};
|
||||
{r_n64_read_ff2, r_n64_read_ff1} <= {r_n64_read_ff1, i_n64_pi_read};
|
||||
{r_n64_write_ff2, r_n64_write_ff1} <= {r_n64_write_ff1, i_n64_pi_write};
|
||||
|
||||
{r_n64_si_clk_ff2, r_n64_si_clk_ff1} <= {r_n64_si_clk_ff1, i_n64_si_clk};
|
||||
|
||||
{r_n64_cic_clk_ff2, r_n64_cic_clk_ff1} <= {r_n64_cic_clk_ff1, i_n64_cic_clk};
|
||||
end
|
||||
{r_n64_si_clk_ff2, r_n64_si_clk_ff1} <= {r_n64_si_clk_ff1, i_n64_si_clk};
|
||||
{r_n64_si_dq_ff2, r_n64_si_dq_ff1} <= {r_n64_si_dq_ff1, io_n64_si_dq};
|
||||
end
|
||||
|
||||
// Tri-state connection management
|
||||
@ -164,7 +136,6 @@ module top (
|
||||
|
||||
// Temporary assignments
|
||||
|
||||
assign w_n64_si_dq_o = 1'b1;
|
||||
assign w_n64_cic_dq_o = 1'b1;
|
||||
assign w_sd_cmd_mode = 1'b0;
|
||||
assign w_sd_dat_mode = 2'b00;
|
||||
@ -188,15 +159,15 @@ module top (
|
||||
wire [31:0] w_pc_i_data;
|
||||
wire [31:0] w_pc_o_data;
|
||||
|
||||
wire w_n64_disable;
|
||||
|
||||
wire w_bus_read_rq;
|
||||
wire w_bus_write_rq;
|
||||
wire w_bus_ack;
|
||||
wire [31:0] w_bus_address;
|
||||
wire [31:0] w_bus_i_data;
|
||||
reg [31:0] r_bus_i_data;
|
||||
wire [31:0] w_bus_o_data;
|
||||
|
||||
wire w_n64_disable;
|
||||
|
||||
assign w_n64_ack = !w_n64_disable && w_bus_ack;
|
||||
assign w_pc_ack = w_n64_disable && w_bus_ack;
|
||||
|
||||
@ -209,9 +180,13 @@ module top (
|
||||
wire w_flash_select;
|
||||
wire w_flash_cfg_select;
|
||||
wire w_sdram_select;
|
||||
wire w_eeprom_select;
|
||||
|
||||
wire w_flash_enable;
|
||||
wire w_sdram_enable;
|
||||
wire w_eeprom_pi_enable;
|
||||
wire w_eeprom_enable;
|
||||
wire w_eeprom_16k_enable;
|
||||
|
||||
wire w_address_valid;
|
||||
|
||||
@ -224,12 +199,20 @@ module top (
|
||||
wire w_sdram_ack;
|
||||
wire [31:0] w_sdram_o_data;
|
||||
|
||||
wire w_eeprom_ack;
|
||||
wire [31:0] w_eeprom_o_data;
|
||||
|
||||
reg r_empty_ack;
|
||||
|
||||
assign w_bus_ack = w_cart_config_ack || w_flash_ack || w_sdram_ack || r_empty_ack;
|
||||
assign w_bus_i_data = w_cart_config_select ? w_cart_config_o_data :
|
||||
(w_flash_select || w_flash_cfg_select) ? w_flash_o_data :
|
||||
w_sdram_select ? w_sdram_o_data : 32'hFFFF_FFFF;
|
||||
assign w_bus_ack = w_cart_config_ack || w_flash_ack || w_sdram_ack || w_eeprom_ack || r_empty_ack;
|
||||
|
||||
always @(*) begin
|
||||
r_bus_i_data = 32'hFFFF_FFFF;
|
||||
if (w_cart_config_select) r_bus_i_data = w_cart_config_o_data;
|
||||
if (w_flash_select || w_flash_cfg_select) r_bus_i_data = w_flash_o_data;
|
||||
if (w_sdram_select) r_bus_i_data = w_sdram_o_data;
|
||||
if (w_eeprom_select) r_bus_i_data = w_eeprom_o_data;
|
||||
end
|
||||
|
||||
always @(posedge w_sys_clk) begin
|
||||
r_empty_ack <= !w_address_valid && (w_bus_read_rq || w_bus_write_rq);
|
||||
@ -264,7 +247,7 @@ module top (
|
||||
.o_write_rq(w_pc_write_rq),
|
||||
.i_ack(w_pc_ack),
|
||||
.o_address(w_pc_address),
|
||||
.i_data(w_bus_i_data),
|
||||
.i_data(r_bus_i_data),
|
||||
.o_data(w_pc_o_data),
|
||||
|
||||
.i_bus_active(w_bus_active),
|
||||
@ -287,12 +270,33 @@ module top (
|
||||
.o_write_rq(w_n64_write_rq),
|
||||
.i_ack(w_n64_ack),
|
||||
.o_address(w_n64_address),
|
||||
.i_data(w_bus_i_data),
|
||||
.i_data(r_bus_i_data),
|
||||
.o_data(w_n64_o_data),
|
||||
|
||||
.i_address_valid(w_address_valid)
|
||||
);
|
||||
|
||||
n64_si n64_si_inst (
|
||||
.i_clk(w_sys_clk),
|
||||
.i_reset(w_sys_reset),
|
||||
|
||||
.i_si_clk(r_n64_si_clk_ff2),
|
||||
.i_si_reset(~r_n64_reset_ff2),
|
||||
.i_si_dq(r_n64_si_dq_ff2),
|
||||
.o_si_dq(w_n64_si_dq_o),
|
||||
|
||||
.i_eeprom_select(w_eeprom_select),
|
||||
.i_read_rq(w_bus_read_rq),
|
||||
.i_write_rq(w_bus_write_rq),
|
||||
.o_ack(w_eeprom_ack),
|
||||
.i_address(w_bus_address),
|
||||
.i_data(w_bus_o_data),
|
||||
.o_data(w_eeprom_o_data),
|
||||
|
||||
.i_eeprom_enable(w_eeprom_enable),
|
||||
.i_eeprom_16k_enable(w_eeprom_16k_enable)
|
||||
);
|
||||
|
||||
address_decoder address_decoder_inst (
|
||||
.i_address(w_bus_address),
|
||||
|
||||
@ -300,9 +304,11 @@ module top (
|
||||
.o_flash(w_flash_select),
|
||||
.o_flash_cfg(w_flash_cfg_select),
|
||||
.o_sdram(w_sdram_select),
|
||||
.o_eeprom(w_eeprom_select),
|
||||
|
||||
.i_flash_enable(w_flash_enable),
|
||||
.i_sdram_enable(w_sdram_enable),
|
||||
.i_eeprom_pi_enable(w_eeprom_pi_enable),
|
||||
|
||||
.o_address_valid(w_address_valid)
|
||||
);
|
||||
@ -325,7 +331,10 @@ module top (
|
||||
.i_n64_disabled(w_n64_disable),
|
||||
|
||||
.o_flash_enable(w_flash_enable),
|
||||
.o_sdram_enable(w_sdram_enable)
|
||||
.o_sdram_enable(w_sdram_enable),
|
||||
.o_eeprom_pi_enable(w_eeprom_pi_enable),
|
||||
.o_eeprom_enable(w_eeprom_enable),
|
||||
.o_eeprom_16k_enable(w_eeprom_16k_enable)
|
||||
);
|
||||
|
||||
flash flash_inst (
|
||||
|
Loading…
Reference in New Issue
Block a user