1 //////////////////////////////////////////////////////////////////////
3 //// OR1200's Load/Store unit ////
5 //// This file is part of the OpenRISC 1200 project ////
6 //// http://www.opencores.org/cores/or1k/ ////
9 //// Interface between CPU and DC. ////
12 //// - make it smaller and faster ////
15 //// - Damjan Lampret, lampret@opencores.org ////
17 //////////////////////////////////////////////////////////////////////
19 //// Copyright (C) 2000 Authors and OPENCORES.ORG ////
21 //// This source file may be used and distributed without ////
22 //// restriction provided that this copyright statement is not ////
23 //// removed from the file and that any derivative work contains ////
24 //// the original copyright notice and the associated disclaimer. ////
26 //// This source file is free software; you can redistribute it ////
27 //// and/or modify it under the terms of the GNU Lesser General ////
28 //// Public License as published by the Free Software Foundation; ////
29 //// either version 2.1 of the License, or (at your option) any ////
30 //// later version. ////
32 //// This source is distributed in the hope that it will be ////
33 //// useful, but WITHOUT ANY WARRANTY; without even the implied ////
34 //// warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR ////
35 //// PURPOSE. See the GNU Lesser General Public License for more ////
38 //// You should have received a copy of the GNU Lesser General ////
39 //// Public License along with this source; if not, download it ////
40 //// from http://www.opencores.org/lgpl.shtml ////
42 //////////////////////////////////////////////////////////////////////
44 // CVS Revision History
47 // Revision 1.4 2002/03/29 15:16:56 lampret
48 // Some of the warnings fixed.
50 // Revision 1.3 2002/02/11 04:33:17 lampret
51 // Speed optimizations (removed duplicate _cyc_ and _stb_). Fixed D/IMMU cache-inhibit attr.
53 // Revision 1.2 2002/01/18 07:56:00 lampret
54 // No more low/high priority interrupts (PICPR removed). Added tick timer exception. Added exception prefix (SR[EPH]). Fixed single-step bug whenreading NPC.
56 // Revision 1.1 2002/01/03 08:16:15 lampret
57 // New prefixes for RTL files, prefixed module names. Updated cache controllers and MMUs.
59 // Revision 1.9 2001/11/30 18:59:47 simons
60 // *** empty log message ***
62 // Revision 1.8 2001/10/21 17:57:16 lampret
63 // Removed params from generic_XX.v. Added translate_off/on in sprs.v and id.v. Removed spr_addr from dc.v and ic.v. Fixed CR+LF.
65 // Revision 1.7 2001/10/14 13:12:09 lampret
68 // Revision 1.1.1.1 2001/10/06 10:18:36 igorm
71 // Revision 1.2 2001/08/09 13:39:33 lampret
74 // Revision 1.1 2001/07/20 00:46:03 lampret
75 // Development version of RTL. Libraries are missing.
79 // synopsys translate_off
80 `include "timescale.v"
81 // synopsys translate_on
82 `include "or1200_defines.v"
87 addrbase
, addrofs
, lsu_op
, lsu_datain
, lsu_dataout
, lsu_stall
, lsu_unstall
,
88 du_stall
, except_align
, except_dtlbmiss
, except_dmmufault
, except_dbuserr
,
91 dcpu_adr_o
, dcpu_cycstb_o
, dcpu_we_o
, dcpu_sel_o
, dcpu_tag_o
, dcpu_dat_o
,
92 dcpu_dat_i
, dcpu_ack_i
, dcpu_rty_i
, dcpu_err_i
, dcpu_tag_i
95 parameter dw
= `OR1200_OPERAND_WIDTH;
96 parameter aw
= `OR1200_REGFILE_ADDR_WIDTH;
105 input [31:0] addrbase
;
106 input [31:0] addrofs
;
107 input [`OR1200_LSUOP_WIDTH-1:0] lsu_op;
108 input [dw
-1:0] lsu_datain
;
109 output [dw
-1:0] lsu_dataout
;
114 output except_dtlbmiss
;
115 output except_dmmufault
;
116 output except_dbuserr
;
119 // External i/f to DC
121 output [31:0] dcpu_adr_o
;
122 output dcpu_cycstb_o
;
124 output [3:0] dcpu_sel_o
;
125 output [3:0] dcpu_tag_o
;
126 output [31:0] dcpu_dat_o
;
127 input [31:0] dcpu_dat_i
;
131 input [3:0] dcpu_tag_i
;
134 // Internal wires/regs
136 reg [3:0] dcpu_sel_o
;
139 // Internal I/F assignments
141 assign lsu_stall
= dcpu_rty_i
& dcpu_cycstb_o
;
142 assign lsu_unstall
= dcpu_ack_i
;
143 assign except_align
= ((lsu_op
== `OR1200_LSUOP_SH) | (lsu_op == `OR1200_LSUOP_LHZ) | (lsu_op == `OR1200_LSUOP_LHS)) & dcpu_adr_o[0]
144 |
((lsu_op
== `OR1200_LSUOP_SW) | (lsu_op == `OR1200_LSUOP_LWZ) | (lsu_op == `OR1200_LSUOP_LWS)) & |dcpu_adr_o[1:0];
145 assign except_dtlbmiss
= dcpu_err_i
& (dcpu_tag_i
== `OR1200_DTAG_TE);
146 assign except_dmmufault
= dcpu_err_i
& (dcpu_tag_i
== `OR1200_DTAG_PE);
147 assign except_dbuserr
= dcpu_err_i
& (dcpu_tag_i
== `OR1200_DTAG_BE);
150 // External I/F assignments
152 assign dcpu_adr_o
= addrbase
+ addrofs
;
153 assign dcpu_cycstb_o
= du_stall | lsu_unstall ?
1'b0 : |lsu_op
;
154 assign dcpu_we_o
= lsu_op
[3];
155 assign dcpu_tag_o
= dcpu_cycstb_o ?
`OR1200_DTAG_ND : `OR1200_DTAG_IDLE;
156 always @(lsu_op
or dcpu_adr_o
)
157 casex({lsu_op
, dcpu_adr_o
[1:0]})
158 {`OR1200_LSUOP_SB, 2'b00} : dcpu_sel_o = 4'b1000;
159 {`OR1200_LSUOP_SB, 2'b01} : dcpu_sel_o = 4'b0100;
160 {`OR1200_LSUOP_SB, 2'b10} : dcpu_sel_o = 4'b0010;
161 {`OR1200_LSUOP_SB, 2'b11} : dcpu_sel_o = 4'b0001;
162 {`OR1200_LSUOP_SH, 2'b00} : dcpu_sel_o = 4'b1100;
163 {`OR1200_LSUOP_SH, 2'b10} : dcpu_sel_o = 4'b0011;
164 {`OR1200_LSUOP_SW, 2'b00} : dcpu_sel_o = 4'b1111;
165 {`OR1200_LSUOP_LBZ, 2'b00}, {`OR1200_LSUOP_LBS, 2'b00} : dcpu_sel_o = 4'b1000;
166 {`OR1200_LSUOP_LBZ, 2'b01}, {`OR1200_LSUOP_LBS, 2'b01} : dcpu_sel_o = 4'b0100;
167 {`OR1200_LSUOP_LBZ, 2'b10}, {`OR1200_LSUOP_LBS, 2'b10} : dcpu_sel_o = 4'b0010;
168 {`OR1200_LSUOP_LBZ, 2'b11}, {`OR1200_LSUOP_LBS, 2'b11} : dcpu_sel_o = 4'b0001;
169 {`OR1200_LSUOP_LHZ, 2'b00}, {`OR1200_LSUOP_LHS, 2'b00} : dcpu_sel_o = 4'b1100;
170 {`OR1200_LSUOP_LHZ, 2'b10}, {`OR1200_LSUOP_LHS, 2'b10} : dcpu_sel_o = 4'b0011;
171 {`OR1200_LSUOP_LWZ, 2'b00}, {`OR1200_LSUOP_LWS, 2'b00} : dcpu_sel_o = 4'b1111;
172 default : dcpu_sel_o
= 4'b0000;
176 // Instantiation of Memory-to-regfile aligner
178 or1200_mem2reg
or1200_mem2reg(
179 .
addr(dcpu_adr_o
[1:0]),
181 .
memdata(dcpu_dat_i
),
182 .
regdata(lsu_dataout
)
186 // Instantiation of Regfile-to-memory aligner
188 or1200_reg2mem
or1200_reg2mem(
189 .
addr(dcpu_adr_o
[1:0]),
191 .
regdata(lsu_datain
),