diff --git a/hw/fpga/addr_decode.sv b/hw/fpga/addr_decode.sv index 01c32cb..2d012d0 100644 --- a/hw/fpga/addr_decode.sv +++ b/hw/fpga/addr_decode.sv @@ -5,7 +5,9 @@ module addr_decode( output logic hex_cs, output logic uart_cs, output logic irq_cs, - output logic board_io_cs + output logic board_io_cs, + output logic mm_cs1, + output logic mm_cs2 ); assign rom_cs = addr >= 16'h8000; @@ -13,6 +15,8 @@ assign sdram_cs = addr < 16'h7ff0; assign hex_cs = addr >= 16'h7ff0 && addr < 16'h7ff4; assign uart_cs = addr >= 16'h7ff4 && addr < 16'h7ff6; assign board_io_cs = addr == 16'h7ff6; +assign mm_cs2 = addr == 16'h7ff7; +assign mm_cs1 = addr >= 16'h7ff8 && addr < 16'h7ffc; assign irq_cs = addr == 16'h7fff; endmodule diff --git a/hw/fpga/memory_mapper.sv b/hw/fpga/memory_mapper.sv new file mode 100644 index 0000000..193911a --- /dev/null +++ b/hw/fpga/memory_mapper.sv @@ -0,0 +1,53 @@ +/* + * This is based off of the 74LS610, but is not identical. + Some of the inputs are flipped so that they are all active high, + and some outputs are reordered. + Notably, when MM is low, MA is present on MO0-MO4, not 8 to 11. + */ + +module memory_mapper( + input clk, + + input rw, + input cs, + + input MM_cs, + + input [3:0] RS, + + input [3:0] MA, + + input logic [11:0] data_in, + output logic [11:0] data_out, + + output logic [11:0] MO +); + +logic [11:0] RAM [16]; + +logic MM; + + +always_ff @(posedge clk) begin + if (MM_cs & ~rw) begin // can't read MM but do you really need too? + MM = |data_in; + end + + if (cs & ~rw) begin // write to registers + RAM[RS] <= data_in; + end else if (cs & rw) begin // read registers + data_out <= RAM[RS]; + end +end + + +always_comb begin + if (MM) begin // normal mode + MO = RAM[MA]; + end else begin // passthrough mode + MO = {8'b0, MA}; + end +end + +endmodule + diff --git a/hw/fpga/sdram.sv b/hw/fpga/sdram.sv index 522596f..6b28f40 100644 --- a/hw/fpga/sdram.sv +++ b/hw/fpga/sdram.sv @@ -2,7 +2,7 @@ module sdram( input rst, input clk_50, input cpu_clk, - input [15:0] addr, + input [23:0] addr, input sdram_cs, input rwb, input [7:0] data_in, @@ -84,4 +84,4 @@ sdram_platform u0 ( .sdram_wire_we_n(DRAM_WE_N) //.we_n ); -endmodule \ No newline at end of file +endmodule diff --git a/hw/fpga/super6502.qsf b/hw/fpga/super6502.qsf index 09cd0fc..fdb7289 100644 --- a/hw/fpga/super6502.qsf +++ b/hw/fpga/super6502.qsf @@ -350,6 +350,7 @@ set_location_assignment PIN_V22 -to DRAM_LDQM set_location_assignment PIN_U22 -to DRAM_RAS_N set_location_assignment PIN_J21 -to DRAM_UDQM set_location_assignment PIN_V20 -to DRAM_WE_N +set_global_assignment -name SYSTEMVERILOG_FILE memory_mapper.sv set_global_assignment -name SYSTEMVERILOG_FILE board_io.sv set_global_assignment -name SYSTEMVERILOG_FILE sdram.sv set_global_assignment -name QIP_FILE sdram_platform/synthesis/sdram_platform.qip diff --git a/hw/fpga/super6502.sv b/hw/fpga/super6502.sv index 896a501..01cf4b8 100644 --- a/hw/fpga/super6502.sv +++ b/hw/fpga/super6502.sv @@ -3,15 +3,15 @@ module super6502( input clk_50, input logic rst_n, input logic button_1, - + input logic [15:0] cpu_addr, inout logic [7:0] cpu_data, - + input logic cpu_vpb, input logic cpu_mlb, input logic cpu_rwb, input logic cpu_sync, - + output logic cpu_led, output logic cpu_resb, output logic cpu_rdy, @@ -20,9 +20,9 @@ module super6502( output logic cpu_phi2, output logic cpu_be, output logic cpu_nmib, - + output logic [6:0] HEX0, HEX1, HEX2, HEX3, HEX4, HEX5, - + input logic UART_RXD, output logic UART_TXD, @@ -42,7 +42,7 @@ module super6502( output DRAM_CAS_N, output DRAM_RAS_N ); - + logic rst; assign rst = ~rst_n; @@ -60,6 +60,7 @@ logic [7:0] sdram_data_out; logic [7:0] uart_data_out; logic [7:0] irq_data_out; logic [7:0] board_io_data_out; +logic [7:0] mm_data_out; logic sdram_cs; logic rom_cs; @@ -67,6 +68,8 @@ logic hex_cs; logic uart_cs; logic irq_cs; logic board_io_cs; +logic mm_cs1; +logic mm_cs2; cpu_clk cpu_clk( .inclk0(clk_50), @@ -84,6 +87,23 @@ assign cpu_be = '1; assign cpu_nmib = '1; assign cpu_irqb = irq_data_out == 0; +logic [11:0] mm_MO; + +logic [23:0] mm_address; +assign mm_address = {mm_MO, cpu_addr[11:0]}; + +memory_mapper memory_mapper( + .clk(clk), + .rw(cpu_rwb), + .cs(mm_cs1), + .MM_cs(mm_cs2), + .RS(cpu_addr[3:0]), + .MA(cpu_addr[15:12]), + .data_in(cpu_data_in), + .data_out(mm_data_out), + .MO(mm_MO) +); + addr_decode decode( .addr(cpu_addr), .sdram_cs(sdram_cs), @@ -91,7 +111,9 @@ addr_decode decode( .hex_cs(hex_cs), .uart_cs(uart_cs), .irq_cs(irq_cs), - .board_io_cs(board_io_cs) + .board_io_cs(board_io_cs), + .mm_cs1(mm_cs1), + .mm_cs2(mm_cs2) ); @@ -106,6 +128,8 @@ always_comb begin cpu_data_out = irq_data_out; else if (board_io_cs) cpu_data_out = board_io_data_out; + else if (mm_cs1) + cpu_data_out = mm_data_out; else cpu_data_out = 'x; end @@ -115,7 +139,7 @@ sdram sdram( .rst(rst), .clk_50(clk_50), .cpu_clk(cpu_phi2), - .addr(cpu_addr), + .addr(mm_address), .sdram_cs(sdram_cs), .rwb(cpu_rwb), .data_in(cpu_data_in), @@ -193,6 +217,6 @@ always_ff @(posedge clk_50) begin end end - + endmodule - \ No newline at end of file +