URL
https://opencores.org/ocsvn/s80186/s80186/trunk
Subversion Repositories s80186
[/] [s80186/] [trunk/] [rtl/] [ModRMDecode.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 ModRMDecode(input logic clk,input logic reset,// Control.input logic start,output logic busy,output logic complete,input logic clear,// Resultsoutput logic [15:0] effective_address,output logic [2:0] regnum,output logic rm_is_reg,output logic [2:0] rm_regnum,output logic bp_as_base,// Registers.output logic [2:0] reg_sel[2],input logic [15:0] regs[2],// Fifo Read Port.output logic fifo_rd_en,input logic [7:0] fifo_rd_data,input logic fifo_empty,// Immediatesoutput logic immed_start,input logic immed_complete,output logic immed_is_8bit,input logic [15:0] immediate);reg [7:0] _modrm;reg _modrm_byte_read;reg _started;reg _registers_fetched;reg [15:0] _cached_effective_address;reg [15:0] _effective_address;wire _has_address = _mod != 2'b11;wire _fifo_valid = start & ~_modrm_byte_read & ~fifo_empty;wire [1:0] _mod = _fifo_valid ? fifo_rd_data[7:6] : _modrm[7:6];wire [2:0] _reg = _fifo_valid ? fifo_rd_data[5:3] : _modrm[5:3];wire [2:0] _rm = _fifo_valid ? fifo_rd_data[2:0] : _modrm[2:0];wire _has_immediate = (_rm == 3'b110 && _mod == 2'b00) || ^_mod;assign busy = (start | _started) & ~complete;assign complete = reset ? 1'b0 :(_modrm_byte_read || _fifo_valid) &&(!_has_address || _registers_fetched) &&(!_has_immediate || immed_complete);assign immed_start = _has_immediate && _modrm_byte_read;assign immed_is_8bit = _mod == 2'b01;assign effective_address = complete ? _effective_address : _cached_effective_address;always_comb begincase (_mod)2'b00: bp_as_base = (_rm == 3'b010 || _rm == 3'b011);2'b01: bp_as_base = (_rm == 3'b010 || _rm == 3'b011 || _rm == 3'b110);2'b10: bp_as_base = (_rm == 3'b010 || _rm == 3'b011 || _rm == 3'b110);default: bp_as_base = 1'b0;endcaseendalways_ff @(posedge clk or posedge reset) beginif (reset)_started <= 1'b0;else if (complete)_started <= 1'b0;else if (start)_started <= 1'b1;endalways_ff @(posedge clk or posedge reset)if (reset)_registers_fetched <= 1'b0;else if (complete)_registers_fetched <= 1'b0;else if (~fifo_empty & start & ~_modrm_byte_read)_registers_fetched <= 1'b1;always_comb begincase (_rm)3'b000, 3'b001, 3'b111: reg_sel[0] = BX;3'b010, 3'b011, 3'b110: reg_sel[0] = BP;3'b100: reg_sel[0] = SI;3'b101: reg_sel[0] = DI;endcasecase (_rm)3'b000, 3'b010: reg_sel[1] = SI;3'b001, 3'b011: reg_sel[1] = DI;default: reg_sel[1] = 0;endcaseendalways_comb beginregnum = _reg;rm_regnum = _rm;rm_is_reg = 1'b0;_effective_address = 16'b0;case (_mod)2'b00: begincase (_rm)3'b000, 3'b001, 3'b010, 3'b011: _effective_address = regs[0] + regs[1];3'b100, 3'b101, 3'b111: _effective_address = regs[0];3'b110: _effective_address = immediate;endcaseend2'b01, 2'b10: begincase (_rm)3'b000, 3'b001, 3'b010, 3'b011: _effective_address = regs[0] + regs[1] + immediate;3'b100, 3'b101, 3'b110, 3'b111: _effective_address = regs[0] + immediate;endcaseend2'b11: beginrm_regnum = _rm;rm_is_reg = 1'b1;endendcaseendalways_ff @(posedge clk)if (complete)_cached_effective_address <= _effective_address;always_ff @(posedge clk or posedge reset)if (reset)_modrm_byte_read <= 1'b0;else if (complete)_modrm_byte_read <= 1'b0;else if (fifo_rd_en)_modrm_byte_read <= 1;assign fifo_rd_en = ~fifo_empty & start & ~_modrm_byte_read;always_ff @(posedge clk or posedge reset)if (reset)_modrm <= 8'b0;else if (clear)_modrm <= 8'b0;else if (~fifo_empty & start & ~_modrm_byte_read)_modrm <= fifo_rd_data;endmodule
