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

Subversion Repositories ao486

[/] [ao486/] [trunk/] [rtl/] [ao486/] [pipeline/] [read_segment.v] - Blame information for rev 2

Details | Compare with Previous | View Log

Line No. Rev Author Line
1 2 alfik
/*
2
 * Copyright (c) 2014, Aleksander Osman
3
 * All rights reserved.
4
 *
5
 * Redistribution and use in source and binary forms, with or without
6
 * modification, are permitted provided that the following conditions are met:
7
 *
8
 * * Redistributions of source code must retain the above copyright notice, this
9
 *   list of conditions and the following disclaimer.
10
 *
11
 * * Redistributions in binary form must reproduce the above copyright notice,
12
 *   this list of conditions and the following disclaimer in the documentation
13
 *   and/or other materials provided with the distribution.
14
 *
15
 * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
16
 * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
17
 * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
18
 * DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE
19
 * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
20
 * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR
21
 * SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER
22
 * CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY,
23
 * OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
24
 * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
25
 */
26
 
27
`include "defines.v"
28
 
29
module read_segment(
30
 
31
    //general input
32
    input       [63:0]  es_cache,
33
    input       [63:0]  cs_cache,
34
    input       [63:0]  ss_cache,
35
    input       [63:0]  ds_cache,
36
    input       [63:0]  fs_cache,
37
    input       [63:0]  gs_cache,
38
    input       [63:0]  tr_cache,
39
    input       [63:0]  ldtr_cache,
40
 
41
    input               es_cache_valid,
42
    input               cs_cache_valid,
43
    input               ss_cache_valid,
44
    input               ds_cache_valid,
45
    input               fs_cache_valid,
46
    input               gs_cache_valid,
47
 
48
    //address control
49
    input               address_stack_pop,
50
    input               address_stack_pop_next,
51
    input               address_enter_last,
52
    input               address_enter,
53
    input               address_leave,
54
 
55
    input               address_edi,
56
 
57
    //read control
58
    input               read_virtual,
59
    input               read_rmw_virtual,
60
    input               write_virtual_check,
61
 
62
    input       [31:0]  rd_address_effective,
63
    input               rd_address_effective_ready,
64
    input       [3:0]   read_length,
65
 
66
    input       [2:0]   rd_prefix_group_2_seg,
67
 
68
    //output
69
    output      [31:0]  tr_base,
70
    output      [31:0]  ldtr_base,
71
 
72
    output      [31:0]  tr_limit,
73
    output      [31:0]  ldtr_limit,
74
 
75
    output              rd_seg_gp_fault_init,
76
    output              rd_seg_ss_fault_init,
77
 
78
    output      [31:0]  rd_seg_linear
79
);
80
 
81
//------------------------------------------------------------------------------
82
 
83
wire [31:0] es_limit;
84
wire [31:0] cs_limit;
85
wire [31:0] ss_limit;
86
wire [31:0] ds_limit;
87
wire [31:0] fs_limit;
88
wire [31:0] gs_limit;
89
 
90
wire [31:0] es_base;
91
wire [31:0] cs_base;
92
wire [31:0] ss_base;
93
wire [31:0] ds_base;
94
wire [31:0] fs_base;
95
wire [31:0] gs_base;
96
 
97
wire [31:0] es_left;
98
wire [31:0] cs_left;
99
wire [31:0] ss_left;
100
wire [31:0] ds_left;
101
wire [31:0] fs_left;
102
wire [31:0] gs_left;
103
 
104
wire [2:0]  seg_select;
105
wire        seg_read;
106
wire        seg_write;
107
 
108
wire        seg_limit_overflow;
109
wire [4:0]  seg_left;
110
wire        seg_invalid_read_access;
111
wire        seg_invalid_write_access;
112
wire        seg_valid;
113
 
114
wire        seg_fault;
115
 
116
//------------------------------------------------------------------------------
117
 
118
//------------------------------------------------------------------------------
119
 
120
//------------------------------------------------------------------------------
121
 
122
assign es_limit    = es_cache[`DESC_BIT_G]? { es_cache[51:48], es_cache[15:0], 12'hFFF } : { 12'd0, es_cache[51:48], es_cache[15:0] };
123
assign cs_limit    = cs_cache[`DESC_BIT_G]? { cs_cache[51:48], cs_cache[15:0], 12'hFFF } : { 12'd0, cs_cache[51:48], cs_cache[15:0] };
124
assign ss_limit    = ss_cache[`DESC_BIT_G]? { ss_cache[51:48], ss_cache[15:0], 12'hFFF } : { 12'd0, ss_cache[51:48], ss_cache[15:0] };
125
assign ds_limit    = ds_cache[`DESC_BIT_G]? { ds_cache[51:48], ds_cache[15:0], 12'hFFF } : { 12'd0, ds_cache[51:48], ds_cache[15:0] };
126
assign fs_limit    = fs_cache[`DESC_BIT_G]? { fs_cache[51:48], fs_cache[15:0], 12'hFFF } : { 12'd0, fs_cache[51:48], fs_cache[15:0] };
127
assign gs_limit    = gs_cache[`DESC_BIT_G]? { gs_cache[51:48], gs_cache[15:0], 12'hFFF } : { 12'd0, gs_cache[51:48], gs_cache[15:0] };
128
assign tr_limit    = tr_cache  [`DESC_BIT_G]? {   tr_cache[51:48],   tr_cache[15:0], 12'hFFF } : { 12'd0, tr_cache  [51:48],   tr_cache[15:0] };
129
assign ldtr_limit  = ldtr_cache[`DESC_BIT_G]? { ldtr_cache[51:48], ldtr_cache[15:0], 12'hFFF } : { 12'd0, ldtr_cache[51:48], ldtr_cache[15:0] };
130
 
131
assign es_base     = { es_cache[63:56], es_cache[39:16] };
132
assign cs_base     = { cs_cache[63:56], cs_cache[39:16] };
133
assign ss_base     = { ss_cache[63:56], ss_cache[39:16] };
134
assign ds_base     = { ds_cache[63:56], ds_cache[39:16] };
135
assign fs_base     = { fs_cache[63:56], fs_cache[39:16] };
136
assign gs_base     = { gs_cache[63:56], gs_cache[39:16] };
137
assign tr_base     = {   tr_cache[63:56],   tr_cache[39:16] };
138
assign ldtr_base   = { ldtr_cache[63:56], ldtr_cache[39:16] };
139
 
140
// (CODE or not EXPAND-DOWN)
141
assign es_left = (es_cache[43] || !es_cache[42])? es_limit - rd_address_effective : { {16{es_cache[54]}}, 16'hFFFF } - rd_address_effective;
142
assign cs_left = (cs_cache[43] || !cs_cache[42])? cs_limit - rd_address_effective : { {16{cs_cache[54]}}, 16'hFFFF } - rd_address_effective;
143
assign ss_left = (ss_cache[43] || !ss_cache[42])? ss_limit - rd_address_effective : { {16{ss_cache[54]}}, 16'hFFFF } - rd_address_effective;
144
assign ds_left = (ds_cache[43] || !ds_cache[42])? ds_limit - rd_address_effective : { {16{ds_cache[54]}}, 16'hFFFF } - rd_address_effective;
145
assign fs_left = (fs_cache[43] || !fs_cache[42])? fs_limit - rd_address_effective : { {16{fs_cache[54]}}, 16'hFFFF } - rd_address_effective;
146
assign gs_left = (gs_cache[43] || !gs_cache[42])? gs_limit - rd_address_effective : { {16{gs_cache[54]}}, 16'hFFFF } - rd_address_effective;
147
 
148
//------------------------------------------------------------------------------
149
 
150
assign seg_select =
151
    (address_stack_pop || address_stack_pop_next || address_enter_last || address_enter || address_leave)?  3'd2 :
152
    (address_edi)?                                                                                          3'd0 :
153
                                                                                                            rd_prefix_group_2_seg;
154
 
155
assign seg_read  = read_virtual || read_rmw_virtual;
156
assign seg_write = read_rmw_virtual || write_virtual_check;
157
 
158
assign seg_limit_overflow =
159
    (seg_select == 3'd0 && (((es_cache[43] || !es_cache[42]) && rd_address_effective > es_limit) || (!es_cache[43] && es_cache[42] && (rd_address_effective <= es_limit || rd_address_effective > { {16{es_cache[54]}}, 16'hFFFF })))) ||
160
    (seg_select == 3'd1 && (((cs_cache[43] || !cs_cache[42]) && rd_address_effective > cs_limit) || (!cs_cache[43] && cs_cache[42] && (rd_address_effective <= cs_limit || rd_address_effective > { {16{cs_cache[54]}}, 16'hFFFF })))) ||
161
    (seg_select == 3'd2 && (((ss_cache[43] || !ss_cache[42]) && rd_address_effective > ss_limit) || (!ss_cache[43] && ss_cache[42] && (rd_address_effective <= ss_limit || rd_address_effective > { {16{ss_cache[54]}}, 16'hFFFF })))) ||
162
    (seg_select == 3'd3 && (((ds_cache[43] || !ds_cache[42]) && rd_address_effective > ds_limit) || (!ds_cache[43] && ds_cache[42] && (rd_address_effective <= ds_limit || rd_address_effective > { {16{ds_cache[54]}}, 16'hFFFF })))) ||
163
    (seg_select == 3'd4 && (((fs_cache[43] || !fs_cache[42]) && rd_address_effective > fs_limit) || (!fs_cache[43] && fs_cache[42] && (rd_address_effective <= fs_limit || rd_address_effective > { {16{fs_cache[54]}}, 16'hFFFF })))) ||
164
    (seg_select == 3'd5 && (((gs_cache[43] || !gs_cache[42]) && rd_address_effective > gs_limit) || (!gs_cache[43] && gs_cache[42] && (rd_address_effective <= gs_limit || rd_address_effective > { {16{gs_cache[54]}}, 16'hFFFF }))));
165
 
166
//NOTE: only valid for (not SYSTEM)
167
assign seg_left =
168
    (seg_select == 3'd0)?   ((es_left >= 32'd15)? 5'd16 : es_left[3:0] + 4'd1) :
169
    (seg_select == 3'd1)?   ((cs_left >= 32'd15)? 5'd16 : cs_left[3:0] + 4'd1) :
170
    (seg_select == 3'd2)?   ((ss_left >= 32'd15)? 5'd16 : ss_left[3:0] + 4'd1) :
171
    (seg_select == 3'd3)?   ((ds_left >= 32'd15)? 5'd16 : ds_left[3:0] + 4'd1) :
172
    (seg_select == 3'd4)?   ((fs_left >= 32'd15)? 5'd16 : fs_left[3:0] + 4'd1) :
173
                            ((gs_left >= 32'd15)? 5'd16 : gs_left[3:0] + 4'd1);
174
 
175
//NOTE: only valid for SEGMENT (not SYSTEM)
176
// for read: CODE and (not READABLE); for write: DATA and (not WRITABLE)
177
assign seg_invalid_read_access =
178
    (seg_select == 3'd0)?   (es_cache[43] && !es_cache[41]) :
179
    (seg_select == 3'd1)?   (cs_cache[43] && !cs_cache[41]) :
180
    (seg_select == 3'd2)?   (ss_cache[43] && !ss_cache[41]) :
181
    (seg_select == 3'd3)?   (ds_cache[43] && !ds_cache[41]) :
182
    (seg_select == 3'd4)?   (fs_cache[43] && !fs_cache[41]) :
183
                            (gs_cache[43] && !gs_cache[41]);
184
 
185
assign seg_invalid_write_access =
186
    (seg_select == 3'd0)?   (es_cache[43] || !es_cache[41]) :
187
    (seg_select == 3'd1)?   (cs_cache[43] || !cs_cache[41]) :
188
    (seg_select == 3'd2)?   (ss_cache[43] || !ss_cache[41]) :
189
    (seg_select == 3'd3)?   (ds_cache[43] || !ds_cache[41]) :
190
    (seg_select == 3'd4)?   (fs_cache[43] || !fs_cache[41]) :
191
                            (gs_cache[43] || !gs_cache[41]);
192
assign seg_valid =
193
    (seg_select == 3'd0)?   es_cache[`DESC_BIT_P] && es_cache_valid :
