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

Subversion Repositories yifive

[/] [yifive/] [trunk/] [caravel_yifive/] [verilog/] [rtl/] [syntacore/] [scr1/] [src/] [core/] [pipeline/] [scr1_pipe_lsu.sv] - Blame information for rev 21

Details | Compare with Previous | View Log

Line No. Rev Author Line
1 11 dinesha
/// Copyright by Syntacore LLC © 2016-2020. See LICENSE for details
2
/// @file       
3
/// @brief      Load/Store Unit (LSU)
4
///
5
 
6
//------------------------------------------------------------------------------
7
 //
8
 // Functionality:
9
 // - Performs load and store operations in Data Memory
10
 // - Generates DMEM address misalign and access fault exceptions
11
 // - Passes DMEM operations information to TDU and generates LSU breakpoint exception
12
 //
13
 // Structure:
14
 // - FSM
15
 // - Exceptions logic
16
 // - LSU <-> EXU interface
17
 // - LSU <-> DMEM interface
18
 // - LSU <-> TDU interface
19
 //
20
//------------------------------------------------------------------------------
21
 
22
`include "scr1_arch_description.svh"
23
`include "scr1_arch_types.svh"
24
`include "scr1_memif.svh"
25
`include "scr1_riscv_isa_decoding.svh"
26
`ifdef SCR1_TDU_EN
27
`include "scr1_tdu.svh"
28
`endif // SCR1_TDU_EN
29
 
30
module scr1_pipe_lsu (
31
    // Common
32
    input   logic                               rst_n,                      // LSU reset
33
    input   logic                               clk,                        // LSU clock
34
 
35
    // LSU <-> EXU interface
36
    input   logic                               exu2lsu_req_i,              // Request to LSU
37
    input   type_scr1_lsu_cmd_sel_e             exu2lsu_cmd_i,              // LSU command
38
    input   logic [`SCR1_XLEN-1:0]              exu2lsu_addr_i,             // Address of DMEM
39
    input   logic [`SCR1_XLEN-1:0]              exu2lsu_sdata_i,            // Data for store
40
    output  logic                               lsu2exu_rdy_o,              // LSU received DMEM response
41
    output  logic [`SCR1_XLEN-1:0]              lsu2exu_ldata_o,            // Load data
42
    output  logic                               lsu2exu_exc_o,              // Exception from LSU
43
    output  type_scr1_exc_code_e                lsu2exu_exc_code_o,         // Exception code
44
 
45
`ifdef SCR1_TDU_EN
46
    // LSU <-> TDU interface
47
    output  type_scr1_brkm_lsu_mon_s            lsu2tdu_dmon_o,             // Data address stream monitoring
48
    input   logic                               tdu2lsu_ibrkpt_exc_req_i,   // Instruction BP exception request
49
    input   logic                               tdu2lsu_dbrkpt_exc_req_i,   // Data BP exception request
50
`endif // SCR1_TDU_EN
51
 
52
    // LSU <-> DMEM interface
53
    output  logic                               lsu2dmem_req_o,             // Data memory request
54 21 dinesha
    output  logic                               lsu2dmem_cmd_o,             // Data memory command (READ/WRITE)
55
    output  logic [1:0]                         lsu2dmem_width_o,           // Data memory data width
56 11 dinesha
    output  logic [`SCR1_DMEM_AWIDTH-1:0]       lsu2dmem_addr_o,            // Data memory address
57
    output  logic [`SCR1_DMEM_DWIDTH-1:0]       lsu2dmem_wdata_o,           // Data memory write data
58
    input   logic                               dmem2lsu_req_ack_i,         // Data memory request acknowledge
