URL
https://opencores.org/ocsvn/vg_z80_sbc/vg_z80_sbc/trunk
Subversion Repositories vg_z80_sbc
[/] [vg_z80_sbc/] [trunk/] [rtl/] [wb_mmu.v] - Rev 4
Go to most recent revision | Compare with Previous | Blame | View Log
////////////////////////////////////////////////////////////////////// //// //// //// $Id: wb_mmu.v,v 1.2 2008-12-02 15:15:37 hharte Exp $ //// //// wb_mmu.v - Simple Memory Mapping Unit with Wishbone //// //// Slave interface for configuration. //// //// //// //// This file is part of the Vector Graphic Z80 SBC Project //// //// http://www.opencores.org/projects/vg_z80_sbc/ //// //// //// //// Author: //// //// - Howard M. Harte (hharte@opencores.org) //// //// //// ////////////////////////////////////////////////////////////////////// //// //// //// Copyright (C) 2008 Howard M. Harte //// //// //// //// This source file may be used and distributed without //// //// restriction provided that this copyright statement is not //// //// removed from the file and that any derivative work contains //// //// the original copyright notice and the associated disclaimer. //// //// //// //// This source file is free software; you can redistribute it //// //// and/or modify it under the terms of the GNU Lesser General //// //// Public License as published by the Free Software Foundation; //// //// either version 2.1 of the License, or (at your option) any //// //// later version. //// //// //// //// This source 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 Lesser General Public License for more //// //// details. //// //// //// //// You should have received a copy of the GNU Lesser General //// //// Public License along with this source; if not, download it //// //// from http://www.opencores.org/lgpl.shtml //// //// //// ////////////////////////////////////////////////////////////////////// //+---------------------------------------------------------------------------+ //| //| Simple Memory Mapping Unit (MMU) for allowing a CPU with a 16-bit address //| space to access a 16MB address space, using 16 4K pages. //| //| The MMU has a table of 16 4K "pages" that can be map an address in the //| 64K space into a corresponding address in a 16MB space. Each 4K page can //| map to any 4K boundary in a 16MB (24-bit) physical address space. //| //| The MMU occupies four byte-wide memory locations, and must be accessed as //| bytes. The registers are as follows: //| //| 0 - MMR_L Lower 8-bits = MMR_L <ll> //| 1 - MMR_H Upper 4-bits = MMR_H <h> //| 2 - ADR_INDEX (0x0-0xF to select the memory region modified by the MMR_x //| registers. This register defaults to 0 at reset. //| 3 - LOCK Writing 0xA5 to this register unlocks to MMU, any other //| value locks it. When locked, the MMR_L, MMR_H registers //| are read-only. Reading the LOCK register returns 0x51 //| if locked, 0x50 if unlocked. The MMU is locked on reset. //| //| The MMU forms the final 24-bit address on the 4K page as follows: //| //| <pxxx> - 64K unmapped address (mmu_adr_i) //| <h>:<llxxx> - 16M mapped address (mmu_adr_o) //| //| where: p = 4K page in 64K address space //| h = MMR_H register //| l = MMR_L register //| x = address bits passed through the MMU unchanged. //| //+---------------------------------------------------------------------------+ module wb_mmu( clk_i, nrst_i, wbs_adr_i, wbs_dat_o, wbs_dat_i, wbs_sel_i, wbs_we_i, wbs_stb_i, wbs_cyc_i, wbs_ack_o, mmu_adr_i, mmu_adr_o ); // // Default address and data bus width // parameter aw = 10; //number of address-bits parameter dw = 32; //number of data-bits // Wishbone Slave Interface input clk_i; input nrst_i; input [aw-1:0] wbs_adr_i; output reg [dw-1:0] wbs_dat_o; input [dw-1:0] wbs_dat_i; input [3:0] wbs_sel_i; input wbs_we_i; input wbs_stb_i; input wbs_cyc_i; output reg wbs_ack_o; // MMU Address Interface output [23:0] mmu_adr_o; input [23:0] mmu_adr_i; // Internal storage for mapping and state information reg [11:0] mmu_lut[0:15]; reg [3:0] adr_index; reg mmu_lock; // // generate wishbone register bank writes wire wbs_acc = wbs_cyc_i & wbs_stb_i; // WISHBONE access wire wbs_wr = wbs_acc & wbs_we_i; // WISHBONE write access wire wbs_rd = wbs_acc & !wbs_we_i; // WISHBONE read access reg [4:0] i; always @(posedge clk_i or negedge nrst_i) if(~nrst_i) // Reset begin wbs_ack_o <= 1'b0; adr_index <= 4'b0; mmu_lock <= 1'b1; // Lock MMU on reset // Initial values for MMU mapping table. mmu_lut[0] <= 12'h101; // 0x0xxx - Shadow of Monitor, only used to jump to monitor at 0xE000. // But not the same copy as at E000, because the init patches RST38. mmu_lut[1] <= 12'h102; // 0x1000 mmu_lut[2] <= 12'h103; // 0x2000 mmu_lut[3] <= 12'h101; // 0x3000 mmu_lut[4] <= 12'h102; // 0x4000 mmu_lut[5] <= 12'h103; // 0x5000 mmu_lut[6] <= 12'h101; // 0x6000 mmu_lut[7] <= 12'h102; // 0x7000 mmu_lut[8] <= 12'h803; // 0x8000 mmu_lut[9] <= 12'h809; // 0x9000 mmu_lut[10] <= 12'h80A; // 0xA000 mmu_lut[11] <= 12'h80B; // 0xB000 mmu_lut[12] <= 12'h200; // 0xC000 - FLASH (ZMON) mmu_lut[13] <= 12'hF02; // 0xD000 - MMU mmu_lut[14] <= 12'h100; // 0xE000 - FLASH (MON4.3) mmu_lut[15] <= 12'h600; // 0xF000 - VGA end else begin if(wbs_wr) // Wishbone Write, decode byte enables to determine register offset. case(wbs_sel_i) 4'b0001: begin // Data L Register if(mmu_lock == 1'b0) mmu_lut[adr_index[3:0]][7:0] <= wbs_dat_i[7:0]; end 4'b0010: begin // Data H Register if(mmu_lock == 1'b0) mmu_lut[adr_index[3:0]][11:8] <= wbs_dat_i[11:8]; end 4'b0100: begin // Index Register adr_index <= wbs_dat_i[19:16]; end 4'b1000: begin // Lock Register if(wbs_dat_i[31:24] == 8'hA5) begin mmu_lock <= 1'b0; end else begin mmu_lock <= 1'b1; end end endcase if(wbs_rd) begin case(wbs_sel_i) // Wishbone Read, decode byte enables to determine register offset. 4'b0001: begin // Data L Register wbs_dat_o <= {20'b0, mmu_lut[adr_index[3:0]]}; end 4'b0010: begin // Data H Register wbs_dat_o <= {20'b0, mmu_lut[adr_index[3:0]]}; end 4'b0100: begin // Index Register wbs_dat_o <= {20'b0, adr_index, 8'b0}; end 4'b1000: begin // Lock Register wbs_dat_o <= {4'h5, 3'b0, mmu_lock, 24'b0}; end endcase end wbs_ack_o <= #1 wbs_acc & !wbs_ack_o; end // Make the address mapping based on the MMU input address. wire [11:0] mmu_out = { mmu_lut[mmu_adr_i[15:12]] }; // Output the mapped address with the lower 12-bits passed through. assign mmu_adr_o = {mmu_out[11:0], mmu_adr_i[11:0]}; endmodule
Go to most recent revision | Compare with Previous | Blame | View Log