2023-02-13 16:49:17 +00:00
|
|
|
/* memory.v - implementation of memory external to the 9086 CPU for testing purposes
|
|
|
|
|
|
|
|
This file is part of the 9086 project.
|
|
|
|
|
|
|
|
Copyright (c) 2023 Efthymios Kritikos
|
|
|
|
|
|
|
|
This program is free software: you can redistribute it and/or modify
|
|
|
|
it under the terms of the GNU General Public License as published by
|
|
|
|
the Free Software Foundation, either version 3 of the License, or
|
|
|
|
(at your option) any later version.
|
|
|
|
|
|
|
|
This program is distributed in the hope that it will be useful,
|
|
|
|
but WITHOUT ANY WARRANTY; without even the implied warranty of
|
|
|
|
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
|
|
|
GNU General Public License for more details.
|
|
|
|
|
|
|
|
You should have received a copy of the GNU General Public License
|
|
|
|
along with this program. If not, see <http://www.gnu.org/licenses/>. */
|
|
|
|
|
2023-05-03 23:48:55 +00:00
|
|
|
/* This warning is because we don't use the full address bus. */
|
2023-03-04 08:37:43 +00:00
|
|
|
/* verilator lint_off UNUSEDSIGNAL */
|
2023-12-03 19:24:12 +00:00
|
|
|
module doublemem
|
|
|
|
#(
|
|
|
|
parameter RAM_SIZE_IN_BYTES,
|
|
|
|
parameter ADDRESS_WIDTH=$clog2(RAM_SIZE_IN_BYTES)
|
|
|
|
)
|
|
|
|
( input [ ADDRESS_WIDTH-1 : 0 ] address,
|
|
|
|
output [15:0] cpu_read_data,
|
|
|
|
input [15:0] cpu_write_data,
|
|
|
|
input rd,
|
|
|
|
input wr,
|
|
|
|
input BHE,
|
|
|
|
input cs,
|
|
|
|
input clock
|
|
|
|
);
|
2023-03-04 08:37:43 +00:00
|
|
|
/* verilator lint_on UNUSEDSIGNAL */
|
|
|
|
|
2023-12-03 19:24:12 +00:00
|
|
|
reg [15:0] memory [0:(RAM_SIZE_IN_BYTES/2)-1];
|
|
|
|
|
2023-03-04 08:37:43 +00:00
|
|
|
|
2023-02-08 11:57:22 +00:00
|
|
|
initial begin
|
2023-11-02 00:29:14 +00:00
|
|
|
`ifndef YOSYS
|
2023-02-11 01:11:37 +00:00
|
|
|
string boot_code;
|
2023-02-16 01:46:22 +00:00
|
|
|
if(!$value$plusargs("BOOT_CODE=%s",boot_code))begin
|
|
|
|
$display("No boot code specified. Please add +BOOT_CODE=<path> to your vvp args");
|
|
|
|
$finish;
|
|
|
|
end
|
2023-12-07 16:39:04 +00:00
|
|
|
$readmemh(boot_code, memory,0,(RAM_SIZE_IN_BYTES/2)-1);
|
2023-11-02 00:29:14 +00:00
|
|
|
`else
|
|
|
|
//TODO: don't have it hard coded
|
2024-02-09 23:28:21 +00:00
|
|
|
$readmemh("../boot_code/i2c_bootloader.stxt", memory,0,(RAM_SIZE_IN_BYTES/2)-1); // 2KiB
|
2023-11-02 00:29:14 +00:00
|
|
|
`endif
|
2023-02-08 11:57:22 +00:00
|
|
|
end
|
2023-02-14 13:13:40 +00:00
|
|
|
|
2023-03-03 06:29:06 +00:00
|
|
|
|
2023-12-04 17:04:22 +00:00
|
|
|
`ifdef USE_HIGH_IMPEDANCE
|
|
|
|
assign cpu_read_data[7:0] = !address[0:0] & !rd & !cs ? memory[address[ADDRESS_WIDTH-1:1]][15:8] : `16'hz;
|
|
|
|
assign cpu_read_data[15:8] = !BHE & !rd & !cs ? memory[address[ADDRESS_WIDTH-1:1]][ 7:0] : `16'hz;
|
|
|
|
`else
|
|
|
|
assign cpu_read_data[7:0] = memory[address[ADDRESS_WIDTH-1:1]][15:8];
|
|
|
|
assign cpu_read_data[15:8] = memory[address[ADDRESS_WIDTH-1:1]][ 7:0];
|
|
|
|
`endif
|
2023-11-06 08:12:58 +00:00
|
|
|
|
2023-02-14 13:13:40 +00:00
|
|
|
|
2023-11-15 18:43:03 +00:00
|
|
|
always @(posedge clock) begin
|
|
|
|
if( cs == 0 && wr == 0) begin
|
2023-05-10 07:35:14 +00:00
|
|
|
if(BHE==0)
|
2023-12-03 19:24:12 +00:00
|
|
|
memory[address[ADDRESS_WIDTH-1:1]][7:0]<=cpu_write_data[15:8];
|
2023-05-10 07:35:14 +00:00
|
|
|
if(address[0]==0)
|
2023-12-03 19:24:12 +00:00
|
|
|
memory[address[ADDRESS_WIDTH-1:1]][15:8]<=cpu_write_data[7:0];
|
2023-05-10 07:35:14 +00:00
|
|
|
end
|
2023-02-14 13:13:40 +00:00
|
|
|
end
|
|
|
|
|
2023-02-08 11:57:22 +00:00
|
|
|
endmodule
|