Some of the warnings fixed.
[or1200.git] / rtl / verilog / or1200_lsu.v
blobfa6b2e57cdf567b6d0f8608bc5bd1873ea2ce5c0
1 //////////////////////////////////////////////////////////////////////
2 //// ////
3 //// OR1200's Load/Store unit ////
4 //// ////
5 //// This file is part of the OpenRISC 1200 project ////
6 //// http://www.opencores.org/cores/or1k/ ////
7 //// ////
8 //// Description ////
9 //// Interface between CPU and DC. ////
10 //// ////
11 //// To Do: ////
12 //// - make it smaller and faster ////
13 //// ////
14 //// Author(s): ////
15 //// - Damjan Lampret, lampret@opencores.org ////
16 //// ////
17 //////////////////////////////////////////////////////////////////////
18 //// ////
19 //// Copyright (C) 2000 Authors and OPENCORES.ORG ////
20 //// ////
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. ////
25 //// ////
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. ////
31 //// ////
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 ////
36 //// details. ////
37 //// ////
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 ////
41 //// ////
42 //////////////////////////////////////////////////////////////////////
44 // CVS Revision History
46 // $Log$
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
66 // MP3 version.
68 // Revision 1.1.1.1 2001/10/06 10:18:36 igorm
69 // no message
71 // Revision 1.2 2001/08/09 13:39:33 lampret
72 // Major clean-up.
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"
84 module or1200_lsu(
86 // Internal i/f
87 addrbase, addrofs, lsu_op, lsu_datain, lsu_dataout, lsu_stall, lsu_unstall,
88 du_stall, except_align, except_dtlbmiss, except_dmmufault, except_dbuserr,
90 // External i/f to DC
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;
99 // I/O
103 // Internal i/f
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;
110 output lsu_stall;
111 output lsu_unstall;
112 input du_stall;
113 output except_align;
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;
123 output dcpu_we_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;
128 input dcpu_ack_i;
129 input dcpu_rty_i;
130 input dcpu_err_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;
173 endcase
176 // Instantiation of Memory-to-regfile aligner
178 or1200_mem2reg or1200_mem2reg(
179 .addr(dcpu_adr_o[1:0]),
180 .lsu_op(lsu_op),
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]),
190 .lsu_op(lsu_op),
191 .regdata(lsu_datain),
192 .memdata(dcpu_dat_o)
195 endmodule