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 |
|
// |