OpenCores
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] - Blame information for rev 35

Details | Compare with Previous | View Log

Line No. Rev Author Line
1 3 hharte
//////////////////////////////////////////////////////////////////////
2
////                                                              ////
3 29 hharte
////  $Id: wb_mmu.v,v 1.4 2008-12-15 06:42:44 hharte Exp $        ////
4 3 hharte
////  wb_mmu.v - Simple Memory Mapping Unit with Wishbone         ////
5
////             Slave interface for configuration.               ////
6
////                                                              ////
7
////  This file is part of the Vector Graphic Z80 SBC Project     ////
8
////  http://www.opencores.org/projects/vg_z80_sbc/               ////
9
////                                                              ////
10
////  Author:                                                     ////
11
////      - Howard M. Harte (hharte@opencores.org)                ////
12
////                                                              ////
13
//////////////////////////////////////////////////////////////////////
14
////                                                              ////
15
//// Copyright (C) 2008 Howard M. Harte                           ////
16
////                                                              ////
17
//// This source file may be used and distributed without         ////
18
//// restriction provided that this copyright statement is not    ////
19
//// removed from the file and that any derivative work contains  ////
20
//// the original copyright notice and the associated disclaimer. ////
21
////                                                              ////
22
//// This source file is free software; you can redistribute it   ////
23
//// and/or modify it under the terms of the GNU Lesser General   ////
24
//// Public License as published by the Free Software Foundation; ////
25
//// either version 2.1 of the License, or (at your option) any   ////
26
//// later version.                                               ////
27
////                                                              ////
28
//// This source is distributed in the hope that it will be       ////
29
//// useful, but WITHOUT ANY WARRANTY; without even the implied   ////
30
//// warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR      ////
31
//// PURPOSE.  See the GNU Lesser General Public License for more ////
32
//// details.                                                     ////
33
////                                                              ////
34
//// You should have received a copy of the GNU Lesser General    ////
35
//// Public License along with this source; if not, download it   ////
36
//// from http://www.opencores.org/lgpl.shtml                     ////
37
////                                                              ////
38
//////////////////////////////////////////////////////////////////////
39
 
40
//+---------------------------------------------------------------------------+
41
//|
42
//| Simple Memory Mapping Unit (MMU) for allowing a CPU with a 16-bit address
43
//| space to access a 16MB address space, using 16 4K pages.
44
//| 
45
//| The MMU has a table of 16 4K "pages" that can be map an address in the
46
//| 64K space into a corresponding address in a 16MB space.  Each 4K page can
47
//| map to any 4K boundary in a 16MB (24-bit) physical address space.
48
//| 
49
//| The MMU occupies four byte-wide memory locations, and must be accessed as
50
//| bytes.  The registers are as follows:
51
//|
52
//| 0 - MMR_L       Lower 8-bits = MMR_L  <ll>
53
//| 1 - MMR_H       Upper 4-bits = MMR_H  <h>
54
//| 2 - ADR_INDEX   (0x0-0xF to select the memory region modified by the MMR_x
55
//|                 registers.  This register defaults to 0 at reset.
56
//| 3 - LOCK        Writing 0xA5 to this register unlocks to MMU, any other
57
//|                 value locks it.  When locked, the MMR_L, MMR_H registers
58
//|                 are read-only.  Reading the LOCK register returns 0x51
59
//|                 if locked, 0x50 if unlocked.  The MMU is locked on reset.
60
//| 
61
//| The MMU forms the final 24-bit address on the 4K page as follows:
62
//|
63
//|      <pxxx> - 64K unmapped address (mmu_adr_i)
64
//| <h>:<llxxx> - 16M mapped address (mmu_adr_o)
65
//| 
66
//| where: p = 4K page in 64K address space
67
//|        h = MMR_H register
68
//|        l = MMR_L register
69
//|        x = address bits passed through the MMU unchanged.
70
//|
71
//+---------------------------------------------------------------------------+
72
module wb_mmu(
73
    clk_i, nrst_i, wbs_adr_i, wbs_dat_o, wbs_dat_i, wbs_sel_i, wbs_we_i,
74
    wbs_stb_i, wbs_cyc_i, wbs_ack_o,
75
    mmu_adr_i,
76 29 hharte
    mmu_adr_o,
77
    rom_sel_i
78 3 hharte
);
79 29 hharte
 
80
//`define USE_SERIAL_MONITOR  // Define to use MON4.0C Serial Monitor, 'G E80C' to boot floppy
81 3 hharte
    // Wishbone Slave Interface
82 4 hharte
    input          clk_i;
83
    input          nrst_i;
84 9 hharte
    input    [1:0] wbs_adr_i;
85
    output reg [7:0] wbs_dat_o;
86
    input    [7:0] wbs_dat_i;
87 4 hharte
    input    [3:0] wbs_sel_i;
88
    input          wbs_we_i;
89
    input          wbs_stb_i;
90
    input          wbs_cyc_i;
91
    output  reg    wbs_ack_o;
92 3 hharte
 
93
    // MMU Address Interface
94
    output  [23:0] mmu_adr_o;
95
    input   [23:0] mmu_adr_i;
96 29 hharte
 
97
    // Reset memory mapping selection
98
    input          rom_sel_i;
99 3 hharte
 
100
    // Internal storage for mapping and state information
101 4 hharte
    reg     [11:0] mmu_lut[0:15];
102
    reg      [3:0] adr_index;
103
    reg            mmu_lock;
104 3 hharte
 
105
    //
106
    // generate wishbone register bank writes
