OpenCores
URL https://opencores.org/ocsvn/raptor64/raptor64/trunk

Subversion Repositories raptor64

[/] [raptor64/] [trunk/] [rtl/] [verilog/] [SimpleMMU.v] - Blame information for rev 52

Details | Compare with Previous | View Log

Line No. Rev Author Line
1 52 robfinch
`timescale 1ns / 1ps
2
//=============================================================================
3
//        __
4
//   \\__/ o\    (C) 2011,2012  Robert Finch
5
//    \  __ /    All rights reserved.
6
//     \/_//     robfinch<remove>@opencores.org
7
//       ||
8
//  
9
//      SimpleMMU.v
10
//  - maps 128MB into 512 256kB blocks
11
//  - supports 32 tasks per mmu
12
//  
13
// This source file is free software: you can redistribute it and/or modify 
14
// it under the terms of the GNU Lesser General Public License as published 
15
// by the Free Software Foundation, either version 3 of the License, or     
16
// (at your option) any later version.                                      
17
//                                                                          
18
// This source file is distributed in the hope that it will be useful,      
19
// but WITHOUT ANY WARRANTY; without even the implied warranty of           
20
// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the            
21
// GNU General Public License for more details.                             
22
//                                                                          
23
// You should have received a copy of the GNU General Public License        
24
// along with this program.  If not, see <http://www.gnu.org/licenses/>.    
25
//                                                                          
26
//
27
// 20 block RAMs // 106 LUTs // 42 FF's // 190 MHz
28
//=============================================================================
29
//
30
module SimpleMMU(num, rst_i, clk_i, dma_i, kernel_mode, cyc_i, stb_i, ack_o, we_i, adr_i, dat_i, dat_o, rclk, pc_i, pc_o, ea_i, ea_o);
31
parameter pIOAddress = 24'hDC4000;
32
input [2:0] num;         // mmu number
33
input rst_i;                    // core reset
34
input clk_i;                    // clock
35
input dma_i;                    // 1=DMA cycle is active
36
input kernel_mode;              // 1=processor is in kernel mode
37
input cyc_i;                    // bus cycle active
38
input stb_i;                    // data transfer strobe
39
output ack_o;                   // data transfer acknowledge
40
input we_i;                             // write enable
41
input [23:0] adr_i;              // I/O register address
42
input [15:0] dat_i;              // data input
43
output [15:0] dat_o;     // data output
44
reg [15:0] dat_o;
45
input rclk;                             // read clock (~clk)
46
input [27:0] pc_i;               // program counter / instruction pointer input
47
output [27:0] pc_o;              // mapped version of program counter
48
reg [27:0] pc_o;
49
input [27:0] ea_i;               // effective data address input
50
output [27:0] ea_o;              // effective data address mapped
51
reg [27:0] ea_o;
52
 
53
reg map_enable;
54
reg forceHi;
55
reg su;                                 // 1= system
56
reg [3:0] fuse;
57
reg ofuse3;
58
reg [7:0] accessKey;
59
reg [7:0] operateKey;
60
reg [2:0] kvmmu;
61
reg ack1, ack2;
62
 
63
always @(posedge clk_i)
64
begin
65
        ack1 <= cs;
66
        ack2 <= ack1 & cs;
67
end
68
assign ack_o = cs ? (we_i ? 1'b1 : ack2) : 1'b0;
69
 
70
wire cs = cyc_i && stb_i && (adr_i[23:12]==pIOAddress[23:12]);
71
wire [7:0] oKey =
72
        dma_i ? 8'd1 :
73
        su ? 8'd0 :
74
        operateKey
75
        ;
76
reg [13:0] rmrad;
77
reg [13:0] rmra;
78
reg [13:0] rmrb;
79
wire [13:0] mwa = {accessKey[4:0],adr_i[9:1]};
80
wire [13:0] mrad = {accessKey[4:0],adr_i[9:1]};
81
wire [13:0] mra = {oKey[4:0],pc_i[26:18]};
82
wire [13:0] mrb = {oKey[4:0],ea_i[26:18]};
83
wire [9:0] mro0,mro1,mro2;
84
 
85
always @(posedge clk_i) rmrad <= mrad;
86
always @(posedge rclk) rmra <= mra;
87
always @(posedge rclk) rmrb <= mrb;
88
wire thisMMU = kvmmu==accessKey[7:5];
89
 
90
wire pe_stb;
91
wire pe_km;
92
edge_det u1 (.rst(rst_i), .clk(clk_i), .ce(1'b1), .i(stb_i), .pe(pe_stb), .ne(), .ee() );
93
edge_det u2 (.rst(rst_i), .clk(clk_i), .ce(1'b1), .i(kernel_mode), .pe(pe_km), .ne(), .ee() );
94
 
95
mapram u3
96
(
97
        .wclk(clk_i),
98
        .wr(cs & we_i & su & ~adr_i[10] & thisMMU),
99
        .wa(mwa),
100
        .i(dat_i[9:0]),
101
        .rclk(~clk_i),
102
        .ra0(mrad),
103
        .ra1(mra),
104
        .ra2(mrb),
105
        .o0(mro0),
106
        .o1(mro1),
107
        .o2(mro2)
108
);
109
 
110
always @(posedge clk_i)
111
if (rst_i) begin
112
        map_enable <= 1'b0;
113
        kvmmu <= 3'd0;
114
        su <= 1'b1;
115
        fuse <= 4'hF;
116
        ofuse3 <= 1'b1;
117
        accessKey <= 8'h00;
118
        operateKey <= 8'h00;
119
end
120
else begin
121
        ofuse3 <= fuse[3];
122
        if (!fuse[3] && !dma_i && pe_stb)
123
                fuse <= fuse - 4'd1;
124
        if (fuse[3] & !ofuse3)
125
                su <= 1'b0;
126
        else if (pe_km)
127
                su <= 1'b1;
128
 
129
        if (cs) begin
130
                if (we_i) begin
131
                        if (su) begin
132
                                casex(adr_i[10:0])
133
//                              11'b0xxxxxxxxxx:        if (thisMMU) map[mwa] <= dat_i[9:0];
134
                                11'h40x:        if (oKey==8'h00 && (adr_i[2:0]==num))
135
                                                                        kvmmu <= dat_i[2:0];
136
                                11'h412:        fuse <= dat_i[2:0];
137
                                11'h414:        accessKey <= dat_i[7:0];
138
                                11'h416:        operateKey <= dat_i[7:0];
139
                                11'h418:        map_enable <= dat_i[0];
140
                                endcase
141
                        end
142
                end
143
                else begin
144
                        if ((adr_i[2:0]==num) && oKey==8'd0 && adr_i[10:4]==7'b1000000)
145
                                dat_o <= {5'd0,kvmmu};
146
                        else if (thisMMU)
147
                                casex(adr_i[10:0])
148
                                11'b0xxxxxxxxxx:        dat_o <= mro0;
149
                                11'h410:        dat_o <= su;
150
                                11'h412:        dat_o <= fuse;
151
                                11'h414:        dat_o <= accessKey;
152
                                11'h416:        dat_o <= operateKey;
153
                                11'h418:        dat_o <= map_enable;
154
                                default:        dat_o <= 16'h0000;
155
                                endcase
156
                        else
157
                                dat_o <= 16'h0000;
158
                end
159
        end
160
        else
161
                dat_o <= 16'h0000;
162
end
163
 
164
always @(pc_i) pc_o[17:0] <= pc_i[17:0];
165
always @(ea_i) ea_o[17:0] <= ea_i[17:0];
166
 
167
always @(rmra or oKey or kvmmu or mro1 or cs or map_enable)
168
begin
169
        if (!map_enable)
170
                pc_o[27:18] <= pc_i[27:18];
171
        else if (kvmmu==oKey[7:5])
172
                pc_o[27:18] <= mro1;
173
        else
174
                pc_o[27:18] <= 10'h000;
175
end
176
 
177
always @(rmrb or oKey or kvmmu or mro2 or cs or cyc_i or ea_i or map_enable)
178
begin
179
        if (cyc_i|~map_enable)          // I/O cycles are not mapped
180
                ea_o[27:18] <= ea_i[27:18];
181
        else if (kvmmu==oKey[7:5])
182
                ea_o[27:18] <= mro2;
183
        else
184
                ea_o[27:18] <= 10'h000;
185
end
186
 
187
endmodule
188
 
189
module mapram(wclk, wr, wa, i, rclk, ra0, ra1, ra2, o0, o1, o2);
190
input wclk;
191
input wr;
192
input [13:0] wa;
193
input [9:0] i;
194
input rclk;
195
input [13:0] ra0;
196
input [13:0] ra1;
197
input [13:0] ra2;
198
output [9:0] o0;
199
output [9:0] o1;
200
output [9:0] o2;
201
 
202
reg [9:0] map [0:16383];
203
reg [13:0] rra0,rra1,rra2;
204
 
205
always @(posedge wclk)
206
        if (wr) map[wa] <= i;
207
always @(posedge rclk) rra0 <= ra0;
208
always @(posedge rclk) rra1 <= ra1;
209
always @(posedge rclk) rra2 <= ra2;
210
 
211
assign o0 = map[rra0];
212
assign o1 = map[rra1];
213
assign o2 = map[rra2];
214
 
215
endmodule

powered by: WebSVN 2.1.0

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