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

Subversion Repositories openrisc_me

Compare Revisions

  • This comparison shows the changes necessary to convert path
    /openrisc/trunk/orpsocv2/rtl/verilog/or1200
    from Rev 482 to Rev 483
    Reverse comparison

Rev 482 → Rev 483

/or1200_cpu.v
86,6 → 86,11
// SPR interface
supv, spr_addr, spr_dat_cpu, spr_dat_pic, spr_dat_tt, spr_dat_pm,
spr_dat_dmmu, spr_dat_immu, spr_dat_du, spr_cs, spr_we, mtspr_dc_done
 
`ifdef OR1200_RAM_PARITY
,p_err_rf
`endif
);
 
parameter dw = `OR1200_OPERAND_WIDTH;
207,6 → 212,14
input sig_tick;
 
//
// Register file parity error indicator
//
`ifdef OR1200_RAM_PARITY
output p_err_rf;
`endif
//
// Internal wires
//
wire [31:0] if_insn;
531,6 → 544,9
or1200_rf or1200_rf(
.clk(clk),
.rst(rst),
`ifdef OR1200_RAM_PARITY
.p_err(p_err_rf),
`endif
.cy_we_i(cy_we_alu),
.cy_we_o(cy_we_rf),
.supv(sr[`OR1200_SR_SM]),
/or1200_immu_top.v
69,6 → 69,11
mbist_si_i, mbist_so_o, mbist_ctrl_i,
`endif
 
`ifdef OR1200_RAM_PARITY
// Parity error indicator
p_err,
`endif
 
// QMEM i/f
qmemimmu_rty_i, qmemimmu_err_i, qmemimmu_tag_i, qmemimmu_adr_o, qmemimmu_cycstb_o, qmemimmu_ci_o
);
122,6 → 127,10
output mbist_so_o;
`endif
 
`ifdef OR1200_RAM_PARITY
output [1:0] p_err;
`endif
//
// IC I/F
//
158,7 → 167,8
reg dis_spr_access_frst_clk;
reg dis_spr_access_scnd_clk;
`endif
 
reg [31:0] spr_dat_reg;
//
// Implemented bits inside match and translate registers
//
172,6 → 182,9
// 2 bits for protection
// 1 bit for cache inhibit
 
 
assign icpu_adr_boot = `OR1200_BOOT_ADR;
//
// icpu_adr_o
//
180,7 → 193,7
// default value
if (rst == `OR1200_RST_VALUE) begin
// select async. value due to reset state
icpu_adr_default <= 32'h0000_0100;
icpu_adr_o <= 32'h0000_0100;
icpu_adr_select <= 1'b1;
end
// selected value (different from default) is written
187,27 → 200,13
// into FF after reset state
else if (icpu_adr_select) begin
// dynamic value can only be assigned to FF out of reset!
icpu_adr_default <= icpu_adr_boot;
icpu_adr_o <= icpu_adr_boot;
// select FF value
icpu_adr_select <= 1'b0;
end
else begin
icpu_adr_default <= icpu_adr_i;
icpu_adr_o <= icpu_adr_i;
end
 
// select async. value for boot address after reset - PC jumps to the address
// selected after boot!
//assign icpu_adr_boot = {(boot_adr_sel_i ? `OR1200_EXCEPT_EPH1_P :
// `OR1200_EXCEPT_EPH0_P), 12'h100} ;
assign icpu_adr_boot = `OR1200_BOOT_ADR; // jb
 
always @(icpu_adr_boot or icpu_adr_default or icpu_adr_select)
if (icpu_adr_select)
// async. value is selected due to reset state
icpu_adr_o = icpu_adr_boot ;
else
// FF value is selected 2nd clock after reset state
icpu_adr_o = icpu_adr_default ;
`else
Unsupported !!!
`endif
220,8 → 219,8
assign page_cross = icpu_adr_i[31:`OR1200_IMMU_PS] != icpu_vpn_r;
 
//
// 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.
// 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 `OR1200_RST_EVENT rst)
if (rst == `OR1200_RST_VALUE)
244,6 → 243,10
`ifdef OR1200_BIST
assign mbist_so_o = mbist_si_i;
`endif
`ifdef OR1200_RAM_PARITY
assign p_err = 0;
`endif
`else
 
//
292,7 → 295,8
// OR1200_ITAG_TE - TLB miss Exception
// OR1200_ITAG_PE - Page fault Exception
//
assign icpu_tag_o = miss ? `OR1200_ITAG_TE : fault ? `OR1200_ITAG_PE : qmemimmu_tag_i;
assign icpu_tag_o = miss ? `OR1200_ITAG_TE :
fault ? `OR1200_ITAG_PE : qmemimmu_tag_i;
 
//
// icpu_rty_o
304,7 → 308,11
//
// icpu_err_o
//
assign icpu_err_o = miss | fault | qmemimmu_err_i;
assign icpu_err_o = miss | fault | qmemimmu_err_i
`ifdef OR1200_RAM_PARITY
| (|p_err)
`endif
;
 
//
// Assert itlb_en_r after one clock cycle and when there is no
314,7 → 322,7
if (rst == `OR1200_RST_VALUE)
itlb_en_r <= 1'b0;
else
itlb_en_r <= itlb_en & ~itlb_spr_access;
itlb_en_r <= itlb_en & ~itlb_spr_access;
 
//
// ITLB lookup successful
322,12 → 330,13
assign itlb_done = itlb_en_r & ~page_cross;
 
//
// Cut transfer when access (mtspr/mfspr) to/from ITLB occure or if something goes
// wrong with translation. If IC is disabled, use delayed signals.
// Cut transfer when access (mtspr/mfspr) to/from ITLB occurs or if something
// goes wrong with translation. If IC is disabled, use delayed signals.
//
// assign qmemimmu_cycstb_o = (!ic_en & immu_en) ? ~(miss | fault) & icpu_cycstb_i & ~page_cross : (miss | fault) ? 1'b0 : icpu_cycstb_i & ~page_cross; // DL
//assign qmemimmu_cycstb_o = immu_en ? ~(miss | fault) & icpu_cycstb_i & ~page_cross & itlb_done : icpu_cycstb_i & ~page_cross;
assign qmemimmu_cycstb_o = immu_en ? ~(miss | fault) & icpu_cycstb_i & ~page_cross & itlb_done & ~itlb_spr_access : icpu_cycstb_i & ~page_cross;
assign qmemimmu_cycstb_o = immu_en ?
~(miss | fault) & icpu_cycstb_i & ~page_cross &
itlb_done & ~itlb_spr_access :
icpu_cycstb_i & ~page_cross;
 
//
// Cache Inhibit
337,8 → 346,6
// assign qmemimmu_ci_o = immu_en ? itlb_done & itlb_ci : `OR1200_IMMU_CI;
// However this causes an async combinatorial loop so we stick to
// no cache inhibit.
//assign qmemimmu_ci_o = `OR1200_IMMU_CI;
// Cache inhibit without an async combinatorial loop
assign qmemimmu_ci_o = immu_en ? itlb_ci : `OR1200_IMMU_CI;
 
 
346,10 → 353,10
// Physical address is either translated virtual address or
// simply equal when IMMU is disabled
//
//assign qmemimmu_adr_o = itlb_done ? {itlb_ppn, icpu_adr_i[`OR1200_IMMU_PS-1:0]} : {icpu_vpn_r, icpu_adr_i[`OR1200_IMMU_PS-1:0]}; // DL: immu_en
assign qmemimmu_adr_o = immu_en & itlb_done ? {itlb_ppn, icpu_adr_i[`OR1200_IMMU_PS-1:2], 2'h0} : {icpu_vpn_r, icpu_adr_i[`OR1200_IMMU_PS-1:2], 2'h0};
assign qmemimmu_adr_o = immu_en & itlb_done ?
{itlb_ppn, icpu_adr_i[`OR1200_IMMU_PS-1:2], 2'h0} :
{icpu_vpn_r, icpu_adr_i[`OR1200_IMMU_PS-1:2], 2'h0};
 
reg [31:0] spr_dat_reg;
//
// Output to SPRS unit
//
367,8 → 374,8
// Page fault exception logic
//
assign fault = itlb_done &
( (!supv & !itlb_uxe) // Execute in user mode not enabled
|| (supv & !itlb_sxe)); // Execute in supv mode not enabled
((!supv & !itlb_uxe) // Execute in user mode not enabled
|| (supv & !itlb_sxe));// Execute in supv mode not en.
 
//
// TLB Miss exception logic
404,6 → 411,10
.mbist_ctrl_i(mbist_ctrl_i),
`endif
 
`ifdef OR1200_RAM_PARITY
.p_err(p_err),
`endif
 
// SPR access
.spr_cs(itlb_spr_access),
.spr_write(spr_write),
/or1200_ic_tag.v
63,6 → 63,11
mbist_si_i, mbist_so_o, mbist_ctrl_i,
`endif
 
`ifdef OR1200_RAM_PARITY
// Parity error indicator
p_err,
`endif
// Internal i/f
addr, en, we, datain, tag_v, tag
);
89,6 → 94,15
output mbist_so_o;
`endif
 
`ifdef OR1200_RAM_PARITY
parameter tag_ram_extra_width = 24 - `OR1200_ICTAG_W;
output p_err;
wire [24-2:0] tag_wire;
`else
wire [dw-2:0] tag_wire;
`endif
//
// Internal i/f
//
97,8 → 111,9
input we;
input [dw-1:0] datain;
output tag_v;
output [dw-2:0] tag;
output [dw-2:0] tag;
 
`ifdef OR1200_NO_IC
 