107
    wire wbs_acc = wbs_cyc_i & wbs_stb_i;    // WISHBONE access
108
    wire wbs_wr  = wbs_acc & wbs_we_i;       // WISHBONE write access
109
    wire wbs_rd  = wbs_acc & !wbs_we_i;      // WISHBONE read access
110 4 hharte
    reg      [4:0] i;
111 3 hharte
 
112
    always @(posedge clk_i or negedge nrst_i)
113 4 hharte
        if(~nrst_i) // Reset
114 3 hharte
        begin
115
            wbs_ack_o <= 1'b0;
116
            adr_index <= 4'b0;
117
            mmu_lock <= 1'b1;               // Lock MMU on reset
118 4 hharte
 
119 3 hharte
            // Initial values for MMU mapping table.
120 29 hharte
            mmu_lut[0]  <= 12'h100;      // 0x0xxx - Shadow of Monitor, only used to jump to monitor at 0xE000.
121 3 hharte
                                         // But not the same copy as at E000, because the init patches RST38.        
122 29 hharte
            mmu_lut[1]  <= 12'h201;      // 0x1000
123 9 hharte
            mmu_lut[2]  <= 12'h801;      // 0x2000
124
            mmu_lut[3]  <= 12'h802;      // 0x3000
125
            mmu_lut[4]  <= 12'h803;      // 0x4000
126
            mmu_lut[5]  <= 12'h804;      // 0x5000
127
            mmu_lut[6]  <= 12'h805;      // 0x6000
128
            mmu_lut[7]  <= 12'h806;      // 0x7000
129
            mmu_lut[8]  <= 12'h807;      // 0x8000
130
            mmu_lut[9]  <= 12'h808;      // 0x9000
131
            mmu_lut[10] <= 12'h809;      // 0xA000
132
            mmu_lut[11] <= 12'h200;      // 0xB000 - SRAM2-0
133 29 hharte
            mmu_lut[12] <= 12'h101;      // 0xC000 - SRAM0-3
134
`ifdef USE_SERIAL_MONITOR
135
            // Use Serial Monitor
136
            mmu_lut[13] <= 12'h103;  // 0xD000 - MON 4.3  (Flashwriter2 Monitor)
137
            mmu_lut[14] <= 12'h102;  // 0xE000 - MON 4.0c (Serial Monitor)
138
`else
139
            // Use Flashwriter2 Monitor
140
            mmu_lut[13] <= 12'h102;  // 0xD000 - MON 4.0c (Serial Monitor)
141
            mmu_lut[14] <= 12'h103;  // 0xE000 - MON 4.3  (Flashwriter2 Monitor)
142
`endif // USE_SERIAL_MONITOR
143 4 hharte
            mmu_lut[15] <= 12'h600;      // 0xF000 - VGA
144 3 hharte
        end
145
        else begin
146
            if(wbs_wr)  // Wishbone Write, decode byte enables to determine register offset.
147 9 hharte
                case(wbs_adr_i)
148
                    2'h0: begin   // Data L Register
149 3 hharte
                        if(mmu_lock == 1'b0)
150 9 hharte
                            mmu_lut[adr_index[3:0]][7:0] <= wbs_dat_i;
151 3 hharte
                    end
152 9 hharte
                    2'h1: begin   // Data H Register
153 3 hharte
                        if(mmu_lock == 1'b0)
154 9 hharte
                            mmu_lut[adr_index[3:0]][11:8] <= wbs_dat_i[3:0];
155 3 hharte
                    end
156 9 hharte
                    2'h2: begin   // Index Register
157
                        adr_index <= wbs_dat_i[3:0];
158 3 hharte
                    end
159 9 hharte
                    2'h3: begin   // Lock Register
160
                        if(wbs_dat_i == 8'hA5) begin
161 3 hharte
                            mmu_lock <= 1'b0;
162
                        end else begin
163
                            mmu_lock <= 1'b1;
164
                        end
165
                    end
166
                endcase
167
 
168
            if(wbs_rd) begin
169 9 hharte
                case(wbs_adr_i) // Wishbone Read, decode byte enables to determine register offset.
170
                    2'h0: begin   // Data L Register
171
                        wbs_dat_o <= mmu_lut[adr_index[3:0]][7:0];
172 3 hharte
                    end
173 9 hharte
                    2'h1: begin   // Data H Register
174
                        wbs_dat_o <= { 4'h0, mmu_lut[adr_index[3:0]][11:8] };
175 3 hharte
                    end
176 9 hharte
                    2'h2: begin   // Index Register
177
                        wbs_dat_o <= {4'b0, adr_index};
178 3 hharte
                    end
179 9 hharte
                    2'h3: begin   // Lock Register
180
                        wbs_dat_o <= {4'h5, 3'b0, mmu_lock};
181 3 hharte
                    end
182
                endcase
183
            end
184
 
185 29 hharte
            wbs_ack_o <= wbs_acc & !wbs_ack_o;
186 3 hharte
        end
187
 
188
    // Make the address mapping based on the MMU input address.
189
    wire [11:0] mmu_out = { mmu_lut[mmu_adr_i[15:12]] };
190
 
191
    // Output the mapped address with the lower 12-bits passed through.
192
    assign mmu_adr_o = {mmu_out[11:0], mmu_adr_i[11:0]};
193
 
194
endmodule
195
 
196
 

powered by: WebSVN 2.1.0

© copyright 1999-2024 OpenCores.org, equivalent to Oliscience, all rights reserved. OpenCores®, registered trademark.