OpenCores
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;

powered by: WebSVN 2.1.0

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