//
109,9 → 124,15
`ifdef OR1200_BIST
assign mbist_so_o = mbist_si_i;
`endif
`ifdef OR1200_RAM_PARITY
assign p_err = 0;
`endif
 
`else
 
assign tag = tag_wire[dw-2:0];
//
// Instantiation of TAG RAM block
//
118,7 → 139,11
or1200_spram #
(
.aw(`OR1200_ICTAG),
`ifdef OR1200_RAM_PARITY
.dw(24)
`else
.dw(`OR1200_ICTAG_W)
`endif
)
ic_tag0
(
129,15 → 154,18
.mbist_ctrl_i(mbist_ctrl_i),
`endif
.clk(clk),
.rst(rst),
.ce(en),
.we(we),
//.oe(1'b1),
.addr(addr),
`ifdef OR1200_RAM_PARITY
.p_err(p_err),
.di({{tag_ram_extra_width{1'b0}},datain}),
`else
.di(datain),
.doq({tag, tag_v})
`ifdef OR1200_RAM_PARITY
, .p_err()
`endif
.doq({tag_wire, tag_v})
);
`endif
 
/or1200_ic_ram.v
63,6 → 63,11
mbist_si_i, mbist_so_o, mbist_ctrl_i,
`endif
 
`ifdef OR1200_RAM_PARITY
// Parity error indicator
p_err,
`endif
// Internal i/f
addr, en, we, datain, dataout
);
90,6 → 95,10
output mbist_so_o;
`endif
 
`ifdef OR1200_RAM_PARITY
output p_err;
`endif
`ifdef OR1200_NO_IC
 
//
100,6 → 109,10
assign mbist_so_o = mbist_si_i;
`endif
 
`ifdef OR1200_RAM_PARITY
assign p_err = 0;
`endif
 
`else
 
//
118,6 → 131,10
.mbist_so_o(mbist_so_o),
.mbist_ctrl_i(mbist_ctrl_i),
`endif
`ifdef OR1200_RAM_PARITY
.p_err(p_err),
`endif
.rst(rst),
.clk(clk),
.ce(en),
.we(we[0]),
125,9 → 142,6
.addr(addr),
.di(datain),
.doq(dataout)
`ifdef OR1200_RAM_PARITY
, .p_err()
`endif
);
`endif
 
/or1200_parity_chk.v
61,8 → 61,10
input [dw-1:0] d_i; // Data word in
input p_i; // Parity bit in
output err_o; // Error indicator out
assign err_o = ((^d_i[dw-1:0]) != p_i);
 
// Is nice if X's don't propegate through here during simulation, so use
// !==
assign err_o = ((^d_i[dw-1:0]) !== p_i);
 
endmodule // or1200_parity_chk
 
/or1200_dmmu_tlb.v
69,6 → 69,11
mbist_si_i, mbist_so_o, mbist_ctrl_i,
`endif
 
`ifdef OR1200_RAM_PARITY
// Parity error indicator
p_err,
`endif
// SPR access
spr_cs, spr_write, spr_addr, spr_dat_i, spr_dat_o
);
108,6 → 113,10
output mbist_so_o;
`endif
 
`ifdef OR1200_RAM_PARITY
output [1:0] p_err;
`endif
//
// SPR access
//
126,7 → 135,11
wire tlb_mr_en;
wire tlb_mr_we;
wire [`OR1200_DTLBMRW-1:0] tlb_mr_ram_in;
`ifdef OR1200_RAM_PARITY
wire [`OR1200_DTLBMRW-1+2:0] tlb_mr_ram_out;
`else
wire [`OR1200_DTLBMRW-1:0] tlb_mr_ram_out;
`endif
wire tlb_tr_en;
wire tlb_tr_we;
wire [`OR1200_DTLBTRW-1:0] tlb_tr_ram_in;
142,6 → 155,11
assign mbist_so_o = mbist_tr_so;
`endif
 
`ifdef OR1200_RAM_PARITY
wire [1:0] p_err_wire;
reg p_err_en;
`endif
//
// Implemented bits inside match and translate registers
//
187,7 → 205,7
//
// Assign outputs from Match registers
//
assign {vpn, v} = tlb_mr_ram_out;
assign {vpn, v} = tlb_mr_ram_out[`OR1200_DTLBMRW-1:0];
 
//
// Assign to Match registers inputs
212,14 → 230,31
//
// Generate hit
//
assign hit = (vpn == vaddr[`OR1200_DTLB_TAG]) & v;
assign hit = (vpn == vaddr[`OR1200_DTLB_TAG]) & v
`ifdef OR1200_RAM_PARITY
& !p_err
`endif
;
 
