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
|