194
    (seg_select == 3'd1)?   cs_cache[`DESC_BIT_P] && cs_cache_valid :
195
    (seg_select == 3'd2)?   ss_cache[`DESC_BIT_P] && ss_cache_valid :
196
    (seg_select == 3'd3)?   ds_cache[`DESC_BIT_P] && ds_cache_valid :
197
    (seg_select == 3'd4)?   fs_cache[`DESC_BIT_P] && fs_cache_valid :
198
                            gs_cache[`DESC_BIT_P] && gs_cache_valid;
199
 
200
//------------------------------------------------------------------------------    
201
 
202
assign seg_fault =
203
    (rd_address_effective_ready && (seg_read || seg_write)) &&
204
    ((seg_invalid_read_access && seg_read) || (seg_invalid_write_access && seg_write) ||
205
     seg_limit_overflow || (seg_left < { 1'b0, read_length }) || ~(seg_valid));
206
 
207
assign rd_seg_gp_fault_init = seg_select != 3'd2 && seg_fault;
208
assign rd_seg_ss_fault_init = seg_select == 3'd2 && seg_fault;
209
 
210
//------------------------------------------------------------------------------
211
 
212
assign rd_seg_linear =
213
    (seg_select == 3'd0)?       es_base + rd_address_effective :
214
    (seg_select == 3'd1)?       cs_base + rd_address_effective :
215
    (seg_select == 3'd2)?       ss_base + rd_address_effective :
216
    (seg_select == 3'd3)?       ds_base + rd_address_effective :
217
    (seg_select == 3'd4)?       fs_base + rd_address_effective :
218
                                gs_base + rd_address_effective;
219
 
220
//------------------------------------------------------------------------------
221
 
222
// synthesis translate_off
223
wire _unused_ok = &{ 1'b0,
224
    es_cache[53:52], es_cache[46:44], es_cache[40],
225
    cs_cache[53:52], cs_cache[46:44], cs_cache[40],
226
    ss_cache[53:52], ss_cache[46:44], ss_cache[40],
227
    ds_cache[53:52], ds_cache[46:44], ds_cache[40],
228
    fs_cache[53:52], fs_cache[46:44], fs_cache[40],
229
    gs_cache[53:52], gs_cache[46:44], gs_cache[40],
230
    tr_cache[54:52], tr_cache[47:40],
231
    ldtr_cache[54:52], ldtr_cache[47:40],
232
    1'b0 };
233
// synthesis translate_on
234
 
235
//------------------------------------------------------------------------------
236
 
237
endmodule

powered by: WebSVN 2.1.0

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