URL
https://opencores.org/ocsvn/or1k/or1k/trunk
Subversion Repositories or1k
Compare Revisions
- This comparison shows the changes necessary to convert path
/
- from Rev 659 to Rev 660
- ↔ Reverse comparison
Rev 659 → Rev 660
/trunk/or1200/rtl/verilog/or1200_du.v
44,6 → 44,9
// CVS Revision History |
// |
// $Log: not supported by cvs2svn $ |
// Revision 1.4 2002/01/28 01:16:00 lampret |
// Changed 'void' nop-ops instead of insn[0] to use insn[16]. Debug unit stalls the tick timer. Prepared new flag generation for add and and insns. Blocked DC/IC while they are turned off. Fixed I/D MMU SPRs layout except WAYs. TODO: smart IC invalidate, l.j 2 and TLB ways. |
// |
// Revision 1.3 2002/01/18 07:56:00 lampret |
// No more low/high priority interrupts (PICPR removed). Added tick timer exception. Added exception prefix (SR[EPH]). Fixed single-step bug whenreading NPC. |
// |
88,8 → 91,8
module or1200_du( |
// RISC Internal Interface |
clk, rst, |
dcpu_cyc_i, dcpu_stb_i, dcpu_we_i, |
icpu_cyc_i, icpu_stb_i, ex_freeze, branch_op, ex_insn, du_dsr, |
dcpu_cycstb_i, dcpu_we_i, |
icpu_cycstb_i, ex_freeze, branch_op, ex_insn, du_dsr, |
du_stall, du_addr, du_dat_i, du_dat_o, du_read, du_write, du_except, |
spr_cs, spr_write, spr_addr, spr_dat_i, spr_dat_o, |
|
110,11 → 113,9
// |
input clk; // Clock |
input rst; // Reset |
input dcpu_cyc_i; // LSU status |
input dcpu_stb_i; // LSU status |
input dcpu_cycstb_i; // LSU status |
input dcpu_we_i; // LSU status |
input [`OR1200_FETCHOP_WIDTH-1:0] icpu_cyc_i; // IFETCH unit status |
input [`OR1200_FETCHOP_WIDTH-1:0] icpu_stb_i; // IFETCH unit status |
input [`OR1200_FETCHOP_WIDTH-1:0] icpu_cycstb_i; // IFETCH unit status |
input ex_freeze; // EX stage freeze |
input [`OR1200_BRANCHOP_WIDTH-1:0] branch_op; // Branch op |
input [dw-1:0] ex_insn; // EX insn |
150,8 → 151,8
// |
// Some connections go directly from the CPU through DU to Debug I/F |
// |
assign dbg_lss_o = dcpu_cyc_i & dcpu_stb_i ? {dcpu_we_i, 3'b000} : 4'b0000; |
assign dbg_is_o = {1'b0, icpu_cyc_i & icpu_stb_i}; |
assign dbg_lss_o = dcpu_cycstb_i ? {dcpu_we_i, 3'b000} : 4'b0000; |
assign dbg_is_o = {1'b0, icpu_cycstb_i}; |
assign dbg_wp_o = 11'b000_0000_0000; |
assign dbg_dat_o = du_dat_i; |
|
/trunk/or1200/rtl/verilog/or1200_ic_top.v
44,6 → 44,9
// CVS Revision History |
// |
// $Log: not supported by cvs2svn $ |
// Revision 1.4 2002/02/01 19:56:54 lampret |
// Fixed combinational loops. |
// |
// Revision 1.3 2002/01/28 01:16:00 lampret |
// Changed 'void' nop-ops instead of insn[0] to use insn[16]. Debug unit stalls the tick timer. Prepared new flag generation for add and and insns. Blocked DC/IC while they are turned off. Fixed I/D MMU SPRs layout except WAYs. TODO: smart IC invalidate, l.j 2 and TLB ways. |
// |
94,7 → 97,7
|
// Internal i/f |
ic_en, |
icimmu_adr_i, icimmu_cyc_i, icimmu_stb_i, icimmu_ci_i, |
icimmu_adr_i, icimmu_cycstb_i, icimmu_ci_i, |
icpu_we_i, icpu_sel_i, icpu_tag_i, |
icpu_dat_o, icpu_ack_o, icimmu_rty_o, icimmu_err_o, icimmu_tag_o, |
|
133,8 → 136,7
// |
input ic_en; |
input [31:0] icimmu_adr_i; |
input icimmu_cyc_i; |
input icimmu_stb_i; |
input icimmu_cycstb_i; |
input icimmu_ci_i; |
input icpu_we_i; |
input [3:0] icpu_sel_i; |
173,6 → 175,7
wire icfsm_first_miss_ack; |
wire icfsm_first_miss_err; |
wire icfsm_burst; |
wire icfsm_tag_we; |
|
// |
// Simple assignments |
179,7 → 182,7
// |
assign icbiu_adr_o = ic_addr; |
assign ic_inv = spr_cs & spr_write; |
assign ictag_we = (icfsm_biu_read & icbiu_ack_i) | ic_inv; |
assign ictag_we = icfsm_tag_we | ic_inv; |
assign ictag_addr = ic_inv ? spr_dat_i[`OR1200_ICINDXH:`OR1200_ICLS] : ic_addr[`OR1200_ICINDXH:`OR1200_ICLS]; |
assign ictag_en = ic_inv | ic_en; |
assign ictag_v = ~ic_inv; |
193,8 → 196,8
// |
// Bypases of the IC when IC is disabled |
// |
assign icbiu_cyc_o = (ic_en) ? icfsm_biu_read : icimmu_cyc_i; |
assign icbiu_stb_o = (ic_en) ? icfsm_biu_read : icimmu_stb_i; |
assign icbiu_cyc_o = (ic_en) ? icfsm_biu_read : icimmu_cycstb_i; |
assign icbiu_stb_o = (ic_en) ? icfsm_biu_read : icimmu_cycstb_i; |
assign icbiu_we_o = 1'b0; |
assign icbiu_sel_o = (ic_en & icfsm_biu_read) ? 4'b1111 : icpu_sel_i; |
assign icbiu_cab_o = (ic_en) ? icfsm_burst : 1'b0; |
239,8 → 242,7
.clk(clk), |
.rst(rst), |
.ic_en(ic_en), |
.icimmu_cyc_i(icimmu_cyc_i), |
.icimmu_stb_i(icimmu_stb_i), |
.icimmu_cycstb_i(icimmu_cycstb_i), |
.icimmu_ci_i(icimmu_ci_i), |
.icpu_sel_i(icpu_sel_i), |
.tagcomp_miss(tagcomp_miss), |
253,7 → 255,8
.first_hit_ack(icfsm_first_hit_ack), |
.first_miss_ack(icfsm_first_miss_ack), |
.first_miss_err(icfsm_first_miss_err), |
.burst(icfsm_burst) |
.burst(icfsm_burst), |
.tag_we(icfsm_tag_we) |
); |
|
// |
/trunk/or1200/rtl/verilog/or1200_defines.v
44,6 → 44,9
// CVS Revision History |
// |
// $Log: not supported by cvs2svn $ |
// Revision 1.7 2002/02/01 19:56:54 lampret |
// Fixed combinational loops. |
// |
// Revision 1.6 2002/01/19 14:10:22 lampret |
// Fixed OR1200_XILINX_RAM32X1D. |
// |
131,7 → 134,7
// |
//`define OR1200_VERBOSE |
|
|
//`define OR1200_ASIC |
//////////////////////////////////////////////////////// |
// |
// Typical configuration for an ASIC |
182,8 → 185,8
// |
// Select between ASIC optimized and generic multiplier |
// |
//`define OR1200_ASIC_MULTP2_32X32 |
`define OR1200_GENERIC_MULTP2_32X32 |
`define OR1200_ASIC_MULTP2_32X32 |
//`define OR1200_GENERIC_MULTP2_32X32 |
|
// |
// Size/type of insn/data cache if implemented |
948,7 → 951,7
// |
// Address that selects between TLB TR and MR |
// |
`define OR1200_DTLB_TM_ADDR 8 |
`define OR1200_DTLB_TM_ADDR 7 |
|
// |
// DTLBMR fields |
988,7 → 991,19
`define OR1200_DTLBMRW `OR1200_DTLB_TAGW+1 // +1 because of V bit |
`define OR1200_DTLBTRW 32-`OR1200_DMMU_PS+5 // +5 because of protection bits and CI |
|
// |
// Cache inhibit while DMMU is not enabled/implemented |
// |
// cache inhibited 0GB-4GB 1'b1 |
// cache inhibited 0GB-2GB !dcpu_adr_[31] |
// cache inhibited 0GB-1GB 2GB-3GB !dcpu_adr_[30] |
// cache inhibited 1GB-2GB 3GB-4GB dcpu_adr_[30] |
// cache inhibited 2GB-4GB (default) dcpu_adr_[31] |
// cached 0GB-4GB 1'b0 |
// |
`define OR1200_DMMU_CI dcpu_adr_i[31] |
|
|
////////////////////////////////////////////// |
// |
// Insn MMU (IMMU) |
997,7 → 1012,7
// |
// Address that selects between TLB TR and MR |
// |
`define OR1200_ITLB_TM_ADDR 8 |
`define OR1200_ITLB_TM_ADDR 7 |
|
// |
// ITLBMR fields |
1035,7 → 1050,19
`define OR1200_ITLBMRW `OR1200_ITLB_TAGW+1 // +1 because of V bit |
`define OR1200_ITLBTRW 32-`OR1200_IMMU_PS+3 // +3 because of protection bits and CI |
|
// |
// Cache inhibit while IMMU is not enabled/implemented |
// |
// cache inhibited 0GB-4GB 1'b1 |
// cache inhibited 0GB-2GB !icpu_adr_[31] |
// cache inhibited 0GB-1GB 2GB-3GB !icpu_adr_[30] |
// cache inhibited 1GB-2GB 3GB-4GB icpu_adr_[30] |
// cache inhibited 2GB-4GB (default) icpu_adr_[31] |
// cached 0GB-4GB 1'b0 |
// |
`define OR1200_IMMU_CI icpu_adr_i[31] |
|
|
///////////////////////////////////////////////// |
// |
// Insn cache (IC) |
/trunk/or1200/rtl/verilog/or1200_cpu.v
45,6 → 45,9
// CVS Revision History |
// |
// $Log: not supported by cvs2svn $ |
// Revision 1.6 2002/02/01 19:56:54 lampret |
// Fixed combinational loops. |
// |
// Revision 1.5 2002/01/28 01:15:59 lampret |
// Changed 'void' nop-ops instead of insn[0] to use insn[16]. Debug unit stalls the tick timer. Prepared new flag generation for add and and insns. Blocked DC/IC while they are turned off. Fixed I/D MMU SPRs layout except WAYs. TODO: smart IC invalidate, l.j 2 and TLB ways. |
// |
121,7 → 124,7
|
// Insn interface |
ic_en, |
icpu_adr_o, icpu_cyc_o, icpu_stb_o, icpu_we_o, icpu_sel_o, icpu_tag_o, |
icpu_adr_o, icpu_cycstb_o, icpu_we_o, icpu_sel_o, icpu_tag_o, |
icpu_dat_i, icpu_ack_i, icpu_rty_i, icpu_err_i, icpu_adr_i, icpu_tag_i, |
immu_en, |
|
131,7 → 134,7
|
// Data interface |
dc_en, |
dcpu_adr_o, dcpu_cyc_o, dcpu_stb_o, dcpu_we_o, dcpu_sel_o, dcpu_tag_o, dcpu_dat_o, |
dcpu_adr_o, dcpu_cycstb_o, dcpu_we_o, dcpu_sel_o, dcpu_tag_o, dcpu_dat_o, |
dcpu_dat_i, dcpu_ack_i, dcpu_rty_i, dcpu_err_i, dcpu_tag_i, |
dmmu_en, |
|
161,8 → 164,7
// |
output ic_en; |
output [31:0] icpu_adr_o; |
output icpu_cyc_o; |
output icpu_stb_o; |
output icpu_cycstb_o; |
output icpu_we_o; |
output [3:0] icpu_sel_o; |
output [3:0] icpu_tag_o; |
197,8 → 199,7
// Data (DC) interface |
// |
output [31:0] dcpu_adr_o; |
output dcpu_cyc_o; |
output dcpu_stb_o; |
output dcpu_cycstb_o; |
output dcpu_we_o; |
output [3:0] dcpu_sel_o; |
output [3:0] dcpu_tag_o; |
367,8 → 368,7
.clk(clk), |
.rst(rst), |
.icpu_adr_o(icpu_adr_o), |
.icpu_cyc_o(icpu_cyc_o), |
.icpu_stb_o(icpu_stb_o), |
.icpu_cycstb_o(icpu_cycstb_o), |
.icpu_sel_o(icpu_sel_o), |
.icpu_tag_o(icpu_tag_o), |
.icpu_ack_i(icpu_ack_i), |
622,8 → 622,7
.except_dbuserr(except_dbuserr), |
|
.dcpu_adr_o(dcpu_adr_o), |
.dcpu_cyc_o(dcpu_cyc_o), |
.dcpu_stb_o(dcpu_stb_o), |
.dcpu_cycstb_o(dcpu_cycstb_o), |
.dcpu_we_o(dcpu_we_o), |
.dcpu_sel_o(dcpu_sel_o), |
.dcpu_tag_o(dcpu_tag_o), |
/trunk/or1200/rtl/verilog/or1200_immu_top.v
44,6 → 44,9
// CVS Revision History |
// |
// $Log: not supported by cvs2svn $ |
// Revision 1.4 2002/02/01 19:56:54 lampret |
// Fixed combinational loops. |
// |
// Revision 1.3 2002/01/28 01:16:00 lampret |
// Changed 'void' nop-ops instead of insn[0] to use insn[16]. Debug unit stalls the tick timer. Prepared new flag generation for add and and insns. Blocked DC/IC while they are turned off. Fixed I/D MMU SPRs layout except WAYs. TODO: smart IC invalidate, l.j 2 and TLB ways. |
// |
87,7 → 90,7
clk, rst, |
|
// CPU i/f |
ic_en, immu_en, supv, icpu_adr_i, icpu_cyc_i, icpu_stb_i, |
ic_en, immu_en, supv, icpu_adr_i, icpu_cycstb_i, |
icpu_adr_o, icpu_tag_o, icpu_rty_o, icpu_err_o, |
|
// SPR access |
94,7 → 97,7
spr_cs, spr_write, spr_addr, spr_dat_i, spr_dat_o, |
|
// IC i/f |
icimmu_rty_i, icimmu_err_i, icimmu_tag_i, icimmu_adr_o, icimmu_cyc_o, icimmu_stb_o, icimmu_ci_o |
icimmu_rty_i, icimmu_err_i, icimmu_tag_i, icimmu_adr_o, icimmu_cycstb_o, icimmu_ci_o |
); |
|
parameter dw = `OR1200_OPERAND_WIDTH; |
117,8 → 120,7
input immu_en; |
input supv; |
input [aw-1:0] icpu_adr_i; |
input icpu_cyc_i; |
input icpu_stb_i; |
input icpu_cycstb_i; |
output [aw-1:0] icpu_adr_o; |
output [3:0] icpu_tag_o; |
output icpu_rty_o; |
140,8 → 142,7
input icimmu_err_i; |
input [3:0] icimmu_tag_i; |
output [aw-1:0] icimmu_adr_o; |
output icimmu_cyc_o; |
output icimmu_stb_o; |
output icimmu_cycstb_o; |
output icimmu_ci_o; |
|
// |
160,6 → 161,7
wire miss; |
reg [31:0] icpu_adr_o; |
reg itlb_en_r; |
reg [31:`OR1200_IMMU_PS] icpu_vpn_r; |
|
// |
// Implemented bits inside match and translate registers |
195,11 → 197,10
assign spr_dat_o = 32'h00000000; |
assign icimmu_adr_o = icpu_adr_i; |
assign icpu_tag_o = icimmu_tag_i; |
assign icimmu_cyc_o = icpu_cyc_i; |
assign icimmu_stb_o = icpu_stb_i; |
assign icimmu_cycstb_o = icpu_cycstb_i; |
assign icpu_rty_o = icimmu_rty_i; |
assign icpu_err_o = icimmu_err_i; |
assign icimmu_ci_o = icpu_adr_i[31]; |
assign icimmu_ci_o = `OR1200_IMMU_CI; |
|
`else |
|
245,25 → 246,35
// |
// Assert itlb_done one clock cycle after new address is first presented and tlb is enabled. |
// |
assign itlb_done = (icpu_adr_i == icpu_adr_o) & itlb_en_r; |
// assign itlb_done = (icpu_adr_i == icpu_adr_o) & itlb_en_r; |
assign itlb_done = itlb_en_r; |
|
// |
// Cut transfer if something goes wrong with translation. If IC is disabled, |
// use delayed signals. |
// |
assign icimmu_cyc_o = (!ic_en & immu_en) ? ~(miss | fault) & itlb_done & icpu_cyc_i : (miss | fault) ? 1'b0 : icpu_cyc_i; |
assign icimmu_stb_o = (!ic_en & immu_en) ? ~(miss | fault) & itlb_done & icpu_stb_i : (miss | fault) ? 1'b0 : icpu_stb_i; |
assign icimmu_cycstb_o = (!ic_en & immu_en) ? ~(miss | fault) & icpu_cycstb_i : (miss | fault) ? 1'b0 : icpu_cycstb_i; |
|
// |
// Cache Inhibit |
// |
assign icimmu_ci_o = immu_en ? itlb_done & itlb_ci : icpu_adr_i[31]; |
assign icimmu_ci_o = immu_en ? itlb_done & itlb_ci : `OR1200_IMMU_CI; |
|
// |
// Register icpu_adr_i's VPN for use when IMMU is not enabled but PPN is expected to come |
// one clock cycle after offset part. |
// |
always @(posedge clk or posedge rst) |
if (rst) |
icpu_vpn_r <= #1 {31-`OR1200_IMMU_PS{1'b0}}; |
else |
icpu_vpn_r <= #1 icpu_adr_i[31:`OR1200_IMMU_PS]; |
|
// |
// Physical address is either translated virtual address or |
// simply equal when IMMU is disabled |
// |
assign icimmu_adr_o = immu_en ? {itlb_ppn, icpu_adr_i[`OR1200_IMMU_PS-1:0]} : icpu_adr_i; |
assign icimmu_adr_o = immu_en ? {itlb_ppn, icpu_adr_i[`OR1200_IMMU_PS-1:0]} : {icpu_vpn_r, icpu_adr_i[`OR1200_IMMU_PS-1:0]}; |
|
// |
// Output to SPRS unit |
285,7 → 296,7
// |
// ITLB Enable |
// |
assign itlb_en = immu_en & icpu_cyc_i & icpu_stb_i; |
assign itlb_en = immu_en & icpu_cycstb_i; |
|
// |
// Instantiation of ITLB |
/trunk/or1200/rtl/verilog/or1200_dc_fsm.v
44,6 → 44,9
// CVS Revision History |
// |
// $Log: not supported by cvs2svn $ |
// Revision 1.4 2002/02/01 19:56:54 lampret |
// Fixed combinational loops. |
// |
// Revision 1.3 2002/01/28 01:15:59 lampret |
// Changed 'void' nop-ops instead of insn[0] to use insn[16]. Debug unit stalls the tick timer. Prepared new flag generation for add and and insns. Blocked DC/IC while they are turned off. Fixed I/D MMU SPRs layout except WAYs. TODO: smart IC invalidate, l.j 2 and TLB ways. |
// |
95,10 → 98,10
clk, rst, |
|
// Internal i/f to top level DC |
dc_en, dcdmmu_cyc_i, dcdmmu_stb_i, dcdmmu_ci_i, dcpu_we_i, dcpu_sel_i, |
dc_en, dcdmmu_cycstb_i, dcdmmu_ci_i, dcpu_we_i, dcpu_sel_i, |
tagcomp_miss, biudata_valid, biudata_error, start_addr, saved_addr, |
dcram_we, biu_read, biu_write, first_hit_ack, first_miss_ack, first_miss_err, |
burst |
burst, tag_we, dc_addr |
); |
|
// |
107,8 → 110,7
input clk; |
input rst; |
input dc_en; |
input dcdmmu_cyc_i; |
input dcdmmu_stb_i; |
input dcdmmu_cycstb_i; |
input dcdmmu_ci_i; |
input dcpu_we_i; |
input [3:0] dcpu_sel_i; |
124,22 → 126,26
output first_miss_ack; |
output first_miss_err; |
output burst; |
output tag_we; |
output [31:0] dc_addr; |
|
// |
// Internal wires and regs |
// |
reg [31:0] saved_addr; |
reg [31:0] saved_addr_r; |
reg [2:0] state; |
reg [2:0] cnt; |
reg hitmiss_eval; |
reg store; |
reg load; |
reg cache_inhibit; |
wire first_store_hit_ack; |
|
// |
// Generate of DCRAM write enables |
// |
assign dcram_we = {4{load & biudata_valid & (state != `OR1200_DCFSM_ILOAD)}} | {4{first_store_hit_ack}} & dcpu_sel_i; |
assign dcram_we = {4{load & biudata_valid & !cache_inhibit}} | {4{first_store_hit_ack}} & dcpu_sel_i; |
assign tag_we = biu_read & biudata_valid & !cache_inhibit; |
|
// |
// BIU read and write |
147,6 → 153,9
assign biu_read = (hitmiss_eval & tagcomp_miss) | (!hitmiss_eval & load); |
assign biu_write = store; |
|
assign dc_addr = (biu_read | biu_write) & !hitmiss_eval ? saved_addr : start_addr; |
assign saved_addr = saved_addr_r; |
|
// |
// Assert for cache hit first word ready |
// Assert for store cache hit first word ready |
153,15 → 162,15
// Assert for cache miss first word stored/loaded OK |
// Assert for cache miss first word stored/loaded with an error |
// |
assign first_hit_ack = (state == `OR1200_DCFSM_CLOAD) & !tagcomp_miss | first_store_hit_ack; |
assign first_store_hit_ack = (state == `OR1200_DCFSM_CSTORE) & !tagcomp_miss & biudata_valid; |
assign first_miss_ack = ((state == `OR1200_DCFSM_CLOAD) | (state == `OR1200_DCFSM_CSTORE) | (state == `OR1200_DCFSM_ILOAD) | (state == `OR1200_DCFSM_ISTORE)) & biudata_valid; |
assign first_miss_err = ((state == `OR1200_DCFSM_CLOAD) | (state == `OR1200_DCFSM_CSTORE) | (state == `OR1200_DCFSM_ILOAD) | (state == `OR1200_DCFSM_ISTORE)) & biudata_error; |
assign first_hit_ack = (state == `OR1200_DCFSM_CLOAD) & !tagcomp_miss & !cache_inhibit & !dcdmmu_ci_i | first_store_hit_ack; |
assign first_store_hit_ack = (state == `OR1200_DCFSM_CSTORE) & !tagcomp_miss & biudata_valid & !cache_inhibit & !dcdmmu_ci_i; |
assign first_miss_ack = ((state == `OR1200_DCFSM_CLOAD) | (state == `OR1200_DCFSM_CSTORE)) & biudata_valid; |
assign first_miss_err = ((state == `OR1200_DCFSM_CLOAD) | (state == `OR1200_DCFSM_CSTORE)) & biudata_error; |
|
// |
// Assert burst when doing reload of complete cache line |
// |
assign burst = (state == `OR1200_DCFSM_CLOAD) & tagcomp_miss |
assign burst = (state == `OR1200_DCFSM_CLOAD) & tagcomp_miss & !cache_inhibit |
| (state == `OR1200_DCFSM_LREFILL3) |
`ifdef OR1200_DC_STORE_REFILL |
| (state == `OR1200_DCFSM_SREFILL4) |
174,42 → 183,31
always @(posedge clk or posedge rst) begin |
if (rst) begin |
state <= #1 `OR1200_DCFSM_IDLE; |
saved_addr <= #1 32'b0; |
saved_addr_r <= #1 32'b0; |
hitmiss_eval <= #1 1'b0; |
store <= #1 1'b0; |
load <= #1 1'b0; |
cnt <= #1 3'b000; |
cache_inhibit <= #1 1'b0; |
end |
else |
case (state) // synopsys parallel_case |
`OR1200_DCFSM_IDLE : |
if (dc_en & dcdmmu_ci_i & dcdmmu_cyc_i & dcdmmu_stb_i & dcpu_we_i) begin // store to cache-inhibited area |
state <= #1 `OR1200_DCFSM_ISTORE; |
saved_addr <= #1 start_addr; |
hitmiss_eval <= #1 1'b0; |
store <= #1 1'b1; |
load <= #1 1'b0; |
end |
else if (dc_en & dcdmmu_ci_i & dcdmmu_cyc_i & dcdmmu_stb_i) begin // load from cache-inhibited area |
state <= #1 `OR1200_DCFSM_ILOAD; |
saved_addr <= #1 start_addr; |
hitmiss_eval <= #1 1'b0; |
store <= #1 1'b0; |
load <= #1 1'b1; |
end |
else if (dc_en & dcdmmu_cyc_i & dcdmmu_stb_i & dcpu_we_i) begin // store to cached area |
if (dc_en & dcdmmu_cycstb_i & dcpu_we_i) begin // store |
state <= #1 `OR1200_DCFSM_CSTORE; |
saved_addr <= #1 start_addr; |
saved_addr_r <= #1 start_addr; |
hitmiss_eval <= #1 1'b1; |
store <= #1 1'b1; |
load <= #1 1'b0; |
cache_inhibit <= #1 1'b0; |
end |
else if (dc_en & dcdmmu_cyc_i & dcdmmu_stb_i) begin // load from cached area |
else if (dc_en & dcdmmu_cycstb_i) begin // load |
state <= #1 `OR1200_DCFSM_CLOAD; |
saved_addr <= #1 start_addr; |
saved_addr_r <= #1 start_addr; |
hitmiss_eval <= #1 1'b1; |
store <= #1 1'b0; |
load <= #1 1'b1; |
cache_inhibit <= #1 1'b0; |
end |
else begin // idle |
state <= #1 `OR1200_DCFSM_IDLE; |
216,39 → 214,55
hitmiss_eval <= #1 1'b0; |
store <= #1 1'b0; |
load <= #1 1'b0; |
cache_inhibit <= #1 1'b0; |
end |
`OR1200_DCFSM_CLOAD: // load from cached area |
`OR1200_DCFSM_CLOAD: begin // load |
if (dcdmmu_cycstb_i & dcdmmu_ci_i) |
cache_inhibit <= #1 1'b1; |
if (hitmiss_eval) |
saved_addr_r[31:13] <= #1 start_addr[31:13]; |
if (!dc_en) |
state <= #1 `OR1200_DCFSM_IDLE; |
else if (hitmiss_eval & !(dcdmmu_cyc_i & dcdmmu_stb_i)) begin // load aborted (usually caused by DMMU) |
else if (hitmiss_eval & !dcdmmu_cycstb_i) begin // load aborted (usually caused by DMMU) |
state <= #1 `OR1200_DCFSM_IDLE; |
hitmiss_eval <= #1 1'b0; |
load <= #1 1'b0; |
cache_inhibit <= #1 1'b0; |
end |
else if (biudata_error) begin // load terminated with an error |
state <= #1 `OR1200_DCFSM_IDLE; |
hitmiss_eval <= #1 1'b0; |
load <= #1 1'b0; |
cache_inhibit <= #1 1'b0; |
end |
else if ((cache_inhibit | dcdmmu_ci_i) & biudata_valid) begin // load from cache-inhibited area |
state <= #1 `OR1200_DCFSM_IDLE; |
hitmiss_eval <= #1 1'b0; |
load <= #1 1'b0; |
cache_inhibit <= #1 1'b0; |
end |
else if (tagcomp_miss & biudata_valid) begin // load missed, finish current external load and refill |
state <= #1 `OR1200_DCFSM_LREFILL3; |
saved_addr[3:2] <= #1 saved_addr[3:2] + 'd1; |
saved_addr_r[3:2] <= #1 saved_addr_r[3:2] + 'd1; |
hitmiss_eval <= #1 1'b0; |
cnt <= #1 `OR1200_DCLS-2; |
cache_inhibit <= #1 1'b0; |
end |
else if (!tagcomp_miss) begin // load hit, finish immediately |
else if (!tagcomp_miss & !dcdmmu_ci_i) begin // load hit, finish immediately |
state <= #1 `OR1200_DCFSM_IDLE; |
hitmiss_eval <= #1 1'b0; |
load <= #1 1'b0; |
cache_inhibit <= #1 1'b0; |
end |
else // load in-progress |
hitmiss_eval <= #1 1'b0; |
end |
`OR1200_DCFSM_LREFILL3 : begin |
if (!dc_en) |
state <= #1 `OR1200_DCFSM_IDLE; |
else if (biudata_valid && (|cnt)) begin // refill ack, more loads to come |
cnt <= #1 cnt - 'd1; |
saved_addr[3:2] <= #1 saved_addr[3:2] + 'd1; |
saved_addr_r[3:2] <= #1 saved_addr_r[3:2] + 'd1; |
end |
else if (biudata_valid) begin // last load of line refill |
state <= #1 `OR1200_DCFSM_IDLE; |
255,19 → 269,31
load <= #1 1'b0; |
end |
end |
`OR1200_DCFSM_CSTORE: // store to cached area |
`OR1200_DCFSM_CSTORE: begin // store |
if (dcdmmu_cycstb_i & dcdmmu_ci_i) |
cache_inhibit <= #1 1'b1; |
if (hitmiss_eval) |
saved_addr_r[31:13] <= #1 start_addr[31:13]; |
if (!dc_en) |
state <= #1 `OR1200_DCFSM_IDLE; |
else if (hitmiss_eval & !(dcdmmu_cyc_i & dcdmmu_stb_i)) begin // store aborted (usually caused by DMMU) |
else if (hitmiss_eval & !dcdmmu_cycstb_i) begin // store aborted (usually caused by DMMU) |
state <= #1 `OR1200_DCFSM_IDLE; |
hitmiss_eval <= #1 1'b0; |
store <= #1 1'b0; |
cache_inhibit <= #1 1'b0; |
end |
else if (biudata_error) begin // store terminated with an error |
state <= #1 `OR1200_DCFSM_IDLE; |
hitmiss_eval <= #1 1'b0; |
store <= #1 1'b0; |
cache_inhibit <= #1 1'b0; |
end |
else if ((cache_inhibit | dcdmmu_ci_i) & biudata_valid) begin // store to cache-inhibited area |
state <= #1 `OR1200_DCFSM_IDLE; |
hitmiss_eval <= #1 1'b0; |
store <= #1 1'b0; |
cache_inhibit <= #1 1'b0; |
end |
`ifdef OR1200_DC_STORE_REFILL |
else if (tagcomp_miss & biudata_valid) begin // store missed, finish write-through and do load refill |
state <= #1 `OR1200_DCFSM_SREFILL4; |
275,6 → 301,7
store <= #1 1'b0; |
load <= #1 1'b1; |
cnt <= #1 `OR1200_DCLS-1; |
cache_inhibit <= #1 1'b0; |
end |
`endif |
else if (biudata_valid) begin // store hit, finish write-through |
281,9 → 308,11
state <= #1 `OR1200_DCFSM_IDLE; |
hitmiss_eval <= #1 1'b0; |
store <= #1 1'b0; |
cache_inhibit <= #1 1'b0; |
end |
else // store write-through in-progress |
hitmiss_eval <= #1 1'b0; |
end |
`ifdef OR1200_DC_STORE_REFILL |
`OR1200_DCFSM_SREFILL4 : begin |
if (!dc_en) |
290,7 → 319,7
state <= #1 `OR1200_DCFSM_IDLE; |
else if (biudata_valid && (|cnt)) begin // refill ack, more loads to come |
cnt <= #1 cnt - 'd1; |
saved_addr[3:2] <= #1 saved_addr[3:2] + 'd1; |
saved_addr_r[3:2] <= #1 saved_addr_r[3:2] + 'd1; |
end |
else if (biudata_valid) begin // last load of line refill |
state <= #1 `OR1200_DCFSM_IDLE; |
298,46 → 327,6
end |
end |
`endif |
`OR1200_DCFSM_ILOAD: // load from cache-inhibited area |
if (!dc_en) |
state <= #1 `OR1200_DCFSM_IDLE; |
else if (!(dcdmmu_cyc_i & dcdmmu_stb_i)) begin // load aborted (usually caused by DMMU) |
state <= #1 `OR1200_DCFSM_IDLE; |
hitmiss_eval <= #1 1'b0; |
load <= #1 1'b0; |
end |
else if (biudata_error) begin // load terminated with an error |
state <= #1 `OR1200_DCFSM_IDLE; |
hitmiss_eval <= #1 1'b0; |
load <= #1 1'b0; |
end |
else if (biudata_valid) begin // load from cache inhibit page |
state <= #1 `OR1200_DCFSM_IDLE; |
hitmiss_eval <= #1 1'b0; |
load <= #1 1'b0; |
end |
else // load in-progress |
hitmiss_eval <= #1 1'b0; |
`OR1200_DCFSM_ISTORE: // store to cache-inhibited area |
if (!dc_en) |
state <= #1 `OR1200_DCFSM_IDLE; |
else if (!(dcdmmu_cyc_i & dcdmmu_stb_i)) begin // store aborted (usually caused by DMMU) |
state <= #1 `OR1200_DCFSM_IDLE; |
hitmiss_eval <= #1 1'b0; |
store <= #1 1'b0; |
end |
else if (biudata_error) begin // store terminated with an error |
state <= #1 `OR1200_DCFSM_IDLE; |
hitmiss_eval <= #1 1'b0; |
store <= #1 1'b0; |
end |
else if (biudata_valid) begin // store to cache inhibit page |
state <= #1 `OR1200_DCFSM_IDLE; |
hitmiss_eval <= #1 1'b0; |
store <= #1 1'b0; |
end |
else // store write-through in-progress |
hitmiss_eval <= #1 1'b0; |
default: |
state <= #1 `OR1200_DCFSM_IDLE; |
endcase |
/trunk/or1200/rtl/verilog/or1200_immu_tlb.v
44,6 → 44,9
// CVS Revision History |
// |
// $Log: not supported by cvs2svn $ |
// Revision 1.2 2002/01/28 01:16:00 lampret |
// Changed 'void' nop-ops instead of insn[0] to use insn[16]. Debug unit stalls the tick timer. Prepared new flag generation for add and and insns. Blocked DC/IC while they are turned off. Fixed I/D MMU SPRs layout except WAYs. TODO: smart IC invalidate, l.j 2 and TLB ways. |
// |
// Revision 1.1 2002/01/03 08:16:15 lampret |
// New prefixes for RTL files, prefixed module names. Updated cache controllers and MMUs. |
// |
163,8 → 166,7
// Output to SPRS unit |
// |
assign spr_dat_o = (spr_cs & !spr_write & !spr_addr[`OR1200_ITLB_TM_ADDR]) ? |
// {vpn, {`OR1200_ITLB_INDXH-7{1'b0}}, 2'b11, 5'b00000, v} : |
{vpn, tlb_index, {`OR1200_ITLB_TAGW-1{1'b0}}, v} : |
{vpn, tlb_index & {`OR1200_ITLB_INDXW{v}}, {`OR1200_ITLB_TAGW-7{1'b0}}, 1'b0, 5'b00000, v} : |
(spr_cs & !spr_write & spr_addr[`OR1200_ITLB_TM_ADDR]) ? |
{ppn, {`OR1200_IMMU_PS-8{1'b0}}, uxe, sxe, {4{1'b0}}, ci, 1'b0} : |
32'h00000000; |
/trunk/or1200/rtl/verilog/or1200_dc_top.v
44,6 → 44,9
// CVS Revision History |
// |
// $Log: not supported by cvs2svn $ |
// Revision 1.3 2002/01/28 01:16:00 lampret |
// Changed 'void' nop-ops instead of insn[0] to use insn[16]. Debug unit stalls the tick timer. Prepared new flag generation for add and and insns. Blocked DC/IC while they are turned off. Fixed I/D MMU SPRs layout except WAYs. TODO: smart IC invalidate, l.j 2 and TLB ways. |
// |
// Revision 1.2 2002/01/14 06:18:22 lampret |
// Fixed mem2reg bug in FAST implementation. Updated debug unit to work with new genpc/if. |
// |
91,7 → 94,7
|
// Internal i/f |
dc_en, |
dcdmmu_adr_i, dcdmmu_cyc_i, dcdmmu_stb_i, dcdmmu_ci_i, |
dcdmmu_adr_i, dcdmmu_cycstb_i, dcdmmu_ci_i, |
dcpu_we_i, dcpu_sel_i, dcpu_tag_i, dcpu_dat_i, |
dcpu_dat_o, dcpu_ack_o, dcpu_rty_o, dcdmmu_err_o, dcdmmu_tag_o, |
|
130,8 → 133,7
// |
input dc_en; |
input [31:0] dcdmmu_adr_i; |
input dcdmmu_cyc_i; |
input dcdmmu_stb_i; |
input dcdmmu_cycstb_i; |
input dcdmmu_ci_i; |
input dcpu_we_i; |
input [3:0] dcpu_sel_i; |
172,6 → 174,7
wire dcfsm_first_miss_ack; |
wire dcfsm_first_miss_err; |
wire dcfsm_burst; |
wire dcfsm_tag_we; |
|
// |
// Simple assignments |
178,7 → 181,7
// |
assign dcbiu_adr_o = dc_addr; |
assign dc_inv = spr_cs & spr_write; |
assign dctag_we = (dcfsm_biu_read & dcbiu_ack_i) | dc_inv; |
assign dctag_we = dcfsm_tag_we | dc_inv; |
assign dctag_addr = dc_inv ? spr_dat_i[`OR1200_DCINDXH:`OR1200_DCLS] : dc_addr[`OR1200_DCINDXH:`OR1200_DCLS]; |
assign dctag_en = dc_inv | dc_en; |
assign dctag_v = ~dc_inv; |
192,8 → 195,8
// |
// Bypases of the DC when DC is disabled |
// |
assign dcbiu_cyc_o = (dc_en) ? dcfsm_biu_read | dcfsm_biu_write : dcdmmu_cyc_i; |
assign dcbiu_stb_o = (dc_en) ? dcfsm_biu_read | dcfsm_biu_write : dcdmmu_stb_i; |
assign dcbiu_cyc_o = (dc_en) ? dcfsm_biu_read | dcfsm_biu_write : dcdmmu_cycstb_i; |
assign dcbiu_stb_o = (dc_en) ? dcfsm_biu_read | dcfsm_biu_write : dcdmmu_cycstb_i; |
assign dcbiu_we_o = (dc_en) ? dcfsm_biu_write : dcpu_we_i; |
assign dcbiu_sel_o = (dc_en & dcfsm_biu_read & !dcfsm_biu_write & !dcdmmu_ci_i) ? 4'b1111 : dcpu_sel_i; |
assign dcbiu_cab_o = (dc_en) ? dcfsm_burst : 1'b0; |
209,7 → 212,7
// |
// Select between claddr generated by DC FSM and addr[3:2] generated by LSU |
// |
assign dc_addr = (dcfsm_biu_read | dcfsm_biu_write) ? saved_addr : dcdmmu_adr_i; |
//assign dc_addr = (dcfsm_biu_read | dcfsm_biu_write) ? saved_addr : dcdmmu_adr_i; |
|
// |
// Select between input data generated by LSU or by BIU |
238,8 → 241,7
.clk(clk), |
.rst(rst), |
.dc_en(dc_en), |
.dcdmmu_cyc_i(dcdmmu_cyc_i), |
.dcdmmu_stb_i(dcdmmu_stb_i), |
.dcdmmu_cycstb_i(dcdmmu_cycstb_i), |
.dcdmmu_ci_i(dcdmmu_ci_i), |
.dcpu_we_i(dcpu_we_i), |
.dcpu_sel_i(dcpu_sel_i), |
254,7 → 256,9
.first_hit_ack(dcfsm_first_hit_ack), |
.first_miss_ack(dcfsm_first_miss_ack), |
.first_miss_err(dcfsm_first_miss_err), |
.burst(dcfsm_burst) |
.burst(dcfsm_burst), |
.tag_we(dcfsm_tag_we), |
.dc_addr(dc_addr) |
); |
|
// |
/trunk/or1200/rtl/verilog/or1200_dmmu_top.v
44,6 → 44,9
// CVS Revision History |
// |
// $Log: not supported by cvs2svn $ |
// Revision 1.3 2002/01/28 01:16:00 lampret |
// Changed 'void' nop-ops instead of insn[0] to use insn[16]. Debug unit stalls the tick timer. Prepared new flag generation for add and and insns. Blocked DC/IC while they are turned off. Fixed I/D MMU SPRs layout except WAYs. TODO: smart IC invalidate, l.j 2 and TLB ways. |
// |
// Revision 1.2 2002/01/14 06:18:22 lampret |
// Fixed mem2reg bug in FAST implementation. Updated debug unit to work with new genpc/if. |
// |
84,7 → 87,7
clk, rst, |
|
// CPU i/f |
dc_en, dmmu_en, supv, dcpu_adr_i, dcpu_cyc_i, dcpu_stb_i, dcpu_we_i, |
dc_en, dmmu_en, supv, dcpu_adr_i, dcpu_cycstb_i, dcpu_we_i, |
dcpu_tag_o, dcpu_err_o, |
|
// SPR access |
91,7 → 94,7
spr_cs, spr_write, spr_addr, spr_dat_i, spr_dat_o, |
|
// DC i/f |
dcdmmu_err_i, dcdmmu_tag_i, dcdmmu_adr_o, dcdmmu_cyc_o, dcdmmu_stb_o, dcdmmu_ci_o |
dcdmmu_err_i, dcdmmu_tag_i, dcdmmu_adr_o, dcdmmu_cycstb_o, dcdmmu_ci_o |
); |
|
parameter dw = `OR1200_OPERAND_WIDTH; |
114,8 → 117,7
input dmmu_en; |
input supv; |
input [aw-1:0] dcpu_adr_i; |
input dcpu_cyc_i; |
input dcpu_stb_i; |
input dcpu_cycstb_i; |
input dcpu_we_i; |
output [3:0] dcpu_tag_o; |
output dcpu_err_o; |
135,8 → 137,7
input dcdmmu_err_i; |
input [3:0] dcdmmu_tag_i; |
output [aw-1:0] dcdmmu_adr_o; |
output dcdmmu_cyc_o; |
output dcdmmu_stb_o; |
output dcdmmu_cycstb_o; |
output dcdmmu_ci_o; |
|
// |
155,6 → 156,7
reg dtlb_done; |
wire fault; |
wire miss; |
reg [31:`OR1200_DMMU_PS] dcpu_vpn_r; |
|
// |
// Implemented bits inside match and translate registers |
177,10 → 179,9
assign spr_dat_o = 32'h00000000; |
assign dcdmmu_adr_o = dcpu_adr_i; |
assign dcpu_tag_o = dcdmmu_tag_i; |
assign dcdmmu_cyc_o = dcpu_cyc_i; |
assign dcdmmu_stb_o = dcpu_stb_i; |
assign dcdmmu_cyc_o = dcpu_cycstb_i; |
assign dcpu_err_o = dcdmmu_err_i; |
assign dcdmmu_ci_o = dcpu_adr_i[31]; |
assign dcdmmu_ci_o = `OR1200_DMMU_CI; |
|
`else |
|
215,27 → 216,36
if (rst) |
dtlb_done <= #1 1'b0; |
else if (dtlb_en) |
dtlb_done <= #1 dcpu_cyc_i; |
dtlb_done <= #1 dcpu_cycstb_i; |
else |
dtlb_done <= #1 1'b0; |
|
|
// |
// Cut transfer if something goes wrong with translation. If DC is disabled, |
// use delayed signals. |
// Cut transfer if something goes wrong with translation. Also delayed signals because of translation delay. |
// |
assign dcdmmu_cyc_o = (!dc_en & dmmu_en) ? ~(miss | fault) & dtlb_done & dcpu_cyc_i : (miss | fault) ? 1'b0 : dcpu_cyc_i; |
assign dcdmmu_stb_o = (!dc_en & dmmu_en) ? ~(miss | fault) & dtlb_done & dcpu_stb_i : (miss | fault) ? 1'b0 : dcpu_stb_i; |
assign dcdmmu_cycstb_o = (!dc_en & dmmu_en) ? ~(miss | fault) & dtlb_done & dcpu_cycstb_i : ~(miss | fault) & dcpu_cycstb_i; |
//assign dcdmmu_cycstb_o = (dmmu_en) ? ~(miss | fault) & dcpu_cycstb_i : (miss | fault) ? 1'b0 : dcpu_cycstb_i; |
|
// |
// Cache Inhibit |
// |
assign dcdmmu_ci_o = dmmu_en ? dtlb_done & dtlb_ci : dcpu_adr_i[31]; |
assign dcdmmu_ci_o = dmmu_en ? dtlb_done & dtlb_ci : `OR1200_DMMU_CI; |
|
// |
// Register dcpu_adr_i's VPN for use when DMMU is not enabled but PPN is expected to come |
// one clock cycle after offset part. |
// |
always @(posedge clk or posedge rst) |
if (rst) |
dcpu_vpn_r <= #1 {31-`OR1200_DMMU_PS{1'b0}}; |
else |
dcpu_vpn_r <= #1 dcpu_adr_i[31:`OR1200_DMMU_PS]; |
|
// |
// Physical address is either translated virtual address or |
// simply equal when DMMU is disabled |
// |
// assign dcdmmu_adr_o = dmmu_en ? {dtlb_ppn, dcpu_adr_i[`OR1200_DMMU_PS-1:0]} : {dcpu_vpn_r, dcpu_adr_i[`OR1200_DMMU_PS-1:0]}; |
assign dcdmmu_adr_o = dmmu_en ? {dtlb_ppn, dcpu_adr_i[`OR1200_DMMU_PS-1:0]} : dcpu_adr_i; |
|
// |
260,7 → 270,7
// |
// DTLB Enable |
// |
assign dtlb_en = dmmu_en & dcpu_cyc_i & dcpu_stb_i; |
assign dtlb_en = dmmu_en & dcpu_cycstb_i; |
|
// |
// Instantiation of DTLB |
/trunk/or1200/rtl/verilog/or1200_except.v
44,6 → 44,9
// CVS Revision History |
// |
// $Log: not supported by cvs2svn $ |
// Revision 1.8 2002/01/28 01:16:00 lampret |
// Changed 'void' nop-ops instead of insn[0] to use insn[16]. Debug unit stalls the tick timer. Prepared new flag generation for add and and insns. Blocked DC/IC while they are turned off. Fixed I/D MMU SPRs layout except WAYs. TODO: smart IC invalidate, l.j 2 and TLB ways. |
// |
// Revision 1.7 2002/01/23 07:52:36 lampret |
// Changed default reset values for SR and ESR to match or1ksim's. Fixed flop model in or1200_dpram_32x32 when OR1200_XILINX_RAM32X1D is defined. |
// |
382,7 → 385,7
extend_flush <= #1 1'b0; |
epcr <= #1 32'b0; |
eear <= #1 32'b0; |
esr <= #1 {1'b1, {`OR1200_SR_WIDTH-3{1'b0}}, 2'b11}; |
esr <= #1 {1'b1, {`OR1200_SR_WIDTH-2{1'b0}}, 1'b1}; |
extend_flush_last <= #1 1'b0; |
end |
else begin |
/trunk/or1200/rtl/verilog/or1200_genpc.v
44,6 → 44,9
// CVS Revision History |
// |
// $Log: not supported by cvs2svn $ |
// Revision 1.4 2002/01/28 01:16:00 lampret |
// Changed 'void' nop-ops instead of insn[0] to use insn[16]. Debug unit stalls the tick timer. Prepared new flag generation for add and and insns. Blocked DC/IC while they are turned off. Fixed I/D MMU SPRs layout except WAYs. TODO: smart IC invalidate, l.j 2 and TLB ways. |
// |
// Revision 1.3 2002/01/18 07:56:00 lampret |
// No more low/high priority interrupts (PICPR removed). Added tick timer exception. Added exception prefix (SR[EPH]). Fixed single-step bug whenreading NPC. |
// |
86,7 → 89,7
clk, rst, |
|
// External i/f to IC |
icpu_adr_o, icpu_cyc_o, icpu_stb_o, icpu_sel_o, icpu_tag_o, |
icpu_adr_o, icpu_cycstb_o, icpu_sel_o, icpu_tag_o, |
icpu_ack_i, icpu_rty_i, icpu_err_i, icpu_adr_i, |
|
// Internal i/f |
110,8 → 113,7
// External i/f to IC |
// |
output [31:0] icpu_adr_o; |
output icpu_cyc_o; |
output icpu_stb_o; |
output icpu_cycstb_o; |
output [3:0] icpu_sel_o; |
output [3:0] icpu_tag_o; |
input icpu_ack_i; |
157,9 → 159,8
// |
// Control access to IC subsystem |
// |
// assign icpu_cyc_o = !genpc_freeze & !no_more_dslot; |
assign icpu_cyc_o = !genpc_freeze; |
assign icpu_stb_o = icpu_cyc_o; |
// assign icpu_cycstb_o = !genpc_freeze & !no_more_dslot; |
assign icpu_cycstb_o = !genpc_freeze; |
assign icpu_sel_o = 4'b1111; |
assign icpu_tag_o = `OR1200_ITAG_NI; |
|
/trunk/or1200/rtl/verilog/or1200_ic_fsm.v
44,6 → 44,9
// CVS Revision History |
// |
// $Log: not supported by cvs2svn $ |
// Revision 1.4 2002/02/01 19:56:54 lampret |
// Fixed combinational loops. |
// |
// Revision 1.3 2002/01/28 01:16:00 lampret |
// Changed 'void' nop-ops instead of insn[0] to use insn[16]. Debug unit stalls the tick timer. Prepared new flag generation for add and and insns. Blocked DC/IC while they are turned off. Fixed I/D MMU SPRs layout except WAYs. TODO: smart IC invalidate, l.j 2 and TLB ways. |
// |
92,10 → 95,10
clk, rst, |
|
// Internal i/f to top level IC |
ic_en, icimmu_cyc_i, icimmu_stb_i, icimmu_ci_i, icpu_sel_i, |
ic_en, icimmu_cycstb_i, icimmu_ci_i, icpu_sel_i, |
tagcomp_miss, biudata_valid, biudata_error, start_addr, saved_addr, |
icram_we, biu_read, first_hit_ack, first_miss_ack, first_miss_err, |
burst |
burst, tag_we |
); |
|
// |
104,8 → 107,7
input clk; |
input rst; |
input ic_en; |
input icimmu_cyc_i; |
input icimmu_stb_i; |
input icimmu_cycstb_i; |
input icimmu_ci_i; |
input [3:0] icpu_sel_i; |
input tagcomp_miss; |
119,20 → 121,23
output first_miss_ack; |
output first_miss_err; |
output burst; |
output tag_we; |
|
// |
// Internal wires and regs |
// |
reg [31:0] saved_addr; |
reg [31:0] saved_addr_r; |
reg [2:0] state; |
reg [2:0] cnt; |
reg hitmiss_eval; |
reg load; |
reg cache_inhibit; |
|
// |
// Generate of ICRAM write enables |
// |
assign icram_we = {4{load & biudata_valid & (state != `OR1200_ICFSM_IFETCH)}}; |
assign icram_we = {4{load & biudata_valid & !cache_inhibit}}; |
assign tag_we = biu_read & biudata_valid & !cache_inhibit; |
|
// |
// BIU read and write |
139,19 → 144,22
// |
assign biu_read = (hitmiss_eval & tagcomp_miss) | (!hitmiss_eval & load); |
|
//assign saved_addr = hitmiss_eval ? start_addr : saved_addr_r; |
assign saved_addr = saved_addr_r; |
|
// |
// Assert for cache hit first word ready |
// Assert for cache miss first word stored/loaded OK |
// Assert for cache miss first word stored/loaded with an error |
// |
assign first_hit_ack = (state == `OR1200_ICFSM_CFETCH) & hitmiss_eval & !tagcomp_miss; |
assign first_miss_ack = ((state == `OR1200_ICFSM_CFETCH) | (state == `OR1200_ICFSM_IFETCH)) & biudata_valid; |
assign first_miss_err = ((state == `OR1200_ICFSM_CFETCH) | (state == `OR1200_ICFSM_IFETCH)) & biudata_error; |
assign first_hit_ack = (state == `OR1200_ICFSM_CFETCH) & hitmiss_eval & !tagcomp_miss & !cache_inhibit & !icimmu_ci_i; |
assign first_miss_ack = (state == `OR1200_ICFSM_CFETCH) & biudata_valid; |
assign first_miss_err = (state == `OR1200_ICFSM_CFETCH) & biudata_error; |
|
// |
// Assert burst when doing reload of complete cache line |
// |
assign burst = (state == `OR1200_ICFSM_CFETCH) & tagcomp_miss |
assign burst = (state == `OR1200_ICFSM_CFETCH) & tagcomp_miss & !cache_inhibit |
| (state == `OR1200_ICFSM_LREFILL3); |
|
// |
160,97 → 168,90
always @(posedge clk or posedge rst) begin |
if (rst) begin |
state <= #1 `OR1200_ICFSM_IDLE; |
saved_addr <= #1 32'b0; |
saved_addr_r <= #1 32'b0; |
hitmiss_eval <= #1 1'b0; |
load <= #1 1'b0; |
cnt <= #1 3'b000; |
cache_inhibit <= #1 1'b0; |
end |
else |
case (state) // synopsys parallel_case |
`OR1200_ICFSM_IDLE : |
if (ic_en & icimmu_cyc_i & icimmu_stb_i & icimmu_ci_i) begin // fetch from cache-inhibited area |
state <= #1 `OR1200_ICFSM_IFETCH; |
saved_addr <= #1 start_addr; |
hitmiss_eval <= #1 1'b0; |
load <= #1 1'b1; |
end |
else if (ic_en & icimmu_cyc_i & icimmu_stb_i) begin // fetch from cached area |
if (ic_en & icimmu_cycstb_i) begin // fetch |
state <= #1 `OR1200_ICFSM_CFETCH; |
saved_addr <= #1 start_addr; |
saved_addr_r <= #1 start_addr; |
hitmiss_eval <= #1 1'b1; |
load <= #1 1'b1; |
cache_inhibit <= #1 1'b0; |
end |
else begin // idle |
state <= #1 `OR1200_ICFSM_IDLE; |
hitmiss_eval <= #1 1'b0; |
load <= #1 1'b0; |
cache_inhibit <= #1 1'b0; |
end |
`OR1200_ICFSM_CFETCH: // fetch from cached area |
`OR1200_ICFSM_CFETCH: begin // fetch |
if (icimmu_cycstb_i & icimmu_ci_i) |
cache_inhibit <= #1 1'b1; |
if (hitmiss_eval) |
saved_addr_r[31:13] <= #1 start_addr[31:13]; |
if (!ic_en) |
state <= #1 `OR1200_ICFSM_IDLE; |
else if (hitmiss_eval & !(icimmu_cyc_i & icimmu_stb_i)) begin // fetch aborted (usually caused by IMMU) |
else if (hitmiss_eval & !icimmu_cycstb_i) begin // fetch aborted (usually caused by IMMU) |
state <= #1 `OR1200_ICFSM_IDLE; |
hitmiss_eval <= #1 1'b0; |
load <= #1 1'b0; |
cache_inhibit <= #1 1'b0; |
end |
else if (biudata_error) begin // fetch terminated with an error |
state <= #1 `OR1200_ICFSM_IDLE; |
hitmiss_eval <= #1 1'b0; |
load <= #1 1'b0; |
cache_inhibit <= #1 1'b0; |
end |
else if (cache_inhibit & biudata_valid) begin // fetch from cache-inhibited page |
state <= #1 `OR1200_ICFSM_IDLE; |
hitmiss_eval <= #1 1'b0; |
load <= #1 1'b0; |
cache_inhibit <= #1 1'b0; |
end |
else if (tagcomp_miss & biudata_valid) begin // fetch missed, finish current external fetch and refill |
state <= #1 `OR1200_ICFSM_LREFILL3; |
saved_addr[3:2] <= #1 saved_addr[3:2] + 'd1; |
saved_addr_r[3:2] <= #1 saved_addr_r[3:2] + 'd1; |
hitmiss_eval <= #1 1'b0; |
cnt <= #1 `OR1200_ICLS-2; |
cache_inhibit <= #1 1'b0; |
end |
else if (!tagcomp_miss) begin // fetch hit, finish immediately |
else if (!tagcomp_miss & !icimmu_ci_i) begin // fetch hit, finish immediately |
state <= #1 `OR1200_ICFSM_CFETCH; |
saved_addr <= #1 start_addr; |
saved_addr_r <= #1 start_addr; |
hitmiss_eval <= #1 1'b1; |
load <= #1 1'b1; |
cache_inhibit <= #1 1'b0; |
end |
else if (!icimmu_cyc_i | !icimmu_stb_i) begin // fetch aborted (usually caused by exception) |
else if (!icimmu_cycstb_i) begin // fetch aborted (usually caused by exception) |
state <= #1 `OR1200_ICFSM_IDLE; |
hitmiss_eval <= #1 1'b0; |
load <= #1 1'b0; |
cache_inhibit <= #1 1'b0; |
end |
else // fetch in-progress |
hitmiss_eval <= #1 1'b0; |
end |
`OR1200_ICFSM_LREFILL3 : begin |
if (!ic_en) |
state <= #1 `OR1200_ICFSM_IDLE; |
else if (biudata_valid && (|cnt)) begin // refill ack, more fetchs to come |
cnt <= #1 cnt - 'd1; |
saved_addr[3:2] <= #1 saved_addr[3:2] + 'd1; |
saved_addr_r[3:2] <= #1 saved_addr_r[3:2] + 'd1; |
end |
else if (biudata_valid) begin // last fetch of line refill |
state <= #1 `OR1200_ICFSM_IDLE; |
saved_addr <= #1 start_addr; |
saved_addr_r <= #1 start_addr; |
hitmiss_eval <= #1 1'b0; |
load <= #1 1'b0; |
end |
end |
`OR1200_ICFSM_IFETCH: // fetch from cache-inhibited area |
if (!ic_en) |
state <= #1 `OR1200_ICFSM_IDLE; |
else if (!(icimmu_cyc_i & icimmu_stb_i)) begin // fetch aborted (usually caused by IMMU) |
state <= #1 `OR1200_ICFSM_IDLE; |
hitmiss_eval <= #1 1'b0; |
load <= #1 1'b0; |
end |
else if (biudata_error) begin // fetch terminated with an error |
state <= #1 `OR1200_ICFSM_IDLE; |
hitmiss_eval <= #1 1'b0; |
load <= #1 1'b0; |
end |
else if (biudata_valid) begin // fetch from cache inhibit page |
state <= #1 `OR1200_ICFSM_IDLE; |
hitmiss_eval <= #1 1'b0; |
load <= #1 1'b0; |
end |
else // fetch in-progress |
hitmiss_eval <= #1 1'b0; |
default: |
state <= #1 `OR1200_ICFSM_IDLE; |
endcase |
/trunk/or1200/rtl/verilog/or1200_top.v
44,6 → 44,9
// CVS Revision History |
// |
// $Log: not supported by cvs2svn $ |
// Revision 1.4 2002/02/01 19:56:55 lampret |
// Fixed combinational loops. |
// |
// Revision 1.3 2002/01/28 01:16:00 lampret |
// Changed 'void' nop-ops instead of insn[0] to use insn[16]. Debug unit stalls the tick timer. Prepared new flag generation for add and and insns. Blocked DC/IC while they are turned off. Fixed I/D MMU SPRs layout except WAYs. TODO: smart IC invalidate, l.j 2 and TLB ways. |
// |
247,8 → 250,7
wire dcdmmu_err_dc; |
wire [3:0] dcdmmu_tag_dc; |
wire [aw-1:0] dcdmmu_adr_dmmu; |
wire dcdmmu_cyc_dmmu; |
wire dcdmmu_stb_dmmu; |
wire dcdmmu_cycstb_dmmu; |
wire dcdmmu_ci_dmmu; |
|
// |
277,8 → 279,7
// |
wire ic_en; |
wire [31:0] icpu_adr_cpu; |
wire icpu_cyc_cpu; |
wire icpu_stb_cpu; |
wire icpu_cycstb_cpu; |
wire icpu_we_cpu; |
wire [3:0] icpu_sel_cpu; |
wire [3:0] icpu_tag_cpu; |
295,8 → 296,7
wire icimmu_rty_ic; |
wire icimmu_err_ic; |
wire [3:0] icimmu_tag_ic; |
wire icimmu_cyc_immu; |
wire icimmu_stb_immu; |
wire icimmu_cycstb_immu; |
wire icimmu_ci_immu; |
|
// |
421,8 → 421,7
.immu_en(immu_en), |
.supv(supv), |
.icpu_adr_i(icpu_adr_cpu), |
.icpu_cyc_i(icpu_cyc_cpu), |
.icpu_stb_i(icpu_stb_cpu), |
.icpu_cycstb_i(icpu_cycstb_cpu), |
.icpu_adr_o(icpu_adr_immu), |
.icpu_tag_o(icpu_tag_immu), |
.icpu_rty_o(icpu_rty_immu), |
440,8 → 439,7
.icimmu_err_i(icimmu_err_ic), |
.icimmu_tag_i(icimmu_tag_ic), |
.icimmu_adr_o(icimmu_adr_immu), |
.icimmu_cyc_o(icimmu_cyc_immu), |
.icimmu_stb_o(icimmu_stb_immu), |
.icimmu_cycstb_o(icimmu_cycstb_immu), |
.icimmu_ci_o(icimmu_ci_immu) |
); |
|
455,8 → 453,7
// IC and CPU/IMMU |
.ic_en(ic_en), |
.icimmu_adr_i(icimmu_adr_immu), |
.icimmu_cyc_i(icimmu_cyc_immu), |
.icimmu_stb_i(icimmu_stb_immu), |
.icimmu_cycstb_i(icimmu_cycstb_immu), |
.icimmu_ci_i(icimmu_ci_immu), |
.icpu_we_i(icpu_we_cpu), |
.icpu_sel_i(icpu_sel_cpu), |
495,8 → 492,7
// Connection IC and IFETCHER inside CPU |
.ic_en(ic_en), |
.icpu_adr_o(icpu_adr_cpu), |
.icpu_cyc_o(icpu_cyc_cpu), |
.icpu_stb_o(icpu_stb_cpu), |
.icpu_cycstb_o(icpu_cycstb_cpu), |
.icpu_we_o(icpu_we_cpu), |
.icpu_sel_o(icpu_sel_cpu), |
.icpu_tag_o(icpu_tag_cpu), |
526,8 → 522,7
// Connection DC and CPU |
.dc_en(dc_en), |
.dcpu_adr_o(dcpu_adr_cpu), |
.dcpu_cyc_o(dcpu_cyc_cpu), |
.dcpu_stb_o(dcpu_stb_cpu), |
.dcpu_cycstb_o(dcpu_cycstb_cpu), |
.dcpu_we_o(dcpu_we_cpu), |
.dcpu_sel_o(dcpu_sel_cpu), |
.dcpu_tag_o(dcpu_tag_cpu), |
572,8 → 567,7
.dmmu_en(dmmu_en), |
.supv(supv), |
.dcpu_adr_i(dcpu_adr_cpu), |
.dcpu_cyc_i(dcpu_cyc_cpu), |
.dcpu_stb_i(dcpu_stb_cpu), |
.dcpu_cycstb_i(dcpu_cycstb_cpu), |
.dcpu_we_i(dcpu_we_cpu), |
.dcpu_tag_o(dcpu_tag_dmmu), |
.dcpu_err_o(dcpu_err_dmmu), |
589,8 → 583,7
.dcdmmu_err_i(dcdmmu_err_dc), |
.dcdmmu_tag_i(dcdmmu_tag_dc), |
.dcdmmu_adr_o(dcdmmu_adr_dmmu), |
.dcdmmu_cyc_o(dcdmmu_cyc_dmmu), |
.dcdmmu_stb_o(dcdmmu_stb_dmmu), |
.dcdmmu_cycstb_o(dcdmmu_cycstb_dmmu), |
.dcdmmu_ci_o(dcdmmu_ci_dmmu) |
); |
|
604,8 → 597,7
// DC and CPU/DMMU |
.dc_en(dc_en), |
.dcdmmu_adr_i(dcdmmu_adr_dmmu), |
.dcdmmu_cyc_i(dcdmmu_cyc_dmmu), |
.dcdmmu_stb_i(dcdmmu_stb_dmmu), |
.dcdmmu_cycstb_i(dcdmmu_cycstb_dmmu), |
.dcdmmu_ci_i(dcdmmu_ci_dmmu), |
.dcpu_we_i(dcpu_we_cpu), |
.dcpu_sel_i(dcpu_sel_cpu), |
642,11 → 634,9
// RISC Internal Interface |
.clk(clk_i), |
.rst(rst_i), |
.dcpu_cyc_i(dcpu_cyc_cpu), |
.dcpu_stb_i(dcpu_stb_cpu), |
.dcpu_cycstb_i(dcpu_cycstb_cpu), |
.dcpu_we_i(dcpu_we_cpu), |
.icpu_cyc_i(icpu_cyc_cpu), |
.icpu_stb_i(icpu_stb_cpu), |
.icpu_cycstb_i(icpu_cycstb_cpu), |
.ex_freeze(ex_freeze), |
.branch_op(branch_op), |
.ex_insn(ex_insn), |
/trunk/or1200/rtl/verilog/or1200_dmmu_tlb.v
44,6 → 44,9
// CVS Revision History |
// |
// $Log: not supported by cvs2svn $ |
// Revision 1.2 2002/01/28 01:16:00 lampret |
// Changed 'void' nop-ops instead of insn[0] to use insn[16]. Debug unit stalls the tick timer. Prepared new flag generation for add and and insns. Blocked DC/IC while they are turned off. Fixed I/D MMU SPRs layout except WAYs. TODO: smart IC invalidate, l.j 2 and TLB ways. |
// |
// Revision 1.1 2002/01/03 08:16:15 lampret |
// New prefixes for RTL files, prefixed module names. Updated cache controllers and MMUs. |
// |
165,7 → 168,7
// Output to SPRS unit |
// |
assign spr_dat_o = (spr_cs & !spr_write & !spr_addr[`OR1200_DTLB_TM_ADDR]) ? |
{vpn, tlb_index, {`OR1200_DTLB_TAGW-1{1'b0}}, v} : |
{vpn, tlb_index & {`OR1200_DTLB_INDXW{v}}, {`OR1200_DTLB_TAGW-7{1'b0}}, 1'b0, 5'b00000, v} : |
(spr_cs & !spr_write & spr_addr[`OR1200_DTLB_TM_ADDR]) ? |
{ppn, {`OR1200_DMMU_PS-10{1'b0}}, swe, sre, uwe, ure, {4{1'b0}}, ci, 1'b0} : |
32'h00000000; |
/trunk/or1200/rtl/verilog/or1200_lsu.v
44,6 → 44,9
// CVS Revision History |
// |
// $Log: not supported by cvs2svn $ |
// Revision 1.2 2002/01/18 07:56:00 lampret |
// No more low/high priority interrupts (PICPR removed). Added tick timer exception. Added exception prefix (SR[EPH]). Fixed single-step bug whenreading NPC. |
// |
// Revision 1.1 2002/01/03 08:16:15 lampret |
// New prefixes for RTL files, prefixed module names. Updated cache controllers and MMUs. |
// |
81,7 → 84,7
du_stall, flushpipe, except_align, except_dtlbmiss, except_dmmufault, except_dbuserr, |
|
// External i/f to DC |
dcpu_adr_o, dcpu_cyc_o, dcpu_stb_o, dcpu_we_o, dcpu_sel_o, dcpu_tag_o, dcpu_dat_o, |
dcpu_adr_o, dcpu_cycstb_o, dcpu_we_o, dcpu_sel_o, dcpu_tag_o, dcpu_dat_o, |
dcpu_dat_i, dcpu_ack_i, dcpu_rty_i, dcpu_err_i, dcpu_tag_i |
); |
|
119,8 → 122,7
// External i/f to DC |
// |
output [31:0] dcpu_adr_o; |
output dcpu_cyc_o; |
output dcpu_stb_o; |
output dcpu_cycstb_o; |
output dcpu_we_o; |
output [3:0] dcpu_sel_o; |
output [3:0] dcpu_tag_o; |
139,7 → 141,7
// |
// Internal I/F assignments |
// |
assign lsu_stall = dcpu_rty_i & dcpu_cyc_o; |
assign lsu_stall = dcpu_rty_i & dcpu_cycstb_o; |
assign lsu_unstall = dcpu_ack_i; |
assign except_align = ((lsu_op == `OR1200_LSUOP_SH) | (lsu_op == `OR1200_LSUOP_LHZ) | (lsu_op == `OR1200_LSUOP_LHS)) & dcpu_adr_o[0] |
| ((lsu_op == `OR1200_LSUOP_SW) | (lsu_op == `OR1200_LSUOP_LWZ) | (lsu_op == `OR1200_LSUOP_LWS)) & |dcpu_adr_o[1:0]; |
151,10 → 153,9
// External I/F assignments |
// |
assign dcpu_adr_o = addrbase + addrofs; |
assign dcpu_cyc_o = du_stall | lsu_unstall ? 1'b0 : |lsu_op; |
assign dcpu_stb_o = dcpu_cyc_o; |
assign dcpu_cycstb_o = du_stall | lsu_unstall ? 1'b0 : |lsu_op; |
assign dcpu_we_o = lsu_op[3]; |
assign dcpu_tag_o = dcpu_cyc_o ? `OR1200_DTAG_ND : `OR1200_DTAG_IDLE; |
assign dcpu_tag_o = dcpu_cycstb_o ? `OR1200_DTAG_ND : `OR1200_DTAG_IDLE; |
always @(lsu_op or dcpu_adr_o) |
casex({lsu_op, dcpu_adr_o[1:0]}) |
{`OR1200_LSUOP_SB, 2'b00} : dcpu_sel_o = 4'b1000; |