//
// TLB index is normally vaddr[18:13]. If it is SPR access then index is
// spr_addr[5:0].
//
assign tlb_index = spr_cs ? spr_addr[`OR1200_DTLB_INDXW-1:0] : vaddr[`OR1200_DTLB_INDX];
assign tlb_index = spr_cs ? spr_addr[`OR1200_DTLB_INDXW-1:0] :
vaddr[`OR1200_DTLB_INDX];
 
`ifdef OR1200_RAM_PARITY
always @(posedge clk)
if (rst)
p_err_en <= 0;
else
p_err_en <= (tlb_mr_en & !tlb_mr_we) | (tlb_tr_en & !tlb_tr_we);
assign p_err = (p_err_en & (tlb_mr_en & !tlb_mr_we) |
(tlb_tr_en & !tlb_tr_we)) ? p_err_wire : 0;
`endif
 
//
// Instantiation of DTLB Match Registers
//
227,11 → 262,16
or1200_spram #
(
.aw(6),
`ifdef OR1200_RAM_PARITY
.dw(16)
`else
.dw(14)
`endif
)
dtlb_ram
dtlb_mr_ram
(
.clk(clk),
.rst(rst),
`ifdef OR1200_BIST
// RAM BIST
.mbist_si_i(mbist_mr_si),
241,17 → 281,18
.ce(tlb_mr_en),
.we(tlb_mr_we),
.addr(tlb_index),
`ifdef OR1200_RAM_PARITY
.p_err(p_err_wire[0]),
.di({2'b00,tlb_mr_ram_in}),
`else
.di(tlb_mr_ram_in),
`endif
.doq(tlb_mr_ram_out)
`ifdef OR1200_RAM_PARITY
, .p_err()
`endif
);
//
// Instantiation of DTLB Translate Registers
//
//or1200_spram_64x24 dtlb_tr_ram(
or1200_spram #
(
.aw(6),
260,6 → 301,7
dtlb_tr_ram
(
.clk(clk),
.rst(rst),
`ifdef OR1200_BIST
// RAM BIST
.mbist_si_i(mbist_tr_si),
266,14 → 308,14
.mbist_so_o(mbist_tr_so),
.mbist_ctrl_i(mbist_ctrl_i),
`endif
`ifdef OR1200_RAM_PARITY
.p_err(p_err_wire[1]),
`endif
.ce(tlb_tr_en),
.we(tlb_tr_we),
.addr(tlb_index),
.di(tlb_tr_ram_in),
.di(tlb_tr_ram_in),
.doq(tlb_tr_ram_out)
`ifdef OR1200_RAM_PARITY
, .p_err()
`endif
);
endmodule // or1200_dmmu_tlb
/or1200_rf.v
56,6 → 56,11
// Clock and reset
clk, rst,
 
`ifdef OR1200_RAM_PARITY
// Parity error indicator
p_err,
`endif
 
// Write i/f
cy_we_i, cy_we_o, supv, wb_freeze, addrw, dataw, we, flushpipe,
 
111,7 → 116,15
input [31:0] spr_dat_i;
output [31:0] spr_dat_o;
input du_read;
 
`ifdef OR1200_RAM_PARITY
output p_err;
wire [1:0] p_err_wire;
reg ena_r, enb_r;
`endif
 
//
// Internal wires and regs
//
149,7 → 162,6
spr_du_cs <= spr_cs & du_read;
 
assign spr_cs_fe = spr_du_cs & !(spr_cs & du_read);
 
//
// SPR access is valid when spr_cs is asserted and
181,12 → 193,12
//
// RF write address is either from SPRS or normal from CPU control
//
assign rf_addrw = (spr_valid & spr_write) ? spr_addr[4:0] : addrw;
assign rf_addrw = rst ? 0 : (spr_valid & spr_write) ? spr_addr[4:0] : addrw;
 
//
// RF write data is either from SPRS or normal from CPU datapath
//
assign rf_dataw = (spr_valid & spr_write) ? spr_dat_i : dataw;
assign rf_dataw = rst ? 0 : (spr_valid & spr_write) ? spr_dat_i : dataw;
 
//
// RF write enable is either from SPRS or normal from CPU control
197,30 → 209,43
else if (~wb_freeze)
rf_we_allow <= ~flushpipe;
 
//assign rf_we = ((spr_valid & spr_write) | (we & ~wb_freeze)) & rf_we_allow & (supv | (|rf_addrw));
assign rf_we = ((spr_valid & spr_write) | (we & ~wb_freeze)) & rf_we_allow;
//assign cy_we_o = cy_we_i && rf_we;
assign rf_we = rst ? 1 : ((spr_valid & spr_write) | (we & ~wb_freeze)) &
rf_we_allow;
 
assign cy_we_o = cy_we_i && ~wb_freeze && rf_we_allow;
//
// CS RF A asserted when instruction reads operand A and ID stage
// is not stalled
//
//assign rf_ena = rda & ~id_freeze | spr_valid; // probably works with fixed binutils
assign rf_ena = (rda & ~id_freeze) | (spr_valid & !spr_write) | spr_cs_fe; // probably works with fixed binutils
// assign rf_ena = 1'b1; // does not work with single-stepping
//assign rf_ena = ~id_freeze | spr_valid; // works with broken binutils
assign rf_ena = (rda & ~id_freeze) | (spr_valid & !spr_write) | spr_cs_fe;
 
//
// CS RF B asserted when instruction reads operand B and ID stage
// is not stalled
//
//assign rf_enb = rdb & ~id_freeze | spr_valid;
assign rf_enb = rdb & ~id_freeze;
// assign rf_enb = 1'b1;
//assign rf_enb = ~id_freeze | spr_valid; // works with broken binutils
 
`ifdef OR1200_RAM_PARITY
always @(posedge clk)
if (rst) begin
ena_r <= 0;
enb_r <= 0;
end
else if (p_err) begin
ena_r <= 0;
enb_r <= 0;
end
else begin
ena_r <= rf_ena;
enb_r <= rf_enb;
end
assign p_err = (p_err_wire[0] & ena_r) | (p_err_wire[1] & enb_r);
`endif
 
`ifdef OR1200_RFRAM_TWOPORT
 
//
273,13 → 298,18
.do_b()
);
 
`ifdef OR1200_RAM_PARITY
assign p_err_wire = 0;
`endif
 
`else
 
`ifdef OR1200_RFRAM_DUALPORT
 
//
// Instantiation of register file two-port RAM A
//
`ifdef OR1200_RFRAM_DUALPORT
//
// Instantiation of register file two-port RAM A
//
or1200_dpram #
(
.aw(5),
287,8 → 317,9
)
rf_a
(
.rst(rst),
// Port A
.clk_a(clk),
.clk_a(clk),
.ce_a(rf_ena),
.addr_a(rf_addra),
.do_a(from_rfa),
300,9 → 331,9
.addr_b(rf_addrw),
.di_b(rf_dataw)
`ifdef OR1200_RAM_PARITY
, .p_err()
`endif
`ifdef OR1200_RAM_PARITY
, .p_err(p_err_wire[0])
`endif
);
 
//
315,6 → 346,7
)
rf_b
(
.rst(rst),
// Port A
.clk_a(clk),
.ce_a(rf_enb),
327,12 → 359,13
.we_b(rf_we),
.addr_b(rf_addrw),
.di_b(rf_dataw)
`ifdef OR1200_RAM_PARITY
, .p_err()
`endif
 
);
`ifdef OR1200_RAM_PARITY
, .p_err(p_err_wire[1])
`endif
 
);
 
`else
 