59
    input   logic [`SCR1_DMEM_DWIDTH-1:0]       dmem2lsu_rdata_i,           // Data memory read data
60 21 dinesha
    input   logic [1:0]                         dmem2lsu_resp_i             // Data memory response
61 11 dinesha
);
62
 
63
//------------------------------------------------------------------------------
64
// Local types declaration
65
//------------------------------------------------------------------------------
66
 
67 21 dinesha
//typedef enum logic {
68
parameter  SCR1_LSU_FSM_IDLE = 1'b0;
69
parameter  SCR1_LSU_FSM_BUSY = 1'b1;
70
//} type_scr1_lsu_fsm_e;
71 11 dinesha
 
72
//------------------------------------------------------------------------------
73
// Local signals declaration
74
//------------------------------------------------------------------------------
75
 
76
// LSU FSM signals
77 21 dinesha
logic                       lsu_fsm_curr;       // LSU FSM current state
78
logic                       lsu_fsm_next;       // LSU FSM next state
79 11 dinesha
logic                       lsu_fsm_idle;       // LSU FSM is in IDLE state
80
 
81
// LSU Command register signals
82
logic                       lsu_cmd_upd;        // LSU Command register update
83
type_scr1_lsu_cmd_sel_e     lsu_cmd_ff;         // LSU Command register value
84
logic                       lsu_cmd_ff_load;    // Registered LSU Command is load
85
logic                       lsu_cmd_ff_store;   // Registered LSU Command is store
86
 
87
// DMEM command and width flags
88
logic                       dmem_cmd_load;      // DMEM command is load
89
logic                       dmem_cmd_store;     // DMEM Command is store
90
logic                       dmem_wdth_word;     // DMEM data width is WORD
91
logic                       dmem_wdth_hword;    // DMEM data width is HALFWORD
92
logic                       dmem_wdth_byte;     // DMEM data width is BYTE
93
 
94
// DMEM response and request control signals
95
logic                       dmem_resp_ok;       // DMEM response is OK
96
logic                       dmem_resp_er;       // DMEM response is erroneous
97
logic                       dmem_resp_received; // DMEM response is received
98
logic                       dmem_req_vd;        // DMEM request is valid (req_ack received)
99
 
100
// Exceptions signals
101
logic                       lsu_exc_req;        // LSU exception request
102
logic                       dmem_addr_mslgn;    // DMEM address is misaligned
103
logic                       dmem_addr_mslgn_l;  // DMEM load address is misaligned
104
logic                       dmem_addr_mslgn_s;  // DMEM store address is misaligned
105
`ifdef SCR1_TDU_EN
106
logic                       lsu_exc_hwbrk;      // LSU hardware breakpoint exception
107
`endif // SCR1_TDU_EN
108
 
109
//------------------------------------------------------------------------------
110
// Control logic
111
//------------------------------------------------------------------------------
112
 
113
// DMEM response and request control signals
114
assign dmem_resp_ok       = (dmem2lsu_resp_i == SCR1_MEM_RESP_RDY_OK);
115
assign dmem_resp_er       = (dmem2lsu_resp_i == SCR1_MEM_RESP_RDY_ER);
116
assign dmem_resp_received = dmem_resp_ok | dmem_resp_er;
117
assign dmem_req_vd        = exu2lsu_req_i & dmem2lsu_req_ack_i & ~lsu_exc_req;
118
 
119
// LSU load and store command flags
120
assign dmem_cmd_load  = (exu2lsu_cmd_i == SCR1_LSU_CMD_LB )
121
                      | (exu2lsu_cmd_i == SCR1_LSU_CMD_LBU)
122
                      | (exu2lsu_cmd_i == SCR1_LSU_CMD_LH )
123
                      | (exu2lsu_cmd_i == SCR1_LSU_CMD_LHU)
124
                      | (exu2lsu_cmd_i == SCR1_LSU_CMD_LW );
125
assign dmem_cmd_store = (exu2lsu_cmd_i == SCR1_LSU_CMD_SB )
126
                      | (exu2lsu_cmd_i == SCR1_LSU_CMD_SH )
127
                      | (exu2lsu_cmd_i == SCR1_LSU_CMD_SW );
128
 
129
// LSU data width flags
130
assign dmem_wdth_word  = (exu2lsu_cmd_i == SCR1_LSU_CMD_LW )
131
                       | (exu2lsu_cmd_i == SCR1_LSU_CMD_SW );
132
assign dmem_wdth_hword = (exu2lsu_cmd_i == SCR1_LSU_CMD_LH )
133
                       | (exu2lsu_cmd_i == SCR1_LSU_CMD_LHU)
134
                       | (exu2lsu_cmd_i == SCR1_LSU_CMD_SH );
135
assign dmem_wdth_byte  = (exu2lsu_cmd_i == SCR1_LSU_CMD_LB )
136
                       | (exu2lsu_cmd_i == SCR1_LSU_CMD_LBU)
137
                       | (exu2lsu_cmd_i == SCR1_LSU_CMD_SB );
138
 
139
// LSU command register
140
assign lsu_cmd_upd = lsu_fsm_idle & dmem_req_vd;
141
 
142
always_ff @(posedge clk, negedge rst_n) begin
143
    if (~rst_n) begin
144
        lsu_cmd_ff <= SCR1_LSU_CMD_NONE;
145
    end else if (lsu_cmd_upd) begin
146
        lsu_cmd_ff <= exu2lsu_cmd_i;
147
    end
148
end
149
 
150
// LSU registered load and store command flags
151
assign lsu_cmd_ff_load  = (lsu_cmd_ff == SCR1_LSU_CMD_LB )
152
                        | (lsu_cmd_ff == SCR1_LSU_CMD_LBU)
153
                        | (lsu_cmd_ff == SCR1_LSU_CMD_LH )
154
                        | (lsu_cmd_ff == SCR1_LSU_CMD_LHU)
155
                        | (lsu_cmd_ff == SCR1_LSU_CMD_LW );
156
assign lsu_cmd_ff_store = (lsu_cmd_ff == SCR1_LSU_CMD_SB )
157
                        | (lsu_cmd_ff == SCR1_LSU_CMD_SH )
158
                        | (lsu_cmd_ff == SCR1_LSU_CMD_SW );
159
 
160
//------------------------------------------------------------------------------
161
// LSU FSM
162
//------------------------------------------------------------------------------
163
 //
164
 // LSU FSM is used to control the LSU <-> DMEM interface
165
 //
166
//
167
 
168
// Updating LSU FSM state
169
always_ff @(posedge clk, negedge rst_n) begin
170
    if (~rst_n) begin
171
        lsu_fsm_curr <= SCR1_LSU_FSM_IDLE;
172
    end else begin
173
        lsu_fsm_curr <= lsu_fsm_next;
174
    end
175
end
176
 
177
// LSU FSM next state logic
178
always_comb begin
179
    case (lsu_fsm_curr)
180
        SCR1_LSU_FSM_IDLE: begin
181
            lsu_fsm_next = dmem_req_vd        ? SCR1_LSU_FSM_BUSY
182
                                              : SCR1_LSU_FSM_IDLE;
183
        end
184
        SCR1_LSU_FSM_BUSY: begin
185
            lsu_fsm_next = dmem_resp_received ? SCR1_LSU_FSM_IDLE
186
                                              : SCR1_LSU_FSM_BUSY;
187
        end
188
    endcase
189
end
190
 
191
assign lsu_fsm_idle = (lsu_fsm_curr == SCR1_LSU_FSM_IDLE);
192
 
193
//------------------------------------------------------------------------------
194
// Exceptions logic
195
//------------------------------------------------------------------------------
196
 //
197
 // The following types of exceptions are supported:
198
 // - Load address misalign
199
 // - Load access fault
200
 // - Store address misalign
201
 // - Store access fault
202
 // - LSU breakpoint exception
203
//
204
 
205
// DMEM addr misalign logic
206
assign dmem_addr_mslgn   = exu2lsu_req_i & ( (dmem_wdth_hword & exu2lsu_addr_i[0])
207
                                           | (dmem_wdth_word  & |exu2lsu_addr_i[1:0]));
208
assign dmem_addr_mslgn_l = dmem_addr_mslgn & dmem_cmd_load;
209
assign dmem_addr_mslgn_s = dmem_addr_mslgn & dmem_cmd_store;
210
 
211
// Exception code logic
212
always_comb begin
213
    case (1'b1)
214
        dmem_resp_er     : lsu2exu_exc_code_o = lsu_cmd_ff_load  ? SCR1_EXC_CODE_LD_ACCESS_FAULT
215
                                              : lsu_cmd_ff_store ? SCR1_EXC_CODE_ST_ACCESS_FAULT
216
                                                                 : SCR1_EXC_CODE_INSTR_MISALIGN;
217
`ifdef SCR1_TDU_EN
218
        lsu_exc_hwbrk    : lsu2exu_exc_code_o = SCR1_EXC_CODE_BREAKPOINT;
219
`endif // SCR1_TDU_EN
220
        dmem_addr_mslgn_l: lsu2exu_exc_code_o = SCR1_EXC_CODE_LD_ADDR_MISALIGN;
221
        dmem_addr_mslgn_s: lsu2exu_exc_code_o = SCR1_EXC_CODE_ST_ADDR_MISALIGN;
222
        default          : lsu2exu_exc_code_o = SCR1_EXC_CODE_INSTR_MISALIGN;
223
    endcase // 1'b1
224
end
225
 
226
assign lsu_exc_req = dmem_addr_mslgn_l | dmem_addr_mslgn_s
227
`ifdef SCR1_TDU_EN
228
                   | lsu_exc_hwbrk
229
`endif // SCR1_TDU_EN
230
;
231
 
232
//------------------------------------------------------------------------------
233
// LSU <-> EXU interface
234
//------------------------------------------------------------------------------
235
 
236
assign lsu2exu_rdy_o = dmem_resp_received;
237
assign lsu2exu_exc_o = dmem_resp_er | lsu_exc_req;
238
 
239
// Sign- or zero-extending data received from DMEM
240
always_comb begin
241
    case (lsu_cmd_ff)
242
        SCR1_LSU_CMD_LH : lsu2exu_ldata_o = {{16{dmem2lsu_rdata_i[15]}}, dmem2lsu_rdata_i[15:0]};
243
        SCR1_LSU_CMD_LHU: lsu2exu_ldata_o = { 16'b0,                     dmem2lsu_rdata_i[15:0]};
244
        SCR1_LSU_CMD_LB : lsu2exu_ldata_o = {{24{dmem2lsu_rdata_i[7]}},  dmem2lsu_rdata_i[7:0]};
245
        SCR1_LSU_CMD_LBU: lsu2exu_ldata_o = { 24'b0,                     dmem2lsu_rdata_i[7:0]};
246
        default         : lsu2exu_ldata_o = dmem2lsu_rdata_i;
247
    endcase // lsu_cmd_ff
248
end
249
 
250
//------------------------------------------------------------------------------
251
// LSU <-> DMEM interface
252
//------------------------------------------------------------------------------
253
 
254
assign lsu2dmem_req_o   = exu2lsu_req_i & ~lsu_exc_req & lsu_fsm_idle;
255
assign lsu2dmem_addr_o  = exu2lsu_addr_i;
256
assign lsu2dmem_wdata_o = exu2lsu_sdata_i;
257
assign lsu2dmem_cmd_o   = dmem_cmd_store  ? SCR1_MEM_CMD_WR : SCR1_MEM_CMD_RD;
258
assign lsu2dmem_width_o = dmem_wdth_byte  ? SCR1_MEM_WIDTH_BYTE
259
                        : dmem_wdth_hword ? SCR1_MEM_WIDTH_HWORD
260
                                          : SCR1_MEM_WIDTH_WORD;
261
 
262
`ifdef SCR1_TDU_EN
263
//------------------------------------------------------------------------------
264
// LSU <-> TDU interface
265
//------------------------------------------------------------------------------
266
 
267
assign lsu2tdu_dmon_o.vd    = exu2lsu_req_i & lsu_fsm_idle & ~tdu2lsu_ibrkpt_exc_req_i;
268
assign lsu2tdu_dmon_o.addr  = exu2lsu_addr_i;
269
assign lsu2tdu_dmon_o.load  = dmem_cmd_load;
270
assign lsu2tdu_dmon_o.store = dmem_cmd_store;
271
 
272
assign lsu_exc_hwbrk = (exu2lsu_req_i & tdu2lsu_ibrkpt_exc_req_i)
273
                     | tdu2lsu_dbrkpt_exc_req_i;
274
 
275
`endif // SCR1_TDU_EN
276
 
277
`ifdef SCR1_TRGT_SIMULATION
278
//------------------------------------------------------------------------------
279
// Assertions
280
//------------------------------------------------------------------------------
281
 
282
// X checks
283
 
284
SCR1_SVA_LSU_XCHECK_CTRL : assert property (
285
    @(negedge clk) disable iff (~rst_n)
286
    !$isunknown({exu2lsu_req_i, lsu_fsm_curr
287
`ifdef SCR1_TDU_EN
288
        , tdu2lsu_ibrkpt_exc_req_i, tdu2lsu_dbrkpt_exc_req_i
289
`endif // SCR1_TDU_EN
290
    })
291
    ) else $error("LSU Error: unknown control value");
292
 
293
SCR1_SVA_LSU_XCHECK_CMD : assert property (
294
    @(negedge clk) disable iff (~rst_n)
295
    exu2lsu_req_i |-> !$isunknown({exu2lsu_cmd_i, exu2lsu_addr_i})
296
    ) else $error("LSU Error: undefined CMD or address");
297
 
298
SCR1_SVA_LSU_XCHECK_SDATA : assert property (
299
    @(negedge clk) disable iff (~rst_n)
300
    (exu2lsu_req_i & (lsu2dmem_cmd_o == SCR1_MEM_CMD_WR)) |-> !$isunknown({exu2lsu_sdata_i})
301
    ) else $error("LSU Error: undefined store data");
302
 
303
SCR1_SVA_LSU_XCHECK_EXC : assert property (
304
    @(negedge clk) disable iff (~rst_n)
305
    lsu2exu_exc_o |-> !$isunknown(lsu2exu_exc_code_o)
306
    ) else $error("LSU Error: exception code undefined");
307
 
308
SCR1_SVA_LSU_IMEM_CTRL : assert property (
309
    @(negedge clk) disable iff (~rst_n)
310
    lsu2dmem_req_o |-> !$isunknown({lsu2dmem_cmd_o, lsu2dmem_width_o, lsu2dmem_addr_o})
311
    ) else $error("LSU Error: undefined dmem control");
312
 
313
SCR1_SVA_LSU_IMEM_ACK : assert property (
314
    @(negedge clk) disable iff (~rst_n)
315
    lsu2dmem_req_o |-> !$isunknown(dmem2lsu_req_ack_i)
316
    ) else $error("LSU Error: undefined dmem ack");
317
 
318
SCR1_SVA_LSU_IMEM_WDATA : assert property (
319
    @(negedge clk) disable iff (~rst_n)
320
    lsu2dmem_req_o & (lsu2dmem_cmd_o == SCR1_MEM_CMD_WR)
321
    |-> !$isunknown(lsu2dmem_wdata_o[8:0])
322
    ) else $error("LSU Error: undefined dmem wdata");
323
 
324
// Behavior checks
325
 
326
SCR1_SVA_LSU_EXC_ONEHOT : assert property (
327
    @(negedge clk) disable iff (~rst_n)
328
    $onehot0({dmem_resp_er, dmem_addr_mslgn_l, dmem_addr_mslgn_s})
329
    ) else $error("LSU Error: more than one exception at a time");
330
 
331
SCR1_SVA_LSU_UNEXPECTED_DMEM_RESP : assert property (
332
    @(negedge clk) disable iff (~rst_n)
333
    lsu_fsm_idle |-> ~dmem_resp_received
334
    ) else $error("LSU Error: not expecting memory response");
335
 
336
SCR1_SVA_LSU_REQ_EXC : assert property (
337
    @(negedge clk) disable iff (~rst_n)
338
    lsu2exu_exc_o |-> exu2lsu_req_i
339
    ) else $error("LSU Error: impossible exception");
340
 
341
`ifdef SCR1_TDU_EN
342
 
343
SCR1_COV_LSU_MISALIGN_BRKPT : cover property (
344
    @(negedge clk) disable iff (~rst_n)
345
    (dmem_addr_mslgn_l | dmem_addr_mslgn_s) & lsu_exc_hwbrk
346
);
347
`endif // SCR1_TDU_EN
348
 
349
`endif // SCR1_TRGT_SIMULATION
350
 
351
endmodule : scr1_pipe_lsu

powered by: WebSVN 2.1.0

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