URL
https://opencores.org/ocsvn/s80186/s80186/trunk
Subversion Repositories s80186
[/] [s80186/] [trunk/] [rtl/] [LoadStore.sv] - Rev 2
Compare with Previous | Blame | View Log
// Copyright Jamie Iles, 2017//// This file is part of s80x86.//// s80x86 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.//// s80x86 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 s80x86. If not, see <http://www.gnu.org/licenses/>.module LoadStore(input logic clk,input logic reset,// Memory Address Registerinput logic write_mar,input logic [15:0] segment,input [15:0] mar_in,// Memory Data Registeroutput [15:0] mar_out,output [15:0] mdr_out,input logic write_mdr,input [15:0] mdr_in,// Memory busoutput logic [19:1] m_addr,input logic [15:0] m_data_in,output logic [15:0] m_data_out,output logic m_access,input logic m_ack,output logic m_wr_en,output logic [1:0] m_bytesel,// Controlinput logic io,input logic start,input logic is_8bit,input logic wr_en,output logic busy,output logic complete);reg [15:0] mar;reg [15:0] mdr;assign busy = (start | fetching | second_byte) & ~complete;assign m_access = (start | fetching | second_byte) & ~complete & ~m_ack;assign m_addr = !io ?{segment, 3'b0} + {3'b0, mar[15:1]} + {18'b0, second_byte} :{3'b0, mar[15:1]} + {18'b0, second_byte};assign m_wr_en = wr_en;assign mdr_out = mdr;assign mar_out = mar;always_comb beginif (unaligned && !second_byte)m_data_out = {mdr[7:0], 8'b0};else if (unaligned && second_byte)m_data_out = {8'b0, mdr[15:8]};elsem_data_out = mdr;endalways_comb beginif (!is_8bit && !unaligned)m_bytesel = 2'b11;else if (unaligned && !second_byte)m_bytesel = 2'b10;elsem_bytesel = 2'b01;endwire unaligned = mar[0];reg fetching;reg second_byte;always_ff @(posedge clk or posedge reset)if (reset)fetching <= 1'b0;elsefetching <= start ? 1'b1 : complete ? 1'b0 : fetching;always_ff @(posedge clk or posedge reset)if (reset)mar <= 16'b0;elsemar <= write_mar ? mar_in : mar;always_ff @(posedge clk)complete <= m_ack && (is_8bit || (unaligned && second_byte) || !unaligned);always_ff @(posedge clk or posedge reset)if (reset) beginsecond_byte <= 1'b0;end else beginif (m_ack && unaligned && !second_byte && !is_8bit)second_byte <= 1'b1;else if ((start && !fetching) || complete)second_byte <= 1'b0;endalways_ff @(posedge clk or posedge reset) beginif (reset)mdr <= 16'b0;else if (start && !fetching && !wr_en)mdr <= 16'b0;else if (write_mdr)mdr <= mdr_in;else if (!wr_en && m_ack && !unaligned)mdr <= is_8bit ? {8'b0, m_data_in[7:0]} : m_data_in;else if (!wr_en && m_ack && unaligned && !second_byte)mdr[7:0] <= unaligned ? m_data_in[15:8] : m_data_in[7:0];else if (!wr_en && m_ack && unaligned && second_byte)mdr[15:8] <= unaligned ? m_data_in[7:0] : m_data_in[15:8];endendmodule