`ifdef OR1200_RFRAM_GENERIC
362,6 → 395,10
.di_w(rf_dataw)
);
 
`ifdef OR1200_RAM_PARITY
assign p_err_wire = 0;
`endif
 
`else
 
//
/or1200_ic_top.v
71,6 → 71,11
mbist_si_i, mbist_so_o, mbist_ctrl_i,
`endif
 
`ifdef OR1200_RAM_PARITY
// Parity error indicator
p_err,
`endif
 
// SPRs
spr_cs, spr_write, spr_dat_i
);
125,6 → 130,10
output mbist_so_o;
`endif
 
`ifdef OR1200_RAM_PARITY
output [1:0] p_err;
`endif
//
// SPR access
//
144,9 → 153,10
wire ictag_we;
wire [31:0] ic_addr;
wire icfsm_biu_read;
/* verilator lint_off UNOPTFLAT */
reg tagcomp_miss;
/* verilator lint_on UNOPTFLAT */
 
//reg tagcomp_miss;
wire tagcomp_miss;
 
wire [`OR1200_ICINDXH:`OR1200_ICLS] ictag_addr;
wire ictag_en;
wire ictag_v;
169,6 → 179,20
assign mbist_so_o = mbist_tag_so;
`endif
 
`ifdef OR1200_RAM_PARITY
wire [1:0] p_err_wire;
// Indicate an error if we're reading from the RAM (hit)
// Additionally, mask with tag_v as tag ram is properly cleared during
// init, whereas the instruction RAM is not.
assign p_err[0] = (icqmem_ack_o & (!icfsm_first_miss_ack | ic_en)) &
(tag_v & !p_err[1]) ? p_err_wire[0] : 0;
// Whenever there's a tag parity error and we have an instruction fetch
assign p_err[1] = (ictag_en & !ictag_we) ? p_err_wire[1] : 0;
 
`else
`endif
//
// Simple assignments
//
233,13 → 257,12
// Tag comparison
//
// During line invalidate, ensure it stays the same
always @(tag or saved_addr or tag_v) begin
if ((tag != saved_addr[31:`OR1200_ICTAGL]) | !tag_v)
tagcomp_miss = 1'b1;
else
tagcomp_miss = 1'b0;
end
 
assign tagcomp_miss = ((tag != saved_addr[31:`OR1200_ICTAGL]) | !tag_v
`ifdef OR1200_RAM_PARITY
| (|p_err_wire)
`endif
);
//
// Instantiation of IC Finite State Machine
//
275,6 → 298,9
.mbist_so_o(mbist_ram_so),
.mbist_ctrl_i(mbist_ctrl_i),
`endif
`ifdef OR1200_RAM_PARITY
.p_err(p_err_wire[0]),
`endif
.addr(ic_addr[`OR1200_ICINDXH:2]),
.en(ic_en),
.we(icram_we),
294,6 → 320,9
.mbist_so_o(mbist_tag_so),
.mbist_ctrl_i(mbist_ctrl_i),
`endif
`ifdef OR1200_RAM_PARITY
.p_err(p_err_wire[1]),
`endif
.addr(ictag_addr),
.en(ictag_en),
.we(ictag_we),
/or1200_dc_tag.v
61,6 → 61,11
mbist_si_i, mbist_so_o, mbist_ctrl_i,
`endif
 
`ifdef OR1200_RAM_PARITY
// Parity error indicator
p_err,
`endif
 
// Internal i/f
addr, en, we, datain, tag_v, tag, dirty
);
90,6 → 95,13
input [`OR1200_MBIST_CTRL_WIDTH - 1:0] mbist_ctrl_i;
output mbist_so_o;
`endif
`ifdef OR1200_RAM_PARITY
parameter tag_ram_extra_width = 24 - (`OR1200_DCTAG_W+1);
output p_err;
wire [24-3:0] tag_wire;
`else
wire [dw-3:0] tag_wire;
`endif
 
`ifdef OR1200_NO_DC
 
102,8 → 114,14
assign mbist_so_o = mbist_si_i;
`endif
 
`ifdef OR1200_RAM_PARITY
assign p_err = 0;
`endif
 
