/* 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 . */ /* This warning is because we don't use the full address bus. */ /* verilator lint_off UNUSEDSIGNAL */ 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 ); /* verilator lint_on UNUSEDSIGNAL */ reg [15:0] memory [0:(RAM_SIZE_IN_BYTES/2)-1]; initial begin `ifndef YOSYS string boot_code; if(!$value$plusargs("BOOT_CODE=%s",boot_code))begin $display("No boot code specified. Please add +BOOT_CODE= to your vvp args"); $finish; end $readmemh(boot_code, memory,0,(RAM_SIZE_IN_BYTES/2)-1); `else //TODO: don't have it hard coded $readmemh("../boot_code/i2c_bootloader.stxt", memory,0,(RAM_SIZE_IN_BYTES/2)-1); // 2KiB `endif end `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 always @(posedge clock) begin if( cs == 0 && wr == 0) begin if(BHE==0) memory[address[ADDRESS_WIDTH-1:1]][7:0]<=cpu_write_data[15:8]; if(address[0]==0) memory[address[ADDRESS_WIDTH-1:1]][15:8]<=cpu_write_data[7:0]; end end endmodule