`else
 
assign tag = tag_wire[dw-3:0];
//
// Instantiation of TAG RAM block
//
111,7 → 129,11
or1200_spram #
(
.aw(`OR1200_DCTAG),
`ifdef OR1200_RAM_PARITY
.dw(24)
`else
.dw(`OR1200_DCTAG_W + 1)
`endif
)
dc_tag0
(
122,14 → 144,17
.mbist_ctrl_i(mbist_ctrl_i),
`endif
.clk(clk),
.rst(rst),
.ce(en),
.we(we),
.addr(addr),
`ifdef OR1200_RAM_PARITY
.p_err(p_err),
.di({{tag_ram_extra_width{1'b0}},datain}),
`else
.di(datain),
.doq({tag, tag_v, dirty})
`ifdef OR1200_RAM_PARITY
, .p_err()
`endif
.doq({tag_wire, tag_v, dirty})
);
`endif
 
/or1200_spram.v
64,7 → 64,7
mbist_si_i, mbist_so_o, mbist_ctrl_i,
`endif
// Generic synchronous single-port RAM interface
clk, ce, we, addr, di, doq
clk, rst, ce, we, addr, di, doq
`ifdef OR1200_RAM_PARITY
, p_err
`endif
89,6 → 89,7
// Generic synchronous single-port RAM interface
//
input clk; // Clock
input rst; // Reset
input ce; // Chip enable input
input we; // Write enable input
input [aw-1:0] addr; // address bus inputs
110,18 → 111,20
// Generic RAM's registers and wires
//
`ifdef OR1200_RAM_PARITY
reg [(dw+(dw/8))-1:0] mem [(1<<aw)-1:0] /*synthesis syn_ramstyle = "no_rw_check"*/;
parameter par_w = (dw/8);
reg [(dw+par_w)-1:0] mem [(1<<aw)-1:0] /*synthesis syn_ramstyle = "no_rw_check"*/;
`else
reg [dw-1:0] mem [(1<<aw)-1:0] /*synthesis syn_ramstyle = "no_rw_check"*/;
reg [dw-1:0] mem [(1<<aw)-1:0] /*synthesis syn_ramstyle = "no_rw_check"*/;
`endif
reg [aw-1:0] addr_reg; // RAM address register
reg [aw-1:0] addr_reg; // RAM address register
 
`ifdef OR1200_RAM_PARITY
wire [(dw+(dw/8))-1:0] doq_wire;
wire [(dw/8)-1:0] di_p;
wire [(dw/8)-1:0] do_p;
wire [(dw/8)-1:0] parity_err;
wire [(dw+par_w)-1:0] doq_wire;
wire [par_w-1:0] di_p;
wire [par_w-1:0] do_p;
wire [par_w-1:0] parity_err;
reg ce_r;
`else
wire [dw-1:0] doq_wire;
`endif
129,7 → 132,7
`ifdef OR1200_RAM_PARITY
genvar i;
generate
for (i=0;i<(dw/8);i=i+1) begin: paritygen
for (i=0;i<par_w;i=i+1) begin: paritygen
or1200_parity_gen pgen(.d_i(di[(i*8)+7:(i*8)]), .p_o(di_p[i]));
or1200_parity_chk pchk(.d_i(doq_wire[(i*8)+7:(i*8)]),
.p_i(do_p[i]), .err_o(parity_err[i]));
137,32 → 140,35
endgenerate
 
// Extract parity bits of data out
assign do_p = doq_wire[(dw+(dw/8))-1:dw];
assign do_p = doq_wire[(dw+par_w)-1:dw];
 
always @(posedge clk)
if (rst)
ce_r <= 0;
else
ce_r <= ce;
 
// Indicate error
assign p_err = (|parity_err) & ce_r;
// Indicate error
assign p_err = (|parity_err);
 
// Inject a parity error. Can specify GPR number to affect,
// and which parity or data bit to switch.
// Inject a parity error.
task gen_parity_err;
input [aw-1:0] gpr_no;
input [aw-1:0] addr;
input [31:0] parity_bit_no;
input [31:0] data_bit_no;
reg [(dw+(dw/8))-1:0] do_temp;
reg [(dw+par_w)-1:0] do_temp;
begin
do_temp = mem[gpr_no];
do_temp = mem[addr];
// Switch parity bit
if (parity_bit_no > 0 && parity_bit_no <= (dw/8))
do_temp[dw+(parity_bit_no-1)] = ~do_temp[dw+(parity_bit_no-1)];
if (parity_bit_no >= 0 && parity_bit_no < par_w)
do_temp[dw+parity_bit_no] = ~do_temp[dw+parity_bit_no];
// Switch data bit
if (data_bit_no > 0 && data_bit_no <= dw)
do_temp[data_bit_no-1] = ~do_temp[data_bit_no-1];
if (data_bit_no >= 0 && data_bit_no < dw)
do_temp[data_bit_no] = ~do_temp[data_bit_no];
// Write word back
mem[gpr_no] = do_temp;
mem[addr] = do_temp;
end
endtask // gen_parity_err
`endif
 
183,10 → 189,11
// RAM write
//
always @(posedge clk)
`ifdef OR1200_RAM_PARITY
if (we && ce)
`ifdef OR1200_RAM_PARITY
mem[addr] <= {di_p,di};
`else
`else
if (we && ce)
mem[addr] <= di;
`endif
/or1200_dc_ram.v
61,9 → 61,13
// RAM BIST
mbist_si_i, mbist_so_o, mbist_ctrl_i,
`endif
 
`ifdef OR1200_RAM_PARITY
// Parity error indicator
p_err,
`endif
// Internal i/f
addr, en, we, datain, dataout
 
);
 
parameter dw = `OR1200_OPERAND_WIDTH;
79,6 → 83,10
input [3:0] we;
input [dw-1:0] datain;
output [dw-1:0] dataout;
`ifdef OR1200_RAM_PARITY
output p_err;
`endif
 
`ifdef OR1200_BIST
//
98,6 → 106,9
`ifdef OR1200_BIST
assign mbist_so_o = mbist_si_i;
`endif
`ifdef OR1200_RAM_PARITY
assign p_err = 0;
`endif
 
`else
 
109,7 → 120,7
.aw(`OR1200_DCINDX),
.dw(dw)
)
dc_ram
dc_ram0
(
`ifdef OR1200_BIST
// RAM BIST
117,15 → 128,16
.mbist_so_o(mbist_so_o),
.mbist_ctrl_i(mbist_ctrl_i),
`endif
`ifdef OR1200_RAM_PARITY
.p_err(p_err),
`endif
.clk(clk),
.rst(rst),
.ce(en),
.we(we),
.addr(addr),
.di(datain),
.doq(dataout)
`ifdef OR1200_RAM_PARITY
, .p_err()
`endif
);
`endif
 
/or1200_dc_top.v
77,7 → 77,12
// RAM BIST
mbist_si_i, mbist_so_o, mbist_ctrl_i,
`endif
 
`ifdef OR1200_RAM_PARITY
// Parity error indicator
p_err,
`endif
// SPRs
spr_cs, spr_write, spr_dat_i, spr_addr, mtspr_dc_done
);
137,6 → 142,10
output mbist_so_o;
`endif
 
`ifdef OR1200_RAM_PARITY
output [1:0] p_err;
`endif
 
//
// SPR access
//
168,6 → 177,10
 
assign mtspr_dc_done = 1'b1;
 
`ifdef OR1200_RAM_PARITY
assign p_err = 0;
`endif
`else
//
185,7 → 198,7
wire dcfsm_biu_write;
wire dcfsm_dcram_di_sel;
wire dcfsm_biu_do_sel;
reg tagcomp_miss;
wire tagcomp_miss;
wire [`OR1200_DCINDXH:`OR1200_DCLS] dctag_addr;
wire dctag_en;
wire dctag_v;
213,6 → 226,21
assign mbist_so_o = mbist_tag_so;
`endif
 
`ifdef OR1200_RAM_PARITY
wire [1:0] p_err_wire;
 
// Indicate an error if we're reading from the RAM (hit)
// Additionally, mask with tag_v as tag ram is properly cleared during
// init, whereas the data RAM is not.
assign p_err[0] = (dcqmem_ack_o & (!dcfsm_first_miss_ack | dc_en) &
!dcqmem_we_i) &
(tag_v & !p_err[1]) ? p_err_wire[0] : 0;
// Whenever there's a tag parity error and we have an instruction fetch
assign p_err[1] = (dctag_en & !dctag_we) ? p_err_wire[1] : 0;
`endif
// Address out to external bus - always from FSM
assign dcsb_adr_o = dc_addr;
//
288,16 → 316,25
//
// Tag comparison
//
wire [31:`OR1200_DCTAGL] dcqmem_adr_i_tag;
assign dcqmem_adr_i_tag = dcqmem_adr_i[31:`OR1200_DCTAGL];
wire [31:`OR1200_DCTAGL] dcqmem_adr_i_tag;
assign dcqmem_adr_i_tag = dcqmem_adr_i[31:`OR1200_DCTAGL];
/*
always @(tag or dcqmem_adr_i_tag or tag_v) begin
if ((tag != dcqmem_adr_i_tag) || !tag_v)
if ((tag != dcqmem_adr_i_tag) || !tag_v
`ifdef OR1200_RAM_PARITY
| p_err
`endif
)
tagcomp_miss = 1'b1;
else
tagcomp_miss = 1'b0;
end
 
*/
assign tagcomp_miss = (tag != dcqmem_adr_i_tag) | !tag_v
`ifdef OR1200_RAM_PARITY
| (|p_err_wire)
`endif
;
//
// Instantiation of DC Finite State Machine
//
349,6 → 386,9
.mbist_so_o(mbist_ram_so),
.mbist_ctrl_i(mbist_ctrl_i),
`endif
`ifdef OR1200_RAM_PARITY
.p_err(p_err_wire[0]),
`endif
.addr(dc_addr[`OR1200_DCINDXH:2]),
.en(dc_en),
.we(dcram_we),
368,6 → 408,9
.mbist_so_o(mbist_tag_so),
.mbist_ctrl_i(mbist_ctrl_i),
`endif
`ifdef OR1200_RAM_PARITY
.p_err(p_err_wire[1]),
`endif
.addr(dctag_addr),
.en(dctag_en),
.we(dctag_we),
/or1200_immu_tlb.v
69,6 → 69,11
mbist_si_i, mbist_so_o, mbist_ctrl_i,
`endif
 
`ifdef OR1200_RAM_PARITY
// Parity error indicator
p_err,
`endif
// SPR access
spr_cs, spr_write, spr_addr, spr_dat_i, spr_dat_o
);
106,6 → 111,10
output mbist_so_o;
`endif
 
`ifdef OR1200_RAM_PARITY
output [1:0] p_err;
`endif
//
// SPR access
//
124,12 → 133,18
wire tlb_mr_en;
wire tlb_mr_we;
wire [`OR1200_ITLBMRW-1:0] tlb_mr_ram_in;
wire [`OR1200_ITLBMRW-1:0] tlb_mr_ram_out;
wire tlb_tr_en;
wire tlb_tr_we;
wire [`OR1200_ITLBTRW-1:0] tlb_tr_ram_in;
wire [`OR1200_ITLBTRW-1:0] tlb_tr_ram_out;
`ifdef OR1200_RAM_PARITY
wire [`OR1200_ITLBMRW-1+2:0] tlb_mr_ram_out;
wire [`OR1200_ITLBTRW-1+2:0] tlb_tr_ram_out;
`else
wire [`OR1200_ITLBMRW-1:0] tlb_mr_ram_out;
wire [`OR1200_ITLBTRW-1:0] tlb_tr_ram_out;
`endif
 
 
// BIST
`ifdef OR1200_BIST
wire itlb_mr_ram_si;
138,6 → 153,11
wire itlb_tr_ram_so;
`endif
 
`ifdef OR1200_RAM_PARITY
wire [1:0] p_err_wire;
reg p_err_en;
`endif
 
//
// Implemented bits inside match and translate registers
//
177,23 → 197,24
assign spr_dat_o = (!spr_write & !spr_addr[`OR1200_ITLB_TM_ADDR]) ?
{vpn, tlb_index, {`OR1200_ITLB_TAGW-7{1'b0}}, 1'b0, 5'b00000, v} :
(!spr_write & spr_addr[`OR1200_ITLB_TM_ADDR]) ?
{ppn, {`OR1200_IMMU_PS-8{1'b0}}, uxe, sxe, {4{1'b0}}, ci, 1'b0} :
{ppn, {`OR1200_IMMU_PS-8{1'b0}}, uxe, sxe, {4{1'b0}}, ci, 1'b0} :
32'h00000000;
 
//
// Assign outputs from Match registers
//
assign {vpn, v} = tlb_mr_ram_out;
assign {vpn, v} = tlb_mr_ram_out[`OR1200_ITLBMRW-1:0];
 
//
// Assign to Match registers inputs
//
assign tlb_mr_ram_in = {spr_dat_i[`OR1200_ITLB_TAG], spr_dat_i[`OR1200_ITLBMR_V_BITS]};
assign tlb_mr_ram_in = {spr_dat_i[`OR1200_ITLB_TAG],
spr_dat_i[`OR1200_ITLBMR_V_BITS]};
 
//
// Assign outputs from Translate registers
//
assign {ppn, uxe, sxe, ci} = tlb_tr_ram_out;
assign {ppn, uxe, sxe, ci} = tlb_tr_ram_out[`OR1200_ITLBTRW-1:0];
 
//
// Assign to Translate registers inputs
206,13 → 227,18
//
// Generate hit
//
assign hit = (vpn == vaddr[`OR1200_ITLB_TAG]) & v;
assign hit = (vpn == vaddr[`OR1200_ITLB_TAG]) & v
`ifdef OR1200_RAM_PARITY
& !p_err
`endif
;
 
//
// TLB index is normally vaddr[18:13]. If it is SPR access then index is
// spr_addr[5:0].
//
assign tlb_index = spr_cs ? spr_addr[`OR1200_ITLB_INDXW-1:0] : vaddr[`OR1200_ITLB_INDX];
assign tlb_index = spr_cs ? spr_addr[`OR1200_ITLB_INDXW-1:0] :
vaddr[`OR1200_ITLB_INDX];
 
 
`ifdef OR1200_BIST
221,7 → 247,18
assign mbist_so_o = itlb_tr_ram_so;
`endif
 
`ifdef OR1200_RAM_PARITY
always @(posedge clk)
if (rst)
p_err_en <= 0;
else
p_err_en <= (tlb_mr_en & !tlb_mr_we) | (tlb_tr_en & !tlb_tr_we);
 
assign p_err = (p_err_en & (tlb_mr_en & !tlb_mr_we) |
(tlb_tr_en & !tlb_tr_we)) ? p_err_wire : 0;
`endif
 
 
//
// Instantiation of ITLB Match Registers
//
228,11 → 265,16
or1200_spram #
(
.aw(6),
`ifdef OR1200_RAM_PARITY
.dw(16)
`else
.dw(14)
`endif
)
itlb_mr_ram
(
.clk(clk),
.rst(rst),
`ifdef OR1200_BIST
// RAM BIST
.mbist_si_i(itlb_mr_ram_si),
243,11 → 285,13
.we(tlb_mr_we),
//.oe(1'b1),
.addr(tlb_index),
`ifdef OR1200_RAM_PARITY
.p_err(p_err_wire[0]),
.di({2'b00,tlb_mr_ram_in}),
`else
.di(tlb_mr_ram_in),
`endif
.doq(tlb_mr_ram_out)
`ifdef OR1200_RAM_PARITY
, .p_err()
`endif
);
 
//
256,11 → 300,16
or1200_spram #
(
.aw(6),
`ifdef OR1200_RAM_PARITY
.dw(24)
`else
.dw(22)
`endif
)
itlb_tr_ram
(
.clk(clk),
.rst(rst),
`ifdef OR1200_BIST
// RAM BIST
.mbist_si_i(itlb_tr_ram_si),
271,11 → 320,13
.we(tlb_tr_we),
//.oe(1'b1),
.addr(tlb_index),
`ifdef OR1200_RAM_PARITY
.p_err(p_err_wire[1]),
.di({2'b00,tlb_tr_ram_in}),
`else
.di(tlb_tr_ram_in),
`endif
.doq(tlb_tr_ram_out)
`ifdef OR1200_RAM_PARITY
, .p_err()
`endif
);
endmodule
/or1200_spram_32_bw.v
65,7 → 65,7
mbist_si_i, mbist_so_o, mbist_ctrl_i,
`endif
// Generic synchronous single-port RAM interface
clk, ce, we, addr, di, doq
clk, rst, ce, we, addr, di, doq
`ifdef OR1200_RAM_PARITY
, p_err
`endif
88,19 → 88,22
input [`OR1200_MBIST_CTRL_WIDTH - 1:0] mbist_ctrl_i;
output mbist_so_o;
`endif
 
`ifdef OR1200_RAM_PARITY
output p_err; // parity error indicator
`endif
//
// Generic synchronous single-port RAM interface
// Generic synchronous single-port byte-writable RAM interface
//
input clk; // Clock
input rst; // Reset
input ce; // Chip enable input
input [3:0] we; // Write enable input
input [aw-1:0] addr; // address bus inputs
input [dw-1:0] di; // input data bus
output [dw-1:0] doq; // output data bus
`ifdef OR1200_RAM_PARITY
output p_err; // parity error indicator
`endif
 
//
// Internal wires and registers
114,17 → 117,17
// Generic RAM's registers and wires
//
`ifdef OR1200_RAM_PARITY
reg [bw:0] mem0 [(1<<aw)-1:0] /*synthesis syn_ramstyle = "no_rw_check"*/;
reg [bw:0] mem1 [(1<<aw)-1:0] /*synthesis syn_ramstyle = "no_rw_check"*/;
reg [bw:0] mem2 [(1<<aw)-1:0] /*synthesis syn_ramstyle = "no_rw_check"*/;
reg [bw:0] mem3 [(1<<aw)-1:0] /*synthesis syn_ramstyle = "no_rw_check"*/;
reg [bw:0] mem0 [(1<<aw)-1:0] /*synthesis syn_ramstyle = "no_rw_check"*/;
reg [bw:0] mem1 [(1<<aw)-1:0] /*synthesis syn_ramstyle = "no_rw_check"*/;
reg [bw:0] mem2 [(1<<aw)-1:0] /*synthesis syn_ramstyle = "no_rw_check"*/;
reg [bw:0] mem3 [(1<<aw)-1:0] /*synthesis syn_ramstyle = "no_rw_check"*/;
`else
reg [bw-1:0] mem0 [(1<<aw)-1:0] /*synthesis syn_ramstyle = "no_rw_check"*/;
reg [bw-1:0] mem1 [(1<<aw)-1:0] /*synthesis syn_ramstyle = "no_rw_check"*/;
reg [bw-1:0] mem2 [(1<<aw)-1:0] /*synthesis syn_ramstyle = "no_rw_check"*/;
reg [bw-1:0] mem3 [(1<<aw)-1:0] /*synthesis syn_ramstyle = "no_rw_check"*/;
reg [bw-1:0] mem0 [(1<<aw)-1:0] /*synthesis syn_ramstyle = "no_rw_check"*/;
reg [bw-1:0] mem1 [(1<<aw)-1:0] /*synthesis syn_ramstyle = "no_rw_check"*/;
reg [bw-1:0] mem2 [(1<<aw)-1:0] /*synthesis syn_ramstyle = "no_rw_check"*/;
reg [bw-1:0] mem3 [(1<<aw)-1:0] /*synthesis syn_ramstyle = "no_rw_check"*/;
`endif
reg [aw-1:0] addr_reg; // RAM address register
reg [aw-1:0] addr_reg; // RAM address register
 
`ifdef OR1200_RAM_PARITY
wire [(dw+(dw/8))-1:0] doq_wire;
135,6 → 138,7
wire [(dw/8)-1:0] di_p;
wire [(dw/8)-1:0] do_p;
wire [(dw/8)-1:0] parity_err;
reg ce_r;
`else
wire [dw-1:0] doq_wire;
`endif
151,30 → 155,56
 
// Extract parity bits of data out
assign do_p = doq_wire[(dw+(dw/8))-1:dw];
 
always @(posedge clk)
if (rst)
ce_r <= 0;
else
ce_r <= ce;
// Indicate error
assign p_err = (|parity_err);
assign p_err = (|parity_err) & ce_r;
 
// Inject a parity error. Can specify GPR number to affect,
// and which parity or data bit to switch.
task gen_parity_err;
input [aw-1:0] gpr_no;
input [31:0] parity_bit_no;
input [aw-1:0] word_no;
input [31:0] data_bit_no;
reg [(dw+(dw/8))-1:0] do_temp;
reg [bw:0] do_temp;
begin
// TODO
/*
do_temp = mem[gpr_no];
// Switch parity bit
if (parity_bit_no > 0 && parity_bit_no <= (dw/8))
do_temp[dw+(parity_bit_no-1)] = ~do_temp[dw+(parity_bit_no-1)];
// Switch data bit
if (data_bit_no > 0 && data_bit_no <= dw)
do_temp[data_bit_no-1] = ~do_temp[data_bit_no-1];
// Write word back
mem[gpr_no] = do_temp;
*/
// Fish word out
if (data_bit_no < 8) begin
do_temp = mem0[word_no];
end
else if (data_bit_no < 16) begin
do_temp = mem1[word_no];
data_bit_no = data_bit_no - 8;
end
else if (data_bit_no < 24) begin
do_temp = mem2[word_no];
data_bit_no = data_bit_no - 16;
end
else if (data_bit_no < 32) begin
do_temp = mem3[word_no];
data_bit_no = data_bit_no - 24;
end
else begin
do_temp = mem3[word_no];
data_bit_no = 8;
end
 
// Switch bit
do_temp[data_bit_no] = ~do_temp[data_bit_no] ;
 
// Replace word
if (data_bit_no < 8)
mem0[word_no] = do_temp;
else if (data_bit_no < 16)
mem1[word_no] = do_temp;
else if (data_bit_no < 24)
mem2[word_no] = do_temp;
else
mem3[word_no] = do_temp;
end
endtask // gen_parity_err
`endif
232,4 → 262,5
`endif
end
endmodule // or1200_spram
endmodule // or1200_spram_32_bw
 
/or1200_dmmu_top.v
72,6 → 72,11
mbist_si_i, mbist_so_o, mbist_ctrl_i,
`endif
 
`ifdef OR1200_RAM_PARITY
// Parity error indicator
p_err,
`endif
// DC i/f
qmemdmmu_err_i, qmemdmmu_tag_i, qmemdmmu_adr_o, qmemdmmu_cycstb_o, qmemdmmu_ci_o
);
119,6 → 124,10
output mbist_so_o;
`endif
 
`ifdef OR1200_RAM_PARITY
output [1:0] p_err;
`endif
//
// DC I/F
//
176,6 → 185,9
`ifdef OR1200_BIST
assign mbist_so_o = mbist_si_i;
`endif
`ifdef OR1200_RAM_PARITY
assign p_err = 0;
`endif
 
`else
 
294,6 → 306,10
.mbist_ctrl_i(mbist_ctrl_i),
`endif
 
`ifdef OR1200_RAM_PARITY
.p_err(p_err),
`endif
// SPR access
.spr_cs(dtlb_spr_access),
.spr_write(spr_write),
/or1200_top.v
85,6 → 85,11
// RAM BIST
mbist_si_i, mbist_so_o, mbist_ctrl_i,
`endif
 
`ifdef OR1200_RAM_PARITY
mem_parity_err,
`endif
// Power Management
pm_cpustall_i,
pm_clksd_o, pm_dc_gate_o, pm_ic_gate_o, pm_dmmu_gate_o,
195,6 → 200,10
output pm_wakeup_o;
output pm_lvolt_o;
 
`ifdef OR1200_RAM_PARITY
output [8:0] mem_parity_err;
`endif
 
//
// Internal wires and regs
425,6 → 434,17
assign mbist_so_o = mbist_dc_so;
`endif
 
`ifdef OR1200_RAM_PARITY
wire [1:0] p_err_dc;
wire [1:0] p_err_ic;
wire [1:0] p_err_dmmu;
wire [1:0] p_err_immu;
wire p_err_rf;
 
assign mem_parity_err = {p_err_immu,p_err_dmmu,p_err_ic,p_err_dc,p_err_rf};
`endif
wire [3:0] icqmem_sel_qmem;
wire [3:0] icqmem_tag_qmem;
wire [3:0] dcqmem_tag_qmem;
535,6 → 555,10
.mbist_ctrl_i(mbist_ctrl_i),
`endif
 
`ifdef OR1200_RAM_PARITY
.p_err(p_err_immu),
`endif
 
// CPU and IMMU
.ic_en(ic_en),
.immu_en(immu_en),
578,7 → 602,9
.mbist_so_o(mbist_ic_so),
.mbist_ctrl_i(mbist_ctrl_i),
`endif
 
`ifdef OR1200_RAM_PARITY
.p_err(p_err_ic),
`endif
// IC and QMEM
.ic_en(ic_en),
.icqmem_adr_i(icqmem_adr_qmem),
706,6 → 732,11
.spr_cs(spr_cs),
.spr_we(spr_we),
.mtspr_dc_done(mtspr_dc_done)
`ifdef OR1200_RAM_PARITY
// Register file parity error indicator
, .p_err_rf(p_err_rf)
`endif
);
 
//
723,6 → 754,10
.mbist_ctrl_i(mbist_ctrl_i),
`endif
 
`ifdef OR1200_RAM_PARITY
.p_err(p_err_dmmu),
`endif
 
// CPU i/f
.dc_en(dc_en),
.dmmu_en(dmmu_en),
761,7 → 796,9
.mbist_so_o(mbist_dc_so),
.mbist_ctrl_i(mbist_ctrl_i),
`endif
 
`ifdef OR1200_RAM_PARITY
.p_err(p_err_dc),
`endif
// DC and QMEM
.dc_en(dc_en),
.dcqmem_adr_i(dcqmem_adr_qmem),
/or1200_dpram.v
59,6 → 59,7
 
module or1200_dpram
(
rst,
// Generic synchronous double-port RAM interface
clk_a, ce_a, addr_a, do_a,
clk_b, ce_b, we_b, addr_b, di_b
76,6 → 77,7
//
// Generic synchronous double-port RAM interface
//
input rst; // Reset
input clk_a; // Clock
input ce_a; // Chip enable input
input [aw-1:0] addr_a; // address bus inputs
100,8 → 102,10
//
// Generic RAM's registers and wires
//
`ifdef OR1200_RAM_PARITY
reg [(dw+(dw/8))-1:0] mem [(1<<aw)-1:0] /*synthesis syn_ramstyle = "no_rw_check"*/; // RAM content
`ifdef OR1200_RAM_PARITY
parameter par_w = (dw/8);
reg [(dw+par_w)-1:0] mem [(1<<aw)-1:0] /*synthesis syn_ramstyle = "no_rw_check"*/; // RAM content
`else
reg [dw-1:0] mem [(1<<aw)-1:0] /*synthesis syn_ramstyle = "no_rw_check"*/; // RAM content
`endif
108,10 → 112,10
reg [aw-1:0] addr_a_reg; // RAM address registered
 
`ifdef OR1200_RAM_PARITY
wire [(dw+(dw/8))-1:0] do_a_wire;
wire [(dw/8)-1:0] di_p;
wire [(dw/8)-1:0] do_p;
wire [(dw/8)-1:0] parity_err;
wire [(dw+par_w)-1:0] do_a_wire;
wire [par_w-1:0] di_p;
wire [par_w-1:0] do_p;
wire [par_w-1:0] parity_err;
`else
wire [dw-1:0] do_a_wire;
`endif
121,15 → 125,16
function [31:0] get_gpr;
// verilator public
input [aw-1:0] gpr_no;
reg [(dw+(dw/8))-1:0] gpr_temp;
`ifdef OR1200_RAM_PARITY
reg [(dw+par_w)-1:0] gpr_temp;
begin
`ifdef OR1200_RAM_PARITY
gpr_temp = mem[gpr_no];
get_gpr = gpr_temp[31:0];
end
`else
 
get_gpr = mem[gpr_no];
`endif
end
endfunction // get_gpr
 
task set_gpr;
151,7 → 156,7
`ifdef OR1200_RAM_PARITY
genvar i;
generate
for (i=0;i<(dw/8);i=i+1) begin: paritygen
for (i=0;i<par_w;i=i+1) begin: paritygen
or1200_parity_gen pgen(.d_i(di_b[(i*8)+7:(i*8)]), .p_o(di_p[i]));
or1200_parity_chk pchk(.d_i(do_a_wire[(i*8)+7:(i*8)]),
.p_i(do_p[i]), .err_o(parity_err[i]));
159,10 → 164,17
endgenerate
 
// Extract parity bits of data out
assign do_p = do_a_wire[(dw+(dw/8))-1:dw];
assign do_p = do_a_wire[(dw+par_w)-1:dw];
 
reg ce_a_r;
always @(posedge clk_a)
if (rst)
ce_a_r <= 0;
else
ce_a_r <= ce_a;
// Indicate error
assign p_err = (|parity_err);
assign p_err = (|parity_err) & ce_a_r;
 
// Inject a parity error. Can specify GPR number to affect,
// and which parity or data bit to switch.
170,21 → 182,19
input [aw-1:0] gpr_no;
input [31:0] parity_bit_no;
input [31:0] data_bit_no;
reg [(dw+(dw/8))-1:0] do_temp;
reg [(dw+par_w)-1:0] do_temp;
begin
do_temp = mem[gpr_no];
// Switch parity bit
if (parity_bit_no > 0)
do_temp[dw+(parity_bit_no-1)] = ~do_temp[dw+(parity_bit_no-1)];
if (parity_bit_no >= 0 && parity_bit_no < par_w)
do_temp[dw+parity_bit_no] = ~do_temp[dw+parity_bit_no];
// Switch data bit
if (data_bit_no > 0 && data_bit_no <= dw)
do_temp[data_bit_no-1] = ~do_temp[data_bit_no-1];
if (data_bit_no >= 0 && data_bit_no < dw)
do_temp[data_bit_no] = ~do_temp[data_bit_no];
// Write word back
mem[gpr_no] = do_temp;
end
endtask // gen_parity_err
`endif
 
//

powered by: WebSVN 2.1.0

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