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
- from Rev 482 to Rev 483
- ↔ Reverse comparison
Rev 482 → Rev 483
/rtl/verilog/or1200/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]), |
/rtl/verilog/or1200/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), |
/rtl/verilog/or1200/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 |
|
/rtl/verilog/or1200/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 |
|
/rtl/verilog/or1200/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 |
|
/rtl/verilog/or1200/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 |
/rtl/verilog/or1200/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 |
|
// |
/rtl/verilog/or1200/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), |
/rtl/verilog/or1200/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 |
|
/rtl/verilog/or1200/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 |
|
/rtl/verilog/or1200/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 |
|
/rtl/verilog/or1200/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), |
/rtl/verilog/or1200/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 |
/rtl/verilog/or1200/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 |
|
/rtl/verilog/or1200/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), |
/rtl/verilog/or1200/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), |
/rtl/verilog/or1200/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 |
|
// |
/doc/orpsoc.texi
62,6 → 62,7
* Board Designs:: |
* ORDB1A3PE1500:: |
* ML501:: |
* Generic Designs:: |
* Software:: |
* GNU Free Documentation License:: The license for this documentation |
* Index:: |
1353,7 → 1354,30
|
See the ML501 schematic (http://www.xilinx.com/support/documentation/boards_and_kits/ml501_20061010_bw.pdf) for more details on these headers, and refer to the pinouts in the ML501 UCF, in the board's @code{backend/par/bin/ml501.ucf} file. |
|
|
@c **************************************************************************** |
@c Generic Design build chapter |
@c **************************************************************************** |
|
@node Generic |
@chapter Generic |
@cindex Generic design information |
|
@menu |
* Overview:: |
@end menu |
|
|
@node Generic Build Overview |
@section Overview |
|
The paths under @code{boards/generic} contain designs similar to the reference design, in that they are not technology specific, and used for development of certain features of the processor, or peripherals. |
|
An example is the fault tolerance testing build, in @code{boards/generic/ft}, which implements some custom modules in the testbench and ORPSoC top level design, and is in general a very minimal system just for testing. |
|
Additional builds, testing certain parts of the technology, can be developed here. |
|
@c **************************************************************************** |
@c Software section |
@c **************************************************************************** |
|
/sw/tests/or1200/sim/or1200-dctest.c
14,8 → 14,7
#define LOOPS 64 |
#define WORD_STRIDE 8 |
|
// Memory area to test at |
#define TEST_BASE 0x600000 /* 6MB */ |
extern unsigned long _stack; |
|
unsigned long int my_lfsr; |
|
29,6 → 28,8
main() |
{ |
|
unsigned long stack_top = (unsigned long) &_stack; |
|
// Check data cache is present and enabled |
if (!(mfspr(SPR_UPR)& SPR_UPR_DCP) | !(mfspr(SPR_SR) & SPR_SR_DCE)) |
{ |
37,7 → 38,7
return 0; |
} |
|
volatile char* ptr = (volatile char*) TEST_BASE; |
volatile char* ptr = (volatile char*) (stack_top + 256); |
int i; |
|
ptr[0] = 0xab; |
99,7 → 100,7
|
// init LFSR |
my_lfsr = RAND_LFSR_SEED; |
volatile unsigned long int *lptr = (volatile unsigned long int*) TEST_BASE; |
volatile unsigned long int *lptr = (volatile unsigned long int*) (stack_top + 256); |
for(i=0;i<LOOPS;i++) |
{ |
lptr[(i*WORD_STRIDE)-1] = next_rand(); |
/sw/tests/or1200/sim/or1200-mmu.c
94,7 → 94,7
// Set this to 1 to enable the IMMU tests |
#define DO_IMMU_TESTS 1 |
// Set this to 1 to enable the DMMU tests |
#define DO_DMMU_TESTS 1 |
#define DO_DMMU_TESTS 0 |
|
// Symbols defined in linker script |
extern unsigned long _endtext; |
114,7 → 114,9
will be used for testing */ |
#define RAM_START 0x00000000 |
// Assume only 2MB memory |
#define RAM_SIZE 0x00200000 |
#ifndef RAM_SIZE |
# define RAM_SIZE 0x00200000 |
#endif |
|
#define VM_BASE 0xc0000000 |
|
/sw/drivers/or1200/crt0.S
35,6 → 35,37
/* ---[ 0x100: RESET exception ]----------------------------------------- */ |
.org 0x100 |
l.movhi r0, 0 |
l.movhi r1, 0 |
l.movhi r2, 0 |
l.movhi r3, 0 |
l.movhi r4, 0 |
l.movhi r5, 0 |
l.movhi r6, 0 |
l.movhi r7, 0 |
l.movhi r8, 0 |
l.movhi r9, 0 |
l.movhi r10, 0 |
l.movhi r11, 0 |
l.movhi r12, 0 |
l.movhi r13, 0 |
l.movhi r14, 0 |
l.movhi r15, 0 |
l.movhi r16, 0 |
l.movhi r17, 0 |
l.movhi r18, 0 |
l.movhi r19, 0 |
l.movhi r20, 0 |
l.movhi r21, 0 |
l.movhi r22, 0 |
l.movhi r23, 0 |
l.movhi r24, 0 |
l.movhi r25, 0 |
l.movhi r26, 0 |
l.movhi r27, 0 |
l.movhi r28, 0 |
l.movhi r29, 0 |
l.movhi r30, 0 |
l.movhi r31, 0 |
/* Clear status register, set supervisor mode */ |
l.ori r1, r0, SPR_SR_SM |
l.mtspr r0, r1, SPR_SR |
290,11 → 321,6
|
.L10: |
|
/* Initialise stack */ |
/* LOAD_SYMBOL_2_GPR(r1, _stack) |
l.addi r2, r0, -3 |
l.and r1, r1, r2 |
*/ |
/* Clear BSS */ |
LOAD_SYMBOL_2_GPR(r28, _bss_start) |
LOAD_SYMBOL_2_GPR(r30, _bss_end) |
304,12 → 330,10
l.bf 1b |
l.addi r28, r28, 4 |
|
|
/* Initialise UART in a C function */ |
/*l.jal _uart_init |
l.nop*/ |
|
|
/* Jump to main program entry point (argc = argv = 0) */ |
CLEAR_GPR(r3) |
CLEAR_GPR(r4) |
/boards/actel/ordb1a3pe1500/sw/Makefile.inc
8,7 → 8,8
# Figure out actual path the common software directory |
SW_ROOT=$(BOARD_SW_ROOT)/$(PROJ_ROOT)/sw |
|
# Set the BOARD_PATH to point to the root of this board build |
# Set the BOARD to be the path within the board/ path of the project that goes |
# to this project. |
BOARD=actel/ordb1a3pe1500 |
|
# Set RTL_VERILOG_INCLUDE_DIR so software |
/boards/actel/ordb1a3pe1500/sw/board/include/board.h
15,11 → 15,14
// Uncomment the appropriate bootloader define. This will effect the bootrom.S |
// file, which is compiled and converted into Verilog for inclusion at |
// synthesis time. See bootloader/bootloader.S for details on each option. |
|
#ifndef PRELOAD_RAM |
#define BOOTROM_SPI_FLASH |
//#define BOOTROM_GOTO_RESET |
//#define BOOTROM_LOOP_AT_ZERO |
//#define BOOTROM_LOOP_IN_ROM |
#else |
#define BOOTROM_GOTO_RESET |
#endif |
|
// |
// Defines for each core (memory map base, OR1200 interrupt line number, etc.) |
/boards/generic/ft/bench/verilog/include/timescale.v
0,0 → 1,41
////////////////////////////////////////////////////////////////////// |
//// //// |
//// ORPSoC Testbench Timescale //// |
//// //// |
//// Description //// |
//// ORPSoC testbench timescale file //// |
//// //// |
//// To Do: //// |
//// - //// |
//// //// |
//// Author(s): //// |
//// - jb, jb@orsoc.se //// |
//// //// |
//// //// |
////////////////////////////////////////////////////////////////////// |
//// //// |
//// Copyright (C) 2009 Authors and OPENCORES.ORG //// |
//// //// |
//// This source file may be used and distributed without //// |
//// restriction provided that this copyright statement is not //// |
//// removed from the file and that any derivative work contains //// |
//// the original copyright notice and the associated disclaimer. //// |
//// //// |
//// This source file is free software; you can redistribute it //// |
//// and/or modify it under the terms of the GNU Lesser General //// |
//// Public License as published by the Free Software Foundation; //// |
//// either version 2.1 of the License, or (at your option) any //// |
//// later version. //// |
//// //// |
//// This source is distributed in the hope that it will be //// |
//// useful, but WITHOUT ANY WARRANTY; without even the implied //// |
//// warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR //// |
//// PURPOSE. See the GNU Lesser General Public License for more //// |
//// details. //// |
//// //// |
//// You should have received a copy of the GNU Lesser General //// |
//// Public License along with this source; if not, download it //// |
//// from http://www.opencores.org/lgpl.shtml //// |
//// //// |
////////////////////////////////////////////////////////////////////// |
`timescale 1ns/10ps |
/boards/generic/ft/bench/verilog/orpsoc_testbench.v
0,0 → 1,229
////////////////////////////////////////////////////////////////////// |
/// //// |
/// ORPSoC testbench //// |
/// //// |
/// Instantiate ORPSoC, monitors, provide stimulus //// |
/// //// |
/// Julius Baxter, julius@opencores.org //// |
/// //// |
////////////////////////////////////////////////////////////////////// |
//// //// |
//// Copyright (C) 2009, 2010 Authors and OPENCORES.ORG //// |
//// //// |
//// This source file may be used and distributed without //// |
//// restriction provided that this copyright statement is not //// |
//// removed from the file and that any derivative work contains //// |
//// the original copyright notice and the associated disclaimer. //// |
//// //// |
//// This source file is free software; you can redistribute it //// |
//// and/or modify it under the terms of the GNU Lesser General //// |
//// Public License as published by the Free Software Foundation; //// |
//// either version 2.1 of the License, or (at your option) any //// |
//// later version. //// |
//// //// |
//// This source is distributed in the hope that it will be //// |
//// useful, but WITHOUT ANY WARRANTY; without even the implied //// |
//// warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR //// |
//// PURPOSE. See the GNU Lesser General Public License for more //// |
//// details. //// |
//// //// |
//// You should have received a copy of the GNU Lesser General //// |
//// Public License along with this source; if not, download it //// |
//// from http://www.opencores.org/lgpl.shtml //// |
//// //// |
////////////////////////////////////////////////////////////////////// |
|
`include "orpsoc-defines.v" |
`include "orpsoc-testbench-defines.v" |
`include "test-defines.v" |
|
`include "timescale.v" |
|
module orpsoc_testbench; |
|
reg clk = 0; |
reg rst_n = 1; // Active LOW |
|
always |
#((`BOARD_CLOCK_PERIOD)/2) clk <= ~clk; |
|
// Reset, ACTIVE LOW |
initial |
begin |
#1; |
repeat (32) @(negedge clk) |
rst_n <= 1; |
repeat (32) @(negedge clk) |
rst_n <= 0; |
repeat (32) @(negedge clk) |
rst_n <= 1; |
end |
|
`include "orpsoc-params.v" |
|
`ifdef JTAG_DEBUG |
wire tdo_pad_o; |
wire tck_pad_i; |
wire tms_pad_i; |
wire tdi_pad_i; |
`endif |
`ifdef UART0 |
wire uart0_stx_pad_o; |
wire uart0_srx_pad_i; |
`endif |
|
orpsoc_top dut |
( |
.clk_pad_i (clk), |
`ifdef JTAG_DEBUG |
.tms_pad_i (tms_pad_i), |
.tck_pad_i (tck_pad_i), |
.tdi_pad_i (tdi_pad_i), |
.tdo_pad_o (tdo_pad_o), |
`endif |
`ifdef UART0 |
.uart0_stx_pad_o (uart0_stx_pad_o), |
.uart0_srx_pad_i (uart0_srx_pad_i), |
`endif |
.rst_n_pad_i (rst_n) |
); |
|
// |
// Instantiate OR1200 monitor |
// |
or1200_monitor monitor(); |
|
or1200_ft_stim ft_stim(); |
|
`ifndef SIM_QUIET |
`define CPU_ic_top or1200_ic_top |
`define CPU_dc_top or1200_dc_top |
wire ic_en = orpsoc_testbench.dut.or1200_top0.or1200_ic_top.ic_en; |
always @(posedge ic_en) |
$display("Or1200 IC enabled at %t", $time); |
|
wire dc_en = orpsoc_testbench.dut.or1200_top0.or1200_dc_top.dc_en; |
always @(posedge dc_en) |
$display("Or1200 DC enabled at %t", $time); |
`endif |
|
|
`ifdef JTAG_DEBUG |
`ifdef VPI_DEBUG |
// Debugging interface |
vpi_debug_module vpi_dbg |
( |
.tms(tms_pad_i), |
.tck(tck_pad_i), |
.tdi(tdi_pad_i), |
.tdo(tdo_pad_o) |
); |
`else |
// If no VPI debugging, tie off JTAG inputs |
assign tdi_pad_i = 1; |
assign tck_pad_i = 0; |
assign tms_pad_i = 1; |
`endif // !`ifdef VPI_DEBUG_ENABLE |
`endif // `ifdef JTAG_DEBUG |
|
|
initial |
begin |
`ifndef SIM_QUIET |
$display("\n* Starting simulation of ORPSoC RTL.\n* Test: %s\n", |
`TEST_NAME_STRING ); |
`endif |
|
`ifdef VCD |
`ifdef VCD_DELAY |
#(`VCD_DELAY); |
`endif |
|
// Delay by x insns |
`ifdef VCD_DELAY_INSNS |
#10; // Delay until after the value becomes valid |
while (monitor.insns < `VCD_DELAY_INSNS) |
@(posedge clk); |
`endif |
|
`ifdef SIMULATOR_MODELSIM |
// Modelsim can GZip VCDs on the fly if given in the suffix |
`define VCD_SUFFIX ".vcd.gz" |
`else |
`define VCD_SUFFIX ".vcd" |
`endif |
|
`ifndef SIM_QUIET |
$display("* VCD in %s\n", {"../out/",`TEST_NAME_STRING,`VCD_SUFFIX}); |
`endif |
$dumpfile({"../out/",`TEST_NAME_STRING,`VCD_SUFFIX}); |
`ifndef VCD_DEPTH |
`define VCD_DEPTH 0 |
`endif |
$dumpvars(`VCD_DEPTH); |
`endif |
|
end // initial begin |
|
`ifdef END_TIME |
initial begin |
#(`END_TIME); |
`ifndef SIM_QUIET |
$display("* Finish simulation due to END_TIME being set at %t", $time); |
`endif |
$finish; |
end |
`endif |
|
`ifdef END_INSNS |
initial begin |
#10 |
while (monitor.insns < `END_INSNS) |
@(posedge clk); |
`ifndef SIM_QUIET |
$display("* Finish simulation due to END_INSNS count (%d) reached at %t", |
`END_INSNS, $time); |
`endif |
$finish; |
end |
`endif |
|
`ifdef UART0 |
// |
// UART0 decoder |
// |
uart_decoder |
#( |
.uart_baudrate_period_ns(8680) // 115200 baud = period 8.68uS |
) |
uart0_decoder |
( |
.clk(clk), |
.uart_tx(uart0_stx_pad_o) |
); |
|
// UART0 stimulus |
/* |
uart_stim |
#( |
.uart_baudrate_period_ns(8680) // 115200 baud = period 8.68uS |
) |
uart0_stim |
( |
.clk(clk), |
.uart_rx(uart0_srx_pad_i) |
); |
*/ |
// UART0 is looped back for now |
assign uart0_srx_pad_i = uart0_stx_pad_o; |
|
`endif // `ifdef UART0 |
|
endmodule // orpsoc_testbench |
|
// Local Variables: |
// verilog-library-directories:("." "../../rtl/verilog/orpsoc_top") |
// verilog-library-files:() |
// verilog-library-extensions:(".v" ".h") |
// End: |
|
/boards/generic/ft/bench/verilog/or1200_ft_stim.v
0,0 → 1,391
|
|
`include "timescale.v" |
`include "or1200_defines.v" |
`include "orpsoc-testbench-defines.v" |
`include "test-defines.v" |
|
// |
// Top of TB |
// |
`define TB_TOP orpsoc_testbench |
|
// |
// Top of DUT |
// |
`define DUT_TOP `TB_TOP.dut |
|
// |
// Top of OR1200 inside test bench |
// |
`define OR1200_TOP `DUT_TOP.or1200_top0 |
|
|
`define CPU or1200 |
`define CPU_cpu or1200_cpu |
`define CPU_rf or1200_rf |
`define CPU_except or1200_except |
`define CPU_ctrl or1200_ctrl |
`define CPU_sprs or1200_sprs |
`define CPU_ic_top or1200_ic_top |
`define CPU_ic_ram or1200_ic_ram |
`define CPU_ic_tag or1200_ic_tag |
`define CPU_dc_top or1200_dc_top |
`define CPU_dc_ram or1200_dc_ram |
`define CPU_dc_tag or1200_dc_tag |
|
`define CPU_immu_top or1200_immu_top |
`define CPU_immu_tlb or1200_immu_tlb |
`define CPU_dmmu_top or1200_dmmu_top |
`define CPU_dmmu_tlb or1200_dmmu_tlb |
|
`define CPU_CORE_CLK `OR1200_TOP.`CPU_cpu.`CPU_ctrl.clk |
|
`define FT_STIM_MEM_LOC 32'h00000004 |
`define FT_STIM_GO_WORD 32'h88000000 |
|
module or1200_ft_stim; |
|
reg debug_on; |
|
|
`ifdef OR1200_RAM_PARITY |
|
|
|
`define RAM_WB_TOP `DUT_TOP.ram_wb0.ram_wb_b3_0 |
task get_ram_word; |
input [31:0] addr; |
output [31:0] insn; |
begin |
insn = `RAM_WB_TOP.get_mem32(addr[31:2]); |
end |
endtask // get_ram_word |
|
task set_ram_word; |
input [31:0] addr; |
input [31:0] word; |
reg dummy; |
begin |
dummy = `RAM_WB_TOP.set_mem32(addr[31:2], word); |
end |
endtask // set_ram_word |
|
|
task wait_for_start; |
reg [31:0] mem_word; |
begin |
get_ram_word(`FT_STIM_MEM_LOC, mem_word); |
while(mem_word !== `FT_STIM_GO_WORD) |
begin |
|
// if (debug_on) |
// $display("%m: Wait for start, read %h",mem_word); |
|
#100000; |
get_ram_word(`FT_STIM_MEM_LOC, mem_word); |
end |
end |
endtask // wait_for_start |
|
task get_command; |
output [31:0] out_cmd; |
|
reg [31:0] mem_word; |
begin |
get_ram_word(`FT_STIM_MEM_LOC, mem_word); |
while(mem_word === 32'h0) |
begin |
#10000; |
|
// if (debug_on) |
// $display("%m: get_command %h",mem_word); |
|
get_ram_word(`FT_STIM_MEM_LOC, mem_word); |
end |
out_cmd = mem_word; |
end |
endtask // get_command |
|
task ack_command; |
begin |
// if (debug_on) |
// $display("%m: Ack command"); |
set_ram_word(`FT_STIM_MEM_LOC, 0); |
end |
endtask // ack_command |
|
task inject_ic_ram_fault; |
input [31:0] cmd; |
reg [23:0] word_number; |
reg [7:0] bit_number; |
|
begin |
// Get line number from command |
word_number = cmd[15:0]; |
bit_number = cmd[23:16]; |
if (debug_on) |
$display("%m: inject error into IC RAM word 0x%h, data bit %02d", |
word_number, bit_number); |
|
`OR1200_TOP.`CPU_ic_top.`CPU_ic_ram.ic_ram0.gen_parity_err(word_number, |
-1, |
bit_number); |
ack_command; |
end |
endtask // inject_ic_ram_fault |
|
task inject_ic_tag_fault; |
input [31:0] cmd; |
reg [23:0] tag_word; |
reg [7:0] bit_number; |
begin |
// Get line number from command |
tag_word = cmd[15:0]; |
bit_number = cmd[23:16]; |
if (debug_on) |
$display("%m: inject error into IC tag line 0x%h, data bit %02d", |
tag_word, bit_number); |
|
`OR1200_TOP.`CPU_ic_top.`CPU_ic_tag.ic_tag0.gen_parity_err(tag_word, |
-1, |
bit_number); |
ack_command; |
end |
endtask |
|
task inject_dc_ram_fault; |
input [31:0] cmd; |
reg [23:0] word_number; |
reg [7:0] bit_number; |
|
begin |
// Get line number from command |
word_number = cmd[15:0]; |
bit_number = cmd[23:16]; |
if (debug_on) |
$display("%m: inject error into DC RAM word 0x%h, data bit %02d", |
word_number, bit_number); |
|
`OR1200_TOP.`CPU_dc_top.`CPU_dc_ram.dc_ram0.gen_parity_err(word_number, |
bit_number); |
ack_command; |
end |
endtask |
|
task inject_dc_tag_fault; |
input [31:0] cmd; |
reg [23:0] tag_word; |
reg [7:0] bit_number; |
begin |
// Get line number from command |
tag_word = cmd[15:0]; |
bit_number =cmd[23:16]; |
if (debug_on) |
$display("%m: inject error into DC tag line 0x%h, data bit %02d", |
tag_word, bit_number); |
|
`OR1200_TOP.`CPU_dc_top.`CPU_dc_tag.dc_tag0.gen_parity_err(tag_word, |
-1, |
bit_number); |
ack_command; |
end |
endtask |
|
task inject_immu_fault; |
input tr; |
input [31:0] cmd; |
reg [23:0] mem_word; |
reg [7:0] bit_number; |
begin |
// Get line number from command |
mem_word = cmd[15:0]; |
bit_number =cmd[23:16]; |
if (tr) |
begin |
if (debug_on) |
$display("%m: inject error into iTLB TR RAM, 0x%h, bit %02d", |
mem_word, bit_number); |
|
`OR1200_TOP.`CPU_immu_top.`CPU_immu_tlb.itlb_tr_ram.gen_parity_err( |
mem_word, |
-1, |
bit_number); |
end |
else |
begin |
if (debug_on) |
$display("%m: inject error into iTLB MR RAM, 0x%h, bit %02d", |
mem_word, bit_number); |
|
`OR1200_TOP.`CPU_immu_top.`CPU_immu_tlb.itlb_mr_ram.gen_parity_err( |
mem_word, |
-1, |
bit_number); |
|
end // else: !if(tr) |
|
ack_command; |
|
end |
endtask // inject_immu_fault |
|
task inject_dmmu_fault; |
input tr; |
input [31:0] cmd; |
reg [23:0] mem_word; |
reg [7:0] bit_number; |
begin |
// Get line number from command |
mem_word = cmd[15:0]; |
bit_number =cmd[23:16]; |
if (tr) |
begin |
if (debug_on) |
$display("%m: inject error into dtlb TR RAM, 0x%h, bit %02d", |
mem_word, bit_number); |
|
`OR1200_TOP.`CPU_dmmu_top.`CPU_dmmu_tlb.dtlb_tr_ram.gen_parity_err( |
mem_word, |
-1, |
bit_number); |
end |
else |
begin |
if (debug_on) |
$display("%m: inject error into dtlb MR RAM, 0x%h, bit %02d", |
mem_word, bit_number); |
|
`OR1200_TOP.`CPU_dmmu_top.`CPU_dmmu_tlb.dtlb_mr_ram.gen_parity_err( |
mem_word, |
-1, |
bit_number); |
|
end // else: !if(tr) |
|
ack_command; |
|
end |
endtask |
|
|
task inject_rf_fault; |
input [31:0] cmd; |
reg [23:0] gpr_no; |
reg [7:0] bit_number; |
begin |
bit_number =cmd[23:16]; |
gpr_no = cmd[15:0]; |
|
if (debug_on) |
$display("%m: inject error into register file, r%02d, bit %02d", |
gpr_no, bit_number); |
|
`OR1200_TOP.`CPU_cpu.`CPU_rf.rf_a.gen_parity_err( gpr_no, |
-1, |
bit_number); |
`OR1200_TOP.`CPU_cpu.`CPU_rf.rf_b.gen_parity_err( gpr_no, |
-1, |
bit_number); |
|
ack_command; |
|
end |
endtask |
|
reg [31:0] cmd; |
|
|
`define FT_STIM_CMD_WORD_CMD_POS 31:24 |
`define FT_STIM_CMD_WORD_CMD_WIDTH 8 |
`define FT_STIM_CMD_WORD_DATA_POS 23:0 |
`define FT_STIM_CMD_WORD_DATA_WIDTH 24 |
|
`define FT_STIM_CMD_IC_RAM_FAULT `FT_STIM_CMD_WORD_CMD_WIDTH'h1 |
`define FT_STIM_CMD_IC_TAG_FAULT `FT_STIM_CMD_WORD_CMD_WIDTH'h2 |
`define FT_STIM_CMD_DC_RAM_FAULT `FT_STIM_CMD_WORD_CMD_WIDTH'h3 |
`define FT_STIM_CMD_DC_TAG_FAULT `FT_STIM_CMD_WORD_CMD_WIDTH'h4 |
|
`define FT_STIM_CMD_DMMU_MR_FAULT `FT_STIM_CMD_WORD_CMD_WIDTH'h5 |
`define FT_STIM_CMD_DMMU_TR_FAULT `FT_STIM_CMD_WORD_CMD_WIDTH'h6 |
`define FT_STIM_CMD_IMMU_MR_FAULT `FT_STIM_CMD_WORD_CMD_WIDTH'h7 |
`define FT_STIM_CMD_IMMU_TR_FAULT `FT_STIM_CMD_WORD_CMD_WIDTH'h8 |
|
`define FT_STIM_CMD_RF_FAULT `FT_STIM_CMD_WORD_CMD_WIDTH'h9 |
|
`define FT_STIM_CMD_DEBUG_ON `FT_STIM_CMD_WORD_CMD_WIDTH'hff |
`define FT_STIM_CMD_DEBUG_OFF `FT_STIM_CMD_WORD_CMD_WIDTH'hfe |
|
|
initial |
begin |
#10; |
|
// Disable to begin with |
debug_on = 1; |
|
// Wait for software to indicate the test is ready to run. |
wait_for_start; |
|
// Ack our receipt of start |
ack_command; |
|
while(1) |
begin |
cmd = 32'hdeaddead; |
|
get_command(cmd); |
|
case(cmd[`FT_STIM_CMD_WORD_CMD_POS]) |
`FT_STIM_CMD_IC_RAM_FAULT: begin |
inject_ic_ram_fault(cmd); |
end |
`FT_STIM_CMD_IC_TAG_FAULT: begin |
inject_ic_tag_fault(cmd); |
end |
`FT_STIM_CMD_DC_RAM_FAULT: begin |
inject_dc_ram_fault(cmd); |
end |
`FT_STIM_CMD_DC_TAG_FAULT: begin |
inject_dc_tag_fault(cmd); |
end |
`FT_STIM_CMD_DMMU_MR_FAULT: begin |
inject_dmmu_fault(0, cmd); |
end |
`FT_STIM_CMD_DMMU_TR_FAULT: begin |
inject_dmmu_fault(1, cmd); |
end |
`FT_STIM_CMD_IMMU_MR_FAULT: begin |
inject_immu_fault(0, cmd); |
end |
`FT_STIM_CMD_IMMU_TR_FAULT: begin |
inject_immu_fault(1, cmd); |
end |
`FT_STIM_CMD_RF_FAULT: begin |
inject_rf_fault(cmd); |
end |
`FT_STIM_CMD_DEBUG_ON: begin |
$display("%m: Debug on"); |
debug_on = 1; |
ack_command; |
end |
`FT_STIM_CMD_DEBUG_OFF: begin |
$display("%m: Debug off"); |
debug_on = 0; |
ack_command; |
end |
default: |
begin |
$display("%m: Unknown command %h", |
cmd[`FT_STIM_CMD_WORD_CMD_POS]); |
#10000; |
$finish; |
end |
|
endcase // case (cmd[`FT_STIM_CMD_WORD_CMD_POS]) |
|
end // while (1) |
end // initial begin |
|
`endif |
endmodule // or1200_ft_stim |
/boards/generic/ft/bench/verilog/or1200_monitor.v
0,0 → 1,1890
////////////////////////////////////////////////////////////////////// |
//// //// |
//// or1200_monitor.v //// |
//// //// |
//// OR1200 processor monitor module //// |
//// //// |
//// Author(s): //// |
//// - Damjan Lampret, lampret@opencores.org //// |
//// - Julius Baxter, julius@opencores.org //// |
//// //// |
////////////////////////////////////////////////////////////////////// |
//// //// |
//// Copyright (C) 2009, 2010 Authors and OPENCORES.ORG //// |
//// //// |
//// This source file may be used and distributed without //// |
//// restriction provided that this copyright statement is not //// |
//// removed from the file and that any derivative work contains //// |
//// the original copyright notice and the associated disclaimer. //// |
//// //// |
//// This source file is free software; you can redistribute it //// |
//// and/or modify it under the terms of the GNU Lesser General //// |
//// Public License as published by the Free Software Foundation; //// |
//// either version 2.1 of the License, or (at your option) any //// |
//// later version. //// |
//// //// |
//// This source is distributed in the hope that it will be //// |
//// useful, but WITHOUT ANY WARRANTY; without even the implied //// |
//// warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR //// |
//// PURPOSE. See the GNU Lesser General Public License for more //// |
//// details. //// |
//// //// |
//// You should have received a copy of the GNU Lesser General //// |
//// Public License along with this source; if not, download it //// |
//// from http://www.opencores.org/lgpl.shtml //// |
//// //// |
////////////////////////////////////////////////////////////////////// |
|
`include "timescale.v" |
`include "or1200_defines.v" |
`include "orpsoc-testbench-defines.v" |
`include "test-defines.v" |
|
// |
// Top of TB |
// |
`define TB_TOP orpsoc_testbench |
|
// |
// Top of DUT |
// |
`define DUT_TOP `TB_TOP.dut |
|
// |
// Top of OR1200 inside test bench |
// |
`define OR1200_TOP `DUT_TOP.or1200_top0 |
|
// |
// Define to enable lookup file generation |
// |
//`define OR1200_MONITOR_LOOKUP |
|
// |
// Define to enable SPR access log file generation |
// |
//`define OR1200_MONITOR_SPRS |
|
// |
// Enable logging of state during execution |
// |
//`define OR1200_MONITOR_EXEC_STATE |
|
// |
// Enable disassembly of instructions in execution state log |
// |
//`define OR1200_MONITOR_EXEC_LOG_DISASSEMBLY |
|
// |
// Enable verbose report l.nops (to both general log file and stdout) |
// |
`define OR1200_MONITOR_VERBOSE_NOPS |
|
// |
// Enable monitoring of control and execution flow (experimental) |
// |
//`define OR1200_SYSTEM_CHECKER |
|
// Can either individually enable things above, or usually have the scripts |
// running the simulation pass the PROCESSOR_MONITOR_ENABLE_LOGS define to |
// enable them all. |
|
`ifdef PROCESSOR_MONITOR_ENABLE_LOGS |
`define OR1200_MONITOR_EXEC_STATE |
`define OR1200_MONITOR_SPRS |
`define OR1200_MONITOR_LOOKUP |
`endif |
|
// |
// Memory coherence checking (double check instruction in fetch stage against |
// what is in memory.) Useful for cache controller development. |
// |
//`define MEM_COHERENCE_CHECK |
|
// |
// Top of OR1200 inside test bench |
// |
`define CPU or1200 |
`define CPU_cpu or1200_cpu |
`define CPU_rf or1200_rf |
`define CPU_except or1200_except |
`define CPU_ctrl or1200_ctrl |
`define CPU_sprs or1200_sprs |
`define CPU_immu_top or1200_immu_top |
`define CPU_immu_tlb or1200_immu_tlb |
`define CPU_CORE_CLK `OR1200_TOP.`CPU_cpu.`CPU_ctrl.clk |
|
|
`define OR1K_OPCODE_POS 31:26 |
`define OR1K_J_BR_IMM_POS 25:0 |
`define OR1K_RD_POS 25:21 |
`define OR1K_RA_POS 20:16 |
`define OR1K_RB_POS 15:11 |
`define OR1K_ALU_OP_POS 3:0 |
|
`define OR1K_SHROT_OP_POS 7:6 |
`define OR1K_SHROTI_IMM_POS 5:0 |
`define OR1K_SF_OP 25:21 |
|
`define OR1K_XSYNC_OP_POS 25:21 |
|
|
module or1200_monitor; |
|
integer fexe; |
integer finsn; |
|
reg [23:0] ref; |
`ifdef OR1200_MONITOR_SPRS |
integer fspr; |
`endif |
integer fgeneral; |
`ifdef OR1200_MONITOR_LOOKUP |
integer flookup; |
`endif |
integer r3; |
integer insns; |
|
|
// |
// Initialization |
// |
initial begin |
ref = 0; |
`ifdef OR1200_MONITOR_EXEC_STATE |
fexe = $fopen({"../out/",`TEST_NAME_STRING,"-executed.log"}); |
`endif |
`ifdef OR1200_MONITOR_EXEC_LOG_DISASSEMBLY |
finsn = fexe; |
`endif |
$timeformat (-9, 2, " ns", 12); |
`ifdef OR1200_MONITOR_SPRS |
fspr = $fopen({"../out/",`TEST_NAME_STRING,"-sprs.log"}); |
`endif |
fgeneral = $fopen({"../out/",`TEST_NAME_STRING,"-general.log"}); |
`ifdef OR1200_MONITOR_LOOKUP |
flookup = $fopen({"../out/",`TEST_NAME_STRING,"-lookup.log"}); |
`endif |
insns = 0; |
|
end |
|
// |
// Get GPR |
// |
task get_gpr; |
input [4:0] gpr_no; |
output [31:0] gpr; |
integer j; |
begin |
|
`ifdef OR1200_RFRAM_GENERIC |
for(j = 0; j < 32; j = j + 1) begin |
gpr[j] = `OR1200_TOP.`CPU_cpu.`CPU_rf.rf_a.mem[gpr_no*32+j]; |
end |
|
`else |
//gpr = `OR1200_TOP.`CPU_cpu.`CPU_rf.rf_a.mem[gpr_no]; |
gpr = `OR1200_TOP.`CPU_cpu.`CPU_rf.rf_a.get_gpr(gpr_no); |
|
`endif |
|
|
end |
endtask |
|
// |
// Write state of the OR1200 registers into a file |
// |
// Limitation: only a small subset of register file RAMs |
// are supported |
// |
task display_arch_state; |
reg [5:0] i; |
reg [31:0] r; |
integer j; |
begin |
`ifdef OR1200_MONITOR_EXEC_STATE |
ref = ref + 1; |
`ifdef OR1200_MONITOR_LOOKUP |
$fdisplay(flookup, "Instruction %d: %t", insns, $time); |
`endif |
$fwrite(fexe, "\nEXECUTED(%d): %h: %h", insns, |
`OR1200_TOP.`CPU_cpu.`CPU_except.wb_pc, |
`OR1200_TOP.`CPU_cpu.`CPU_ctrl.wb_insn); |
`ifdef OR1200_MONITOR_EXEC_LOG_DISASSEMBLY |
$fwrite(fexe,"\t"); |
// Decode the instruction, print it out |
or1200_print_op(`OR1200_TOP.`CPU_cpu.`CPU_ctrl.wb_insn); |
`endif |
for(i = 0; i < 32; i = i + 1) begin |
if (i % 4 == 0) |
$fdisplay(fexe); |
get_gpr(i, r); |
$fwrite(fexe, "GPR%d: %h ", i, r); |
end |
$fdisplay(fexe); |
r = `OR1200_TOP.`CPU_cpu.`CPU_sprs.sr; |
$fwrite(fexe, "SR : %h ", r); |
r = `OR1200_TOP.`CPU_cpu.`CPU_sprs.epcr; |
$fwrite(fexe, "EPCR0: %h ", r); |
r = `OR1200_TOP.`CPU_cpu.`CPU_sprs.eear; |
$fwrite(fexe, "EEAR0: %h ", r); |
r = `OR1200_TOP.`CPU_cpu.`CPU_sprs.esr; |
$fdisplay(fexe, "ESR0 : %h", r); |
`endif // `ifdef OR1200_MONITOR_EXEC_STATE |
`ifdef OR1200_DISPLAY_EXECUTED |
ref = ref + 1; |
`ifdef OR1200_MONITOR_LOOKUP |
$fdisplay(flookup, "Instruction %d: %t", insns, $time); |
`endif |
$fwrite(fexe, "\nEXECUTED(%d): %h: %h", insns, `OR1200_TOP.`CPU_cpu.`CPU_except.wb_pc, `OR1200_TOP.`CPU_cpu.`CPU_ctrl.wb_insn); |
`endif |
insns = insns + 1; |
end |
endtask // display_arch_state |
|
/* Keep a trace buffer of the last lot of instructions and addresses |
* "executed",as read from the writeback stage, and cause a $finish if we hit |
* an instruction that is invalid, such as all zeros. |
* Currently, only breaks on an all zero instruction, but should probably be |
* made to break for anything with an X in it too. And of course ideally this |
* shouldn't be needed - but is handy if someone changes something and stops |
* the test continuing forever. |
*/ |
integer num_nul_inst; |
initial num_nul_inst = 0; |
|
task monitor_for_crash; |
`define OR1200_MONITOR_CRASH_TRACE_SIZE 32 |
//Trace buffer of 32 instructions |
reg [31:0] insn_trace [0:`OR1200_MONITOR_CRASH_TRACE_SIZE-1]; |
//Trace buffer of the addresses of those instructions |
reg [31:0] addr_trace [0:`OR1200_MONITOR_CRASH_TRACE_SIZE-1]; |
integer i; |
|
begin |
if (`OR1200_TOP.`CPU_cpu.`CPU_ctrl.wb_insn == 32'h00000000) |
num_nul_inst = num_nul_inst + 1; |
else |
num_nul_inst = 0; // Reset it |
|
if (num_nul_inst == 1000) // Sat a loop a bit too long... |
begin |
$fdisplay(fgeneral, "ERROR - no instruction at PC %h", |
`OR1200_TOP.`CPU_cpu.`CPU_except.wb_pc); |
$fdisplay(fgeneral, "Crash trace: Last %d instructions: ", |
`OR1200_MONITOR_CRASH_TRACE_SIZE); |
|
$fdisplay(fgeneral, "PC\t\tINSTR"); |
for(i=`OR1200_MONITOR_CRASH_TRACE_SIZE-1;i>=0;i=i-1) begin |
$fdisplay(fgeneral, "%h\t%h",addr_trace[i], insn_trace[i]); |
end |
#100 $finish; |
end |
else |
begin |
for(i=`OR1200_MONITOR_CRASH_TRACE_SIZE-1;i>0;i=i-1) begin |
insn_trace[i] = insn_trace[i-1]; |
addr_trace[i] = addr_trace[i-1]; |
end |
insn_trace[0] = `OR1200_TOP.`CPU_cpu.`CPU_ctrl.wb_insn; |
addr_trace[0] = `OR1200_TOP.`CPU_cpu.`CPU_except.wb_pc; |
end |
|
end |
endtask // monitor_for_crash |
|
|
// |
// Write state of the OR1200 registers into a file; version for exception |
// |
task display_arch_state_except; |
reg [5:0] i; |
reg [31:0] r; |
integer j; |
begin |
`ifdef OR1200_MONITOR_EXEC_STATE |
ref = ref + 1; |
`ifdef OR1200_MONITOR_LOOKUP |
$fdisplay(flookup, "Instruction %d: %t", insns, $time); |
`endif |
$fwrite(fexe, "\nEXECUTED(%d): %h: %h (exception)", insns, `OR1200_TOP.`CPU_cpu.`CPU_except.ex_pc, `OR1200_TOP.`CPU_cpu.`CPU_ctrl.ex_insn); |
for(i = 0; i < 32; i = i + 1) begin |
if (i % 4 == 0) |
$fdisplay(fexe); |
get_gpr(i, r); |
$fwrite(fexe, "GPR%d: %h ", i, r); |
end |
$fdisplay(fexe); |
r = `OR1200_TOP.`CPU_cpu.`CPU_sprs.sr; |
$fwrite(fexe, "SR : %h ", r); |
r = `OR1200_TOP.`CPU_cpu.`CPU_sprs.epcr; |
$fwrite(fexe, "EPCR0: %h ", r); |
r = `OR1200_TOP.`CPU_cpu.`CPU_sprs.eear; |
$fwrite(fexe, "EEAR0: %h ", r); |
r = `OR1200_TOP.`CPU_cpu.`CPU_sprs.esr; |
$fdisplay(fexe, "ESR0 : %h", r); |
insns = insns + 1; |
`endif // `ifdef OR1200_MONITOR_EXEC_STATE |
`ifdef OR1200_DISPLAY_EXECUTED |
ref = ref + 1; |
`ifdef OR1200_MONITOR_LOOKUP |
$fdisplay(flookup, "Instruction %d: %t", insns, $time); |
`endif |
$fwrite(fexe, "\nEXECUTED(%d): %h: %h (exception)", insns, |
`OR1200_TOP.`CPU_cpu.`CPU_except.ex_pc, |
`OR1200_TOP.`CPU_cpu.`CPU_ctrl.ex_insn); |
insns = insns + 1; |
`endif |
|
end |
endtask |
|
integer iwb_progress; |
reg [31:0] iwb_progress_addr; |
// |
// WISHBONE bus checker |
// |
always @(posedge `OR1200_TOP.iwb_clk_i) |
if (`OR1200_TOP.iwb_rst_i) begin |
iwb_progress = 0; |
iwb_progress_addr = `OR1200_TOP.iwb_adr_o; |
end |
else begin |
if (`OR1200_TOP.iwb_cyc_o && (iwb_progress != 2)) begin |
iwb_progress = 1; |
end |
if (`OR1200_TOP.iwb_stb_o) begin |
if (iwb_progress >= 1) begin |
if (iwb_progress == 1) |
iwb_progress_addr = `OR1200_TOP.iwb_adr_o; |
iwb_progress = 2; |
end |
else begin |
$fdisplay(fgeneral, "WISHBONE protocol violation: `OR1200_TOP.iwb_stb_o raised without `OR1200_TOP.iwb_cyc_o, at %t\n", $time); |
#100 $finish; |
end |
end |
if (`OR1200_TOP.iwb_ack_i & `OR1200_TOP.iwb_err_i) begin |
$fdisplay(fgeneral, "WISHBONE protocol violation: `OR1200_TOP.iwb_ack_i and `OR1200_TOP.iwb_err_i raised at the same time, at %t\n", $time); |
end |
if ((iwb_progress == 2) && (iwb_progress_addr != `OR1200_TOP.iwb_adr_o)) begin |
$fdisplay(fgeneral, "WISHBONE protocol violation: `OR1200_TOP.iwb_adr_o changed while waiting for `OR1200_TOP.iwb_err_i/`OR1200_TOP.iwb_ack_i, at %t\n", $time); |
#10000; |
$finish; |
end |
if (`OR1200_TOP.iwb_ack_i | `OR1200_TOP.iwb_err_i) |
if (iwb_progress == 2) begin |
iwb_progress = 0; |
iwb_progress_addr = `OR1200_TOP.iwb_adr_o; |
end |
else begin |
$fdisplay(fgeneral, "WISHBONE protocol violation: `OR1200_TOP.iwb_ack_i/`OR1200_TOP.iwb_err_i raised without `OR1200_TOP.iwb_cyc_i/`OR1200_TOP.iwb_stb_i, at %t\n", $time); |
#100 $finish; |
end |
if ((iwb_progress == 2) && !`OR1200_TOP.iwb_stb_o) begin |
$fdisplay(fgeneral, "WISHBONE protocol violation: `OR1200_TOP.iwb_stb_o lowered without `OR1200_TOP.iwb_err_i/`OR1200_TOP.iwb_ack_i, at %t\n", $time); |
#100 $finish; |
end |
end |
|
integer dwb_progress; |
reg [31:0] dwb_progress_addr; |
// |
// WISHBONE bus checker |
// |
always @(posedge `OR1200_TOP.dwb_clk_i) |
if (`OR1200_TOP.dwb_rst_i) |
dwb_progress = 0; |
else begin |
if (`OR1200_TOP.dwb_cyc_o && (dwb_progress != 2)) |
dwb_progress = 1; |
if (`OR1200_TOP.dwb_stb_o) |
if (dwb_progress >= 1) begin |
if (dwb_progress == 1) |
dwb_progress_addr = `OR1200_TOP.dwb_adr_o; |
dwb_progress = 2; |
end |
else begin |
$fdisplay(fgeneral, "WISHBONE protocol violation: `OR1200_TOP.dwb_stb_o raised without `OR1200_TOP.dwb_cyc_o, at %t\n", $time); |
#100 $finish; |
end |
if (`OR1200_TOP.dwb_ack_i & `OR1200_TOP.dwb_err_i) begin |
$fdisplay(fgeneral, "WISHBONE protocol violation: `OR1200_TOP.dwb_ack_i and `OR1200_TOP.dwb_err_i raised at the same time, at %t\n", $time); |
end |
if ((dwb_progress == 2) && (dwb_progress_addr != `OR1200_TOP.dwb_adr_o)) begin |
$fdisplay(fgeneral, "WISHBONE protocol violation: `OR1200_TOP.dwb_adr_o changed while waiting for `OR1200_TOP.dwb_err_i/`OR1200_TOP.dwb_ack_i, at %t\n", $time); |
#100 $finish; |
end |
if (`OR1200_TOP.dwb_ack_i | `OR1200_TOP.dwb_err_i) |
if (dwb_progress == 2) begin |
dwb_progress = 0; |
dwb_progress_addr = `OR1200_TOP.dwb_adr_o; |
end |
else begin |
$fdisplay(fgeneral, "WISHBONE protocol violation: `OR1200_TOP.dwb_ack_i/`OR1200_TOP.dwb_err_i raised without `OR1200_TOP.dwb_cyc_i/`OR1200_TOP.dwb_stb_i, at %t\n", $time); |
#100 $finish; |
end |
if ((dwb_progress == 2) && !`OR1200_TOP.dwb_stb_o) begin |
$fdisplay(fgeneral, "WISHBONE protocol violation: `OR1200_TOP.dwb_stb_o lowered without `OR1200_TOP.dwb_err_i/`OR1200_TOP.dwb_ack_i, at %t\n", $time); |
#100 $finish; |
end |
end |
|
// |
// Hooks for: |
// - displaying registers |
// - end of simulation |
// - access to SPRs |
// |
always @(posedge `CPU_CORE_CLK) |
if (!`OR1200_TOP.`CPU_cpu.`CPU_ctrl.wb_freeze) begin |
// #2; |
if (((`OR1200_TOP.`CPU_cpu.`CPU_ctrl.wb_insn[31:26] != `OR1200_OR32_NOP) |
| !`OR1200_TOP.`CPU_cpu.`CPU_ctrl.wb_insn[16]) |
& !(`OR1200_TOP.`CPU_cpu.`CPU_except.except_flushpipe & |
`OR1200_TOP.`CPU_cpu.`CPU_except.ex_dslot)) |
begin |
display_arch_state; |
monitor_for_crash; |
end |
else |
if (`OR1200_TOP.`CPU_cpu.`CPU_except.except_flushpipe) |
display_arch_state_except; |
// small hack to stop simulation (l.nop 1): |
if (`OR1200_TOP.`CPU_cpu.`CPU_ctrl.wb_insn == 32'h1500_0001) begin |
get_gpr(3, r3); |
$fdisplay(fgeneral, "%t: l.nop exit (%h)", $time, r3); |
`ifdef OR1200_MONITOR_VERBOSE_NOPS |
$display("exit(%h)",r3); |
`endif |
$finish; |
end |
// debug if test (l.nop 10) |
if (`OR1200_TOP.`CPU_cpu.`CPU_ctrl.wb_insn == 32'h1500_000a) begin |
$fdisplay(fgeneral, "%t: l.nop dbg_if_test", $time); |
end |
// simulation reports (l.nop 2) |
if (`OR1200_TOP.`CPU_cpu.`CPU_ctrl.wb_insn == 32'h1500_0002) begin |
get_gpr(3, r3); |
$fdisplay(fgeneral, "%t: l.nop report (0x%h)", $time, r3); |
`ifdef OR1200_MONITOR_VERBOSE_NOPS |
$display("report (0x%h);", r3); |
`endif |
end |
// simulation printfs (l.nop 3) |
if (`OR1200_TOP.`CPU_cpu.`CPU_ctrl.wb_insn == 32'h1500_0003) begin |
get_gpr(3, r3); |
$fdisplay(fgeneral, "%t: l.nop printf (%h)", $time, r3); |
end |
if (`OR1200_TOP.`CPU_cpu.`CPU_ctrl.wb_insn == 32'h1500_0004) begin |
// simulation putc (l.nop 4) |
get_gpr(3, r3); |
$write("%c", r3); |
$fdisplay(fgeneral, "%t: l.nop putc (%c)", $time, r3); |
end |
`ifdef OR1200_MONITOR_SPRS |
if (`OR1200_TOP.`CPU_cpu.`CPU_sprs.spr_we) |
$fdisplay(fspr, "%t: Write to SPR : [%h] <- %h", $time, |
`OR1200_TOP.`CPU_cpu.`CPU_sprs.spr_addr, |
`OR1200_TOP.`CPU_cpu.`CPU_sprs.spr_dat_o); |
if ((|`OR1200_TOP.`CPU_cpu.`CPU_sprs.spr_cs) & |
!`OR1200_TOP.`CPU_cpu.`CPU_sprs.spr_we) |
$fdisplay(fspr, "%t: Read from SPR: [%h] -> %h", $time, |
`OR1200_TOP.`CPU_cpu.`CPU_sprs.spr_addr, |
`OR1200_TOP.`CPU_cpu.`CPU_sprs.to_wbmux); |
`endif |
end |
|
|
`ifdef RAM_WB |
`define RAM_WB_TOP `DUT_TOP.ram_wb0.ram_wb_b3_0 |
task get_insn_from_wb_ram; |
input [31:0] addr; |
output [31:0] insn; |
begin |
insn = `RAM_WB_TOP.get_mem32(addr[31:2]); |
end |
endtask // get_insn_from_wb_ram |
`endif |
|
`ifdef VERSATILE_SDRAM |
`define SDRAM_TOP `TB_TOP.sdram0 |
// Bit selects to define the bank |
// 32 MB part with 4 banks |
`define SDRAM_BANK_SEL_BITS 24:23 |
`define SDRAM_WORD_SEL_TOP_BIT 22 |
// Gets instruction word from correct bank |
task get_insn_from_sdram; |
input [31:0] addr; |
output [31:0] insn; |
reg [`SDRAM_WORD_SEL_TOP_BIT-1:0] word_addr; |
|
begin |
word_addr = addr[`SDRAM_WORD_SEL_TOP_BIT:2]; |
if (addr[`SDRAM_BANK_SEL_BITS] == 2'b00) |
begin |
|
//$display("%t: get_insn_from_sdram bank0, word 0x%h, (%h and %h in SDRAM)", $time, word_addr, `SDRAM_TOP.Bank0[{word_addr,1'b0}], `SDRAM_TOP.Bank0[{word_addr,1'b1}]); |
insn[15:0] = `SDRAM_TOP.Bank0[{word_addr,1'b1}]; |
insn[31:16] = `SDRAM_TOP.Bank0[{word_addr,1'b0}]; |
end |
end |
|
endtask // get_insn_from_sdram |
`endif // `ifdef VERSATILE_SDRAM |
|
`ifdef XILINX_DDR2 |
`define DDR2_TOP `TB_TOP.gen_cs[0] |
// Gets instruction word from correct bank |
task get_insn_from_xilinx_ddr2; |
input [31:0] addr; |
output [31:0] insn; |
reg [16*8-1:0] ddr2_array_line0,ddr2_array_line1,ddr2_array_line2, |
ddr2_array_line3; |
integer word_in_line_num; |
begin |
// Get our 4 128-bit chunks (8 half-words in each!! Confused yet?), |
// 16 words total |
`DDR2_TOP.gen[0].u_mem0.memory_read(addr[28:27],addr[26:13],{addr[12:6],3'd0},ddr2_array_line0); |
`DDR2_TOP.gen[1].u_mem0.memory_read(addr[28:27],addr[26:13],{addr[12:6],3'd0},ddr2_array_line1); |
`DDR2_TOP.gen[2].u_mem0.memory_read(addr[28:27],addr[26:13],{addr[12:6],3'd0},ddr2_array_line2); |
`DDR2_TOP.gen[3].u_mem0.memory_read(addr[28:27],addr[26:13],{addr[12:6],3'd0},ddr2_array_line3); |
case (addr[5:2]) |
4'h0: |
begin |
insn[15:0] = ddr2_array_line0[15:0]; |
insn[31:16] = ddr2_array_line1[15:0]; |
end |
4'h1: |
begin |
insn[15:0] = ddr2_array_line2[15:0]; |
insn[31:16] = ddr2_array_line3[15:0]; |
end |
4'h2: |
begin |
insn[15:0] = ddr2_array_line0[31:16]; |
insn[31:16] = ddr2_array_line1[31:16]; |
end |
4'h3: |
begin |
insn[15:0] = ddr2_array_line2[31:16]; |
insn[31:16] = ddr2_array_line3[31:16]; |
end |
4'h4: |
begin |
insn[15:0] = ddr2_array_line0[47:32]; |
insn[31:16] = ddr2_array_line1[47:32]; |
end |
4'h5: |
begin |
insn[15:0] = ddr2_array_line2[47:32]; |
insn[31:16] = ddr2_array_line3[47:32]; |
end |
4'h6: |
begin |
insn[15:0] = ddr2_array_line0[63:48]; |
insn[31:16] = ddr2_array_line1[63:48]; |
end |
4'h7: |
begin |
insn[15:0] = ddr2_array_line2[63:48]; |
insn[31:16] = ddr2_array_line3[63:48]; |
end |
4'h8: |
begin |
insn[15:0] = ddr2_array_line0[79:64]; |
insn[31:16] = ddr2_array_line1[79:64]; |
end |
4'h9: |
begin |
insn[15:0] = ddr2_array_line2[79:64]; |
insn[31:16] = ddr2_array_line3[79:64]; |
end |
4'ha: |
begin |
insn[15:0] = ddr2_array_line0[95:80]; |
insn[31:16] = ddr2_array_line1[95:80]; |
end |
4'hb: |
begin |
insn[15:0] = ddr2_array_line2[95:80]; |
insn[31:16] = ddr2_array_line3[95:80]; |
end |
4'hc: |
begin |
insn[15:0] = ddr2_array_line0[111:96]; |
insn[31:16] = ddr2_array_line1[111:96]; |
end |
4'hd: |
begin |
insn[15:0] = ddr2_array_line2[111:96]; |
insn[31:16] = ddr2_array_line3[111:96]; |
end |
4'he: |
begin |
insn[15:0] = ddr2_array_line0[127:112]; |
insn[31:16] = ddr2_array_line1[127:112]; |
end |
4'hf: |
begin |
insn[15:0] = ddr2_array_line2[127:112]; |
insn[31:16] = ddr2_array_line3[127:112]; |
end |
endcase // case (addr[5:2]) |
end |
endtask // get_insn_from_xilinx_ddr2 |
`endif |
|
|
task get_insn_from_memory; |
input [31:0] id_pc; |
output [31:0] insn; |
begin |
// do a decode of which server we should look in |
case (id_pc[31:28]) |
`ifdef VERSATILE_SDRAM |
4'h0: |
get_insn_from_sdram(id_pc, insn); |
`endif |
`ifdef XILINX_DDR2 |
4'h0: |
get_insn_from_xilinx_ddr2(id_pc, insn); |
`endif |
`ifdef RAM_WB |
4'h0: |
get_insn_from_wb_ram(id_pc, insn); |
`endif |
4'hf: |
// Flash isn't stored in a memory, it's an FSM so just skip/ignore |
insn = `OR1200_TOP.`CPU_cpu.`CPU_ctrl.id_insn; |
default: |
begin |
$fdisplay(fgeneral, "%t: Unknown memory server for address 0x%h", $time,id_pc); |
insn = 32'hxxxxxxxx; // Unknown server |
end |
endcase // case (id_pc[31:28]) |
end |
endtask // get_insn_from_memory |
|
|
// |
// Look in the iMMU TLB MR for this address' page, if MMUs are on and enabled |
// |
task check_for_immu_entry; |
input [31:0] pc; |
output [31:0] physical_pc; |
output mmu_tlb_miss; |
integer w,x; |
|
reg [31:`OR1200_IMMU_PS] pc_vpn; |
|
reg [`OR1200_ITLBTRW-1:0] itlb_tr; |
reg [`OR1200_ITLBMRW-1:0] itlb_mr; |
|
integer tlb_index; |
reg mmu_en; |
|
|
begin |
mmu_tlb_miss = 0; |
|
`ifdef OR1200_NO_IMMU |
physical_pc = pc; |
`else |
mmu_en = `OR1200_TOP.`CPU_immu_top.immu_en; |
// If MMU is enabled |
if (mmu_en) |
begin |
|
// Look in the iTLB for mapping - get virtual page number |
pc_vpn = pc[31:`OR1200_IMMU_PS]; |
|
tlb_index = pc[`OR1200_ITLB_INDX]; |
|
// Look at the ITLB match register |
itlb_mr = `OR1200_TOP.`CPU_immu_top.`CPU_immu_tlb.itlb_mr_ram.mem[tlb_index]; |
|
// Get the translate register here too, in case there's an error, we print it |
itlb_tr = `OR1200_TOP.`CPU_immu_top.`CPU_immu_tlb.itlb_tr_ram.mem[tlb_index]; |
|
if ((itlb_mr[`OR1200_ITLBMR_V_BITS] === 1'b1) & (itlb_mr[`OR1200_ITLBMRW-1:1] === pc[`OR1200_ITLB_TAG])) |
begin |
// Page number in match register matches page number of virtual PC, so get the physical |
// address from the translate memory |
// Now pull the physical page number out of the tranlsate register (it's after bottom 3 bits) |
physical_pc = {itlb_tr[`OR1200_ITLBTRW-1:`OR1200_ITLBTRW-(32-`OR1200_IMMU_PS)],pc[`OR1200_IMMU_PS-1:0]}; |
//$display("check_for_immu_entry: found match for virtual PC 0x%h in entry %d of iMMU, mr = 0x%x tr = 0x%x, phys. PC = 0x%h", pc, pc[`OR1200_ITLB_INDX], itlb_mr, itlb_tr, physical_pc); |
end // if ((itlb_mr[`OR1200_ITLBMR_V_BITS]) & (itlb_mr[`OR1200_ITLBMRW-1:1] == pc[`OR1200_ITLB_TAG])) |
else |
begin |
|
// Wait a couple of clocks, see if we're doing a miss |
@(posedge `CPU_CORE_CLK); |
@(posedge `CPU_CORE_CLK); |
if (!(`OR1200_TOP.`CPU_immu_top.miss)) // MMU should indicate miss |
begin |
$display("%t: check_for_immu_entry - ERROR - no match found for virtual PC 0x%h in entry %d of iMMU, mr = 0x%x tr = 0x%x, and no miss generated", |
$time, pc, pc[`OR1200_ITLB_INDX], itlb_mr, itlb_tr); |
#100; |
$finish; |
end |
else |
begin |
mmu_tlb_miss = 1; // Started a miss, so ignore this instruction |
end |
end // else: !if((itlb_mr[`OR1200_ITLBMR_V_BITS]) & (itlb_mr[`OR1200_ITLBMRW-1:1] == pc[`OR1200_ITLB_TAG])) |
|
end // if (`OR1200_TOP.`CPU_immu_top.immu_en === 1'b1) |
else |
physical_pc = pc; |
`endif // !`ifdef OR1200_NO_IMMU |
end |
endtask // check_for_immu_entry |
|
|
/* |
Instruction memory coherence checking. |
|
For new instruction executed in the pipeline - ensure it matches |
what is in the main program memory. Perform MMU translations if |
it is enabled. |
*/ |
|
reg [31:0] mem_word; |
reg [31:0] last_addr = 0; |
reg [31:0] last_mem_word; |
reg [31:0] physical_pc; |
reg tlb_miss; |
|
|
`ifdef MEM_COHERENCE_CHECK |
`define MEM_COHERENCE_TRIGGER (`OR1200_TOP.`CPU_cpu.`CPU_ctrl.id_void === 1'b0) |
|
`define INSN_TO_CHECK `OR1200_TOP.`CPU_cpu.`CPU_ctrl.id_insn |
`define PC_TO_CHECK `OR1200_TOP.`CPU_cpu.`CPU_except.id_pc |
|
// Check instruction in decode stage is what is in the RAM |
always @(posedge `CPU_CORE_CLK) |
begin |
if (`MEM_COHERENCE_TRIGGER) |
begin |
|
check_for_immu_entry(`PC_TO_CHECK, physical_pc, tlb_miss); |
|
// Check if it's a new PC - will also get triggered if the |
// instruction has changed since we last checked it |
if (((physical_pc !== last_addr) || |
(last_mem_word != `INSN_TO_CHECK)) & !tlb_miss) |
begin |
// Decode stage not void, check instruction |
// get PC |
get_insn_from_memory(physical_pc, mem_word); |
|
if (mem_word !== `INSN_TO_CHECK) |
begin |
$fdisplay(fgeneral, "%t: Instruction mismatch for PC 0x%h (phys. 0x%h) - memory had 0x%h, CPU had 0x%h", |
$time, `PC_TO_CHECK, physical_pc, mem_word, |
`INSN_TO_CHECK); |
$display("%t: Instruction mismatch for PC 0x%h (phys. 0x%h) - memory had 0x%h, CPU had 0x%h", |
$time, `PC_TO_CHECK, physical_pc, mem_word, |
`INSN_TO_CHECK); |
#200; |
$finish; |
end |
last_addr = physical_pc; |
last_mem_word = mem_word; |
|
end // if (((physical_pc !== last_addr) || (last_mem_word != `INSN_TO_CHECK))... |
end // if (`MEM_COHERENCE_TRIGGER) |
end // always @ (posedge `CPU_CORE_CLK) |
|
`endif // `ifdef MEM_COHERENCE_CHECK |
|
// Trigger on each instruction that gets into writeback stage properly |
reg exception_coming1, exception_coming2, exception_here; |
reg will_jump, jumping, jump_dslot, jumped; |
reg rfe, except_during_rfe; |
reg dslot_expt; |
|
|
// Maintain a copy of GPRS for previous instruction |
reg [31:0] current_gprs [0:31]; |
reg [31:0] current_epcr, current_eear, current_esr, current_sr; |
reg [31:0] previous_gprs [0:31]; |
reg [31:0] previous_epcr; |
reg [31:0] previous_eear; |
reg [31:0] previous_esr; |
reg [31:0] previous_sr; |
|
task update_current_gprs; |
integer j; |
begin |
for(j=0;j<32;j=j+1) |
begin |
get_gpr(j,current_gprs[j]); |
end |
current_sr = `OR1200_TOP.`CPU_cpu.or1200_sprs.sr ; |
current_esr = `OR1200_TOP.`CPU_cpu.or1200_sprs.epcr ; |
current_epcr = `OR1200_TOP.`CPU_cpu.or1200_sprs.epcr ; |
current_eear = `OR1200_TOP.`CPU_cpu.or1200_sprs.eear ; |
end |
endtask |
|
task update_previous_gprs; |
integer j; |
begin |
for(j=0;j<32;j=j+1) |
begin |
previous_gprs[j] = current_gprs[j]; |
end |
previous_sr = current_sr; |
previous_esr = current_esr; |
previous_epcr = current_epcr; |
previous_eear = current_eear; |
end |
endtask // update_previous_gprs |
|
// Maintain a list of addresses we expect the processor to execute |
// Whenever we hit a branch or jump or rfe we add to this list - when we |
// execute it then we remove it from the list. |
reg [31:0] expected_addresses [0:31]; |
reg expected_addresses_waiting [0:31]; // List indicating if address is waiting |
reg duplicate_expected_addresses_waiting [0:31]; // List indicating if a waiting address will be cleared by the single return |
integer expected_address_num; |
// Initialise things on reset |
always @(`OR1200_TOP.iwb_rst_i) |
begin |
for (expected_address_num=0;expected_address_num<32;expected_address_num=expected_address_num+1) |
begin |
expected_addresses_waiting[expected_address_num] = 0; |
duplicate_expected_addresses_waiting[expected_address_num] = 0; |
end |
expected_address_num = 0; |
end |
|
task add_expected_address; |
input [31:0] expected_pc; |
begin |
if (expected_address_num == 31) |
begin |
$display("%t: Too many branches not reached",$time); |
#100; |
$finish; |
end |
if (expected_addresses_waiting[expected_address_num]) |
begin |
$display("%t: expected_addresses tracker bugged out. expected_address_num = %0d",$time,expected_address_num); |
#100; |
$finish; |
end |
else |
begin |
`ifdef OR1200_MONITOR_JUMPTRACK_DEBUG_OUTPUT |
// Debugging output... |
$display("%t: Adding address 0x%h to expected list index %0d",$time, expected_pc,expected_address_num); |
`endif |
// Put the expected PC in the list, increase the index |
expected_addresses[expected_address_num] = expected_pc; |
expected_addresses_waiting[expected_address_num] = 1; |
expected_address_num = expected_address_num + 1; |
end // else: !if(expected_addresses_waiting[expected_address_num]) |
end |
endtask // add_address_to_expect |
|
// Use this in the case that there's an execption after a jump, in which |
// case we'll have two entries when we finally jump back (the one the |
// original jump put in, and the one put in by the l.rfe or l.jr/ when |
// returning outside of exception handler), so mark this one as OK for |
// removing the duplicate of |
task mark_duplicate_expected_address; |
begin |
// This will always be done on the first instruction of an exception |
// that has occured after a delay slot instruction, so |
// expected_address_num will be one past the entry for the one we will |
// get a duplicate return call for |
duplicate_expected_addresses_waiting[expected_address_num-1] = 1; |
end |
endtask // mark_duplicate_expected_address |
|
|
task check_expected_address; |
input [31:0] pc; |
input expecting_hit; |
integer i,j; |
reg hit; |
reg duplicates; |
|
begin |
hit = 0; |
//$display("%t: check_expected_addr 0x%h, index %0d", |
// $time,pc, expected_address_num); |
if (expected_address_num > 0) |
begin |
// First check the last jump we did |
if (expected_addresses[expected_address_num-1] == pc) |
begin |
// Jump address hit |
// Debugging printout: |
`ifdef OR1200_MONITOR_JUMPTRACK_DEBUG_OUTPUT |
$display("%t: PC address 0x%h was in expected list, index %0d",$time, pc,expected_address_num-1); |
`endif |
expected_address_num = expected_address_num-1; |
expected_addresses_waiting[expected_address_num] = 0; |
hit = 1; |
end |
else |
begin |
// Check through the list |
for(i=0;i<expected_address_num;i=i+1) |
begin |
if (expected_addresses[i] == pc) |
begin |
// Jump address hit |
// Debugging printout: |
`ifdef OR1200_MONITOR_JUMPTRACK_DEBUG_OUTPUT |
$display("%t: PC address 0x%h was in expected list, index %0d",$time, pc,i); |
`endif |
for(j=i;j<expected_address_num;j=j+1) |
begin |
// Pull all of the ones above us down one |
expected_addresses_waiting[j] |
= expected_addresses_waiting[j+1]; |
expected_addresses[j] |
= expected_addresses[j+1]; |
duplicate_expected_addresses_waiting[j] |
= duplicate_expected_addresses_waiting[j+1]; |
end |
expected_address_num = expected_address_num-1; |
hit = 1; |
// quit out. only allow 1 hit |
i = expected_address_num; |
end |
end |
end // else: !if(expected_addresses[expected_ad... |
end // if (expected_address_num > 0) |
|
// Check for duplicates this way because of the way we've declared |
// the array... |
duplicates=0; |
for(i=0;i<32;i=i+1) |
duplicates = duplicates | duplicate_expected_addresses_waiting[i]; |
|
if (hit & duplicates) |
begin |
// If we got a hit, check for duplicates we're also meant to clear |
`ifdef OR1200_MONITOR_JUMPTRACK_DEBUG_OUTPUT |
$display; |
`endif |
for(i=0;i<expected_address_num;i=i+1) |
begin |
if(duplicate_expected_addresses_waiting[i] & |
expected_addresses_waiting[i] & |
expected_addresses[i] == pc) |
begin |
// Found a duplicate call address, clear it |
duplicate_expected_addresses_waiting[i] = 0; |
expected_addresses_waiting[i] = 0; |
|
// Now reorder the list - pull all the ones above us |
// down by one |
for(j=i;j<expected_address_num;j=j+1) |
begin |
expected_addresses_waiting[j] = expected_addresses_waiting[j+1]; |
expected_addresses[j] = expected_addresses[j+1]; |
duplicate_expected_addresses_waiting[j] = duplicate_expected_addresses_waiting[j+1]; |
end |
expected_address_num = expected_address_num - 1; |
end |
end // for (i=0;i<expected_address_num;i=i+1) |
end // if (hit & duplicates) |
|
if (expecting_hit & !hit) |
begin |
// Expected this address to be one we're supposed to jump to, but it wasn't! |
$display("%t: Failed to find current PC, 0x%h, in expected PCs for branches/jumps",$time,pc); |
#100; |
$finish; |
end |
|
end |
endtask // check_expected_address |
|
// Task to assert value of GPR |
task assert_gpr_val; |
input [5:0] regnum; |
input [31:0] assert_value; |
input [31:0] pc; |
reg [31:0] reg_val; |
|
begin |
get_gpr(regnum, reg_val); |
if (reg_val !== assert_value) |
begin |
$display("%t: Assert r%0d value (0x%h) = 0x%h failed. pc=0x%h", |
$time, regnum, reg_val, assert_value,pc); |
#100; |
$finish; |
end |
end |
endtask // assert_gpr_val |
|
// Task to assert something is true |
task assert_this; |
input assert_result; |
input [31:0] pc; |
begin |
if (!assert_result) |
begin |
$display("%t: Assert failed for instruction at pc=0x%h", |
$time , pc); |
#100; |
$finish; |
end |
end |
endtask // assert_gpr_val |
|
// The jumping variable doesn't get updated until we do the proper check of |
// the current instruction reaching the writeback stage. We need to know |
// earlier, eg. in the exception checking part, if this instruction will |
// jump. We do that with this task. |
task check_for_jump; |
input [31:0] insn; |
reg [5:0] opcode; |
reg flag; |
begin |
opcode = insn[`OR1K_OPCODE_POS]; |
// Use the flag from the previous instruction, as the decision |
// is made in the execute stage not in te writeback stage, |
// which is where we're getting our instructions. |
flag = previous_sr[`OR1200_SR_F]; |
|
case (opcode) |
`OR1200_OR32_J, |
`OR1200_OR32_JR, |
`OR1200_OR32_JAL, |
`OR1200_OR32_JALR: |
will_jump = 1; |
`OR1200_OR32_BNF: |
will_jump = !flag; |
`OR1200_OR32_BF: |
will_jump = flag; |
default: |
will_jump = 0; |
endcase // case (opcode) |
end |
endtask // check_for_jump |
|
|
|
// Detect exceptions from the processor here |
reg [13:0] except_trig_r; |
reg exception_coming; |
|
always @(posedge `CPU_CORE_CLK) |
if (`OR1200_TOP.iwb_rst_i) |
begin |
except_trig_r = 0; |
exception_coming = 0; |
except_during_rfe = 0; |
end |
else if ((|`OR1200_TOP.`CPU_cpu.`CPU_except.except_trig) && !exception_coming) |
begin |
exception_coming = 1; |
except_trig_r = `OR1200_TOP.`CPU_cpu.`CPU_except.except_trig; |
except_during_rfe = rfe; |
end |
|
task check_incoming_exceptions; |
begin |
|
// Exception timing - depends on the trigger. |
// Appears to be: |
// tick timer - dslot - 1 instruction delay, else 2 |
// tlb lookasides - 1 instruction for both |
|
casex (except_trig_r) |
13'b1_xxxx_xxxx_xxxx: begin |
//except_type <= #1 `OR1200_EXCEPT_TICK; |
exception_here = exception_coming2; |
exception_coming2 = jump_dslot ? exception_coming: exception_coming1 ; |
exception_coming1 = jump_dslot ? 0 : exception_coming; |
end |
13'b0_1xxx_xxxx_xxxx: begin |
//except_type <= #1 `OR1200_EXCEPT_INT; |
#1; |
end |
13'b0_01xx_xxxx_xxxx: begin |
//except_type <= #1 `OR1200_EXCEPT_ITLBMISS; |
exception_here = exception_coming2; |
exception_coming2 = jump_dslot ? exception_coming : exception_coming1 ; |
exception_coming1 = jump_dslot ? 0 : exception_coming; |
end |
13'b0_001x_xxxx_xxxx: begin |
//except_type <= #1 `OR1200_EXCEPT_IPF; |
exception_here = exception_coming2; |
exception_coming2 = jump_dslot ? exception_coming : exception_coming1 ; |
exception_coming1 = jump_dslot ? 0 : exception_coming; |
end |
13'b0_0001_xxxx_xxxx: begin |
//except_type <= #1 `OR1200_EXCEPT_BUSERR; |
exception_here = exception_coming; |
exception_coming2 = 0; |
exception_coming1 = 0; |
end |
13'b0_0000_1xxx_xxxx: begin |
//except_type <= #1 `OR1200_EXCEPT_ILLEGAL; |
if (will_jump) |
begin |
// Writeback stage instruction will jump, and we have an |
// illegal instruction in the decode/execute stage, which is |
// the delay slot, so indicate the exception is coming... |
exception_here = exception_coming2; |
exception_coming2 = exception_coming; |
exception_coming1 = 0; |
end |
else |
begin |
exception_here = jump_dslot ? |
exception_coming2 : exception_coming; |
exception_coming2 = jump_dslot ? exception_coming : 0; |
exception_coming1 = 0; |
end |
end |
13'b0_0000_01xx_xxxx: begin |
//except_type <= #1 `OR1200_EXCEPT_ALIGN; |
if(will_jump) |
begin |
exception_here = exception_coming2; |
exception_coming2 = exception_coming; |
exception_coming1 = 0; |
end |
else |
begin |
exception_here = (rfe) ? exception_coming : exception_coming2; |
exception_coming2 = (rfe) ? 0 : exception_coming; |
exception_coming1 = 0; |
end |
end |
13'b0_0000_001x_xxxx: begin |
//except_type <= #1 `OR1200_EXCEPT_DTLBMISS; |
// Looks like except_trig goes high here after we check the |
// instruction before the itlb miss after a delay slot, so we |
// miss the dslot variable (it gets propegated before we call |
// this task) so we use the jumped variable here to see if we |
// are an exception after a delay slot |
//exception_here = (jumped | rfe) ? exception_coming : exception_coming2 ; |
//exception_coming2 = (jumped | rfe) ? 0 : exception_coming; |
|
exception_here = (jumped | rfe) ? exception_coming : exception_coming2 ; |
exception_coming2 = (jumped | rfe) ? 0 : exception_coming; |
|
exception_coming1 = 0; |
end |
13'b0_0000_0001_xxxx: begin |
//except_type <= #1 `OR1200_EXCEPT_DPF; |
if (jumped) begin // Jumped onto illegal instruction |
exception_here = exception_coming ; |
exception_coming2 = 0; |
exception_coming1 = 0; |
end |
else begin |
exception_here = exception_coming2; |
exception_coming2 = exception_coming; |
exception_coming1 = 0; |
end |
end |
13'b0_0000_0000_1xxx: begin // Data Bus Error |
//except_type <= #1 `OR1200_EXCEPT_BUSERR; |
exception_here = exception_coming2 ; |
exception_coming2 = exception_coming; |
exception_coming1 = 0; |
end |
13'b0_0000_0000_01xx: begin |
//except_type <= #1 `OR1200_EXCEPT_RANGE; |
#1; |
end |
13'b0_0000_0000_001x: begin |
// trap |
#1; |
end |
13'b0_0000_0000_0001: begin |
//except_type <= #1 `OR1200_EXCEPT_SYSCALL; |
exception_here = exception_coming2; |
exception_coming2 = jumped ? exception_coming: exception_coming1 ; |
exception_coming1 = jumped ? 0 : exception_coming; |
end |
endcase // casex (except_trig_r) |
|
exception_coming = 0; |
except_during_rfe = 0; |
|
end |
endtask // check_incoming_exceptions |
|
|
|
|
///////////////////////////////////////////////////////////////////////// |
// Execution tracking task |
///////////////////////////////////////////////////////////////////////// |
|
|
`ifdef OR1200_SYSTEM_CHECKER |
always @(posedge `CPU_CORE_CLK) |
begin |
if (`OR1200_TOP.iwb_rst_i) |
begin |
exception_coming1 = 0;exception_coming2 = 0;exception_here= 0; |
jumping = 0; jump_dslot = 0; jumped = 0; |
rfe = 0; |
end |
if (!`OR1200_TOP.`CPU_cpu.`CPU_ctrl.wb_freeze) begin |
//#2 ; |
// If instruction isn't a l.nop with bit 16 set (implementation's |
// filler instruction in pipeline), and do not have an exception |
// signaled with a dslot instruction in the execute stage |
if (((`OR1200_TOP.`CPU_cpu.`CPU_ctrl.wb_insn[`OR1K_OPCODE_POS] != |
`OR1200_OR32_NOP) || !`OR1200_TOP.`CPU_cpu.`CPU_ctrl.wb_insn[16]) |
&& !(`OR1200_TOP.`CPU_cpu.`CPU_except.except_flushpipe && |
`OR1200_TOP.`CPU_cpu.`CPU_except.ex_dslot)) // and not except start |
begin |
|
// Propegate jump-tracking variables |
// If was exception in delay slot, we didn't actually jump |
// so don't set jumped in this case. |
jumped = exception_here ? 0 : jump_dslot; |
jump_dslot = jumping; |
jumping = 0; |
rfe = 0; |
|
// Now, check if current instruction will jump/branch, this is |
// needed by the exception checking code, sets will_jump=1 |
check_for_jump(`OR1200_TOP.`CPU_cpu.`CPU_ctrl.wb_insn); |
|
// Now check if it's an exception this instruction |
check_incoming_exceptions; |
|
// Case where we just went to an exception after a jump, so we |
// mark the address we were meant to jump to as a place which will |
// have duplicate return entries in the expected address list |
if (exception_here & (jumped | jump_dslot)) |
begin |
$display("%t: marked as jump address with exception (dup)" |
,$time); |
mark_duplicate_expected_address; |
end |
|
or1200_check_execution(`OR1200_TOP.`CPU_cpu.`CPU_ctrl.wb_insn, |
`OR1200_TOP.`CPU_cpu.`CPU_except.wb_pc, |
exception_here); |
//$write("%t: pc:0x%h\t",$time, |
// `OR1200_TOP.`CPU_cpu.`CPU_except.wb_pc); |
// Decode the instruction, print it out |
//or1200_print_op(`OR1200_TOP.`CPU_cpu.`CPU_ctrl.wb_insn); |
//$write("\t exc:%0h dsl:%0h\n",exception_here,jump_dslot); |
|
|
|
end |
end // if (!`OR1200_TOP.`CPU_cpu.`CPU_ctrl.wb_freeze) |
end // always @ (posedge `CPU_CORE_CLK) |
`endif |
|
|
task or1200_check_execution; |
input [31:0] insn; |
input [31:0] pc; |
input exception; |
|
reg [5:0] opcode; |
|
reg [25:0] j_imm; |
reg [25:0] br_imm; |
|
reg [4:0] rD_num, rA_num, rB_num; |
reg [31:0] rD_val, rA_val, rB_val; |
reg [15:0] imm_16bit; |
|
reg [15:0] mtspr_imm; |
|
reg [3:0] alu_op; |
reg [1:0] shrot_op; |
|
reg [5:0] shroti_imm; |
|
reg [5:0] sf_op; |
|
reg [5:0] xsync_op; |
|
reg flag; |
|
reg [31:0] br_j_ea; // Branch/jump effective address |
|
|
begin |
|
// Instruction opcode |
opcode = insn[`OR1K_OPCODE_POS]; |
// Immediates for jump or branch instructions |
j_imm = insn[`OR1K_J_BR_IMM_POS]; |
br_imm = insn[`OR1K_J_BR_IMM_POS]; |
// Register numbers (D, A and B) |
rD_num = insn[`OR1K_RD_POS]; |
rA_num = insn[`OR1K_RA_POS]; |
rB_num = insn[`OR1K_RB_POS]; |
// Bottom 16 bits when used as immediates in various instructions |
imm_16bit = insn[15:0]; |
// 16-bit immediate for mtspr instructions |
mtspr_imm = {insn[25:21],insn[10:0]}; |
// ALU op for ALU instructions |
alu_op = insn[`OR1K_ALU_OP_POS]; |
// Shift-rotate op for SHROT ALU instructions |
shrot_op = insn[`OR1K_SHROT_OP_POS]; |
shroti_imm = insn[`OR1K_SHROTI_IMM_POS]; |
|
// Set flag op |
sf_op = insn[`OR1K_SF_OP]; |
|
// Xsync/syscall/trap opcode |
xsync_op = insn[`OR1K_XSYNC_OP_POS]; |
|
// Use the flag from the previous instruction, as the decision |
// is made in the execute stage not in te writeback stage, |
// which is where we're getting our instructions. |
flag = previous_sr[`OR1200_SR_F]; |
|
update_current_gprs; |
|
// Check MSbit of the immediate, sign extend if set |
br_j_ea = j_imm[25] ? pc + {4'hf,j_imm,2'b00} : |
pc + {4'h0,j_imm,2'b00}; |
|
if (exception) |
begin |
$display("%t: exception - at 0x%x",$time, pc); |
// get epcr, put it in the addresses we expect to jump |
// back to |
// Maybe DON'T do this. Because maybe in linux things we |
// interrupt out of, we don't want to execute them again? |
//add_expected_address(current_epcr); |
end |
|
|
check_expected_address(pc, (jumped & !exception)); |
|
rfe = 0; |
|
case (opcode) |
`OR1200_OR32_J: |
begin |
// |
// PC < - exts(Immediate < < 2) + JumpInsnAddr |
// |
//The immediate value is shifted left two bits, sign-extended |
// to program counter width, and then added to the address of |
// the jump instruction. The result is the effective address |
// of the jump. The program unconditionally jumps to EA with |
// a delay of one instruction. |
|
add_expected_address(br_j_ea); |
|
jumping = 1; |
end |
`OR1200_OR32_JAL: |
begin |
// |
//PC < - exts(Immediate < < 2) + JumpInsnAddr |
//LR < - DelayInsnAddr + 4 |
// |
// Link reg is r9, check it is PC+8 |
// |
add_expected_address(br_j_ea); |
assert_gpr_val(9, pc+8, pc); |
jumping = 1; // |
end |
`OR1200_OR32_BNF: |
begin |
//EA < - exts(Immediate < < 2) + BranchInsnAddr |
//PC < - EA if SR[F] cleared |
if (!flag) |
begin |
add_expected_address(br_j_ea); |
jumping = 1; |
end |
end |
`OR1200_OR32_BF: |
begin |
//EA < - exts(Immediate < < 2) + BranchInsnAddr |
//PC < - EA if SR[F] set |
if (flag) |
begin |
add_expected_address(br_j_ea); |
jumping = 1; |
end |
end |
`OR1200_OR32_RFE: |
begin |
add_expected_address(current_epcr); |
// jumping variable keeps track of jumps/branches with delay |
// slot - there is none for l.rfe |
rfe = 1; |
end |
`OR1200_OR32_JR: |
begin |
//PC < - rB |
get_gpr(rB_num, rB_val); |
add_expected_address(rB_val); |
jumping = 1; |
end |
`OR1200_OR32_JALR: |
begin |
//PC < - rB |
//LR < - DelayInsnAddr + 4 |
get_gpr(rB_num, rB_val); |
add_expected_address(rB_val); |
assert_gpr_val(9, pc+8, pc); |
jumping = 1; |
end |
/* |
`OR1200_OR32_LWZ, |
`OR1200_OR32_LBZ, |
`OR1200_OR32_LBS, |
`OR1200_OR32_LHZ, |
`OR1200_OR32_LHS, |
`OR1200_OR32_SW, |
`OR1200_OR32_SB, |
`OR1200_OR32_SH: |
begin |
// Should result in databus access if data cache disabled |
$display("%t: lsu instruction",$time); |
end |
|
`OR1200_OR32_MFSPR, |
`OR1200_OR32_MTSPR: |
begin |
// Confirm RF values end up in the correct SPR |
$display("%t: mxspr",$time); |
end |
|
`OR1200_OR32_MOVHI, |
`OR1200_OR32_ADDI, |
`OR1200_OR32_ADDIC, |
`OR1200_OR32_ANDI, |
`OR1200_OR32_ORI, |
`OR1200_OR32_XORI, |
`OR1200_OR32_MULI, |
`OR1200_OR32_ALU: |
begin |
// Double check operations done on RF and immediate values |
$display("%t: ALU op",$time); |
end |
|
`OR1200_OR32_SH_ROTI: |
begin |
// Rotate according to immediate - maybe should be in ALU ops |
$display("%t: rotate op",$time); |
end |
|
`OR1200_OR32_SFXXI, |
`OR1200_OR32_SFXX: |
begin |
// Set flag - do the check oursevles, check flag |
$display("%t: set flag op",$time); |
end |
|
`OR1200_OR32_MACI, |
`OR1200_OR32_MACMSB: |
begin |
// Either, multiply signed and accumulate, l.mac |
// or multiply signed and subtract, l.msb |
$display("%t: MAC op",$time); |
end |
*/ |
|
/*default: |
begin |
$display("%t: Unknown opcode 0x%h at pc 0x%x\n", |
$time,opcode, pc); |
end |
*/ |
endcase // case (opcode) |
|
update_previous_gprs; |
|
end |
endtask // or1200_check_execution |
|
|
///////////////////////////////////////////////////////////////////////// |
// Instruction decode task |
///////////////////////////////////////////////////////////////////////// |
|
task or1200_print_op; |
input [31:0] insn; |
|
reg [5:0] opcode; |
|
reg [25:0] j_imm; |
reg [25:0] br_imm; |
|
reg [4:0] rD_num, rA_num, rB_num; |
reg [31:0] rA_val, rB_val; |
reg [15:0] imm_16bit; |
reg [10:0] imm_split16bit; |
|
reg [3:0] alu_op; |
reg [1:0] shrot_op; |
|
reg [5:0] shroti_imm; |
|
reg [5:0] sf_op; |
|
reg [5:0] xsync_op; |
|
begin |
// Instruction opcode |
opcode = insn[`OR1K_OPCODE_POS]; |
// Immediates for jump or branch instructions |
j_imm = insn[`OR1K_J_BR_IMM_POS]; |
br_imm = insn[`OR1K_J_BR_IMM_POS]; |
// Register numbers (D, A and B) |
rD_num = insn[`OR1K_RD_POS]; |
rA_num = insn[`OR1K_RA_POS]; |
rB_num = insn[`OR1K_RB_POS]; |
// Bottom 16 bits when used as immediates in various instructions |
imm_16bit = insn[15:0]; |
// Bottom 11 bits used as immediates for l.sX instructions |
|
// Split 16-bit immediate for l.mtspr/l.sX instructions |
imm_split16bit = {insn[25:21],insn[10:0]}; |
// ALU op for ALU instructions |
alu_op = insn[`OR1K_ALU_OP_POS]; |
// Shift-rotate op for SHROT ALU instructions |
shrot_op = insn[`OR1K_SHROT_OP_POS]; |
shroti_imm = insn[`OR1K_SHROTI_IMM_POS]; |
|
// Set flag op |
sf_op = insn[`OR1K_SF_OP]; |
|
// Xsync/syscall/trap opcode |
xsync_op = insn[`OR1K_XSYNC_OP_POS]; |
|
case (opcode) |
`OR1200_OR32_J: |
begin |
$fwrite(finsn,"l.j 0x%h", {j_imm,2'b00}); |
end |
|
`OR1200_OR32_JAL: |
begin |
$fwrite(finsn,"l.jal 0x%h", {j_imm,2'b00}); |
end |
|
`OR1200_OR32_BNF: |
begin |
$fwrite(finsn,"l.bnf 0x%h", {br_imm,2'b00}); |
end |
|
`OR1200_OR32_BF: |
begin |
$fwrite(finsn,"l.bf 0x%h", {br_imm,2'b00}); |
end |
|
`OR1200_OR32_RFE: |
begin |
$fwrite(finsn,"l.rfe"); |
end |
|
`OR1200_OR32_JR: |
begin |
$fwrite(finsn,"l.jr r%0d",rB_num); |
end |
|
`OR1200_OR32_JALR: |
begin |
$fwrite(finsn,"l.jalr r%0d",rB_num); |
end |
|
`OR1200_OR32_LWZ: |
begin |
$fwrite(finsn,"l.lwz r%0d,0x%0h(r%0d)",rD_num,imm_16bit,rA_num); |
end |
|
`OR1200_OR32_LBZ: |
begin |
$fwrite(finsn,"l.lbz r%0d,0x%0h(r%0d)",rD_num,imm_16bit,rA_num); |
end |
|
`OR1200_OR32_LBS: |
begin |
$fwrite(finsn,"l.lbs r%0d,0x%0h(r%0d)",rD_num,imm_16bit,rA_num); |
end |
|
`OR1200_OR32_LHZ: |
begin |
$fwrite(finsn,"l.lhz r%0d,0x%0h(r%0d)",rD_num,imm_16bit,rA_num); |
end |
|
`OR1200_OR32_LHS: |
begin |
$fwrite(finsn,"l.lhs r%0d,0x%0h(r%0d)",rD_num,imm_16bit,rA_num); |
end |
|
`OR1200_OR32_SW: |
begin |
$fwrite(finsn,"l.sw 0x%0h(r%0d),r%0d",imm_split16bit,rA_num,rB_num); |
end |
|
`OR1200_OR32_SB: |
begin |
$fwrite(finsn,"l.sb 0x%0h(r%0d),r%0d",imm_split16bit,rA_num,rB_num); |
end |
|
`OR1200_OR32_SH: |
begin |
$fwrite(finsn,"l.sh 0x%0h(r%0d),r%0d",imm_split16bit,rA_num,rB_num); |
end |
|
`OR1200_OR32_MFSPR: |
begin |
$fwrite(finsn,"l.mfspr r%0d,r%0d,0x%h",rD_num,rA_num,imm_16bit,); |
end |
|
`OR1200_OR32_MTSPR: |
begin |
$fwrite(finsn,"l.mtspr r%0d,r%0d,0x%h",rA_num,rB_num,imm_split16bit); |
end |
|
`OR1200_OR32_MOVHI: |
begin |
if (!insn[16]) |
$fwrite(finsn,"l.movhi r%0d,0x%h",rD_num,imm_16bit); |
else |
$fwrite(finsn,"l.macrc r%0d",rD_num); |
end |
|
`OR1200_OR32_ADDI: |
begin |
$fwrite(finsn,"l.addi r%0d,r%0d,0x%h",rD_num,rA_num,imm_16bit); |
end |
|
`OR1200_OR32_ADDIC: |
begin |
$fwrite(finsn,"l.addic r%0d,r%0d,0x%h",rD_num,rA_num,imm_16bit); |
end |
|
`OR1200_OR32_ANDI: |
begin |
$fwrite(finsn,"l.andi r%0d,r%0d,0x%h",rD_num,rA_num,imm_16bit); |
end |
|
`OR1200_OR32_ORI: |
begin |
$fwrite(finsn,"l.ori r%0d,r%0d,0x%h",rD_num,rA_num,imm_16bit); |
end |
|
`OR1200_OR32_XORI: |
begin |
$fwrite(finsn,"l.xori r%0d,r%0d,0x%h",rD_num,rA_num,imm_16bit); |
end |
|
`OR1200_OR32_MULI: |
begin |
$fwrite(finsn,"l.muli r%0d,r%0d,0x%h",rD_num,rA_num,imm_16bit); |
end |
|
`OR1200_OR32_ALU: |
begin |
case(alu_op) |
`OR1200_ALUOP_ADD: |
$fwrite(finsn,"l.add "); |
`OR1200_ALUOP_ADDC: |
$fwrite(finsn,"l.addc "); |
`OR1200_ALUOP_SUB: |
$fwrite(finsn,"l.sub "); |
`OR1200_ALUOP_AND: |
$fwrite(finsn,"l.and "); |
`OR1200_ALUOP_OR: |
$fwrite(finsn,"l.or "); |
`OR1200_ALUOP_XOR: |
$fwrite(finsn,"l.xor "); |
`OR1200_ALUOP_MUL: |
$fwrite(finsn,"l.mul "); |
`OR1200_ALUOP_SHROT: |
begin |
case(shrot_op) |
`OR1200_SHROTOP_SLL: |
$fwrite(finsn,"l.sll "); |
`OR1200_SHROTOP_SRL: |
$fwrite(finsn,"l.srl "); |
`OR1200_SHROTOP_SRA: |
$fwrite(finsn,"l.sra "); |
`OR1200_SHROTOP_ROR: |
$fwrite(finsn,"l.ror "); |
endcase // case (shrot_op) |
end |
`OR1200_ALUOP_DIV: |
$fwrite(finsn,"l.div "); |
`OR1200_ALUOP_DIVU: |
$fwrite(finsn,"l.divu "); |
`OR1200_ALUOP_CMOV: |
$fwrite(finsn,"l.cmov "); |
endcase // case (alu_op) |
$fwrite(finsn,"r%0d,r%0d,r%0d",rD_num,rA_num,rB_num); |
end |
|
`OR1200_OR32_SH_ROTI: |
begin |
case(shrot_op) |
`OR1200_SHROTOP_SLL: |
$fwrite(finsn,"l.slli "); |
`OR1200_SHROTOP_SRL: |
$fwrite(finsn,"l.srli "); |
`OR1200_SHROTOP_SRA: |
$fwrite(finsn,"l.srai "); |
`OR1200_SHROTOP_ROR: |
$fwrite(finsn,"l.rori "); |
endcase // case (shrot_op) |
$fwrite(finsn,"r%0d,r%0d,0x%h",rD_num,rA_num,shroti_imm); |
end |
|
`OR1200_OR32_SFXXI: |
begin |
case(sf_op[2:0]) |
`OR1200_COP_SFEQ: |
$fwrite(finsn,"l.sfeqi "); |
`OR1200_COP_SFNE: |
$fwrite(finsn,"l.sfnei "); |
`OR1200_COP_SFGT: |
begin |
if (sf_op[`OR1200_SIGNED_COMPARE]) |
$fwrite(finsn,"l.sfgtsi "); |
else |
$fwrite(finsn,"l.sfgtui "); |
end |
`OR1200_COP_SFGE: |
begin |
if (sf_op[`OR1200_SIGNED_COMPARE]) |
$fwrite(finsn,"l.sfgesi "); |
else |
$fwrite(finsn,"l.sfgeui "); |
end |
`OR1200_COP_SFLT: |
begin |
if (sf_op[`OR1200_SIGNED_COMPARE]) |
$fwrite(finsn,"l.sfltsi "); |
else |
$fwrite(finsn,"l.sfltui "); |
end |
`OR1200_COP_SFLE: |
begin |
if (sf_op[`OR1200_SIGNED_COMPARE]) |
$fwrite(finsn,"l.sflesi "); |
else |
$fwrite(finsn,"l.sfleui "); |
end |
endcase // case (sf_op[2:0]) |
|
$fwrite(finsn,"r%0d,0x%h",rA_num, imm_16bit); |
|
end // case: `OR1200_OR32_SFXXI |
|
`OR1200_OR32_SFXX: |
begin |
case(sf_op[2:0]) |
`OR1200_COP_SFEQ: |
$fwrite(finsn,"l.sfeq "); |
`OR1200_COP_SFNE: |
$fwrite(finsn,"l.sfne "); |
`OR1200_COP_SFGT: |
begin |
if (sf_op[`OR1200_SIGNED_COMPARE]) |
$fwrite(finsn,"l.sfgts "); |
else |
$fwrite(finsn,"l.sfgtu "); |
end |
`OR1200_COP_SFGE: |
begin |
if (sf_op[`OR1200_SIGNED_COMPARE]) |
$fwrite(finsn,"l.sfges "); |
else |
$fwrite(finsn,"l.sfgeu "); |
end |
`OR1200_COP_SFLT: |
begin |
if (sf_op[`OR1200_SIGNED_COMPARE]) |
$fwrite(finsn,"l.sflts "); |
else |
$fwrite(finsn,"l.sfltu "); |
end |
`OR1200_COP_SFLE: |
begin |
if (sf_op[`OR1200_SIGNED_COMPARE]) |
$fwrite(finsn,"l.sfles "); |
else |
$fwrite(finsn,"l.sfleu "); |
end |
|
endcase // case (sf_op[2:0]) |
|
$fwrite(finsn,"r%0d,r%0d",rA_num, rB_num); |
|
end |
|
`OR1200_OR32_MACI: |
begin |
$fwrite(finsn,"l.maci r%0d,0x%h",rA_num,imm_16bit); |
end |
|
`OR1200_OR32_MACMSB: |
begin |
if(insn[3:0] == 4'h1) |
$fwrite(finsn,"l.mac "); |
else if(insn[3:0] == 4'h2) |
$fwrite(finsn,"l.msb "); |
|
$fwrite(finsn,"r%0d,r%0d",rA_num,rB_num); |
end |
|
`OR1200_OR32_NOP: |
begin |
$fwrite(finsn,"l.nop 0x%0h",imm_16bit); |
end |
|
`OR1200_OR32_XSYNC: |
begin |
case (xsync_op) |
5'd0: |
$fwrite(finsn,"l.sys 0x%h",imm_16bit); |
5'd8: |
$fwrite(finsn,"l.trap 0x%h",imm_16bit); |
5'd16: |
$fwrite(finsn,"l.msync"); |
5'd20: |
$fwrite(finsn,"l.psync"); |
5'd24: |
$fwrite(finsn,"l.csync"); |
default: |
begin |
$display("%t: Instruction with opcode 0x%h has bad specific type information: 0x%h",$time,opcode,insn); |
$fwrite(finsn,"%t: Instruction with opcode 0x%h has has bad specific type information: 0x%h",$time,opcode,insn); |
end |
endcase // case (xsync_op) |
end |
|
default: |
begin |
$display("%t: Unknown opcode 0x%h",$time,opcode); |
$fwrite(finsn,"%t: Unknown opcode 0x%h",$time,opcode); |
end |
|
endcase // case (opcode) |
|
end |
endtask // or1200_print_op |
|
|
|
endmodule |
boards/generic/ft/bench/verilog/or1200_monitor.v
Property changes :
Added: svn:executable
## -0,0 +1 ##
+*
\ No newline at end of property
Index: boards/generic/ft/rtl/verilog/clkgen/clkgen.v
===================================================================
--- boards/generic/ft/rtl/verilog/clkgen/clkgen.v (nonexistent)
+++ boards/generic/ft/rtl/verilog/clkgen/clkgen.v (revision 483)
@@ -0,0 +1,118 @@
+//////////////////////////////////////////////////////////////////////
+//
+// clkgen
+//
+// Handles clock and reset generation for rest of design
+//
+//
+//////////////////////////////////////////////////////////////////////
+//// ////
+//// Copyright (C) 2009, 2010 Authors and OPENCORES.ORG ////
+//// ////
+//// This source file may be used and distributed without ////
+//// restriction provided that this copyright statement is not ////
+//// removed from the file and that any derivative work contains ////
+//// the original copyright notice and the associated disclaimer. ////
+//// ////
+//// This source file is free software; you can redistribute it ////
+//// and/or modify it under the terms of the GNU Lesser General ////
+//// Public License as published by the Free Software Foundation; ////
+//// either version 2.1 of the License, or (at your option) any ////
+//// later version. ////
+//// ////
+//// This source is distributed in the hope that it will be ////
+//// useful, but WITHOUT ANY WARRANTY; without even the implied ////
+//// warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR ////
+//// PURPOSE. See the GNU Lesser General Public License for more ////
+//// details. ////
+//// ////
+//// You should have received a copy of the GNU Lesser General ////
+//// Public License along with this source; if not, download it ////
+//// from http://www.opencores.org/lgpl.shtml ////
+//// ////
+//////////////////////////////////////////////////////////////////////
+//
+// A simple implementation for the main generic ORPSoC simulations
+//
+
+`include "timescale.v"
+`include "orpsoc-defines.v"
+
+module clkgen
+ (
+ // Main clocks in, depending on board
+ clk_pad_i,
+
+ // Input reset - through a buffer, asynchronous
+ async_rst_o,
+ // Wishbone clock and reset out
+ wb_clk_o,
+ wb_rst_o,
+
+ // JTAG clock
+`ifdef JTAG_DEBUG
+ tck_pad_i,
+ dbg_tck_o,
+`endif
+
+ // Asynchronous, active low reset in
+ rst_n_pad_i
+
+ );
+
+ input clk_pad_i;
+
+ output async_rst_o;
+
+ output wb_rst_o;
+ output wb_clk_o;
+
+`ifdef JTAG_DEBUG
+ input tck_pad_i;
+ output dbg_tck_o;
+`endif
+
+ // Asynchronous, active low reset (pushbutton, typically)
+ input rst_n_pad_i;
+
+ // First, deal with the asychronous reset
+ wire async_rst_n;
+
+ // An input buffer is usually instantiated here
+ assign async_rst_n = rst_n_pad_i;
+
+ // Everyone likes active-high reset signals...
+ assign async_rst_o = ~async_rst_n;
+
+`ifdef JTAG_DEBUG
+ assign dbg_tck_o = tck_pad_i;
+`endif
+
+ //
+ // Declare synchronous reset wires here
+ //
+
+ // An active-low synchronous reset signal (usually a PLL lock signal)
+ wire sync_rst_n;
+ assign sync_rst_n = async_rst_n; // Pretend it's somehow synchronous now
+
+
+ // Here we just assign "board" clock (really test) to wishbone clock
+ assign wb_clk_o = clk_pad_i;
+
+ //
+ // Reset generation
+ //
+ //
+
+ // Reset generation for wishbone
+ reg [15:0] wb_rst_shr;
+ always @(posedge wb_clk_o or posedge async_rst_o)
+ if (async_rst_o)
+ wb_rst_shr <= 16'hffff;
+ else
+ wb_rst_shr <= {wb_rst_shr[14:0], ~(sync_rst_n)};
+
+ assign wb_rst_o = wb_rst_shr[15];
+
+endmodule // clkgen
Index: boards/generic/ft/rtl/verilog/clkgen/README
===================================================================
--- boards/generic/ft/rtl/verilog/clkgen/README (nonexistent)
+++ boards/generic/ft/rtl/verilog/clkgen/README (revision 483)
@@ -0,0 +1,20 @@
+Clock and reset generation module
+
+This module should be used as the main reset and clock generation module. It
+should have the asynchronous resets and unbuffered clock lines coming in, and
+depending on defines in the main design file, generate the appropriate clocks
+and clock-synchronous resets.
+
+Currently Actel and Xilinx technlogies are supported. It is unclear if the way
+it is handling clock-configurations depending on boards is ideal, potentially
+it could become very cluttered if further board support is added and this would
+need to be looked at.
+
+The technology-dependent modules (PLLs, buffers) instantiated here should be
+located under the backend/vendor/rtl paths.
+
+As mentioned previously, it is unclear if this is the best way to manage the
+task of clock and reset generation, particularly if further specialised clock
+domains wish to be added, however there is some benefit in that it is all
+managed in one place and with the strict rules that all clocks and resets come
+to this module to be generated.
\ No newline at end of file
Index: boards/generic/ft/rtl/verilog/include/or1200_defines.v
===================================================================
--- boards/generic/ft/rtl/verilog/include/or1200_defines.v (nonexistent)
+++ boards/generic/ft/rtl/verilog/include/or1200_defines.v (revision 483)
@@ -0,0 +1,1791 @@
+//////////////////////////////////////////////////////////////////////
+//// ////
+//// OR1200's definitions ////
+//// ////
+//// This file is part of the OpenRISC 1200 project ////
+//// http://opencores.org/project,or1k ////
+//// ////
+//// Description ////
+//// Defines for the OR1200 core ////
+//// ////
+//// To Do: ////
+//// - add parameters that are missing ////
+//// ////
+//// Author(s): ////
+//// - Damjan Lampret, lampret@opencores.org ////
+//// ////
+//////////////////////////////////////////////////////////////////////
+//// ////
+//// Copyright (C) 2000 Authors and OPENCORES.ORG ////
+//// ////
+//// This source file may be used and distributed without ////
+//// restriction provided that this copyright statement is not ////
+//// removed from the file and that any derivative work contains ////
+//// the original copyright notice and the associated disclaimer. ////
+//// ////
+//// This source file is free software; you can redistribute it ////
+//// and/or modify it under the terms of the GNU Lesser General ////
+//// Public License as published by the Free Software Foundation; ////
+//// either version 2.1 of the License, or (at your option) any ////
+//// later version. ////
+//// ////
+//// This source is distributed in the hope that it will be ////
+//// useful, but WITHOUT ANY WARRANTY; without even the implied ////
+//// warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR ////
+//// PURPOSE. See the GNU Lesser General Public License for more ////
+//// details. ////
+//// ////
+//// You should have received a copy of the GNU Lesser General ////
+//// Public License along with this source; if not, download it ////
+//// from http://www.opencores.org/lgpl.shtml ////
+//// ////
+//////////////////////////////////////////////////////////////////////
+//
+// $Log: or1200_defines.v,v $
+// Revision 2.0 2010/06/30 11:00:00 ORSoC
+// Minor update:
+// Defines added, bugs fixed.
+
+//
+// Dump VCD
+//
+//`define OR1200_VCD_DUMP
+
+//
+// Generate debug messages during simulation
+//
+//`define OR1200_VERBOSE
+
+// `define OR1200_ASIC
+////////////////////////////////////////////////////////
+//
+// Typical configuration for an ASIC
+//
+`ifdef OR1200_ASIC
+
+//
+// Target ASIC memories
+//
+//`define OR1200_ARTISAN_SSP
+//`define OR1200_ARTISAN_SDP
+//`define OR1200_ARTISAN_STP
+`define OR1200_VIRTUALSILICON_SSP
+//`define OR1200_VIRTUALSILICON_STP_T1
+//`define OR1200_VIRTUALSILICON_STP_T2
+
+//
+// Do not implement Data cache
+//
+//`define OR1200_NO_DC
+
+//
+// Do not implement Insn cache
+//
+//`define OR1200_NO_IC
+
+//
+// Do not implement Data MMU
+//
+//`define OR1200_NO_DMMU
+
+//
+// Do not implement Insn MMU
+//
+//`define OR1200_NO_IMMU
+
+//
+// Select between ASIC optimized and generic multiplier
+//
+//`define OR1200_ASIC_MULTP2_32X32
+`define OR1200_GENERIC_MULTP2_32X32
+
+//
+// Size/type of insn/data cache if implemented
+//
+// `define OR1200_IC_1W_512B
+// `define OR1200_IC_1W_4KB
+`define OR1200_IC_1W_8KB
+// `define OR1200_DC_1W_4KB
+`define OR1200_DC_1W_8KB
+
+`else
+
+
+/////////////////////////////////////////////////////////
+//
+// Typical configuration for an FPGA
+//
+
+//
+// Target FPGA memories
+//
+//`define OR1200_ALTERA_LPM
+//`define OR1200_XILINX_RAMB16
+//`define OR1200_XILINX_RAMB4
+//`define OR1200_XILINX_RAM32X1D
+//`define OR1200_USE_RAM16X1D_FOR_RAM32X1D
+// Generic models should infer RAM blocks at synthesis time (not only effects
+// single port ram.)
+`define OR1200_GENERIC
+
+//
+// Do not implement Data cache
+//
+//`define OR1200_NO_DC
+
+//
+// Do not implement Insn cache
+//
+//`define OR1200_NO_IC
+
+//
+// Do not implement Data MMU
+//
+//`define OR1200_NO_DMMU
+
+//
+// Do not implement Insn MMU
+//
+//`define OR1200_NO_IMMU
+
+//
+// Select between ASIC and generic multiplier
+//
+// (Generic seems to trigger a bug in the Cadence Ncsim simulator)
+//
+//`define OR1200_ASIC_MULTP2_32X32
+`define OR1200_GENERIC_MULTP2_32X32
+
+//
+// Size/type of insn/data cache if implemented
+// (consider available FPGA memory resources)
+//
+//`define OR1200_IC_1W_512B
+`define OR1200_IC_1W_4KB
+//`define OR1200_IC_1W_8KB
+//`define OR1200_IC_1W_16KB
+//`define OR1200_IC_1W_32KB
+`define OR1200_DC_1W_4KB
+//`define OR1200_DC_1W_8KB
+//`define OR1200_DC_1W_16KB
+//`define OR1200_DC_1W_32KB
+
+`endif
+
+
+//////////////////////////////////////////////////////////
+//
+// Do not change below unless you know what you are doing
+//
+
+//
+// Reset active low
+//
+//`define OR1200_RST_ACT_LOW
+
+//
+// Enable RAM BIST
+//
+// At the moment this only works for Virtual Silicon
+// single port RAMs. For other RAMs it has not effect.
+// Special wrapper for VS RAMs needs to be provided
+// with scan flops to facilitate bist scan.
+//
+//`define OR1200_BIST
+
+//
+// Register OR1200 WISHBONE outputs
+// (must be defined/enabled)
+//
+`define OR1200_REGISTERED_OUTPUTS
+
+//
+// Register OR1200 WISHBONE inputs
+//
+// (must be undefined/disabled)
+//
+//`define OR1200_REGISTERED_INPUTS
+
+//
+// Disable bursts if they are not supported by the
+// memory subsystem (only affect cache line fill)
+//
+//`define OR1200_NO_BURSTS
+//
+
+//
+// WISHBONE retry counter range
+//
+// 2^value range for retry counter. Retry counter
+// is activated whenever *wb_rty_i is asserted and
+// until retry counter expires, corresponding
+// WISHBONE interface is deactivated.
+//
+// To disable retry counters and *wb_rty_i all together,
+// undefine this macro.
+//
+//`define OR1200_WB_RETRY 7
+
+//
+// WISHBONE Consecutive Address Burst
+//
+// This was used prior to WISHBONE B3 specification
+// to identify bursts. It is no longer needed but
+// remains enabled for compatibility with old designs.
+//
+// To remove *wb_cab_o ports undefine this macro.
+//
+//`define OR1200_WB_CAB
+
+//
+// WISHBONE B3 compatible interface
+//
+// This follows the WISHBONE B3 specification.
+// It is not enabled by default because most
+// designs still don't use WB b3.
+//
+// To enable *wb_cti_o/*wb_bte_o ports,
+// define this macro.
+//
+`define OR1200_WB_B3
+
+//
+// LOG all WISHBONE accesses
+//
+`define OR1200_LOG_WB_ACCESS
+
+//
+// Enable additional synthesis directives if using
+// _Synopsys_ synthesis tool
+//
+//`define OR1200_ADDITIONAL_SYNOPSYS_DIRECTIVES
+
+//
+// Enables default statement in some case blocks
+// and disables Synopsys synthesis directive full_case
+//
+// By default it is enabled. When disabled it
+// can increase clock frequency.
+//
+`define OR1200_CASE_DEFAULT
+
+//
+// Operand width / register file address width
+//
+// (DO NOT CHANGE)
+//
+`define OR1200_OPERAND_WIDTH 32
+`define OR1200_REGFILE_ADDR_WIDTH 5
+
+//
+// l.add/l.addi/l.and and optional l.addc/l.addic
+// also set (compare) flag when result of their
+// operation equals zero
+//
+// At the time of writing this, default or32
+// C/C++ compiler doesn't generate code that
+// would benefit from this optimization.
+//
+// By default this optimization is disabled to
+// save area.
+//
+//`define OR1200_ADDITIONAL_FLAG_MODIFIERS
+
+//
+// Implement l.addc/l.addic instructions
+//
+// By default implementation of l.addc/l.addic
+// instructions is enabled in case you need them.
+// If you don't use them, then disable implementation
+// to save area.
+//
+//`define OR1200_IMPL_ADDC
+
+//
+// Implement l.sub instruction
+//
+// By default implementation of l.sub instructions
+// is enabled to be compliant with the simulator.
+// If you don't use carry bit, then disable
+// implementation to save area.
+//
+`define OR1200_IMPL_SUB
+
+//
+// Implement carry bit SR[CY]
+//
+//
+// By default implementation of SR[CY] is enabled
+// to be compliant with the simulator. However SR[CY]
+// is explicitly only used by l.addc/l.addic/l.sub
+// instructions and if these three insns are not
+// implemented there is not much point having SR[CY].
+//
+//`define OR1200_IMPL_CY
+
+//
+// Implement rotate in the ALU
+//
+// At the time of writing this, or32
+// C/C++ compiler doesn't generate rotate
+// instructions. However or32 assembler
+// can assemble code that uses rotate insn.
+// This means that rotate instructions
+// must be used manually inserted.
+//
+// By default implementation of rotate
+// is disabled to save area and increase
+// clock frequency.
+//
+//`define OR1200_IMPL_ALU_ROTATE
+
+//
+// Type of ALU compare to implement
+//
+// Try either one to find what yields
+// higher clock frequencyin your case.
+//
+//`define OR1200_IMPL_ALU_COMP1
+`define OR1200_IMPL_ALU_COMP2
+
+//
+// Implement Find First/Last '1'
+//
+`define OR1200_IMPL_ALU_FFL1
+
+//
+// Implement multiplier
+//
+// By default multiplier is implemented
+//
+`define OR1200_MULT_IMPLEMENTED
+
+//
+// Implement multiply-and-accumulate
+//
+// By default MAC is implemented. To
+// implement MAC, multiplier (non-serial) needs to be
+// implemented.
+//
+`define OR1200_MAC_IMPLEMENTED
+
+//
+// Implement optional l.div/l.divu instructions
+//
+// By default divide instructions are not implemented
+// to save area.
+//
+//
+`define OR1200_DIV_IMPLEMENTED
+
+//
+// Serial multiplier.
+//
+//`define OR1200_MULT_SERIAL
+
+//
+// Serial divider.
+// Uncomment to use a serial divider, otherwise will
+// be a generic parallel implementation.
+//
+//`define OR1200_DIV_SERIAL
+
+//
+// Implement HW Single Precision FPU
+//
+`define OR1200_FPU_IMPLEMENTED
+
+
+//
+// Clock ratio RISC clock versus WB clock
+//
+// If you plan to run WB:RISC clock fixed to 1:1, disable
+// both defines
+//
+// For WB:RISC 1:2 or 1:1, enable OR1200_CLKDIV_2_SUPPORTED
+// and use clmode to set ratio
+//
+// For WB:RISC 1:4, 1:2 or 1:1, enable both defines and use
+// clmode to set ratio
+//
+//`define OR1200_CLKDIV_2_SUPPORTED
+//`define OR1200_CLKDIV_4_SUPPORTED
+
+//
+// Type of register file RAM
+//
+// Memory macro w/ two ports (see or1200_tpram_32x32.v)
+//`define OR1200_RFRAM_TWOPORT
+//
+// Memory macro dual port (see or1200_dpram.v)
+`define OR1200_RFRAM_DUALPORT
+
+//
+// Generic (flip-flop based) register file (see or1200_rfram_generic.v)
+//`define OR1200_RFRAM_GENERIC
+// Generic register file supports - 16 registers
+`ifdef OR1200_RFRAM_GENERIC
+// `define OR1200_RFRAM_16REG
+`endif
+
+//
+// Type of mem2reg aligner to implement.
+//
+// Once OR1200_IMPL_MEM2REG2 yielded faster
+// circuit, however with today tools it will
+// most probably give you slower circuit.
+//
+`define OR1200_IMPL_MEM2REG1
+//`define OR1200_IMPL_MEM2REG2
+
+//
+// Parity error detection.
+//
+// Add a parity bit for each byte held in various memories around the OR1200
+// and signal externally in event of parity error.
+`define OR1200_RAM_PARITY
+
+
+//
+// Reset value and event
+//
+`ifdef OR1200_RST_ACT_LOW
+ `define OR1200_RST_VALUE (1'b0)
+ `define OR1200_RST_EVENT negedge
+`else
+ `define OR1200_RST_VALUE (1'b1)
+ `define OR1200_RST_EVENT posedge
+`endif
+
+//
+// ALUOPs
+//
+`define OR1200_ALUOP_WIDTH 4
+`define OR1200_ALUOP_NOP 4'd4
+/* Order defined by arith insns that have two source operands both in regs
+ (see binutils/include/opcode/or32.h) */
+`define OR1200_ALUOP_ADD 4'd0
+`define OR1200_ALUOP_ADDC 4'd1
+`define OR1200_ALUOP_SUB 4'd2
+`define OR1200_ALUOP_AND 4'd3
+`define OR1200_ALUOP_OR 4'd4
+`define OR1200_ALUOP_XOR 4'd5
+`define OR1200_ALUOP_MUL 4'd6
+`define OR1200_ALUOP_CUST5 4'd7
+`define OR1200_ALUOP_SHROT 4'd8
+`define OR1200_ALUOP_DIV 4'd9
+`define OR1200_ALUOP_DIVU 4'd10
+`define OR1200_ALUOP_MULU 4'd11
+/* Values sent to ALU from decode unit - not strictly defined by ISA */
+`define OR1200_ALUOP_MOVHI 4'd12
+`define OR1200_ALUOP_COMP 4'd13
+`define OR1200_ALUOP_MTSR 4'd14
+`define OR1200_ALUOP_MFSR 4'd15
+`define OR1200_ALUOP_CMOV 4'd14
+`define OR1200_ALUOP_FFL1 4'd15
+
+
+// ALU instructions second opcode field (previously multicycle field in
+// machine word)
+`define OR1200_ALUOP2_POS 9:8
+`define OR1200_ALUOP2_WIDTH 2
+
+
+//
+// MACOPs
+//
+`define OR1200_MACOP_WIDTH 3
+`define OR1200_MACOP_NOP 3'b000
+`define OR1200_MACOP_MAC 3'b001
+`define OR1200_MACOP_MSB 3'b010
+
+//
+// Shift/rotate ops
+//
+`define OR1200_SHROTOP_WIDTH 2
+`define OR1200_SHROTOP_NOP 2'd0
+`define OR1200_SHROTOP_SLL 2'd0
+`define OR1200_SHROTOP_SRL 2'd1
+`define OR1200_SHROTOP_SRA 2'd2
+`define OR1200_SHROTOP_ROR 2'd3
+
+// Execution cycles per instruction
+`define OR1200_MULTICYCLE_WIDTH 3
+`define OR1200_ONE_CYCLE 3'd0
+`define OR1200_TWO_CYCLES 3'd1
+
+// Execution control which will "wait on" a module to finish
+`define OR1200_WAIT_ON_WIDTH 2
+`define OR1200_WAIT_ON_FPU `OR1200_WAIT_ON_WIDTH'd1
+`define OR1200_WAIT_ON_MTSPR `OR1200_WAIT_ON_WIDTH'd2
+
+// Operand MUX selects
+`define OR1200_SEL_WIDTH 2
+`define OR1200_SEL_RF 2'd0
+`define OR1200_SEL_IMM 2'd1
+`define OR1200_SEL_EX_FORW 2'd2
+`define OR1200_SEL_WB_FORW 2'd3
+
+//
+// BRANCHOPs
+//
+`define OR1200_BRANCHOP_WIDTH 3
+`define OR1200_BRANCHOP_NOP 3'd0
+`define OR1200_BRANCHOP_J 3'd1
+`define OR1200_BRANCHOP_JR 3'd2
+`define OR1200_BRANCHOP_BAL 3'd3
+`define OR1200_BRANCHOP_BF 3'd4
+`define OR1200_BRANCHOP_BNF 3'd5
+`define OR1200_BRANCHOP_RFE 3'd6
+
+//
+// LSUOPs
+//
+// Bit 0: sign extend
+// Bits 1-2: 00 doubleword, 01 byte, 10 halfword, 11 singleword
+// Bit 3: 0 load, 1 store
+`define OR1200_LSUOP_WIDTH 4
+`define OR1200_LSUOP_NOP 4'b0000
+`define OR1200_LSUOP_LBZ 4'b0010
+`define OR1200_LSUOP_LBS 4'b0011
+`define OR1200_LSUOP_LHZ 4'b0100
+`define OR1200_LSUOP_LHS 4'b0101
+`define OR1200_LSUOP_LWZ 4'b0110
+`define OR1200_LSUOP_LWS 4'b0111
+`define OR1200_LSUOP_LD 4'b0001
+`define OR1200_LSUOP_SD 4'b1000
+`define OR1200_LSUOP_SB 4'b1010
+`define OR1200_LSUOP_SH 4'b1100
+`define OR1200_LSUOP_SW 4'b1110
+
+// Number of bits of load/store EA precalculated in ID stage
+// for balancing ID and EX stages.
+//
+// Valid range: 2,3,...,30,31
+`define OR1200_LSUEA_PRECALC 2
+
+// FETCHOPs
+`define OR1200_FETCHOP_WIDTH 1
+`define OR1200_FETCHOP_NOP 1'b0
+`define OR1200_FETCHOP_LW 1'b1
+
+//
+// Register File Write-Back OPs
+//
+// Bit 0: register file write enable
+// Bits 3-1: write-back mux selects
+//
+`define OR1200_RFWBOP_WIDTH 4
+`define OR1200_RFWBOP_NOP 4'b0000
+`define OR1200_RFWBOP_ALU 3'b000
+`define OR1200_RFWBOP_LSU 3'b001
+`define OR1200_RFWBOP_SPRS 3'b010
+`define OR1200_RFWBOP_LR 3'b011
+`define OR1200_RFWBOP_FPU 3'b100
+
+// Compare instructions
+`define OR1200_COP_SFEQ 3'b000
+`define OR1200_COP_SFNE 3'b001
+`define OR1200_COP_SFGT 3'b010
+`define OR1200_COP_SFGE 3'b011
+`define OR1200_COP_SFLT 3'b100
+`define OR1200_COP_SFLE 3'b101
+`define OR1200_COP_X 3'b111
+`define OR1200_SIGNED_COMPARE 'd3
+`define OR1200_COMPOP_WIDTH 4
+
+//
+// FP OPs
+//
+// MSbit indicates FPU operation valid
+//
+`define OR1200_FPUOP_WIDTH 8
+// FPU unit from Usselman takes 5 cycles from decode, so 4 ex. cycles
+`define OR1200_FPUOP_CYCLES 3'd4
+// FP instruction is double precision if bit 4 is set. We're a 32-bit
+// implementation thus do not support double precision FP
+`define OR1200_FPUOP_DOUBLE_BIT 4
+`define OR1200_FPUOP_ADD 8'b0000_0000
+`define OR1200_FPUOP_SUB 8'b0000_0001
+`define OR1200_FPUOP_MUL 8'b0000_0010
+`define OR1200_FPUOP_DIV 8'b0000_0011
+`define OR1200_FPUOP_ITOF 8'b0000_0100
+`define OR1200_FPUOP_FTOI 8'b0000_0101
+`define OR1200_FPUOP_REM 8'b0000_0110
+`define OR1200_FPUOP_RESERVED 8'b0000_0111
+// FP Compare instructions
+`define OR1200_FPCOP_SFEQ 8'b0000_1000
+`define OR1200_FPCOP_SFNE 8'b0000_1001
+`define OR1200_FPCOP_SFGT 8'b0000_1010
+`define OR1200_FPCOP_SFGE 8'b0000_1011
+`define OR1200_FPCOP_SFLT 8'b0000_1100
+`define OR1200_FPCOP_SFLE 8'b0000_1101
+
+//
+// TAGs for instruction bus
+//
+`define OR1200_ITAG_IDLE 4'h0 // idle bus
+`define OR1200_ITAG_NI 4'h1 // normal insn
+`define OR1200_ITAG_BE 4'hb // Bus error exception
+`define OR1200_ITAG_PE 4'hc // Page fault exception
+`define OR1200_ITAG_TE 4'hd // TLB miss exception
+
+//
+// TAGs for data bus
+//
+`define OR1200_DTAG_IDLE 4'h0 // idle bus
+`define OR1200_DTAG_ND 4'h1 // normal data
+`define OR1200_DTAG_AE 4'ha // Alignment exception
+`define OR1200_DTAG_BE 4'hb // Bus error exception
+`define OR1200_DTAG_PE 4'hc // Page fault exception
+`define OR1200_DTAG_TE 4'hd // TLB miss exception
+
+
+//////////////////////////////////////////////
+//
+// ORBIS32 ISA specifics
+//
+
+// SHROT_OP position in machine word
+`define OR1200_SHROTOP_POS 7:6
+
+//
+// Instruction opcode groups (basic)
+//
+`define OR1200_OR32_J 6'b000000
+`define OR1200_OR32_JAL 6'b000001
+`define OR1200_OR32_BNF 6'b000011
+`define OR1200_OR32_BF 6'b000100
+`define OR1200_OR32_NOP 6'b000101
+`define OR1200_OR32_MOVHI 6'b000110
+`define OR1200_OR32_XSYNC 6'b001000
+`define OR1200_OR32_RFE 6'b001001
+/* */
+`define OR1200_OR32_JR 6'b010001
+`define OR1200_OR32_JALR 6'b010010
+`define OR1200_OR32_MACI 6'b010011
+/* */
+`define OR1200_OR32_LWZ 6'b100001
+`define OR1200_OR32_LBZ 6'b100011
+`define OR1200_OR32_LBS 6'b100100
+`define OR1200_OR32_LHZ 6'b100101
+`define OR1200_OR32_LHS 6'b100110
+`define OR1200_OR32_ADDI 6'b100111
+`define OR1200_OR32_ADDIC 6'b101000
+`define OR1200_OR32_ANDI 6'b101001
+`define OR1200_OR32_ORI 6'b101010
+`define OR1200_OR32_XORI 6'b101011
+`define OR1200_OR32_MULI 6'b101100
+`define OR1200_OR32_MFSPR 6'b101101
+`define OR1200_OR32_SH_ROTI 6'b101110
+`define OR1200_OR32_SFXXI 6'b101111
+/* */
+`define OR1200_OR32_MTSPR 6'b110000
+`define OR1200_OR32_MACMSB 6'b110001
+`define OR1200_OR32_FLOAT 6'b110010
+/* */
+`define OR1200_OR32_SW 6'b110101
+`define OR1200_OR32_SB 6'b110110
+`define OR1200_OR32_SH 6'b110111
+`define OR1200_OR32_ALU 6'b111000
+`define OR1200_OR32_SFXX 6'b111001
+//`define OR1200_OR32_CUST5 6'b111100
+
+
+/////////////////////////////////////////////////////
+//
+// Exceptions
+//
+
+//
+// Exception vectors per OR1K architecture:
+// 0xPPPPP100 - reset
+// 0xPPPPP200 - bus error
+// ... etc
+// where P represents exception prefix.
+//
+// Exception vectors can be customized as per
+// the following formula:
+// 0xPPPPPNVV - exception N
+//
+// P represents exception prefix
+// N represents exception N
+// VV represents length of the individual vector space,
+// usually it is 8 bits wide and starts with all bits zero
+//
+
+//
+// PPPPP and VV parts
+//
+// Sum of these two defines needs to be 28
+//
+`define OR1200_EXCEPT_EPH0_P 20'h00000
+`define OR1200_EXCEPT_EPH1_P 20'hF0000
+`define OR1200_EXCEPT_V 8'h00
+
+//
+// N part width
+//
+`define OR1200_EXCEPT_WIDTH 4
+
+//
+// Definition of exception vectors
+//
+// To avoid implementation of a certain exception,
+// simply comment out corresponding line
+//
+`define OR1200_EXCEPT_UNUSED `OR1200_EXCEPT_WIDTH'hf
+`define OR1200_EXCEPT_TRAP `OR1200_EXCEPT_WIDTH'he
+`define OR1200_EXCEPT_FLOAT `OR1200_EXCEPT_WIDTH'hd
+`define OR1200_EXCEPT_SYSCALL `OR1200_EXCEPT_WIDTH'hc
+`define OR1200_EXCEPT_RANGE `OR1200_EXCEPT_WIDTH'hb
+`define OR1200_EXCEPT_ITLBMISS `OR1200_EXCEPT_WIDTH'ha
+`define OR1200_EXCEPT_DTLBMISS `OR1200_EXCEPT_WIDTH'h9
+`define OR1200_EXCEPT_INT `OR1200_EXCEPT_WIDTH'h8
+`define OR1200_EXCEPT_ILLEGAL `OR1200_EXCEPT_WIDTH'h7
+`define OR1200_EXCEPT_ALIGN `OR1200_EXCEPT_WIDTH'h6
+`define OR1200_EXCEPT_TICK `OR1200_EXCEPT_WIDTH'h5
+`define OR1200_EXCEPT_IPF `OR1200_EXCEPT_WIDTH'h4
+`define OR1200_EXCEPT_DPF `OR1200_EXCEPT_WIDTH'h3
+`define OR1200_EXCEPT_BUSERR `OR1200_EXCEPT_WIDTH'h2
+`define OR1200_EXCEPT_RESET `OR1200_EXCEPT_WIDTH'h1
+`define OR1200_EXCEPT_NONE `OR1200_EXCEPT_WIDTH'h0
+
+
+/////////////////////////////////////////////////////
+//
+// SPR groups
+//
+
+// Bits that define the group
+`define OR1200_SPR_GROUP_BITS 15:11
+
+// Width of the group bits
+`define OR1200_SPR_GROUP_WIDTH 5
+
+// Bits that define offset inside the group
+`define OR1200_SPR_OFS_BITS 10:0
+
+// List of groups
+`define OR1200_SPR_GROUP_SYS 5'd00
+`define OR1200_SPR_GROUP_DMMU 5'd01
+`define OR1200_SPR_GROUP_IMMU 5'd02
+`define OR1200_SPR_GROUP_DC 5'd03
+`define OR1200_SPR_GROUP_IC 5'd04
+`define OR1200_SPR_GROUP_MAC 5'd05
+`define OR1200_SPR_GROUP_DU 5'd06
+`define OR1200_SPR_GROUP_PM 5'd08
+`define OR1200_SPR_GROUP_PIC 5'd09
+`define OR1200_SPR_GROUP_TT 5'd10
+`define OR1200_SPR_GROUP_FPU 5'd11
+
+/////////////////////////////////////////////////////
+//
+// System group
+//
+
+//
+// System registers
+//
+`define OR1200_SPR_CFGR 7'd0
+`define OR1200_SPR_RF 6'd32 // 1024 >> 5
+`define OR1200_SPR_NPC 11'd16
+`define OR1200_SPR_SR 11'd17
+`define OR1200_SPR_PPC 11'd18
+`define OR1200_SPR_FPCSR 11'd20
+`define OR1200_SPR_EPCR 11'd32
+`define OR1200_SPR_EEAR 11'd48
+`define OR1200_SPR_ESR 11'd64
+
+//
+// SR bits
+//
+`define OR1200_SR_WIDTH 17
+`define OR1200_SR_SM 0
+`define OR1200_SR_TEE 1
+`define OR1200_SR_IEE 2
+`define OR1200_SR_DCE 3
+`define OR1200_SR_ICE 4
+`define OR1200_SR_DME 5
+`define OR1200_SR_IME 6
+`define OR1200_SR_LEE 7
+`define OR1200_SR_CE 8
+`define OR1200_SR_F 9
+`define OR1200_SR_CY 10 // Unused
+`define OR1200_SR_OV 11 // Unused
+`define OR1200_SR_OVE 12 // Unused
+`define OR1200_SR_DSX 13 // Unused
+`define OR1200_SR_EPH 14
+`define OR1200_SR_FO 15
+`define OR1200_SR_TED 16
+`define OR1200_SR_CID 31:28 // Unimplemented
+
+//
+// Bits that define offset inside the group
+//
+`define OR1200_SPROFS_BITS 10:0
+
+//
+// Default Exception Prefix
+//
+// 1'b0 - OR1200_EXCEPT_EPH0_P (0x0000_0000)
+// 1'b1 - OR1200_EXCEPT_EPH1_P (0xF000_0000)
+//
+`define OR1200_SR_EPH_DEF 1'b0
+
+
+//
+// FPCSR bits
+//
+`define OR1200_FPCSR_WIDTH 12
+`define OR1200_FPCSR_FPEE 0
+`define OR1200_FPCSR_RM 2:1
+`define OR1200_FPCSR_OVF 3
+`define OR1200_FPCSR_UNF 4
+`define OR1200_FPCSR_SNF 5
+`define OR1200_FPCSR_QNF 6
+`define OR1200_FPCSR_ZF 7
+`define OR1200_FPCSR_IXF 8
+`define OR1200_FPCSR_IVF 9
+`define OR1200_FPCSR_INF 10
+`define OR1200_FPCSR_DZF 11
+`define OR1200_FPCSR_RES 31:12
+
+/////////////////////////////////////////////////////
+//
+// Power Management (PM)
+//
+
+// Define it if you want PM implemented
+//`define OR1200_PM_IMPLEMENTED
+
+// Bit positions inside PMR (don't change)
+`define OR1200_PM_PMR_SDF 3:0
+`define OR1200_PM_PMR_DME 4
+`define OR1200_PM_PMR_SME 5
+`define OR1200_PM_PMR_DCGE 6
+`define OR1200_PM_PMR_UNUSED 31:7
+
+// PMR offset inside PM group of registers
+`define OR1200_PM_OFS_PMR 11'b0
+
+// PM group
+`define OR1200_SPRGRP_PM 5'd8
+
+// Define if PMR can be read/written at any address inside PM group
+`define OR1200_PM_PARTIAL_DECODING
+
+// Define if reading PMR is allowed
+`define OR1200_PM_READREGS
+
+// Define if unused PMR bits should be zero
+`define OR1200_PM_UNUSED_ZERO
+
+
+/////////////////////////////////////////////////////
+//
+// Debug Unit (DU)
+//
+
+// Define it if you want DU implemented
+`define OR1200_DU_IMPLEMENTED
+
+//
+// Define if you want HW Breakpoints
+// (if HW breakpoints are not implemented
+// only default software trapping is
+// possible with l.trap insn - this is
+// however already enough for use
+// with or32 gdb)
+//
+//`define OR1200_DU_HWBKPTS
+
+// Number of DVR/DCR pairs if HW breakpoints enabled
+// Comment / uncomment DU_DVRn / DU_DCRn pairs bellow according to this number !
+// DU_DVR0..DU_DVR7 should be uncommented for 8 DU_DVRDCR_PAIRS
+`define OR1200_DU_DVRDCR_PAIRS 8
+
+// Define if you want trace buffer
+// (for now only available for Xilinx Virtex FPGAs)
+//`define OR1200_DU_TB_IMPLEMENTED
+
+
+//
+// Address offsets of DU registers inside DU group
+//
+// To not implement a register, doq not define its address
+//
+`ifdef OR1200_DU_HWBKPTS
+`define OR1200_DU_DVR0 11'd0
+`define OR1200_DU_DVR1 11'd1
+`define OR1200_DU_DVR2 11'd2
+`define OR1200_DU_DVR3 11'd3
+`define OR1200_DU_DVR4 11'd4
+`define OR1200_DU_DVR5 11'd5
+`define OR1200_DU_DVR6 11'd6
+`define OR1200_DU_DVR7 11'd7
+`define OR1200_DU_DCR0 11'd8
+`define OR1200_DU_DCR1 11'd9
+`define OR1200_DU_DCR2 11'd10
+`define OR1200_DU_DCR3 11'd11
+`define OR1200_DU_DCR4 11'd12
+`define OR1200_DU_DCR5 11'd13
+`define OR1200_DU_DCR6 11'd14
+`define OR1200_DU_DCR7 11'd15
+`endif
+`define OR1200_DU_DMR1 11'd16
+`ifdef OR1200_DU_HWBKPTS
+`define OR1200_DU_DMR2 11'd17
+`define OR1200_DU_DWCR0 11'd18
+`define OR1200_DU_DWCR1 11'd19
+`endif
+`define OR1200_DU_DSR 11'd20
+`define OR1200_DU_DRR 11'd21
+`ifdef OR1200_DU_TB_IMPLEMENTED
+`define OR1200_DU_TBADR 11'h0ff
+`define OR1200_DU_TBIA 11'h1??
+`define OR1200_DU_TBIM 11'h2??
+`define OR1200_DU_TBAR 11'h3??
+`define OR1200_DU_TBTS 11'h4??
+`endif
+
+// Position of offset bits inside SPR address
+`define OR1200_DUOFS_BITS 10:0
+
+// DCR bits
+`define OR1200_DU_DCR_DP 0
+`define OR1200_DU_DCR_CC 3:1
+`define OR1200_DU_DCR_SC 4
+`define OR1200_DU_DCR_CT 7:5
+
+// DMR1 bits
+`define OR1200_DU_DMR1_CW0 1:0
+`define OR1200_DU_DMR1_CW1 3:2
+`define OR1200_DU_DMR1_CW2 5:4
+`define OR1200_DU_DMR1_CW3 7:6
+`define OR1200_DU_DMR1_CW4 9:8
+`define OR1200_DU_DMR1_CW5 11:10
+`define OR1200_DU_DMR1_CW6 13:12
+`define OR1200_DU_DMR1_CW7 15:14
+`define OR1200_DU_DMR1_CW8 17:16
+`define OR1200_DU_DMR1_CW9 19:18
+`define OR1200_DU_DMR1_CW10 21:20
+`define OR1200_DU_DMR1_ST 22
+`define OR1200_DU_DMR1_BT 23
+`define OR1200_DU_DMR1_DXFW 24
+`define OR1200_DU_DMR1_ETE 25
+
+// DMR2 bits
+`define OR1200_DU_DMR2_WCE0 0
+`define OR1200_DU_DMR2_WCE1 1
+`define OR1200_DU_DMR2_AWTC 12:2
+`define OR1200_DU_DMR2_WGB 23:13
+
+// DWCR bits
+`define OR1200_DU_DWCR_COUNT 15:0
+`define OR1200_DU_DWCR_MATCH 31:16
+
+// DSR bits
+`define OR1200_DU_DSR_WIDTH 14
+`define OR1200_DU_DSR_RSTE 0
+`define OR1200_DU_DSR_BUSEE 1
+`define OR1200_DU_DSR_DPFE 2
+`define OR1200_DU_DSR_IPFE 3
+`define OR1200_DU_DSR_TTE 4
+`define OR1200_DU_DSR_AE 5
+`define OR1200_DU_DSR_IIE 6
+`define OR1200_DU_DSR_IE 7
+`define OR1200_DU_DSR_DME 8
+`define OR1200_DU_DSR_IME 9
+`define OR1200_DU_DSR_RE 10
+`define OR1200_DU_DSR_SCE 11
+`define OR1200_DU_DSR_FPE 12
+`define OR1200_DU_DSR_TE 13
+
+// DRR bits
+`define OR1200_DU_DRR_RSTE 0
+`define OR1200_DU_DRR_BUSEE 1
+`define OR1200_DU_DRR_DPFE 2
+`define OR1200_DU_DRR_IPFE 3
+`define OR1200_DU_DRR_TTE 4
+`define OR1200_DU_DRR_AE 5
+`define OR1200_DU_DRR_IIE 6
+`define OR1200_DU_DRR_IE 7
+`define OR1200_DU_DRR_DME 8
+`define OR1200_DU_DRR_IME 9
+`define OR1200_DU_DRR_RE 10
+`define OR1200_DU_DRR_SCE 11
+`define OR1200_DU_DRR_FPE 12
+`define OR1200_DU_DRR_TE 13
+
+// Define if reading DU regs is allowed
+`define OR1200_DU_READREGS
+
+// Define if unused DU registers bits should be zero
+`define OR1200_DU_UNUSED_ZERO
+
+// Define if IF/LSU status is not needed by devel i/f
+`define OR1200_DU_STATUS_UNIMPLEMENTED
+
+/////////////////////////////////////////////////////
+//
+// Programmable Interrupt Controller (PIC)
+//
+
+// Define it if you want PIC implemented
+`define OR1200_PIC_IMPLEMENTED
+
+// Define number of interrupt inputs (2-31)
+`define OR1200_PIC_INTS 20
+
+// Address offsets of PIC registers inside PIC group
+`define OR1200_PIC_OFS_PICMR 2'd0
+`define OR1200_PIC_OFS_PICSR 2'd2
+
+// Position of offset bits inside SPR address
+`define OR1200_PICOFS_BITS 1:0
+
+// Define if you want these PIC registers to be implemented
+`define OR1200_PIC_PICMR
+`define OR1200_PIC_PICSR
+
+// Define if reading PIC registers is allowed
+`define OR1200_PIC_READREGS
+
+// Define if unused PIC register bits should be zero
+`define OR1200_PIC_UNUSED_ZERO
+
+
+/////////////////////////////////////////////////////
+//
+// Tick Timer (TT)
+//
+
+// Define it if you want TT implemented
+`define OR1200_TT_IMPLEMENTED
+
+// Address offsets of TT registers inside TT group
+`define OR1200_TT_OFS_TTMR 1'd0
+`define OR1200_TT_OFS_TTCR 1'd1
+
+// Position of offset bits inside SPR group
+`define OR1200_TTOFS_BITS 0
+
+// Define if you want these TT registers to be implemented
+`define OR1200_TT_TTMR
+`define OR1200_TT_TTCR
+
+// TTMR bits
+`define OR1200_TT_TTMR_TP 27:0
+`define OR1200_TT_TTMR_IP 28
+`define OR1200_TT_TTMR_IE 29
+`define OR1200_TT_TTMR_M 31:30
+
+// Define if reading TT registers is allowed
+`define OR1200_TT_READREGS
+
+
+//////////////////////////////////////////////
+//
+// MAC
+//
+`define OR1200_MAC_ADDR 0 // MACLO 0xxxxxxxx1, MACHI 0xxxxxxxx0
+`define OR1200_MAC_SPR_WE // Define if MACLO/MACHI are SPR writable
+
+//
+// Shift {MACHI,MACLO} into destination register when executing l.macrc
+//
+// According to architecture manual there is no shift, so default value is 0.
+// However the implementation has deviated in this from the arch manual and had
+// hard coded shift by 28 bits which is a useful optimization for MP3 decoding
+// (if using libmad fixed point library). Shifts are no longer default setup,
+// but if you need to remain backward compatible, define your shift bits, which
+// were normally
+// dest_GPR = {MACHI,MACLO}[59:28]
+`define OR1200_MAC_SHIFTBY 0 // 0 = According to arch manual, 28 = obsolete backward compatibility
+
+
+//////////////////////////////////////////////
+//
+// Data MMU (DMMU)
+//
+
+//
+// Address that selects between TLB TR and MR
+//
+`define OR1200_DTLB_TM_ADDR 7
+
+//
+// DTLBMR fields
+//
+`define OR1200_DTLBMR_V_BITS 0
+`define OR1200_DTLBMR_CID_BITS 4:1
+`define OR1200_DTLBMR_RES_BITS 11:5
+`define OR1200_DTLBMR_VPN_BITS 31:13
+
+//
+// DTLBTR fields
+//
+`define OR1200_DTLBTR_CC_BITS 0
+`define OR1200_DTLBTR_CI_BITS 1
+`define OR1200_DTLBTR_WBC_BITS 2
+`define OR1200_DTLBTR_WOM_BITS 3
+`define OR1200_DTLBTR_A_BITS 4
+`define OR1200_DTLBTR_D_BITS 5
+`define OR1200_DTLBTR_URE_BITS 6
+`define OR1200_DTLBTR_UWE_BITS 7
+`define OR1200_DTLBTR_SRE_BITS 8
+`define OR1200_DTLBTR_SWE_BITS 9
+`define OR1200_DTLBTR_RES_BITS 11:10
+`define OR1200_DTLBTR_PPN_BITS 31:13
+
+//
+// DTLB configuration
+//
+`define OR1200_DMMU_PS 13 // 13 for 8KB page size
+`define OR1200_DTLB_INDXW 6 // 6 for 64 entry DTLB 7 for 128 entries
+`define OR1200_DTLB_INDXL `OR1200_DMMU_PS // 13 13
+`define OR1200_DTLB_INDXH `OR1200_DMMU_PS+`OR1200_DTLB_INDXW-1 // 18 19
+`define OR1200_DTLB_INDX `OR1200_DTLB_INDXH:`OR1200_DTLB_INDXL // 18:13 19:13
+`define OR1200_DTLB_TAGW 32-`OR1200_DTLB_INDXW-`OR1200_DMMU_PS // 13 12
+`define OR1200_DTLB_TAGL `OR1200_DTLB_INDXH+1 // 19 20
+`define OR1200_DTLB_TAG 31:`OR1200_DTLB_TAGL // 31:19 31:20
+`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_i[31]
+// cache inhibited 0GB-1GB 2GB-3GB !dcpu_adr_i[30]
+// cache inhibited 1GB-2GB 3GB-4GB dcpu_adr_i[30]
+// cache inhibited 2GB-4GB (default) dcpu_adr_i[31]
+// cached 0GB-4GB 1'b0
+//
+`define OR1200_DMMU_CI dcpu_adr_i[31]
+
+
+//////////////////////////////////////////////
+//
+// Insn MMU (IMMU)
+//
+
+//
+// Address that selects between TLB TR and MR
+//
+`define OR1200_ITLB_TM_ADDR 7
+
+//
+// ITLBMR fields
+//
+`define OR1200_ITLBMR_V_BITS 0
+`define OR1200_ITLBMR_CID_BITS 4:1
+`define OR1200_ITLBMR_RES_BITS 11:5
+`define OR1200_ITLBMR_VPN_BITS 31:13
+
+//
+// ITLBTR fields
+//
+`define OR1200_ITLBTR_CC_BITS 0
+`define OR1200_ITLBTR_CI_BITS 1
+`define OR1200_ITLBTR_WBC_BITS 2
+`define OR1200_ITLBTR_WOM_BITS 3
+`define OR1200_ITLBTR_A_BITS 4
+`define OR1200_ITLBTR_D_BITS 5
+`define OR1200_ITLBTR_SXE_BITS 6
+`define OR1200_ITLBTR_UXE_BITS 7
+`define OR1200_ITLBTR_RES_BITS 11:8
+`define OR1200_ITLBTR_PPN_BITS 31:13
+
+//
+// ITLB configuration
+//
+`define OR1200_IMMU_PS 13 // 13 for 8KB page size
+`define OR1200_ITLB_INDXW 6 // 6 for 64 entry ITLB 7 for 128 entries
+`define OR1200_ITLB_INDXL `OR1200_IMMU_PS // 13 13
+`define OR1200_ITLB_INDXH `OR1200_IMMU_PS+`OR1200_ITLB_INDXW-1 // 18 19
+`define OR1200_ITLB_INDX `OR1200_ITLB_INDXH:`OR1200_ITLB_INDXL // 18:13 19:13
+`define OR1200_ITLB_TAGW 32-`OR1200_ITLB_INDXW-`OR1200_IMMU_PS // 13 12
+`define OR1200_ITLB_TAGL `OR1200_ITLB_INDXH+1 // 19 20
+`define OR1200_ITLB_TAG 31:`OR1200_ITLB_TAGL // 31:19 31:20
+`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
+// Note: all combinations that use icpu_adr_i cause async loop
+//
+// cache inhibited 0GB-4GB 1'b1
+// cache inhibited 0GB-2GB !icpu_adr_i[31]
+// cache inhibited 0GB-1GB 2GB-3GB !icpu_adr_i[30]
+// cache inhibited 1GB-2GB 3GB-4GB icpu_adr_i[30]
+// cache inhibited 2GB-4GB (default) icpu_adr_i[31]
+// cached 0GB-4GB 1'b0
+//
+`define OR1200_IMMU_CI 1'b0
+
+
+/////////////////////////////////////////////////
+//
+// Insn cache (IC)
+//
+
+// 4 for 16 byte line, 5 for 32 byte lines.
+`ifdef OR1200_IC_1W_32KB
+ `define OR1200_ICLS 5
+`else
+ `define OR1200_ICLS 4
+`endif
+
+//
+// IC configurations
+//
+`ifdef OR1200_IC_1W_512B
+`define OR1200_ICSIZE 9 // 512
+`define OR1200_ICINDX `OR1200_ICSIZE-2 // 7
+`define OR1200_ICINDXH `OR1200_ICSIZE-1 // 8
+`define OR1200_ICTAGL `OR1200_ICINDXH+1 // 9
+`define OR1200_ICTAG `OR1200_ICSIZE-`OR1200_ICLS // 5
+`define OR1200_ICTAG_W 24
+`endif
+`ifdef OR1200_IC_1W_4KB
+`define OR1200_ICSIZE 12 // 4096
+`define OR1200_ICINDX `OR1200_ICSIZE-2 // 10
+`define OR1200_ICINDXH `OR1200_ICSIZE-1 // 11
+`define OR1200_ICTAGL `OR1200_ICINDXH+1 // 12
+`define OR1200_ICTAG `OR1200_ICSIZE-`OR1200_ICLS // 8
+`define OR1200_ICTAG_W 21
+`endif
+`ifdef OR1200_IC_1W_8KB
+`define OR1200_ICSIZE 13 // 8192
+`define OR1200_ICINDX `OR1200_ICSIZE-2 // 11
+`define OR1200_ICINDXH `OR1200_ICSIZE-1 // 12
+`define OR1200_ICTAGL `OR1200_ICINDXH+1 // 13
+`define OR1200_ICTAG `OR1200_ICSIZE-`OR1200_ICLS // 9
+`define OR1200_ICTAG_W 20
+`endif
+`ifdef OR1200_IC_1W_16KB
+`define OR1200_ICSIZE 14 // 16384
+`define OR1200_ICINDX `OR1200_ICSIZE-2 // 12
+`define OR1200_ICINDXH `OR1200_ICSIZE-1 // 13
+`define OR1200_ICTAGL `OR1200_ICINDXH+1 // 14
+`define OR1200_ICTAG `OR1200_ICSIZE-`OR1200_ICLS // 10
+`define OR1200_ICTAG_W 19
+`endif
+`ifdef OR1200_IC_1W_32KB
+`define OR1200_ICSIZE 15 // 32768
+`define OR1200_ICINDX `OR1200_ICSIZE-2 // 13
+`define OR1200_ICINDXH `OR1200_ICSIZE-1 // 14
+`define OR1200_ICTAGL `OR1200_ICINDXH+1 // 14
+`define OR1200_ICTAG `OR1200_ICSIZE-`OR1200_ICLS // 10
+`define OR1200_ICTAG_W 18
+`endif
+
+
+/////////////////////////////////////////////////
+//
+// Data cache (DC)
+//
+
+// 4 for 16 bytes, 5 for 32 bytes
+`ifdef OR1200_DC_1W_32KB
+ `define OR1200_DCLS 5
+`else
+ `define OR1200_DCLS 4
+`endif
+
+// Define to enable default behavior of cache as write through
+// Turning this off enabled write back statergy
+//
+`define OR1200_DC_WRITETHROUGH
+
+// Define to enable stores from the stack not doing writethrough.
+// EXPERIMENTAL
+//`define OR1200_DC_NOSTACKWRITETHROUGH
+
+// Data cache SPR definitions
+`define OR1200_SPRGRP_DC_ADR_WIDTH 3
+// Data cache group SPR addresses
+`define OR1200_SPRGRP_DC_DCCR 3'd0 // Not implemented
+`define OR1200_SPRGRP_DC_DCBPR 3'd1 // Not implemented
+`define OR1200_SPRGRP_DC_DCBFR 3'd2
+`define OR1200_SPRGRP_DC_DCBIR 3'd3
+`define OR1200_SPRGRP_DC_DCBWR 3'd4 // Not implemented
+`define OR1200_SPRGRP_DC_DCBLR 3'd5 // Not implemented
+
+//
+// DC configurations
+//
+`ifdef OR1200_DC_1W_4KB
+`define OR1200_DCSIZE 12 // 4096
+`define OR1200_DCINDX `OR1200_DCSIZE-2 // 10
+`define OR1200_DCINDXH `OR1200_DCSIZE-1 // 11
+`define OR1200_DCTAGL `OR1200_DCINDXH+1 // 12
+`define OR1200_DCTAG `OR1200_DCSIZE-`OR1200_DCLS // 8
+`define OR1200_DCTAG_W 21
+`endif
+`ifdef OR1200_DC_1W_8KB
+`define OR1200_DCSIZE 13 // 8192
+`define OR1200_DCINDX `OR1200_DCSIZE-2 // 11
+`define OR1200_DCINDXH `OR1200_DCSIZE-1 // 12
+`define OR1200_DCTAGL `OR1200_DCINDXH+1 // 13
+`define OR1200_DCTAG `OR1200_DCSIZE-`OR1200_DCLS // 9
+`define OR1200_DCTAG_W 20
+`endif
+`ifdef OR1200_DC_1W_16KB
+`define OR1200_DCSIZE 14 // 16384
+`define OR1200_DCINDX `OR1200_DCSIZE-2 // 12
+`define OR1200_DCINDXH `OR1200_DCSIZE-1 // 13
+`define OR1200_DCTAGL `OR1200_DCINDXH+1 // 14
+`define OR1200_DCTAG `OR1200_DCSIZE-`OR1200_DCLS // 10
+`define OR1200_DCTAG_W 19
+`endif
+`ifdef OR1200_DC_1W_32KB
+`define OR1200_DCSIZE 15 // 32768
+`define OR1200_DCINDX `OR1200_DCSIZE-2 // 13
+`define OR1200_DCINDXH `OR1200_DCSIZE-1 // 14
+`define OR1200_DCTAGL `OR1200_DCINDXH+1 // 15
+`define OR1200_DCTAG `OR1200_DCSIZE-`OR1200_DCLS // 10
+`define OR1200_DCTAG_W 18
+`endif
+
+
+/////////////////////////////////////////////////
+//
+// Store buffer (SB)
+//
+
+//
+// Store buffer
+//
+// It will improve performance by "caching" CPU stores
+// using store buffer. This is most important for function
+// prologues because DC can only work in write though mode
+// and all stores would have to complete external WB writes
+// to memory.
+// Store buffer is between DC and data BIU.
+// All stores will be stored into store buffer and immediately
+// completed by the CPU, even though actual external writes
+// will be performed later. As a consequence store buffer masks
+// all data bus errors related to stores (data bus errors
+// related to loads are delivered normally).
+// All pending CPU loads will wait until store buffer is empty to
+// ensure strict memory model. Right now this is necessary because
+// we don't make destinction between cached and cache inhibited
+// address space, so we simply empty store buffer until loads
+// can begin.
+//
+// It makes design a bit bigger, depending what is the number of
+// entries in SB FIFO. Number of entries can be changed further
+// down.
+//
+//`define OR1200_SB_IMPLEMENTED
+
+//
+// Number of store buffer entries
+//
+// Verified number of entries are 4 and 8 entries
+// (2 and 3 for OR1200_SB_LOG). OR1200_SB_ENTRIES must
+// always match 2**OR1200_SB_LOG.
+// To disable store buffer, undefine
+// OR1200_SB_IMPLEMENTED.
+//
+`define OR1200_SB_LOG 2 // 2 or 3
+`define OR1200_SB_ENTRIES 4 // 4 or 8
+
+
+/////////////////////////////////////////////////
+//
+// Quick Embedded Memory (QMEM)
+//
+
+//
+// Quick Embedded Memory
+//
+// Instantiation of dedicated insn/data memory (RAM or ROM).
+// Insn fetch has effective throughput 1insn / clock cycle.
+// Data load takes two clock cycles / access, data store
+// takes 1 clock cycle / access (if there is no insn fetch)).
+// Memory instantiation is shared between insn and data,
+// meaning if insn fetch are performed, data load/store
+// performance will be lower.
+//
+// Main reason for QMEM is to put some time critical functions
+// into this memory and to have predictable and fast access
+// to these functions. (soft fpu, context switch, exception
+// handlers, stack, etc)
+//
+// It makes design a bit bigger and slower. QMEM sits behind
+// IMMU/DMMU so all addresses are physical (so the MMUs can be
+// used with QMEM and QMEM is seen by the CPU just like any other
+// memory in the system). IC/DC are sitting behind QMEM so the
+// whole design timing might be worse with QMEM implemented.
+//
+//`define OR1200_QMEM_IMPLEMENTED
+
+//
+// Base address and mask of QMEM
+//
+// Base address defines first address of QMEM. Mask defines
+// QMEM range in address space. Actual size of QMEM is however
+// determined with instantiated RAM/ROM. However bigger
+// mask will reserve more address space for QMEM, but also
+// make design faster, while more tight mask will take
+// less address space but also make design slower. If
+// instantiated RAM/ROM is smaller than space reserved with
+// the mask, instatiated RAM/ROM will also be shadowed
+// at higher addresses in reserved space.
+//
+`define OR1200_QMEM_IADDR 32'h0080_0000
+`define OR1200_QMEM_IMASK 32'hfff0_0000 // Max QMEM size 1MB
+`define OR1200_QMEM_DADDR 32'h0080_0000
+`define OR1200_QMEM_DMASK 32'hfff0_0000 // Max QMEM size 1MB
+
+//
+// QMEM interface byte-select capability
+//
+// To enable qmem_sel* ports, define this macro.
+//
+//`define OR1200_QMEM_BSEL
+
+//
+// QMEM interface acknowledge
+//
+// To enable qmem_ack port, define this macro.
+//
+//`define OR1200_QMEM_ACK
+
+/////////////////////////////////////////////////////
+//
+// VR, UPR and Configuration Registers
+//
+//
+// VR, UPR and configuration registers are optional. If
+// implemented, operating system can automatically figure
+// out how to use the processor because it knows
+// what units are available in the processor and how they
+// are configured.
+//
+// This section must be last in or1200_defines.v file so
+// that all units are already configured and thus
+// configuration registers are properly set.
+//
+
+// Define if you want configuration registers implemented
+`define OR1200_CFGR_IMPLEMENTED
+
+// Define if you want full address decode inside SYS group
+`define OR1200_SYS_FULL_DECODE
+
+// Offsets of VR, UPR and CFGR registers
+`define OR1200_SPRGRP_SYS_VR 4'h0
+`define OR1200_SPRGRP_SYS_UPR 4'h1
+`define OR1200_SPRGRP_SYS_CPUCFGR 4'h2
+`define OR1200_SPRGRP_SYS_DMMUCFGR 4'h3
+`define OR1200_SPRGRP_SYS_IMMUCFGR 4'h4
+`define OR1200_SPRGRP_SYS_DCCFGR 4'h5
+`define OR1200_SPRGRP_SYS_ICCFGR 4'h6
+`define OR1200_SPRGRP_SYS_DCFGR 4'h7
+
+// VR fields
+`define OR1200_VR_REV_BITS 5:0
+`define OR1200_VR_RES1_BITS 15:6
+`define OR1200_VR_CFG_BITS 23:16
+`define OR1200_VR_VER_BITS 31:24
+
+// VR values
+`define OR1200_VR_REV 6'h08
+`define OR1200_VR_RES1 10'h000
+`define OR1200_VR_CFG 8'h00
+`define OR1200_VR_VER 8'h12
+
+// UPR fields
+`define OR1200_UPR_UP_BITS 0
+`define OR1200_UPR_DCP_BITS 1
+`define OR1200_UPR_ICP_BITS 2
+`define OR1200_UPR_DMP_BITS 3
+`define OR1200_UPR_IMP_BITS 4
+`define OR1200_UPR_MP_BITS 5
+`define OR1200_UPR_DUP_BITS 6
+`define OR1200_UPR_PCUP_BITS 7
+`define OR1200_UPR_PMP_BITS 8
+`define OR1200_UPR_PICP_BITS 9
+`define OR1200_UPR_TTP_BITS 10
+`define OR1200_UPR_FPP_BITS 11
+`define OR1200_UPR_RES1_BITS 23:12
+`define OR1200_UPR_CUP_BITS 31:24
+
+// UPR values
+`define OR1200_UPR_UP 1'b1
+`ifdef OR1200_NO_DC
+`define OR1200_UPR_DCP 1'b0
+`else
+`define OR1200_UPR_DCP 1'b1
+`endif
+`ifdef OR1200_NO_IC
+`define OR1200_UPR_ICP 1'b0
+`else
+`define OR1200_UPR_ICP 1'b1
+`endif
+`ifdef OR1200_NO_DMMU
+`define OR1200_UPR_DMP 1'b0
+`else
+`define OR1200_UPR_DMP 1'b1
+`endif
+`ifdef OR1200_NO_IMMU
+`define OR1200_UPR_IMP 1'b0
+`else
+`define OR1200_UPR_IMP 1'b1
+`endif
+`ifdef OR1200_MAC_IMPLEMENTED
+`define OR1200_UPR_MP 1'b1
+`else
+`define OR1200_UPR_MP 1'b0
+`endif
+`ifdef OR1200_DU_IMPLEMENTED
+`define OR1200_UPR_DUP 1'b1
+`else
+`define OR1200_UPR_DUP 1'b0
+`endif
+`define OR1200_UPR_PCUP 1'b0 // Performance counters not present
+`ifdef OR1200_PM_IMPLEMENTED
+`define OR1200_UPR_PMP 1'b1
+`else
+`define OR1200_UPR_PMP 1'b0
+`endif
+`ifdef OR1200_PIC_IMPLEMENTED
+`define OR1200_UPR_PICP 1'b1
+`else
+`define OR1200_UPR_PICP 1'b0
+`endif
+`ifdef OR1200_TT_IMPLEMENTED
+`define OR1200_UPR_TTP 1'b1
+`else
+`define OR1200_UPR_TTP 1'b0
+`endif
+`ifdef OR1200_FPU_IMPLEMENTED
+`define OR1200_UPR_FPP 1'b1
+`else
+`define OR1200_UPR_FPP 1'b0
+`endif
+`define OR1200_UPR_RES1 12'h000
+`define OR1200_UPR_CUP 8'h00
+
+// CPUCFGR fields
+`define OR1200_CPUCFGR_NSGF_BITS 3:0
+`define OR1200_CPUCFGR_HGF_BITS 4
+`define OR1200_CPUCFGR_OB32S_BITS 5
+`define OR1200_CPUCFGR_OB64S_BITS 6
+`define OR1200_CPUCFGR_OF32S_BITS 7
+`define OR1200_CPUCFGR_OF64S_BITS 8
+`define OR1200_CPUCFGR_OV64S_BITS 9
+`define OR1200_CPUCFGR_RES1_BITS 31:10
+
+// CPUCFGR values
+`define OR1200_CPUCFGR_NSGF 4'h0
+`ifdef OR1200_RFRAM_16REG
+ `define OR1200_CPUCFGR_HGF 1'b1
+`else
+ `define OR1200_CPUCFGR_HGF 1'b0
+`endif
+`define OR1200_CPUCFGR_OB32S 1'b1
+`define OR1200_CPUCFGR_OB64S 1'b0
+`ifdef OR1200_FPU_IMPLEMENTED
+ `define OR1200_CPUCFGR_OF32S 1'b1
+`else
+ `define OR1200_CPUCFGR_OF32S 1'b0
+`endif
+
+`define OR1200_CPUCFGR_OF64S 1'b0
+`define OR1200_CPUCFGR_OV64S 1'b0
+`define OR1200_CPUCFGR_RES1 22'h000000
+
+// DMMUCFGR fields
+`define OR1200_DMMUCFGR_NTW_BITS 1:0
+`define OR1200_DMMUCFGR_NTS_BITS 4:2
+`define OR1200_DMMUCFGR_NAE_BITS 7:5
+`define OR1200_DMMUCFGR_CRI_BITS 8
+`define OR1200_DMMUCFGR_PRI_BITS 9
+`define OR1200_DMMUCFGR_TEIRI_BITS 10
+`define OR1200_DMMUCFGR_HTR_BITS 11
+`define OR1200_DMMUCFGR_RES1_BITS 31:12
+
+// DMMUCFGR values
+`ifdef OR1200_NO_DMMU
+`define OR1200_DMMUCFGR_NTW 2'h0 // Irrelevant
+`define OR1200_DMMUCFGR_NTS 3'h0 // Irrelevant
+`define OR1200_DMMUCFGR_NAE 3'h0 // Irrelevant
+`define OR1200_DMMUCFGR_CRI 1'b0 // Irrelevant
+`define OR1200_DMMUCFGR_PRI 1'b0 // Irrelevant
+`define OR1200_DMMUCFGR_TEIRI 1'b0 // Irrelevant
+`define OR1200_DMMUCFGR_HTR 1'b0 // Irrelevant
+`define OR1200_DMMUCFGR_RES1 20'h00000
+`else
+`define OR1200_DMMUCFGR_NTW 2'h0 // 1 TLB way
+`define OR1200_DMMUCFGR_NTS 3'h`OR1200_DTLB_INDXW // Num TLB sets
+`define OR1200_DMMUCFGR_NAE 3'h0 // No ATB entries
+`define OR1200_DMMUCFGR_CRI 1'b0 // No control register
+`define OR1200_DMMUCFGR_PRI 1'b0 // No protection reg
+`define OR1200_DMMUCFGR_TEIRI 1'b1 // TLB entry inv reg impl.
+`define OR1200_DMMUCFGR_HTR 1'b0 // No HW TLB reload
+`define OR1200_DMMUCFGR_RES1 20'h00000
+`endif
+
+// IMMUCFGR fields
+`define OR1200_IMMUCFGR_NTW_BITS 1:0
+`define OR1200_IMMUCFGR_NTS_BITS 4:2
+`define OR1200_IMMUCFGR_NAE_BITS 7:5
+`define OR1200_IMMUCFGR_CRI_BITS 8
+`define OR1200_IMMUCFGR_PRI_BITS 9
+`define OR1200_IMMUCFGR_TEIRI_BITS 10
+`define OR1200_IMMUCFGR_HTR_BITS 11
+`define OR1200_IMMUCFGR_RES1_BITS 31:12
+
+// IMMUCFGR values
+`ifdef OR1200_NO_IMMU
+`define OR1200_IMMUCFGR_NTW 2'h0 // Irrelevant
+`define OR1200_IMMUCFGR_NTS 3'h0 // Irrelevant
+`define OR1200_IMMUCFGR_NAE 3'h0 // Irrelevant
+`define OR1200_IMMUCFGR_CRI 1'b0 // Irrelevant
+`define OR1200_IMMUCFGR_PRI 1'b0 // Irrelevant
+`define OR1200_IMMUCFGR_TEIRI 1'b0 // Irrelevant
+`define OR1200_IMMUCFGR_HTR 1'b0 // Irrelevant
+`define OR1200_IMMUCFGR_RES1 20'h00000
+`else
+`define OR1200_IMMUCFGR_NTW 2'h0 // 1 TLB way
+`define OR1200_IMMUCFGR_NTS 3'h`OR1200_ITLB_INDXW // Num TLB sets
+`define OR1200_IMMUCFGR_NAE 3'h0 // No ATB entry
+`define OR1200_IMMUCFGR_CRI 1'b0 // No control reg
+`define OR1200_IMMUCFGR_PRI 1'b0 // No protection reg
+`define OR1200_IMMUCFGR_TEIRI 1'b1 // TLB entry inv reg impl
+`define OR1200_IMMUCFGR_HTR 1'b0 // No HW TLB reload
+`define OR1200_IMMUCFGR_RES1 20'h00000
+`endif
+
+// DCCFGR fields
+`define OR1200_DCCFGR_NCW_BITS 2:0
+`define OR1200_DCCFGR_NCS_BITS 6:3
+`define OR1200_DCCFGR_CBS_BITS 7
+`define OR1200_DCCFGR_CWS_BITS 8
+`define OR1200_DCCFGR_CCRI_BITS 9
+`define OR1200_DCCFGR_CBIRI_BITS 10
+`define OR1200_DCCFGR_CBPRI_BITS 11
+`define OR1200_DCCFGR_CBLRI_BITS 12
+`define OR1200_DCCFGR_CBFRI_BITS 13
+`define OR1200_DCCFGR_CBWBRI_BITS 14
+`define OR1200_DCCFGR_RES1_BITS 31:15
+
+// DCCFGR values
+`ifdef OR1200_NO_DC
+`define OR1200_DCCFGR_NCW 3'h0 // Irrelevant
+`define OR1200_DCCFGR_NCS 4'h0 // Irrelevant
+`define OR1200_DCCFGR_CBS 1'b0 // Irrelevant
+`define OR1200_DCCFGR_CWS 1'b0 // Irrelevant
+`define OR1200_DCCFGR_CCRI 1'b0 // Irrelevant
+`define OR1200_DCCFGR_CBIRI 1'b0 // Irrelevant
+`define OR1200_DCCFGR_CBPRI 1'b0 // Irrelevant
+`define OR1200_DCCFGR_CBLRI 1'b0 // Irrelevant
+`define OR1200_DCCFGR_CBFRI 1'b0 // Irrelevant
+`define OR1200_DCCFGR_CBWBRI 1'b0 // Irrelevant
+`define OR1200_DCCFGR_RES1 17'h00000
+`else
+`define OR1200_DCCFGR_NCW 3'h0 // 1 cache way
+`define OR1200_DCCFGR_NCS (`OR1200_DCTAG) // Num cache sets
+`define OR1200_DCCFGR_CBS `OR1200_DCLS==4 ? 1'b0 : 1'b1 // 16 byte cache block
+`ifdef OR1200_DC_WRITETHROUGH
+ `define OR1200_DCCFGR_CWS 1'b0 // Write-through strategy
+`else
+ `define OR1200_DCCFGR_CWS 1'b1 // Write-back strategy
+`endif
+`define OR1200_DCCFGR_CCRI 1'b1 // Cache control reg impl.
+`define OR1200_DCCFGR_CBIRI 1'b1 // Cache block inv reg impl.
+`define OR1200_DCCFGR_CBPRI 1'b0 // Cache block prefetch reg not impl.
+`define OR1200_DCCFGR_CBLRI 1'b0 // Cache block lock reg not impl.
+`define OR1200_DCCFGR_CBFRI 1'b1 // Cache block flush reg impl.
+`ifdef OR1200_DC_WRITETHROUGH
+ `define OR1200_DCCFGR_CBWBRI 1'b0 // Cache block WB reg not impl.
+`else
+ `define OR1200_DCCFGR_CBWBRI 1'b1 // Cache block WB reg impl.
+`endif
+`define OR1200_DCCFGR_RES1 17'h00000
+`endif
+
+// ICCFGR fields
+`define OR1200_ICCFGR_NCW_BITS 2:0
+`define OR1200_ICCFGR_NCS_BITS 6:3
+`define OR1200_ICCFGR_CBS_BITS 7
+`define OR1200_ICCFGR_CWS_BITS 8
+`define OR1200_ICCFGR_CCRI_BITS 9
+`define OR1200_ICCFGR_CBIRI_BITS 10
+`define OR1200_ICCFGR_CBPRI_BITS 11
+`define OR1200_ICCFGR_CBLRI_BITS 12
+`define OR1200_ICCFGR_CBFRI_BITS 13
+`define OR1200_ICCFGR_CBWBRI_BITS 14
+`define OR1200_ICCFGR_RES1_BITS 31:15
+
+// ICCFGR values
+`ifdef OR1200_NO_IC
+`define OR1200_ICCFGR_NCW 3'h0 // Irrelevant
+`define OR1200_ICCFGR_NCS 4'h0 // Irrelevant
+`define OR1200_ICCFGR_CBS 1'b0 // Irrelevant
+`define OR1200_ICCFGR_CWS 1'b0 // Irrelevant
+`define OR1200_ICCFGR_CCRI 1'b0 // Irrelevant
+`define OR1200_ICCFGR_CBIRI 1'b0 // Irrelevant
+`define OR1200_ICCFGR_CBPRI 1'b0 // Irrelevant
+`define OR1200_ICCFGR_CBLRI 1'b0 // Irrelevant
+`define OR1200_ICCFGR_CBFRI 1'b0 // Irrelevant
+`define OR1200_ICCFGR_CBWBRI 1'b0 // Irrelevant
+`define OR1200_ICCFGR_RES1 17'h00000
+`else
+`define OR1200_ICCFGR_NCW 3'h0 // 1 cache way
+`define OR1200_ICCFGR_NCS (`OR1200_ICTAG) // Num cache sets
+`define OR1200_ICCFGR_CBS `OR1200_ICLS==4 ? 1'b0: 1'b1 // 16 byte cache block
+`define OR1200_ICCFGR_CWS 1'b0 // Irrelevant
+`define OR1200_ICCFGR_CCRI 1'b1 // Cache control reg impl.
+`define OR1200_ICCFGR_CBIRI 1'b1 // Cache block inv reg impl.
+`define OR1200_ICCFGR_CBPRI 1'b0 // Cache block prefetch reg not impl.
+`define OR1200_ICCFGR_CBLRI 1'b0 // Cache block lock reg not impl.
+`define OR1200_ICCFGR_CBFRI 1'b1 // Cache block flush reg impl.
+`define OR1200_ICCFGR_CBWBRI 1'b0 // Irrelevant
+`define OR1200_ICCFGR_RES1 17'h00000
+`endif
+
+// DCFGR fields
+`define OR1200_DCFGR_NDP_BITS 3:0
+`define OR1200_DCFGR_WPCI_BITS 4
+`define OR1200_DCFGR_RES1_BITS 31:5
+
+// DCFGR values
+`ifdef OR1200_DU_HWBKPTS
+`define OR1200_DCFGR_NDP 4'h`OR1200_DU_DVRDCR_PAIRS // # of DVR/DCR pairs
+`ifdef OR1200_DU_DWCR0
+`define OR1200_DCFGR_WPCI 1'b1
+`else
+`define OR1200_DCFGR_WPCI 1'b0 // WP counters not impl.
+`endif
+`else
+`define OR1200_DCFGR_NDP 4'h0 // Zero DVR/DCR pairs
+`define OR1200_DCFGR_WPCI 1'b0 // WP counters not impl.
+`endif
+`define OR1200_DCFGR_RES1 27'd0
+
+///////////////////////////////////////////////////////////////////////////////
+// Boot Address Selection //
+// //
+// Allows a definable boot address, potentially different to the usual reset //
+// vector to allow for power-on code to be run, if desired. //
+// //
+// OR1200_BOOT_ADR should be the 32-bit address of the boot location //
+// OR1200_BOOT_PCREG_DEFAULT should be ((OR1200_BOOT_ADR-4)>>2) //
+// //
+// For default reset behavior uncomment the settings under the "Boot 0x100" //
+// comment below. //
+// //
+///////////////////////////////////////////////////////////////////////////////
+// Boot from 0xf0000100
+//`define OR1200_BOOT_PCREG_DEFAULT 30'h3c00003f
+//`define OR1200_BOOT_ADR 32'hf0000100
+// Boot from 0x100
+ `define OR1200_BOOT_PCREG_DEFAULT 30'h0000003f
+ `define OR1200_BOOT_ADR 32'h00000100
Index: boards/generic/ft/rtl/verilog/include/orpsoc-defines.v
===================================================================
--- boards/generic/ft/rtl/verilog/include/orpsoc-defines.v (nonexistent)
+++ boards/generic/ft/rtl/verilog/include/orpsoc-defines.v (revision 483)
@@ -0,0 +1,70 @@
+//////////////////////////////////////////////////////////////////////
+//// ////
+//// orpsoc-defines ////
+//// ////
+//// Top level ORPSoC defines file ////
+//// ////
+//// Included in toplevel and testbench ////
+//// ////
+//////////////////////////////////////////////////////////////////////
+//// ////
+//// Copyright (C) 2009, 2010 Authors and OPENCORES.ORG ////
+//// ////
+//// This source file may be used and distributed without ////
+//// restriction provided that this copyright statement is not ////
+//// removed from the file and that any derivative work contains ////
+//// the original copyright notice and the associated disclaimer. ////
+//// ////
+//// This source file is free software; you can redistribute it ////
+//// and/or modify it under the terms of the GNU Lesser General ////
+//// Public License as published by the Free Software Foundation; ////
+//// either version 2.1 of the License, or (at your option) any ////
+//// later version. ////
+//// ////
+//// This source is distributed in the hope that it will be ////
+//// useful, but WITHOUT ANY WARRANTY; without even the implied ////
+//// warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR ////
+//// PURPOSE. See the GNU Lesser General Public License for more ////
+//// details. ////
+//// ////
+//// You should have received a copy of the GNU Lesser General ////
+//// Public License along with this source; if not, download it ////
+//// from http://www.opencores.org/lgpl.shtml ////
+//// ////
+//////////////////////////////////////////////////////////////////////
+
+// Define board clock - main system clock period
+// 20ns period = 50MHz freq.
+`define BOARD_CLOCK_PERIOD 20
+
+// Included modules: define to include
+//`define JTAG_DEBUG
+//`define UART0
+`define RAM_WB
+
+// end of included module defines - keep this comment line here
+
+//
+// Arbiter defines
+//
+
+// Uncomment to register things through arbiter (hopefully quicker design)
+// Instruction bus arbiter
+//`define ARBITER_IBUS_REGISTERING
+`define ARBITER_IBUS_WATCHDOG
+// Watchdog timeout: 2^(ARBITER_IBUS_WATCHDOG_TIMER_WIDTH+1) cycles
+`define ARBITER_IBUS_WATCHDOG_TIMER_WIDTH 12
+
+// Data bus arbiter
+
+//`define ARBITER_DBUS_REGISTERING
+`define ARBITER_DBUS_WATCHDOG
+// Watchdog timeout: 2^(ARBITER_DBUS_WATCHDOG_TIMER_WIDTH+1) cycles
+`define ARBITER_DBUS_WATCHDOG_TIMER_WIDTH 12
+
+// Byte bus (peripheral bus) arbiter
+// Don't really need the watchdog here - the databus will pick it up
+//`define ARBITER_BYTEBUS_WATCHDOG
+// Watchdog timeout: 2^(ARBITER_BYTEBUS_WATCHDOG_TIMER_WIDTH+1) cycles
+`define ARBITER_BYTEBUS_WATCHDOG_TIMER_WIDTH 9
+
Index: boards/generic/ft/rtl/verilog/include/orpsoc-params.v
===================================================================
--- boards/generic/ft/rtl/verilog/include/orpsoc-params.v (nonexistent)
+++ boards/generic/ft/rtl/verilog/include/orpsoc-params.v (revision 483)
@@ -0,0 +1,124 @@
+//////////////////////////////////////////////////////////////////////
+//// ////
+//// orpsoc-params ////
+//// ////
+//// Top level ORPSoC parameters file ////
+//// ////
+//// Included in toplevel and testbench ////
+//// ////
+//////////////////////////////////////////////////////////////////////
+//// ////
+//// Copyright (C) 2009, 2010 Authors and OPENCORES.ORG ////
+//// ////
+//// This source file may be used and distributed without ////
+//// restriction provided that this copyright statement is not ////
+//// removed from the file and that any derivative work contains ////
+//// the original copyright notice and the associated disclaimer. ////
+//// ////
+//// This source file is free software; you can redistribute it ////
+//// and/or modify it under the terms of the GNU Lesser General ////
+//// Public License as published by the Free Software Foundation; ////
+//// either version 2.1 of the License, or (at your option) any ////
+//// later version. ////
+//// ////
+//// This source is distributed in the hope that it will be ////
+//// useful, but WITHOUT ANY WARRANTY; without even the implied ////
+//// warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR ////
+//// PURPOSE. See the GNU Lesser General Public License for more ////
+//// details. ////
+//// ////
+//// You should have received a copy of the GNU Lesser General ////
+//// Public License along with this source; if not, download it ////
+//// from http://www.opencores.org/lgpl.shtml ////
+//// ////
+//////////////////////////////////////////////////////////////////////
+
+///////////////////////////
+// //
+// Peripheral parameters //
+// //
+///////////////////////////
+
+// UART 0 params
+parameter wbs_d_uart0_data_width = 8;
+parameter uart0_wb_adr = 8'h90;
+parameter uart0_data_width = 8;
+parameter uart0_addr_width = 3;
+
+// Parity error unit
+parameter peh_wb_adr = 8'he0;
+
+// ROM
+parameter wbs_i_rom0_data_width = 32;
+parameter wbs_i_rom0_addr_width = 6;
+parameter rom0_wb_adr = 4'hf;
+
+//////////////////////////////////////////////////////
+// //
+// Wishbone bus parameters //
+// //
+//////////////////////////////////////////////////////
+
+////////////////////////
+// //
+// Arbiter parameters //
+// //
+////////////////////////
+
+parameter wb_dw = 32; // Default Wishbone full word width
+parameter wb_aw = 32; // Default Wishbone full address width
+
+///////////////////////////
+// //
+// Instruction bus //
+// //
+///////////////////////////
+parameter ibus_arb_addr_match_width = 4;
+// Slave addresses
+parameter ibus_arb_slave0_adr = rom0_wb_adr; // ROM
+parameter ibus_arb_slave1_adr = 4'h0; // Main memory
+
+///////////////////////////
+// //
+// Data bus //
+// //
+///////////////////////////
+// Has auto foward to last slave when no address hits
+parameter dbus_arb_wb_addr_match_width = 8;
+parameter dbus_arb_wb_num_slaves = 2;
+// Slave addresses
+parameter dbus_arb_slave0_adr = 4'h0; // Main memory (SDRAM/FPGA SRAM)
+parameter dbus_arb_slave1_adr = 8'hxx; // Default slave - address don't care (X)
+
+///////////////////////////////
+// //
+// Byte-wide peripheral bus //
+// //
+///////////////////////////////
+parameter bbus_arb_wb_addr_match_width = 8;
+parameter bbus_arb_wb_num_slaves = 1; // Update this when changing slaves!
+// Slave addresses
+parameter bbus_arb_slave0_adr = peh_wb_adr;
+parameter bbus_arb_slave1_adr = 0 /* UNASSIGNED */;
+parameter bbus_arb_slave2_adr = 0 /* UNASSIGNED */;
+parameter bbus_arb_slave3_adr = 0 /* UNASSIGNED */;
+parameter bbus_arb_slave4_adr = 0 /* UNASSIGNED */;
+parameter bbus_arb_slave5_adr = 0 /* UNASSIGNED */;
+parameter bbus_arb_slave6_adr = 0 /* UNASSIGNED */;
+parameter bbus_arb_slave7_adr = 0 /* UNASSIGNED */;
+parameter bbus_arb_slave8_adr = 0 /* UNASSIGNED */;
+parameter bbus_arb_slave9_adr = 0 /* UNASSIGNED */;
+parameter bbus_arb_slave10_adr = 0 /* UNASSIGNED */;
+parameter bbus_arb_slave11_adr = 0 /* UNASSIGNED */;
+parameter bbus_arb_slave12_adr = 0 /* UNASSIGNED */;
+parameter bbus_arb_slave13_adr = 0 /* UNASSIGNED */;
+parameter bbus_arb_slave14_adr = 0 /* UNASSIGNED */;
+parameter bbus_arb_slave15_adr = 0 /* UNASSIGNED */;
+parameter bbus_arb_slave16_adr = 0 /* UNASSIGNED */;
+parameter bbus_arb_slave17_adr = 0 /* UNASSIGNED */;
+parameter bbus_arb_slave18_adr = 0 /* UNASSIGNED */;
+parameter bbus_arb_slave19_adr = 0 /* UNASSIGNED */;
+
+
+
+
Index: boards/generic/ft/rtl/verilog/orpsoc_top/orpsoc_top.v
===================================================================
--- boards/generic/ft/rtl/verilog/orpsoc_top/orpsoc_top.v (nonexistent)
+++ boards/generic/ft/rtl/verilog/orpsoc_top/orpsoc_top.v (revision 483)
@@ -0,0 +1,828 @@
+//////////////////////////////////////////////////////////////////////
+/// ////
+/// ORPSoC top level ////
+/// ////
+/// Define I/O ports, instantiate modules ////
+/// ////
+/// Julius Baxter, julius@opencores.org ////
+/// ////
+//////////////////////////////////////////////////////////////////////
+//// ////
+//// Copyright (C) 2009, 2010 Authors and OPENCORES.ORG ////
+//// ////
+//// This source file may be used and distributed without ////
+//// restriction provided that this copyright statement is not ////
+//// removed from the file and that any derivative work contains ////
+//// the original copyright notice and the associated disclaimer. ////
+//// ////
+//// This source file is free software; you can redistribute it ////
+//// and/or modify it under the terms of the GNU Lesser General ////
+//// Public License as published by the Free Software Foundation; ////
+//// either version 2.1 of the License, or (at your option) any ////
+//// later version. ////
+//// ////
+//// This source is distributed in the hope that it will be ////
+//// useful, but WITHOUT ANY WARRANTY; without even the implied ////
+//// warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR ////
+//// PURPOSE. See the GNU Lesser General Public License for more ////
+//// details. ////
+//// ////
+//// You should have received a copy of the GNU Lesser General ////
+//// Public License along with this source; if not, download it ////
+//// from http://www.opencores.org/lgpl.shtml ////
+//// ////
+//////////////////////////////////////////////////////////////////////
+
+`include "orpsoc-defines.v"
+`include "or1200_defines.v"
+
+module orpsoc_top
+ (
+`ifdef JTAG_DEBUG
+ tdo_pad_o, tms_pad_i, tck_pad_i, tdi_pad_i,
+`endif
+ clk_pad_i,
+ rst_n_pad_i
+ );
+
+`include "orpsoc-params.v"
+
+ input clk_pad_i;
+ input rst_n_pad_i;
+
+`ifdef JTAG_DEBUG
+ output tdo_pad_o;
+ input tms_pad_i;
+ input tck_pad_i;
+ input tdi_pad_i;
+`endif
+
+
+ ////////////////////////////////////////////////////////////////////////
+ //
+ // Clock and reset generation module
+ //
+ ////////////////////////////////////////////////////////////////////////
+
+ //
+ // Wires
+ //
+ wire async_rst;
+ wire wb_clk, wb_rst;
+ wire dbg_tck;
+
+
+ clkgen clkgen0
+ (
+
+ .clk_pad_i (clk_pad_i),
+
+ .async_rst_o (async_rst),
+
+ .wb_clk_o (wb_clk),
+ .wb_rst_o (wb_rst),
+
+`ifdef JTAG_DEBUG
+ .tck_pad_i (tck_pad_i),
+ .dbg_tck_o (dbg_tck),
+`endif
+
+ // Asynchronous active low reset
+ .rst_n_pad_i (rst_n_pad_i)
+ );
+
+
+ ////////////////////////////////////////////////////////////////////////
+ //
+ // Arbiter
+ //
+ ////////////////////////////////////////////////////////////////////////
+
+ // Wire naming convention:
+ // First: wishbone master or slave (wbm/wbs)
+ // Second: Which bus it's on instruction or data (i/d)
+ // Third: Between which module and the arbiter the wires are
+ // Fourth: Signal name
+ // Fifth: Direction relative to module (not bus/arbiter!)
+ // ie. wbm_d_or12_adr_o is address OUT from the or1200
+
+ // OR1200 instruction bus wires
+ wire [wb_aw-1:0] wbm_i_or12_adr_o;
+ wire [wb_dw-1:0] wbm_i_or12_dat_o;
+ wire [3:0] wbm_i_or12_sel_o;
+ wire wbm_i_or12_we_o;
+ wire wbm_i_or12_cyc_o;
+ wire wbm_i_or12_stb_o;
+ wire [2:0] wbm_i_or12_cti_o;
+ wire [1:0] wbm_i_or12_bte_o;
+
+ wire [wb_dw-1:0] wbm_i_or12_dat_i;
+ wire wbm_i_or12_ack_i;
+ wire wbm_i_or12_err_i;
+ wire wbm_i_or12_rty_i;
+
+ // OR1200 data bus wires
+ wire [wb_aw-1:0] wbm_d_or12_adr_o;
+ wire [wb_dw-1:0] wbm_d_or12_dat_o;
+ wire [3:0] wbm_d_or12_sel_o;
+ wire wbm_d_or12_we_o;
+ wire wbm_d_or12_cyc_o;
+ wire wbm_d_or12_stb_o;
+ wire [2:0] wbm_d_or12_cti_o;
+ wire [1:0] wbm_d_or12_bte_o;
+
+ wire [wb_dw-1:0] wbm_d_or12_dat_i;
+ wire wbm_d_or12_ack_i;
+ wire wbm_d_or12_err_i;
+ wire wbm_d_or12_rty_i;
+
+ // Debug interface bus wires
+ wire [wb_aw-1:0] wbm_d_dbg_adr_o;
+ wire [wb_dw-1:0] wbm_d_dbg_dat_o;
+ wire [3:0] wbm_d_dbg_sel_o;
+ wire wbm_d_dbg_we_o;
+ wire wbm_d_dbg_cyc_o;
+ wire wbm_d_dbg_stb_o;
+ wire [2:0] wbm_d_dbg_cti_o;
+ wire [1:0] wbm_d_dbg_bte_o;
+
+ wire [wb_dw-1:0] wbm_d_dbg_dat_i;
+ wire wbm_d_dbg_ack_i;
+ wire wbm_d_dbg_err_i;
+ wire wbm_d_dbg_rty_i;
+
+ // Byte bus bridge master signals
+ wire [wb_aw-1:0] wbm_b_d_adr_o;
+ wire [wb_dw-1:0] wbm_b_d_dat_o;
+ wire [3:0] wbm_b_d_sel_o;
+ wire wbm_b_d_we_o;
+ wire wbm_b_d_cyc_o;
+ wire wbm_b_d_stb_o;
+ wire [2:0] wbm_b_d_cti_o;
+ wire [1:0] wbm_b_d_bte_o;
+
+ wire [wb_dw-1:0] wbm_b_d_dat_i;
+ wire wbm_b_d_ack_i;
+ wire wbm_b_d_err_i;
+ wire wbm_b_d_rty_i;
+
+ // Instruction bus slave wires //
+
+ // rom0 instruction bus wires
+ wire [31:0] wbs_i_rom0_adr_i;
+ wire [wbs_i_rom0_data_width-1:0] wbs_i_rom0_dat_i;
+ wire [3:0] wbs_i_rom0_sel_i;
+ wire wbs_i_rom0_we_i;
+ wire wbs_i_rom0_cyc_i;
+ wire wbs_i_rom0_stb_i;
+ wire [2:0] wbs_i_rom0_cti_i;
+ wire [1:0] wbs_i_rom0_bte_i;
+ wire [wbs_i_rom0_data_width-1:0] wbs_i_rom0_dat_o;
+ wire wbs_i_rom0_ack_o;
+ wire wbs_i_rom0_err_o;
+ wire wbs_i_rom0_rty_o;
+
+ // mc0 instruction bus wires
+ wire [31:0] wbs_i_mc0_adr_i;
+ wire [31:0] wbs_i_mc0_dat_i;
+ wire [3:0] wbs_i_mc0_sel_i;
+ wire wbs_i_mc0_we_i;
+ wire wbs_i_mc0_cyc_i;
+ wire wbs_i_mc0_stb_i;
+ wire [2:0] wbs_i_mc0_cti_i;
+ wire [1:0] wbs_i_mc0_bte_i;
+ wire [31:0] wbs_i_mc0_dat_o;
+ wire wbs_i_mc0_ack_o;
+ wire wbs_i_mc0_err_o;
+ wire wbs_i_mc0_rty_o;
+
+ // Data bus slave wires //
+
+ // mc0 data bus wires
+ wire [31:0] wbs_d_mc0_adr_i;
+ wire [31:0] wbs_d_mc0_dat_i;
+ wire [3:0] wbs_d_mc0_sel_i;
+ wire wbs_d_mc0_we_i;
+ wire wbs_d_mc0_cyc_i;
+ wire wbs_d_mc0_stb_i;
+ wire [2:0] wbs_d_mc0_cti_i;
+ wire [1:0] wbs_d_mc0_bte_i;
+ wire [31:0] wbs_d_mc0_dat_o;
+ wire wbs_d_mc0_ack_o;
+ wire wbs_d_mc0_err_o;
+ wire wbs_d_mc0_rty_o;
+
+ // memory parity error handler wires
+ wire [31:0] wbs_d_peh_adr_i;
+ wire [7:0] wbs_d_peh_dat_i;
+ wire [3:0] wbs_d_peh_sel_i;
+ wire wbs_d_peh_we_i;
+ wire wbs_d_peh_cyc_i;
+ wire wbs_d_peh_stb_i;
+ wire [2:0] wbs_d_peh_cti_i;
+ wire [1:0] wbs_d_peh_bte_i;
+ wire [7:0] wbs_d_peh_dat_o;
+ wire wbs_d_peh_ack_o;
+ wire wbs_d_peh_err_o;
+ wire wbs_d_peh_rty_o;
+
+ //
+ // Wishbone instruction bus arbiter
+ //
+
+ arbiter_ibus arbiter_ibus0
+ (
+ // Instruction Bus Master
+ // Inputs to arbiter from master
+ .wbm_adr_o (wbm_i_or12_adr_o),
+ .wbm_dat_o (wbm_i_or12_dat_o),
+ .wbm_sel_o (wbm_i_or12_sel_o),
+ .wbm_we_o (wbm_i_or12_we_o),
+ .wbm_cyc_o (wbm_i_or12_cyc_o),
+ .wbm_stb_o (wbm_i_or12_stb_o),
+ .wbm_cti_o (wbm_i_or12_cti_o),
+ .wbm_bte_o (wbm_i_or12_bte_o),
+ // Outputs to master from arbiter
+ .wbm_dat_i (wbm_i_or12_dat_i),
+ .wbm_ack_i (wbm_i_or12_ack_i),
+ .wbm_err_i (wbm_i_or12_err_i),
+ .wbm_rty_i (wbm_i_or12_rty_i),
+
+ // Slave 0
+ // Inputs to slave from arbiter
+ .wbs0_adr_i (wbs_i_rom0_adr_i),
+ .wbs0_dat_i (wbs_i_rom0_dat_i),
+ .wbs0_sel_i (wbs_i_rom0_sel_i),
+ .wbs0_we_i (wbs_i_rom0_we_i),
+ .wbs0_cyc_i (wbs_i_rom0_cyc_i),
+ .wbs0_stb_i (wbs_i_rom0_stb_i),
+ .wbs0_cti_i (wbs_i_rom0_cti_i),
+ .wbs0_bte_i (wbs_i_rom0_bte_i),
+ // Outputs from slave to arbiter
+ .wbs0_dat_o (wbs_i_rom0_dat_o),
+ .wbs0_ack_o (wbs_i_rom0_ack_o),
+ .wbs0_err_o (wbs_i_rom0_err_o),
+ .wbs0_rty_o (wbs_i_rom0_rty_o),
+
+ // Slave 1
+ // Inputs to slave from arbiter
+ .wbs1_adr_i (wbs_i_mc0_adr_i),
+ .wbs1_dat_i (wbs_i_mc0_dat_i),
+ .wbs1_sel_i (wbs_i_mc0_sel_i),
+ .wbs1_we_i (wbs_i_mc0_we_i),
+ .wbs1_cyc_i (wbs_i_mc0_cyc_i),
+ .wbs1_stb_i (wbs_i_mc0_stb_i),
+ .wbs1_cti_i (wbs_i_mc0_cti_i),
+ .wbs1_bte_i (wbs_i_mc0_bte_i),
+ // Outputs from slave to arbiter
+ .wbs1_dat_o (wbs_i_mc0_dat_o),
+ .wbs1_ack_o (wbs_i_mc0_ack_o),
+ .wbs1_err_o (wbs_i_mc0_err_o),
+ .wbs1_rty_o (wbs_i_mc0_rty_o),
+
+ // Clock, reset inputs
+ .wb_clk (wb_clk),
+ .wb_rst (wb_rst));
+
+ defparam arbiter_ibus0.wb_addr_match_width = ibus_arb_addr_match_width;
+
+ defparam arbiter_ibus0.slave0_adr = ibus_arb_slave0_adr; // ROM
+ defparam arbiter_ibus0.slave1_adr = ibus_arb_slave1_adr; // Main memory
+
+ //
+ // Wishbone data bus arbiter
+ //
+
+ arbiter_dbus arbiter_dbus0
+ (
+ // Master 0
+ // Inputs to arbiter from master
+ .wbm0_adr_o (wbm_d_or12_adr_o),
+ .wbm0_dat_o (wbm_d_or12_dat_o),
+ .wbm0_sel_o (wbm_d_or12_sel_o),
+ .wbm0_we_o (wbm_d_or12_we_o),
+ .wbm0_cyc_o (wbm_d_or12_cyc_o),
+ .wbm0_stb_o (wbm_d_or12_stb_o),
+ .wbm0_cti_o (wbm_d_or12_cti_o),
+ .wbm0_bte_o (wbm_d_or12_bte_o),
+ // Outputs to master from arbiter
+ .wbm0_dat_i (wbm_d_or12_dat_i),
+ .wbm0_ack_i (wbm_d_or12_ack_i),
+ .wbm0_err_i (wbm_d_or12_err_i),
+ .wbm0_rty_i (wbm_d_or12_rty_i),
+
+ // Master 0
+ // Inputs to arbiter from master
+ .wbm1_adr_o (wbm_d_dbg_adr_o),
+ .wbm1_dat_o (wbm_d_dbg_dat_o),
+ .wbm1_we_o (wbm_d_dbg_we_o),
+ .wbm1_cyc_o (wbm_d_dbg_cyc_o),
+ .wbm1_sel_o (wbm_d_dbg_sel_o),
+ .wbm1_stb_o (wbm_d_dbg_stb_o),
+ .wbm1_cti_o (wbm_d_dbg_cti_o),
+ .wbm1_bte_o (wbm_d_dbg_bte_o),
+ // Outputs to master from arbiter
+ .wbm1_dat_i (wbm_d_dbg_dat_i),
+ .wbm1_ack_i (wbm_d_dbg_ack_i),
+ .wbm1_err_i (wbm_d_dbg_err_i),
+ .wbm1_rty_i (wbm_d_dbg_rty_i),
+
+ // Slaves
+
+ .wbs0_adr_i (wbs_d_mc0_adr_i),
+ .wbs0_dat_i (wbs_d_mc0_dat_i),
+ .wbs0_sel_i (wbs_d_mc0_sel_i),
+ .wbs0_we_i (wbs_d_mc0_we_i),
+ .wbs0_cyc_i (wbs_d_mc0_cyc_i),
+ .wbs0_stb_i (wbs_d_mc0_stb_i),
+ .wbs0_cti_i (wbs_d_mc0_cti_i),
+ .wbs0_bte_i (wbs_d_mc0_bte_i),
+ .wbs0_dat_o (wbs_d_mc0_dat_o),
+ .wbs0_ack_o (wbs_d_mc0_ack_o),
+ .wbs0_err_o (wbs_d_mc0_err_o),
+ .wbs0_rty_o (wbs_d_mc0_rty_o),
+
+ .wbs1_adr_i (wbm_b_d_adr_o),
+ .wbs1_dat_i (wbm_b_d_dat_o),
+ .wbs1_sel_i (wbm_b_d_sel_o),
+ .wbs1_we_i (wbm_b_d_we_o),
+ .wbs1_cyc_i (wbm_b_d_cyc_o),
+ .wbs1_stb_i (wbm_b_d_stb_o),
+ .wbs1_cti_i (wbm_b_d_cti_o),
+ .wbs1_bte_i (wbm_b_d_bte_o),
+ .wbs1_dat_o (wbm_b_d_dat_i),
+ .wbs1_ack_o (wbm_b_d_ack_i),
+ .wbs1_err_o (wbm_b_d_err_i),
+ .wbs1_rty_o (wbm_b_d_rty_i),
+
+ // Clock, reset inputs
+ .wb_clk (wb_clk),
+ .wb_rst (wb_rst));
+
+ // These settings are from top level params file
+ defparam arbiter_dbus0.wb_addr_match_width = dbus_arb_wb_addr_match_width;
+ defparam arbiter_dbus0.wb_num_slaves = dbus_arb_wb_num_slaves;
+ defparam arbiter_dbus0.slave0_adr = dbus_arb_slave0_adr;
+ defparam arbiter_dbus0.slave1_adr = dbus_arb_slave1_adr;
+
+ //
+ // Wishbone byte-wide bus arbiter
+ //
+
+ arbiter_bytebus arbiter_bytebus0
+ (
+
+ // Master 0
+ // Inputs to arbiter from master
+ .wbm0_adr_o (wbm_b_d_adr_o),
+ .wbm0_dat_o (wbm_b_d_dat_o),
+ .wbm0_sel_o (wbm_b_d_sel_o),
+ .wbm0_we_o (wbm_b_d_we_o),
+ .wbm0_cyc_o (wbm_b_d_cyc_o),
+ .wbm0_stb_o (wbm_b_d_stb_o),
+ .wbm0_cti_o (wbm_b_d_cti_o),
+ .wbm0_bte_o (wbm_b_d_bte_o),
+ // Outputs to master from arbiter
+ .wbm0_dat_i (wbm_b_d_dat_i),
+ .wbm0_ack_i (wbm_b_d_ack_i),
+ .wbm0_err_i (wbm_b_d_err_i),
+ .wbm0_rty_i (wbm_b_d_rty_i),
+
+ // Byte bus slaves
+
+ .wbs0_adr_i (wbs_d_peh_adr_i),
+ .wbs0_dat_i (wbs_d_peh_dat_i),
+ .wbs0_we_i (wbs_d_peh_we_i),
+ .wbs0_cyc_i (wbs_d_peh_cyc_i),
+ .wbs0_stb_i (wbs_d_peh_stb_i),
+ .wbs0_cti_i (wbs_d_peh_cti_i),
+ .wbs0_bte_i (wbs_d_peh_bte_i),
+ .wbs0_dat_o (wbs_d_peh_dat_o),
+ .wbs0_ack_o (wbs_d_peh_ack_o),
+ .wbs0_err_o (wbs_d_peh_err_o),
+ .wbs0_rty_o (wbs_d_peh_rty_o),
+
+ // Clock, reset inputs
+ .wb_clk (wb_clk),
+ .wb_rst (wb_rst));
+
+ defparam arbiter_bytebus0.wb_addr_match_width = bbus_arb_wb_addr_match_width;
+ defparam arbiter_bytebus0.wb_num_slaves = bbus_arb_wb_num_slaves;
+
+ defparam arbiter_bytebus0.slave0_adr = bbus_arb_slave0_adr;
+
+`ifdef JTAG_DEBUG
+ ////////////////////////////////////////////////////////////////////////
+ //
+ // JTAG TAP
+ //
+ ////////////////////////////////////////////////////////////////////////
+
+ //
+ // Wires
+ //
+ wire dbg_if_select;
+ wire dbg_if_tdo;
+ wire jtag_tap_tdo;
+ wire jtag_tap_shift_dr, jtag_tap_pause_dr,
+ jtag_tap_update_dr, jtag_tap_capture_dr;
+ //
+ // Instantiation
+ //
+
+ jtag_tap jtag_tap0
+ (
+ // Ports to pads
+ .tdo_pad_o (tdo_pad_o),
+ .tms_pad_i (tms_pad_i),
+ .tck_pad_i (dbg_tck),
+ .trst_pad_i (async_rst),
+ .tdi_pad_i (tdi_pad_i),
+
+ .tdo_padoe_o (),
+
+ .tdo_o (jtag_tap_tdo),
+
+ .shift_dr_o (jtag_tap_shift_dr),
+ .pause_dr_o (jtag_tap_pause_dr),
+ .update_dr_o (jtag_tap_update_dr),
+ .capture_dr_o (jtag_tap_capture_dr),
+
+ .extest_select_o (),
+ .sample_preload_select_o (),
+ .mbist_select_o (),
+ .debug_select_o (dbg_if_select),
+
+
+ .bs_chain_tdi_i (1'b0),
+ .mbist_tdi_i (1'b0),
+ .debug_tdi_i (dbg_if_tdo)
+
+ );
+
+ ////////////////////////////////////////////////////////////////////////
+`endif // `ifdef JTAG_DEBUG
+
+ ////////////////////////////////////////////////////////////////////////
+ //
+ // OpenRISC processor
+ //
+ ////////////////////////////////////////////////////////////////////////
+
+ //
+ // Wires
+ //
+
+ wire [19:0] or1200_pic_ints;
+
+ wire [31:0] or1200_dbg_dat_i;
+ wire [31:0] or1200_dbg_adr_i;
+ wire or1200_dbg_we_i;
+ wire or1200_dbg_stb_i;
+ wire or1200_dbg_ack_o;
+ wire [31:0] or1200_dbg_dat_o;
+
+ wire or1200_dbg_stall_i;
+ wire or1200_dbg_ewt_i;
+ wire [3:0] or1200_dbg_lss_o;
+ wire [1:0] or1200_dbg_is_o;
+ wire [10:0] or1200_dbg_wp_o;
+ wire or1200_dbg_bp_o;
+ wire or1200_dbg_rst;
+
+ wire or1200_clk, or1200_rst;
+ wire sig_tick;
+ wire [8:0] or1200_mem_parity_err;
+ wire parity_err_reset;
+
+ wire or1200_wb_rst;
+
+ //
+ // Assigns
+ //
+ assign or1200_clk = wb_clk;
+ assign or1200_rst = wb_rst | or1200_dbg_rst | parity_err_reset;
+ assign or1200_wb_rst = wb_rst | or1200_dbg_rst | parity_err_reset;
+
+ //
+ // Instantiation
+ //
+ or1200_top or1200_top0
+ (
+ // Instruction bus, clocks, reset
+ .iwb_clk_i (wb_clk),
+ .iwb_rst_i (or1200_wb_rst),
+ .iwb_ack_i (wbm_i_or12_ack_i),
+ .iwb_err_i (wbm_i_or12_err_i),
+ .iwb_rty_i (wbm_i_or12_rty_i),
+ .iwb_dat_i (wbm_i_or12_dat_i),
+
+ .iwb_cyc_o (wbm_i_or12_cyc_o),
+ .iwb_adr_o (wbm_i_or12_adr_o),
+ .iwb_stb_o (wbm_i_or12_stb_o),
+ .iwb_we_o (wbm_i_or12_we_o),
+ .iwb_sel_o (wbm_i_or12_sel_o),
+ .iwb_dat_o (wbm_i_or12_dat_o),
+ .iwb_cti_o (wbm_i_or12_cti_o),
+ .iwb_bte_o (wbm_i_or12_bte_o),
+
+ // Data bus, clocks, reset
+ .dwb_clk_i (wb_clk),
+ .dwb_rst_i (or1200_wb_rst),
+ .dwb_ack_i (wbm_d_or12_ack_i),
+ .dwb_err_i (wbm_d_or12_err_i),
+ .dwb_rty_i (wbm_d_or12_rty_i),
+ .dwb_dat_i (wbm_d_or12_dat_i),
+
+ .dwb_cyc_o (wbm_d_or12_cyc_o),
+ .dwb_adr_o (wbm_d_or12_adr_o),
+ .dwb_stb_o (wbm_d_or12_stb_o),
+ .dwb_we_o (wbm_d_or12_we_o),
+ .dwb_sel_o (wbm_d_or12_sel_o),
+ .dwb_dat_o (wbm_d_or12_dat_o),
+ .dwb_cti_o (wbm_d_or12_cti_o),
+ .dwb_bte_o (wbm_d_or12_bte_o),
+
+ // Debug interface ports
+ .dbg_stall_i (or1200_dbg_stall_i),
+ //.dbg_ewt_i (or1200_dbg_ewt_i),
+ .dbg_ewt_i (1'b0),
+ .dbg_lss_o (or1200_dbg_lss_o),
+ .dbg_is_o (or1200_dbg_is_o),
+ .dbg_wp_o (or1200_dbg_wp_o),
+ .dbg_bp_o (or1200_dbg_bp_o),
+
+ .dbg_adr_i (or1200_dbg_adr_i),
+ .dbg_we_i (or1200_dbg_we_i ),
+ .dbg_stb_i (or1200_dbg_stb_i),
+ .dbg_dat_i (or1200_dbg_dat_i),
+ .dbg_dat_o (or1200_dbg_dat_o),
+ .dbg_ack_o (or1200_dbg_ack_o),
+
+ .pm_clksd_o (),
+ .pm_dc_gate_o (),
+ .pm_ic_gate_o (),
+ .pm_dmmu_gate_o (),
+ .pm_immu_gate_o (),
+ .pm_tt_gate_o (),
+ .pm_cpu_gate_o (),
+ .pm_wakeup_o (),
+ .pm_lvolt_o (),
+
+ // Core clocks, resets
+ .clk_i (or1200_clk),
+ .rst_i (or1200_rst),
+
+ .clmode_i (2'b00),
+ // Interrupts
+ .pic_ints_i (or1200_pic_ints),
+ .sig_tick(sig_tick),
+ /*
+ .mbist_so_o (),
+ .mbist_si_i (0),
+ .mbist_ctrl_i (0),
+ */
+
+`ifdef OR1200_RAM_PARITY
+ .mem_parity_err (or1200_mem_parity_err),
+`endif
+ .pm_cpustall_i (1'b0)
+
+ );
+
+ ////////////////////////////////////////////////////////////////////////
+
+
+`ifdef JTAG_DEBUG
+ ////////////////////////////////////////////////////////////////////////
+ //
+ // OR1200 Debug Interface
+ //
+ ////////////////////////////////////////////////////////////////////////
+
+ dbg_if dbg_if0
+ (
+ // OR1200 interface
+ .cpu0_clk_i (or1200_clk),
+ .cpu0_rst_o (or1200_dbg_rst),
+ .cpu0_addr_o (or1200_dbg_adr_i),
+ .cpu0_data_o (or1200_dbg_dat_i),
+ .cpu0_stb_o (or1200_dbg_stb_i),
+ .cpu0_we_o (or1200_dbg_we_i),
+ .cpu0_data_i (or1200_dbg_dat_o),
+ .cpu0_ack_i (or1200_dbg_ack_o),
+
+
+ .cpu0_stall_o (or1200_dbg_stall_i),
+ .cpu0_bp_i (or1200_dbg_bp_o),
+
+ // TAP interface
+ .tck_i (dbg_tck),
+ .tdi_i (jtag_tap_tdo),
+ .tdo_o (dbg_if_tdo),
+ .rst_i (wb_rst),
+ .shift_dr_i (jtag_tap_shift_dr),
+ .pause_dr_i (jtag_tap_pause_dr),
+ .update_dr_i (jtag_tap_update_dr),
+ .debug_select_i (dbg_if_select),
+
+ // Wishbone debug master
+ .wb_clk_i (wb_clk),
+ .wb_dat_i (wbm_d_dbg_dat_i),
+ .wb_ack_i (wbm_d_dbg_ack_i),
+ .wb_err_i (wbm_d_dbg_err_i),
+ .wb_adr_o (wbm_d_dbg_adr_o),
+ .wb_dat_o (wbm_d_dbg_dat_o),
+ .wb_cyc_o (wbm_d_dbg_cyc_o),
+ .wb_stb_o (wbm_d_dbg_stb_o),
+ .wb_sel_o (wbm_d_dbg_sel_o),
+ .wb_we_o (wbm_d_dbg_we_o ),
+ .wb_cti_o (wbm_d_dbg_cti_o),
+ .wb_cab_o (/* UNUSED */),
+ .wb_bte_o (wbm_d_dbg_bte_o)
+ );
+
+ ////////////////////////////////////////////////////////////////////////
+`else // !`ifdef JTAG_DEBUG
+
+ assign or1200_dbg_rst = 0;
+
+ assign wbm_d_dbg_adr_o = 0;
+ assign wbm_d_dbg_dat_o = 0;
+ assign wbm_d_dbg_cyc_o = 0;
+ assign wbm_d_dbg_stb_o = 0;
+ assign wbm_d_dbg_sel_o = 0;
+ assign wbm_d_dbg_we_o = 0;
+ assign wbm_d_dbg_cti_o = 0;
+ assign wbm_d_dbg_bte_o = 0;
+
+ assign or1200_dbg_adr_i = 0;
+ assign or1200_dbg_dat_i = 0;
+ assign or1200_dbg_stb_i = 0;
+ assign or1200_dbg_we_i = 0;
+ assign or1200_dbg_stall_i = 0;
+
+ ////////////////////////////////////////////////////////////////////////
+`endif // !`ifdef JTAG_DEBUG
+
+`ifdef OR1200_RAM_PARITY
+ ////////////////////////////////////////////////////////////////////////
+ //
+ // Parity error handler
+ //
+ ////////////////////////////////////////////////////////////////////////
+ wire parity_err_int;
+
+ parity_err_handler perrhndler
+ (
+ .clk(wb_clk),
+ .parity_err(or1200_mem_parity_err),
+ .wb_rst(wb_rst),
+ .reset(parity_err_reset),
+ .interrupt(parity_err_int),
+ .wb_dat_o(wbs_d_peh_dat_o),
+ .wb_ack_o(wbs_d_peh_ack_o),
+ .wb_stb_i(wbs_d_peh_stb_i)
+ );
+
+ assign wbs_d_peh_err_o = 0;
+ assign wbs_d_peh_rty_o = 0;
+
+`endif
+ ////////////////////////////////////////////////////////////////////////
+ //
+ // ROM
+ //
+ ////////////////////////////////////////////////////////////////////////
+`ifdef BOOTROM
+ rom rom0
+ (
+ .wb_dat_o (wbs_i_rom0_dat_o),
+ .wb_ack_o (wbs_i_rom0_ack_o),
+ .wb_adr_i (wbs_i_rom0_adr_i[(wbs_i_rom0_addr_width+2)-1:2]),
+ .wb_stb_i (wbs_i_rom0_stb_i),
+ .wb_cyc_i (wbs_i_rom0_cyc_i),
+ .wb_cti_i (wbs_i_rom0_cti_i),
+ .wb_bte_i (wbs_i_rom0_bte_i),
+ .wb_clk (wb_clk),
+ .wb_rst (wb_rst));
+
+ defparam rom0.addr_width = wbs_i_rom0_addr_width;
+`else // !`ifdef BOOTROM
+ assign wbs_i_rom0_dat_o = 0;
+ assign wbs_i_rom0_ack_o = 0;
+`endif // !`ifdef BOOTROM
+
+
+ assign wbs_i_rom0_err_o = 0;
+ assign wbs_i_rom0_rty_o = 0;
+
+ ////////////////////////////////////////////////////////////////////////
+
+`ifdef RAM_WB
+ ////////////////////////////////////////////////////////////////////////
+ //
+ // Generic main RAM
+ //
+ ////////////////////////////////////////////////////////////////////////
+
+
+ ram_wb ram_wb0
+ (
+ // Wishbone slave interface 0
+ .wbm0_dat_i (wbs_i_mc0_dat_i),
+ .wbm0_adr_i (wbs_i_mc0_adr_i),
+ .wbm0_sel_i (wbs_i_mc0_sel_i),
+ .wbm0_cti_i (wbs_i_mc0_cti_i),
+ .wbm0_bte_i (wbs_i_mc0_bte_i),
+ .wbm0_we_i (wbs_i_mc0_we_i ),
+ .wbm0_cyc_i (wbs_i_mc0_cyc_i),
+ .wbm0_stb_i (wbs_i_mc0_stb_i),
+ .wbm0_dat_o (wbs_i_mc0_dat_o),
+ .wbm0_ack_o (wbs_i_mc0_ack_o),
+ .wbm0_err_o (wbs_i_mc0_err_o),
+ .wbm0_rty_o (wbs_i_mc0_rty_o),
+ // Wishbone slave interface 1
+ .wbm1_dat_i (wbs_d_mc0_dat_i),
+ .wbm1_adr_i (wbs_d_mc0_adr_i),
+ .wbm1_sel_i (wbs_d_mc0_sel_i),
+ .wbm1_cti_i (wbs_d_mc0_cti_i),
+ .wbm1_bte_i (wbs_d_mc0_bte_i),
+ .wbm1_we_i (wbs_d_mc0_we_i ),
+ .wbm1_cyc_i (wbs_d_mc0_cyc_i),
+ .wbm1_stb_i (wbs_d_mc0_stb_i),
+ .wbm1_dat_o (wbs_d_mc0_dat_o),
+ .wbm1_ack_o (wbs_d_mc0_ack_o),
+ .wbm1_err_o (wbs_d_mc0_err_o),
+ .wbm1_rty_o (wbs_d_mc0_rty_o),
+ // Wishbone slave interface 2
+ .wbm2_dat_i ('d0),
+ .wbm2_adr_i ('d0),
+ .wbm2_sel_i (4'd0),
+ .wbm2_cti_i (3'd0),
+ .wbm2_bte_i (2'd0),
+ .wbm2_we_i (1'd0),
+ .wbm2_cyc_i (1'd0),
+ .wbm2_stb_i (1'd0),
+ .wbm2_dat_o (),
+ .wbm2_ack_o (),
+ .wbm2_err_o (),
+ .wbm2_rty_o (),
+ // Clock, reset
+ .wb_clk_i (wb_clk),
+ .wb_rst_i (wb_rst));
+
+ defparam ram_wb0.aw = wb_aw;
+ defparam ram_wb0.dw = wb_dw;
+
+ defparam ram_wb0.mem_size_bytes = (1024*1024); // 1024MB
+ defparam ram_wb0.mem_adr_width = 20; // log2(1024*1024)
+
+
+ ////////////////////////////////////////////////////////////////////////
+`endif
+
+ ////////////////////////////////////////////////////////////////////////
+ //
+ // OR1200 Interrupt assignment
+ //
+ ////////////////////////////////////////////////////////////////////////
+
+ assign or1200_pic_ints[0] = 0; // Non-maskable inside OR1200
+ assign or1200_pic_ints[1] = 0; // Non-maskable inside OR1200
+ assign or1200_pic_ints[2] = 0;
+ assign or1200_pic_ints[3] = 0;
+ assign or1200_pic_ints[4] = 0;
+`ifdef OR1200_RAM_PARITY
+ assign or1200_pic_ints[5] = parity_err_int;
+`else
+ assign or1200_pic_ints[5] = 0;
+`endif
+
+`ifdef SPI0
+ assign or1200_pic_ints[6] = spi0_irq;
+`else
+ assign or1200_pic_ints[6] = 0;
+`endif
+ assign or1200_pic_ints[7] = 0;
+ assign or1200_pic_ints[8] = 0;
+ assign or1200_pic_ints[9] = 0;
+ assign or1200_pic_ints[10] = 0;
+ assign or1200_pic_ints[11] = 0;
+ assign or1200_pic_ints[12] = 0;
+ assign or1200_pic_ints[13] = 0;
+ assign or1200_pic_ints[14] = 0;
+ assign or1200_pic_ints[15] = 0;
+ assign or1200_pic_ints[16] = 0;
+ assign or1200_pic_ints[17] = 0;
+ assign or1200_pic_ints[18] = 0;
+ assign or1200_pic_ints[19] = 0;
+
+endmodule // top
+
+// Local Variables:
+// verilog-library-directories:("." "../arbiter" "../or1200" "../dbg_if" "../jtag_tap" "../rom" "../simple_spi" )
+// verilog-library-files:()
+// verilog-library-extensions:(".v" ".h")
+// End:
+
boards/generic/ft/rtl/verilog/orpsoc_top/orpsoc_top.v
Property changes :
Added: svn:executable
## -0,0 +1 ##
+*
\ No newline at end of property
Index: boards/generic/ft/rtl/verilog/arbiter/arbiter_bytebus.v
===================================================================
--- boards/generic/ft/rtl/verilog/arbiter/arbiter_bytebus.v (nonexistent)
+++ boards/generic/ft/rtl/verilog/arbiter/arbiter_bytebus.v (revision 483)
@@ -0,0 +1,1192 @@
+//////////////////////////////////////////////////////////////////////
+/// ////
+/// Wishbone arbiter, byte-wide data path, no bursting ////
+/// ////
+/// Simple arbiter, single master, multiple slave, for byte-wide ////
+/// peripherals ////
+/// ////
+/// Julius Baxter, julius@opencores.org ////
+/// ////
+//////////////////////////////////////////////////////////////////////
+//// ////
+//// Copyright (C) 2009, 2010 Authors and OPENCORES.ORG ////
+//// ////
+//// This source file may be used and distributed without ////
+//// restriction provided that this copyright statement is not ////
+//// removed from the file and that any derivative work contains ////
+//// the original copyright notice and the associated disclaimer. ////
+//// ////
+//// This source file is free software; you can redistribute it ////
+//// and/or modify it under the terms of the GNU Lesser General ////
+//// Public License as published by the Free Software Foundation; ////
+//// either version 2.1 of the License, or (at your option) any ////
+//// later version. ////
+//// ////
+//// This source is distributed in the hope that it will be ////
+//// useful, but WITHOUT ANY WARRANTY; without even the implied ////
+//// warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR ////
+//// PURPOSE. See the GNU Lesser General Public License for more ////
+//// details. ////
+//// ////
+//// You should have received a copy of the GNU Lesser General ////
+//// Public License along with this source; if not, download it ////
+//// from http://www.opencores.org/lgpl.shtml ////
+//// ////
+//////////////////////////////////////////////////////////////////////
+
+//
+// Things to update when changing slave config:
+//
+// 1. Port list
+// 2. Port specification
+// 3. Slave addr select parameter
+// 4. Slave addr selects
+// 5. Slave input mux logic
+// 6. The four different master out mux logics (dat_o mux, and ack, rty & err)
+//
+`include "orpsoc-defines.v"
+module arbiter_bytebus
+ (
+
+ // Master in
+ wbm0_adr_o,
+ wbm0_dat_o,
+ wbm0_sel_o,
+ wbm0_we_o,
+ wbm0_cyc_o,
+ wbm0_stb_o,
+ wbm0_cti_o,
+ wbm0_bte_o,
+ wbm0_dat_i,
+ wbm0_ack_i,
+ wbm0_err_i,
+ wbm0_rty_i,
+
+ // Slave one
+ // Wishbone Slave interface
+ wbs0_adr_i,
+ wbs0_dat_i,
+ wbs0_we_i,
+ wbs0_cyc_i,
+ wbs0_stb_i,
+ wbs0_cti_i,
+ wbs0_bte_i,
+ wbs0_dat_o,
+ wbs0_ack_o,
+ wbs0_err_o,
+ wbs0_rty_o,
+/*
+ // Slave two
+ // Wishbone Slave interface
+ wbs1_adr_i,
+ wbs1_dat_i,
+ wbs1_we_i,
+ wbs1_cyc_i,
+ wbs1_stb_i,
+ wbs1_cti_i,
+ wbs1_bte_i,
+ wbs1_dat_o,
+ wbs1_ack_o,
+ wbs1_err_o,
+ wbs1_rty_o,
+
+ // Slave three
+ // Wishbone Slave interface
+ wbs2_adr_i,
+ wbs2_dat_i,
+ wbs2_we_i,
+ wbs2_cyc_i,
+ wbs2_stb_i,
+ wbs2_cti_i,
+ wbs2_bte_i,
+ wbs2_dat_o,
+ wbs2_ack_o,
+ wbs2_err_o,
+ wbs2_rty_o,
+
+ // Slave four
+ // Wishbone Slave interface
+ wbs3_adr_i,
+ wbs3_dat_i,
+ wbs3_we_i,
+ wbs3_cyc_i,
+ wbs3_stb_i,
+ wbs3_cti_i,
+ wbs3_bte_i,
+ wbs3_dat_o,
+ wbs3_ack_o,
+ wbs3_err_o,
+ wbs3_rty_o,
+
+ // Slave five
+ // Wishbone Slave interface
+ wbs4_adr_i,
+ wbs4_dat_i,
+ wbs4_we_i,
+ wbs4_cyc_i,
+ wbs4_stb_i,
+ wbs4_cti_i,
+ wbs4_bte_i,
+ wbs4_dat_o,
+ wbs4_ack_o,
+ wbs4_err_o,
+ wbs4_rty_o,
+
+ // Slave six
+ // Wishbone Slave interface
+ wbs5_adr_i,
+ wbs5_dat_i,
+ wbs5_we_i,
+ wbs5_cyc_i,
+ wbs5_stb_i,
+ wbs5_cti_i,
+ wbs5_bte_i,
+ wbs5_dat_o,
+ wbs5_ack_o,
+ wbs5_err_o,
+ wbs5_rty_o,
+
+ // Slave seven
+ // Wishbone Slave interface
+ wbs6_adr_i,
+ wbs6_dat_i,
+ wbs6_we_i,
+ wbs6_cyc_i,
+ wbs6_stb_i,
+ wbs6_cti_i,
+ wbs6_bte_i,
+ wbs6_dat_o,
+ wbs6_ack_o,
+ wbs6_err_o,
+ wbs6_rty_o,
+
+ // Slave eight
+ // Wishbone Slave interface
+ wbs7_adr_i,
+ wbs7_dat_i,
+ wbs7_we_i,
+ wbs7_cyc_i,
+ wbs7_stb_i,
+ wbs7_cti_i,
+ wbs7_bte_i,
+ wbs7_dat_o,
+ wbs7_ack_o,
+ wbs7_err_o,
+ wbs7_rty_o,
+
+ // Slave nine
+ // Wishbone Slave interface
+ wbs8_adr_i,
+ wbs8_dat_i,
+ wbs8_we_i,
+ wbs8_cyc_i,
+ wbs8_stb_i,
+ wbs8_cti_i,
+ wbs8_bte_i,
+ wbs8_dat_o,
+ wbs8_ack_o,
+ wbs8_err_o,
+ wbs8_rty_o,
+
+ // Slave ten
+ // Wishbone Slave interface
+ wbs9_adr_i,
+ wbs9_dat_i,
+ wbs9_we_i,
+ wbs9_cyc_i,
+ wbs9_stb_i,
+ wbs9_cti_i,
+ wbs9_bte_i,
+ wbs9_dat_o,
+ wbs9_ack_o,
+ wbs9_err_o,
+ wbs9_rty_o,
+
+ // Slave eleven
+ // Wishbone Slave interface
+ wbs10_adr_i,
+ wbs10_dat_i,
+ wbs10_we_i,
+ wbs10_cyc_i,
+ wbs10_stb_i,
+ wbs10_cti_i,
+ wbs10_bte_i,
+ wbs10_dat_o,
+ wbs10_ack_o,
+ wbs10_err_o,
+ wbs10_rty_o,
+
+ // Slave twelve
+ // Wishbone Slave interface
+ wbs11_adr_i,
+ wbs11_dat_i,
+ wbs11_we_i,
+ wbs11_cyc_i,
+ wbs11_stb_i,
+ wbs11_cti_i,
+ wbs11_bte_i,
+ wbs11_dat_o,
+ wbs11_ack_o,
+ wbs11_err_o,
+ wbs11_rty_o,
+
+ // Slave thirteen
+ // Wishbone Slave interface
+ wbs12_adr_i,
+ wbs12_dat_i,
+ wbs12_we_i,
+ wbs12_cyc_i,
+ wbs12_stb_i,
+ wbs12_cti_i,
+ wbs12_bte_i,
+ wbs12_dat_o,
+ wbs12_ack_o,
+ wbs12_err_o,
+ wbs12_rty_o,
+
+ // Slave fourteen
+ // Wishbone Slave interface
+ wbs13_adr_i,
+ wbs13_dat_i,
+ wbs13_we_i,
+ wbs13_cyc_i,
+ wbs13_stb_i,
+ wbs13_cti_i,
+ wbs13_bte_i,
+ wbs13_dat_o,
+ wbs13_ack_o,
+ wbs13_err_o,
+ wbs13_rty_o,
+
+ // Slave fifteen
+ // Wishbone Slave interface
+ wbs14_adr_i,
+ wbs14_dat_i,
+ wbs14_we_i,
+ wbs14_cyc_i,
+ wbs14_stb_i,
+ wbs14_cti_i,
+ wbs14_bte_i,
+ wbs14_dat_o,
+ wbs14_ack_o,
+ wbs14_err_o,
+ wbs14_rty_o,
+
+ // Slave sixteen
+ // Wishbone Slave interface
+ wbs15_adr_i,
+ wbs15_dat_i,
+ wbs15_we_i,
+ wbs15_cyc_i,
+ wbs15_stb_i,
+ wbs15_cti_i,
+ wbs15_bte_i,
+
+ wbs15_dat_o,
+ wbs15_ack_o,
+ wbs15_err_o,
+ wbs15_rty_o,
+
+ // Slave seventeen
+ // Wishbone Slave interface
+ wbs16_adr_i,
+ wbs16_dat_i,
+ wbs16_we_i,
+ wbs16_cyc_i,
+ wbs16_stb_i,
+ wbs16_cti_i,
+ wbs16_bte_i,
+
+ wbs16_dat_o,
+ wbs16_ack_o,
+ wbs16_err_o,
+ wbs16_rty_o,
+
+
+ // Slave eighteen
+ // Wishbone Slave interface
+ wbs17_adr_i,
+ wbs17_dat_i,
+ wbs17_we_i,
+ wbs17_cyc_i,
+ wbs17_stb_i,
+ wbs17_cti_i,
+ wbs17_bte_i,
+
+ wbs17_dat_o,
+ wbs17_ack_o,
+ wbs17_err_o,
+ wbs17_rty_o,
+
+ // Slave nineteen
+ // Wishbone Slave interface
+ wbs18_adr_i,
+ wbs18_dat_i,
+ wbs18_we_i,
+ wbs18_cyc_i,
+ wbs18_stb_i,
+ wbs18_cti_i,
+ wbs18_bte_i,
+
+ wbs18_dat_o,
+ wbs18_ack_o,
+ wbs18_err_o,
+ wbs18_rty_o,
+
+ // Slave twenty
+ // Wishbone Slave interface
+ wbs19_adr_i,
+ wbs19_dat_i,
+ wbs19_we_i,
+ wbs19_cyc_i,
+ wbs19_stb_i,
+ wbs19_cti_i,
+ wbs19_bte_i,
+
+ wbs19_dat_o,
+ wbs19_ack_o,
+ wbs19_err_o,
+ wbs19_rty_o,
+
+ */
+
+ wb_clk, wb_rst
+ );
+
+
+ parameter wb_dat_width = 32;
+ parameter wbs_dat_width = 8;
+ parameter wb_adr_width = 32;
+
+ parameter wb_addr_match_width = 8;
+
+ parameter wb_num_slaves = 20; // Currently can handle up to 20
+
+ // Slave addresses
+
+ parameter slave0_adr = 8'h00;
+ parameter slave1_adr = 8'h00;
+ parameter slave2_adr = 8'h00;
+ parameter slave3_adr = 8'h00;
+ parameter slave4_adr = 8'h00;
+ parameter slave5_adr = 8'h00;
+ parameter slave6_adr = 8'h00;
+ parameter slave7_adr = 8'h00;
+ parameter slave8_adr = 8'h00;
+ parameter slave9_adr = 8'h00;
+ parameter slave10_adr = 8'h00;
+ parameter slave11_adr = 8'h00;
+ parameter slave12_adr = 8'h00;
+ parameter slave13_adr = 8'h00;
+ parameter slave14_adr = 8'h00;
+ parameter slave15_adr = 8'h00;
+ parameter slave16_adr = 8'h00;
+ parameter slave17_adr = 8'h00;
+ parameter slave18_adr = 8'h00;
+ parameter slave19_adr = 8'h00;
+
+
+`define WB_ARB_ADDR_MATCH_SEL wb_adr_width-1:wb_adr_width-wb_addr_match_width
+
+ input wb_clk;
+ input wb_rst;
+
+ // WB Master one
+ input [wb_adr_width-1:0] wbm0_adr_o;
+ input [wb_dat_width-1:0] wbm0_dat_o;
+ input [3:0] wbm0_sel_o;
+ input wbm0_we_o;
+ input wbm0_cyc_o;
+ input wbm0_stb_o;
+ input [2:0] wbm0_cti_o;
+ input [1:0] wbm0_bte_o;
+ output [wb_dat_width-1:0] wbm0_dat_i;
+ output wbm0_ack_i;
+ output wbm0_err_i;
+ output wbm0_rty_i;
+
+
+ // Slave one
+ // Wishbone Slave interface
+ output [wb_adr_width-1:0] wbs0_adr_i;
+ output [wbs_dat_width-1:0] wbs0_dat_i;
+ output wbs0_we_i;
+ output wbs0_cyc_i;
+ output wbs0_stb_i;
+ output [2:0] wbs0_cti_i;
+ output [1:0] wbs0_bte_i;
+ input [wbs_dat_width-1:0] wbs0_dat_o;
+ input wbs0_ack_o;
+ input wbs0_err_o;
+ input wbs0_rty_o;
+
+/*
+ // Wishbone Slave interface
+ output [wb_adr_width-1:0] wbs1_adr_i;
+ output [wbs_dat_width-1:0] wbs1_dat_i;
+ output wbs1_we_i;
+ output wbs1_cyc_i;
+ output wbs1_stb_i;
+ output [2:0] wbs1_cti_i;
+ output [1:0] wbs1_bte_i;
+ input [wbs_dat_width-1:0] wbs1_dat_o;
+ input wbs1_ack_o;
+ input wbs1_err_o;
+ input wbs1_rty_o;
+
+
+ // Wishbone Slave interface
+ output [wb_adr_width-1:0] wbs2_adr_i;
+ output [wbs_dat_width-1:0] wbs2_dat_i;
+ output wbs2_we_i;
+ output wbs2_cyc_i;
+ output wbs2_stb_i;
+ output [2:0] wbs2_cti_i;
+ output [1:0] wbs2_bte_i;
+ input [wbs_dat_width-1:0] wbs2_dat_o;
+ input wbs2_ack_o;
+ input wbs2_err_o;
+ input wbs2_rty_o;
+
+
+ // Wishbone Slave interface
+ output [wb_adr_width-1:0] wbs3_adr_i;
+ output [wbs_dat_width-1:0] wbs3_dat_i;
+ output wbs3_we_i;
+ output wbs3_cyc_i;
+ output wbs3_stb_i;
+ output [2:0] wbs3_cti_i;
+ output [1:0] wbs3_bte_i;
+ input [wbs_dat_width-1:0] wbs3_dat_o;
+ input wbs3_ack_o;
+ input wbs3_err_o;
+ input wbs3_rty_o;
+
+
+ // Wishbone Slave interface
+ output [wb_adr_width-1:0] wbs4_adr_i;
+ output [wbs_dat_width-1:0] wbs4_dat_i;
+ output wbs4_we_i;
+ output wbs4_cyc_i;
+ output wbs4_stb_i;
+ output [2:0] wbs4_cti_i;
+ output [1:0] wbs4_bte_i;
+ input [wbs_dat_width-1:0] wbs4_dat_o;
+ input wbs4_ack_o;
+ input wbs4_err_o;
+ input wbs4_rty_o;
+
+
+ // Wishbone Slave interface
+ output [wb_adr_width-1:0] wbs5_adr_i;
+ output [wbs_dat_width-1:0] wbs5_dat_i;
+ output wbs5_we_i;
+ output wbs5_cyc_i;
+ output wbs5_stb_i;
+ output [2:0] wbs5_cti_i;
+ output [1:0] wbs5_bte_i;
+ input [wbs_dat_width-1:0] wbs5_dat_o;
+ input wbs5_ack_o;
+ input wbs5_err_o;
+ input wbs5_rty_o;
+
+
+ // Wishbone Slave interface
+ output [wb_adr_width-1:0] wbs6_adr_i;
+ output [wbs_dat_width-1:0] wbs6_dat_i;
+ output wbs6_we_i;
+ output wbs6_cyc_i;
+ output wbs6_stb_i;
+ output [2:0] wbs6_cti_i;
+ output [1:0] wbs6_bte_i;
+ input [wbs_dat_width-1:0] wbs6_dat_o;
+ input wbs6_ack_o;
+ input wbs6_err_o;
+ input wbs6_rty_o;
+
+
+ // Wishbone Slave interface
+ output [wb_adr_width-1:0] wbs7_adr_i;
+ output [wbs_dat_width-1:0] wbs7_dat_i;
+ output wbs7_we_i;
+ output wbs7_cyc_i;
+ output wbs7_stb_i;
+ output [2:0] wbs7_cti_i;
+ output [1:0] wbs7_bte_i;
+ input [wbs_dat_width-1:0] wbs7_dat_o;
+ input wbs7_ack_o;
+ input wbs7_err_o;
+ input wbs7_rty_o;
+
+
+ // Wishbone Slave interface
+ output [wb_adr_width-1:0] wbs8_adr_i;
+ output [wbs_dat_width-1:0] wbs8_dat_i;
+ output wbs8_we_i;
+ output wbs8_cyc_i;
+ output wbs8_stb_i;
+ output [2:0] wbs8_cti_i;
+ output [1:0] wbs8_bte_i;
+ input [wbs_dat_width-1:0] wbs8_dat_o;
+ input wbs8_ack_o;
+ input wbs8_err_o;
+ input wbs8_rty_o;
+
+
+ // Wishbone Slave interface
+ output [wb_adr_width-1:0] wbs9_adr_i;
+ output [wbs_dat_width-1:0] wbs9_dat_i;
+ output wbs9_we_i;
+ output wbs9_cyc_i;
+ output wbs9_stb_i;
+ output [2:0] wbs9_cti_i;
+ output [1:0] wbs9_bte_i;
+ input [wbs_dat_width-1:0] wbs9_dat_o;
+ input wbs9_ack_o;
+ input wbs9_err_o;
+ input wbs9_rty_o;
+
+
+ // Wishbone Slave interface
+ output [wb_adr_width-1:0] wbs10_adr_i;
+ output [wbs_dat_width-1:0] wbs10_dat_i;
+ output wbs10_we_i;
+ output wbs10_cyc_i;
+ output wbs10_stb_i;
+ output [2:0] wbs10_cti_i;
+ output [1:0] wbs10_bte_i;
+ input [wbs_dat_width-1:0] wbs10_dat_o;
+ input wbs10_ack_o;
+ input wbs10_err_o;
+ input wbs10_rty_o;
+
+
+ // Wishbone Slave interface
+ output [wb_adr_width-1:0] wbs11_adr_i;
+ output [wbs_dat_width-1:0] wbs11_dat_i;
+ output wbs11_we_i;
+ output wbs11_cyc_i;
+ output wbs11_stb_i;
+ output [2:0] wbs11_cti_i;
+ output [1:0] wbs11_bte_i;
+ input [wbs_dat_width-1:0] wbs11_dat_o;
+ input wbs11_ack_o;
+ input wbs11_err_o;
+ input wbs11_rty_o;
+
+
+ // Wishbone Slave interface
+ output [wb_adr_width-1:0] wbs12_adr_i;
+ output [wbs_dat_width-1:0] wbs12_dat_i;
+ output wbs12_we_i;
+ output wbs12_cyc_i;
+ output wbs12_stb_i;
+ output [2:0] wbs12_cti_i;
+ output [1:0] wbs12_bte_i;
+ input [wbs_dat_width-1:0] wbs12_dat_o;
+ input wbs12_ack_o;
+ input wbs12_err_o;
+ input wbs12_rty_o;
+
+ // Wishbone Slave interface
+ output [wb_adr_width-1:0] wbs13_adr_i;
+ output [wbs_dat_width-1:0] wbs13_dat_i;
+ output wbs13_we_i;
+ output wbs13_cyc_i;
+ output wbs13_stb_i;
+ output [2:0] wbs13_cti_i;
+ output [1:0] wbs13_bte_i;
+ input [wbs_dat_width-1:0] wbs13_dat_o;
+ input wbs13_ack_o;
+ input wbs13_err_o;
+ input wbs13_rty_o;
+
+
+ // Wishbone Slave interface
+ output [wb_adr_width-1:0] wbs14_adr_i;
+ output [wbs_dat_width-1:0] wbs14_dat_i;
+ output wbs14_we_i;
+ output wbs14_cyc_i;
+ output wbs14_stb_i;
+ output [2:0] wbs14_cti_i;
+ output [1:0] wbs14_bte_i;
+ input [wbs_dat_width-1:0] wbs14_dat_o;
+ input wbs14_ack_o;
+ input wbs14_err_o;
+ input wbs14_rty_o;
+
+
+ // Wishbone Slave interface
+ output [wb_adr_width-1:0] wbs15_adr_i;
+ output [wbs_dat_width-1:0] wbs15_dat_i;
+ output wbs15_we_i;
+ output wbs15_cyc_i;
+ output wbs15_stb_i;
+ output [2:0] wbs15_cti_i;
+ output [1:0] wbs15_bte_i;
+ input [wbs_dat_width-1:0] wbs15_dat_o;
+ input wbs15_ack_o;
+ input wbs15_err_o;
+ input wbs15_rty_o;
+
+
+ // Wishbone Slave interface
+ output [wb_adr_width-1:0] wbs16_adr_i;
+ output [wbs_dat_width-1:0] wbs16_dat_i;
+ output wbs16_we_i;
+ output wbs16_cyc_i;
+ output wbs16_stb_i;
+ output [2:0] wbs16_cti_i;
+ output [1:0] wbs16_bte_i;
+ input [wbs_dat_width-1:0] wbs16_dat_o;
+ input wbs16_ack_o;
+ input wbs16_err_o;
+ input wbs16_rty_o;
+
+
+ // Wishbone Slave interface
+ output [wb_adr_width-1:0] wbs17_adr_i;
+ output [wbs_dat_width-1:0] wbs17_dat_i;
+ output wbs17_we_i;
+ output wbs17_cyc_i;
+ output wbs17_stb_i;
+ output [2:0] wbs17_cti_i;
+ output [1:0] wbs17_bte_i;
+ input [wbs_dat_width-1:0] wbs17_dat_o;
+ input wbs17_ack_o;
+ input wbs17_err_o;
+ input wbs17_rty_o;
+
+ // Wishbone Slave interface
+ output [wb_adr_width-1:0] wbs18_adr_i;
+ output [wbs_dat_width-1:0] wbs18_dat_i;
+ output wbs18_we_i;
+ output wbs18_cyc_i;
+ output wbs18_stb_i;
+ output [2:0] wbs18_cti_i;
+ output [1:0] wbs18_bte_i;
+ input [wbs_dat_width-1:0] wbs18_dat_o;
+ input wbs18_ack_o;
+ input wbs18_err_o;
+ input wbs18_rty_o;
+
+ // Wishbone Slave interface
+ output [wb_adr_width-1:0] wbs19_adr_i;
+ output [wbs_dat_width-1:0] wbs19_dat_i;
+ output wbs19_we_i;
+ output wbs19_cyc_i;
+ output wbs19_stb_i;
+ output [2:0] wbs19_cti_i;
+ output [1:0] wbs19_bte_i;
+ input [wbs_dat_width-1:0] wbs19_dat_o;
+ input wbs19_ack_o;
+ input wbs19_err_o;
+ input wbs19_rty_o;
+ */
+
+ reg watchdog_err;
+
+ // Master input mux output wires
+ wire [wb_adr_width-1:0] wbm_adr_o;
+ wire [wbs_dat_width-1:0] wbm_dat_o;
+ wire [3:0] wbm_sel_o;
+ wire wbm_we_o;
+ wire wbm_cyc_o;
+ wire wbm_stb_o;
+ wire [2:0] wbm_cti_o;
+ wire [1:0] wbm_bte_o;
+
+ wire [wbs_dat_width-1:0] wbm_dat_byte_i;
+ wire wbm_ack_i;
+ wire wbm_err_i;
+ wire wbm_rty_i;
+
+
+ // Master input mux (not really used, only one master on this bus)
+ assign wbm_adr_o = wbm0_adr_o;
+
+ // Select the right byte and put it on the data out line
+ // !BIG ENDIAN!
+ assign wbm_dat_o = wbm0_sel_o[3] ? wbm0_dat_o[31:24] :
+ wbm0_sel_o[2] ? wbm0_dat_o[23:16] :
+ wbm0_sel_o[1] ? wbm0_dat_o[15:8] :
+ wbm0_dat_o[7:0];
+
+ assign wbm_we_o = wbm0_we_o;
+
+ assign wbm_cyc_o = wbm0_stb_o;
+
+ assign wbm_stb_o = wbm0_stb_o;
+
+ // Will we really need these for byte-peripherals
+ assign wbm_cti_o = wbm0_cti_o;
+
+ assign wbm_bte_o = wbm0_bte_o;
+
+ // Signals back to the master
+ assign wbm0_dat_i = (wbm0_sel_o[3]) ? {wbm_dat_byte_i, 24'd0} :
+ (wbm0_sel_o[2]) ? {8'd0, wbm_dat_byte_i, 16'd0} :
+ (wbm0_sel_o[1]) ? {16'd0, wbm_dat_byte_i, 8'd0} :
+ {24'd0, wbm_dat_byte_i};
+
+ assign wbm0_ack_i = wbm_ack_i;
+ assign wbm0_err_i = wbm_err_i;
+ assign wbm0_rty_i = wbm_rty_i;
+
+`ifdef ARBITER_BYTEBUS_WATCHDOG
+ reg [`ARBITER_BYTEBUS_WATCHDOG_TIMER_WIDTH:0] watchdog_timer;
+ reg wbm_stb_r; // Register strobe
+ wire wbm_stb_edge; // Detect its edge
+
+ always @(posedge wb_clk)
+ wbm_stb_r <= wbm_stb_o;
+
+ assign wbm_stb_edge = (wbm_stb_o & !wbm_stb_r);
+
+ // Counter logic
+ always @(posedge wb_clk)
+ if (wb_rst) watchdog_timer <= 0;
+ else if (wbm_ack_i) // When we see an ack, turn off timer
+ watchdog_timer <= 0;
+ else if (wbm_stb_edge) // New access means start timer again
+ watchdog_timer <= 1;
+ else if (|watchdog_timer) // Continue counting if counter > 0
+ watchdog_timer <= watchdog_timer + 1;
+
+ always @(posedge wb_clk)
+ watchdog_err <= (&watchdog_timer);
+
+`else // !`ifdef ARBITER_BYTEBUS_WATCHDOG
+ always @(posedge wb_clk)
+ watchdog_err <= 0;
+
+`endif // !`ifdef ARBITER_BYTEBUS_WATCHDOG
+
+
+ // Wishbone slave mux out wires
+ wire [wb_adr_width-1:0] wbs_adr_i;
+ wire [wbs_dat_width-1:0] wbs_dat_i;
+ wire wbs_we_i;
+ wire wbs_cyc_i;
+ wire wbs_stb_i;
+ wire [2:0] wbs_cti_i;
+ wire [1:0] wbs_bte_i;
+ wire [wbs_dat_width-1:0] wbs_dat_o;
+ wire wbs_ack_o;
+ wire wbs_err_o;
+ wire wbs_rty_o;
+
+
+ // Slave select wire
+ wire [wb_num_slaves-1:0] wb_slave_sel;
+
+ // Slave out mux in wires
+ wire [wbs_dat_width-1:0] wbs_dat_o_mux_i [0:wb_num_slaves-1];
+ wire wbs_ack_o_mux_i [0:wb_num_slaves-1];
+ wire wbs_err_o_mux_i [0:wb_num_slaves-1];
+ wire wbs_rty_o_mux_i [0:wb_num_slaves-1];
+
+ // Slave selects
+ assign wb_slave_sel[0] = wbm_adr_o[`WB_ARB_ADDR_MATCH_SEL] == slave0_adr;
+ /*
+ assign wb_slave_sel[1] = wbm_adr_o[`WB_ARB_ADDR_MATCH_SEL] == slave1_adr;
+ assign wb_slave_sel[2] = wbm_adr_o[`WB_ARB_ADDR_MATCH_SEL] == slave2_adr;
+ assign wb_slave_sel[3] = wbm_adr_o[`WB_ARB_ADDR_MATCH_SEL] == slave3_adr;
+ assign wb_slave_sel[4] = wbm_adr_o[`WB_ARB_ADDR_MATCH_SEL] == slave4_adr;
+ assign wb_slave_sel[5] = wbm_adr_o[`WB_ARB_ADDR_MATCH_SEL] == slave5_adr;
+ assign wb_slave_sel[6] = wbm_adr_o[`WB_ARB_ADDR_MATCH_SEL] == slave6_adr;
+ assign wb_slave_sel[7] = wbm_adr_o[`WB_ARB_ADDR_MATCH_SEL] == slave7_adr;
+ assign wb_slave_sel[8] = wbm_adr_o[`WB_ARB_ADDR_MATCH_SEL] == slave8_adr;
+ assign wb_slave_sel[9] = wbm_adr_o[`WB_ARB_ADDR_MATCH_SEL] == slave9_adr;
+ assign wb_slave_sel[10] = wbm_adr_o[`WB_ARB_ADDR_MATCH_SEL] == slave10_adr;
+ assign wb_slave_sel[11] = wbm_adr_o[`WB_ARB_ADDR_MATCH_SEL] == slave11_adr;
+ assign wb_slave_sel[12] = wbm_adr_o[`WB_ARB_ADDR_MATCH_SEL] == slave12_adr;
+ assign wb_slave_sel[13] = wbm_adr_o[`WB_ARB_ADDR_MATCH_SEL] == slave13_adr;
+ assign wb_slave_sel[14] = wbm_adr_o[`WB_ARB_ADDR_MATCH_SEL] == slave14_adr;
+ assign wb_slave_sel[15] = wbm_adr_o[`WB_ARB_ADDR_MATCH_SEL] == slave15_adr;
+ assign wb_slave_sel[16] = wbm_adr_o[`WB_ARB_ADDR_MATCH_SEL] == slave16_adr;
+ assign wb_slave_sel[16] = wbm_adr_o[`WB_ARB_ADDR_MATCH_SEL] == slave17_adr;
+ assign wb_slave_sel[16] = wbm_adr_o[`WB_ARB_ADDR_MATCH_SEL] == slave18_adr;
+ assign wb_slave_sel[16] = wbm_adr_o[`WB_ARB_ADDR_MATCH_SEL] == slave19_adr;
+ */
+
+
+ // Assign master inputs to slaves and slave inputs for MUXing back to master
+
+ // Slave 0 inputs
+ assign wbs0_adr_i = wbm_adr_o;
+ assign wbs0_dat_i = wbm_dat_o;
+ assign wbs0_cyc_i = wbm_cyc_o & wb_slave_sel[0];
+ assign wbs0_stb_i = wbm_stb_o & wb_slave_sel[0];
+ assign wbs0_we_i = wbm_we_o;
+ assign wbs0_cti_i = wbm_cti_o;
+ assign wbs0_bte_i = wbm_bte_o;
+ assign wbs_dat_o_mux_i[0] = wbs0_dat_o;
+ assign wbs_ack_o_mux_i[0] = wbs0_ack_o & wb_slave_sel[0];
+ assign wbs_err_o_mux_i[0] = wbs0_err_o & wb_slave_sel[0];
+ assign wbs_rty_o_mux_i[0] = wbs0_rty_o & wb_slave_sel[0];
+
+ /*
+ // Slave 1 inputs
+ assign wbs1_adr_i = wbm_adr_o;
+ assign wbs1_dat_i = wbm_dat_o;
+ assign wbs1_cyc_i = wbm_cyc_o & wb_slave_sel[1];
+ assign wbs1_stb_i = wbm_stb_o & wb_slave_sel[1];
+ assign wbs1_we_i = wbm_we_o;
+ assign wbs1_cti_i = wbm_cti_o;
+ assign wbs1_bte_i = wbm_bte_o;
+ assign wbs_dat_o_mux_i[1] = wbs1_dat_o;
+ assign wbs_ack_o_mux_i[1] = wbs1_ack_o & wb_slave_sel[1];
+ assign wbs_err_o_mux_i[1] = wbs1_err_o & wb_slave_sel[1];
+ assign wbs_rty_o_mux_i[1] = wbs1_rty_o & wb_slave_sel[1];
+
+
+ // Slave 2 inputs
+ assign wbs2_adr_i = wbm_adr_o;
+ assign wbs2_dat_i = wbm_dat_o;
+ assign wbs2_cyc_i = wbm_cyc_o & wb_slave_sel[2];
+ assign wbs2_stb_i = wbm_stb_o & wb_slave_sel[2];
+ assign wbs2_we_i = wbm_we_o;
+ assign wbs2_cti_i = wbm_cti_o;
+ assign wbs2_bte_i = wbm_bte_o;
+ assign wbs_dat_o_mux_i[2] = wbs2_dat_o;
+ assign wbs_ack_o_mux_i[2] = wbs2_ack_o & wb_slave_sel[2];
+ assign wbs_err_o_mux_i[2] = wbs2_err_o & wb_slave_sel[2];
+ assign wbs_rty_o_mux_i[2] = wbs2_rty_o & wb_slave_sel[2];
+
+
+ // Slave 3 inputs
+ assign wbs3_adr_i = wbm_adr_o;
+ assign wbs3_dat_i = wbm_dat_o;
+ assign wbs3_cyc_i = wbm_cyc_o & wb_slave_sel[3];
+ assign wbs3_stb_i = wbm_stb_o & wb_slave_sel[3];
+ assign wbs3_we_i = wbm_we_o;
+ assign wbs3_cti_i = wbm_cti_o;
+ assign wbs3_bte_i = wbm_bte_o;
+ assign wbs_dat_o_mux_i[3] = wbs3_dat_o;
+ assign wbs_ack_o_mux_i[3] = wbs3_ack_o & wb_slave_sel[3];
+ assign wbs_err_o_mux_i[3] = wbs3_err_o & wb_slave_sel[3];
+ assign wbs_rty_o_mux_i[3] = wbs3_rty_o & wb_slave_sel[3];
+
+
+ // Slave 4 inputs
+ assign wbs4_adr_i = wbm_adr_o;
+ assign wbs4_dat_i = wbm_dat_o;
+ assign wbs4_cyc_i = wbm_cyc_o & wb_slave_sel[4];
+ assign wbs4_stb_i = wbm_stb_o & wb_slave_sel[4];
+ assign wbs4_we_i = wbm_we_o;
+ assign wbs4_cti_i = wbm_cti_o;
+ assign wbs4_bte_i = wbm_bte_o;
+ assign wbs_dat_o_mux_i[4] = wbs4_dat_o;
+ assign wbs_ack_o_mux_i[4] = wbs4_ack_o & wb_slave_sel[4];
+ assign wbs_err_o_mux_i[4] = wbs4_err_o & wb_slave_sel[4];
+ assign wbs_rty_o_mux_i[4] = wbs4_rty_o & wb_slave_sel[4];
+
+
+ // Slave 5 inputs
+ assign wbs5_adr_i = wbm_adr_o;
+ assign wbs5_dat_i = wbm_dat_o;
+ assign wbs5_cyc_i = wbm_cyc_o & wb_slave_sel[5];
+ assign wbs5_stb_i = wbm_stb_o & wb_slave_sel[5];
+ assign wbs5_we_i = wbm_we_o;
+ assign wbs5_cti_i = wbm_cti_o;
+ assign wbs5_bte_i = wbm_bte_o;
+ assign wbs_dat_o_mux_i[5] = wbs5_dat_o;
+ assign wbs_ack_o_mux_i[5] = wbs5_ack_o & wb_slave_sel[5];
+ assign wbs_err_o_mux_i[5] = wbs5_err_o & wb_slave_sel[5];
+ assign wbs_rty_o_mux_i[5] = wbs5_rty_o & wb_slave_sel[5];
+
+
+ // Slave 6 inputs
+ assign wbs6_adr_i = wbm_adr_o;
+ assign wbs6_dat_i = wbm_dat_o;
+ assign wbs6_cyc_i = wbm_cyc_o & wb_slave_sel[6];
+ assign wbs6_stb_i = wbm_stb_o & wb_slave_sel[6];
+ assign wbs6_we_i = wbm_we_o;
+ assign wbs6_cti_i = wbm_cti_o;
+ assign wbs6_bte_i = wbm_bte_o;
+ assign wbs_dat_o_mux_i[6] = wbs6_dat_o;
+ assign wbs_ack_o_mux_i[6] = wbs6_ack_o & wb_slave_sel[6];
+ assign wbs_err_o_mux_i[6] = wbs6_err_o & wb_slave_sel[6];
+ assign wbs_rty_o_mux_i[6] = wbs6_rty_o & wb_slave_sel[6];
+
+
+ // Slave 7 inputs
+ assign wbs7_adr_i = wbm_adr_o;
+ assign wbs7_dat_i = wbm_dat_o;
+ assign wbs7_cyc_i = wbm_cyc_o & wb_slave_sel[7];
+ assign wbs7_stb_i = wbm_stb_o & wb_slave_sel[7];
+ assign wbs7_we_i = wbm_we_o;
+ assign wbs7_cti_i = wbm_cti_o;
+ assign wbs7_bte_i = wbm_bte_o;
+ assign wbs_dat_o_mux_i[7] = wbs7_dat_o;
+ assign wbs_ack_o_mux_i[7] = wbs7_ack_o & wb_slave_sel[7];
+ assign wbs_err_o_mux_i[7] = wbs7_err_o & wb_slave_sel[7];
+ assign wbs_rty_o_mux_i[7] = wbs7_rty_o & wb_slave_sel[7];
+
+
+ // Slave 8 inputs
+ assign wbs8_adr_i = wbm_adr_o;
+ assign wbs8_dat_i = wbm_dat_o;
+ assign wbs8_cyc_i = wbm_cyc_o & wb_slave_sel[8];
+ assign wbs8_stb_i = wbm_stb_o & wb_slave_sel[8];
+ assign wbs8_we_i = wbm_we_o;
+ assign wbs8_cti_i = wbm_cti_o;
+ assign wbs8_bte_i = wbm_bte_o;
+ assign wbs_dat_o_mux_i[8] = wbs8_dat_o;
+ assign wbs_ack_o_mux_i[8] = wbs8_ack_o & wb_slave_sel[8];
+ assign wbs_err_o_mux_i[8] = wbs8_err_o & wb_slave_sel[8];
+ assign wbs_rty_o_mux_i[8] = wbs8_rty_o & wb_slave_sel[8];
+
+
+ // Slave 9 inputs
+ assign wbs9_adr_i = wbm_adr_o;
+ assign wbs9_dat_i = wbm_dat_o;
+ assign wbs9_cyc_i = wbm_cyc_o & wb_slave_sel[9];
+ assign wbs9_stb_i = wbm_stb_o & wb_slave_sel[9];
+ assign wbs9_we_i = wbm_we_o;
+ assign wbs9_cti_i = wbm_cti_o;
+ assign wbs9_bte_i = wbm_bte_o;
+ assign wbs_dat_o_mux_i[9] = wbs9_dat_o;
+ assign wbs_ack_o_mux_i[9] = wbs9_ack_o & wb_slave_sel[9];
+ assign wbs_err_o_mux_i[9] = wbs9_err_o & wb_slave_sel[9];
+ assign wbs_rty_o_mux_i[9] = wbs9_rty_o & wb_slave_sel[9];
+
+
+ // Slave 10 inputs
+ assign wbs10_adr_i = wbm_adr_o;
+ assign wbs10_dat_i = wbm_dat_o;
+ assign wbs10_cyc_i = wbm_cyc_o & wb_slave_sel[10];
+ assign wbs10_stb_i = wbm_stb_o & wb_slave_sel[10];
+ assign wbs10_we_i = wbm_we_o;
+ assign wbs10_cti_i = wbm_cti_o;
+ assign wbs10_bte_i = wbm_bte_o;
+ assign wbs_dat_o_mux_i[10] = wbs10_dat_o;
+ assign wbs_ack_o_mux_i[10] = wbs10_ack_o & wb_slave_sel[10];
+ assign wbs_err_o_mux_i[10] = wbs10_err_o & wb_slave_sel[10];
+ assign wbs_rty_o_mux_i[10] = wbs10_rty_o & wb_slave_sel[10];
+
+
+ // Slave 11 inputs
+ assign wbs11_adr_i = wbm_adr_o;
+ assign wbs11_dat_i = wbm_dat_o;
+ assign wbs11_cyc_i = wbm_cyc_o & wb_slave_sel[11];
+ assign wbs11_stb_i = wbm_stb_o & wb_slave_sel[11];
+ assign wbs11_we_i = wbm_we_o;
+ assign wbs11_cti_i = wbm_cti_o;
+ assign wbs11_bte_i = wbm_bte_o;
+ assign wbs_dat_o_mux_i[11] = wbs11_dat_o;
+ assign wbs_ack_o_mux_i[11] = wbs11_ack_o & wb_slave_sel[11];
+ assign wbs_err_o_mux_i[11] = wbs11_err_o & wb_slave_sel[11];
+ assign wbs_rty_o_mux_i[11] = wbs11_rty_o & wb_slave_sel[11];
+
+ // Slave 12 inputs
+ assign wbs12_adr_i = wbm_adr_o;
+ assign wbs12_dat_i = wbm_dat_o;
+ assign wbs12_cyc_i = wbm_cyc_o & wb_slave_sel[12];
+ assign wbs12_stb_i = wbm_stb_o & wb_slave_sel[12];
+ assign wbs12_we_i = wbm_we_o;
+ assign wbs12_cti_i = wbm_cti_o;
+ assign wbs12_bte_i = wbm_bte_o;
+ assign wbs_dat_o_mux_i[12] = wbs12_dat_o;
+ assign wbs_ack_o_mux_i[12] = wbs12_ack_o & wb_slave_sel[12];
+ assign wbs_err_o_mux_i[12] = wbs12_err_o & wb_slave_sel[12];
+ assign wbs_rty_o_mux_i[12] = wbs12_rty_o & wb_slave_sel[12];
+
+
+ // Slave 13 inputs
+ assign wbs13_adr_i = wbm_adr_o;
+ assign wbs13_dat_i = wbm_dat_o;
+ assign wbs13_cyc_i = wbm_cyc_o & wb_slave_sel[13];
+ assign wbs13_stb_i = wbm_stb_o & wb_slave_sel[13];
+ assign wbs13_we_i = wbm_we_o;
+ assign wbs13_cti_i = wbm_cti_o;
+ assign wbs13_bte_i = wbm_bte_o;
+ assign wbs_dat_o_mux_i[13] = wbs13_dat_o;
+ assign wbs_ack_o_mux_i[13] = wbs13_ack_o & wb_slave_sel[13];
+ assign wbs_err_o_mux_i[13] = wbs13_err_o & wb_slave_sel[13];
+ assign wbs_rty_o_mux_i[13] = wbs13_rty_o & wb_slave_sel[13];
+
+
+ // Slave 14 inputs
+ assign wbs14_adr_i = wbm_adr_o;
+ assign wbs14_dat_i = wbm_dat_o;
+ assign wbs14_cyc_i = wbm_cyc_o & wb_slave_sel[14];
+ assign wbs14_stb_i = wbm_stb_o & wb_slave_sel[14];
+ assign wbs14_we_i = wbm_we_o;
+ assign wbs14_cti_i = wbm_cti_o;
+ assign wbs14_bte_i = wbm_bte_o;
+ assign wbs_dat_o_mux_i[14] = wbs14_dat_o;
+ assign wbs_ack_o_mux_i[14] = wbs14_ack_o & wb_slave_sel[14];
+ assign wbs_err_o_mux_i[14] = wbs14_err_o & wb_slave_sel[14];
+ assign wbs_rty_o_mux_i[14] = wbs14_rty_o & wb_slave_sel[14];
+
+
+ // Slave 15 inputs
+ assign wbs15_adr_i = wbm_adr_o;
+ assign wbs15_dat_i = wbm_dat_o;
+ assign wbs15_cyc_i = wbm_cyc_o & wb_slave_sel[15];
+ assign wbs15_stb_i = wbm_stb_o & wb_slave_sel[15];
+ assign wbs15_we_i = wbm_we_o;
+ assign wbs15_cti_i = wbm_cti_o;
+ assign wbs15_bte_i = wbm_bte_o;
+ assign wbs_dat_o_mux_i[15] = wbs15_dat_o;
+ assign wbs_ack_o_mux_i[15] = wbs15_ack_o & wb_slave_sel[15];
+ assign wbs_err_o_mux_i[15] = wbs15_err_o & wb_slave_sel[15];
+ assign wbs_rty_o_mux_i[15] = wbs15_rty_o & wb_slave_sel[15];
+
+
+ // Slave 16 inputs
+ assign wbs16_adr_i = wbm_adr_o;
+ assign wbs16_dat_i = wbm_dat_o;
+ assign wbs16_cyc_i = wbm_cyc_o & wb_slave_sel[16];
+ assign wbs16_stb_i = wbm_stb_o & wb_slave_sel[16];
+ assign wbs16_we_i = wbm_we_o;
+ assign wbs16_cti_i = wbm_cti_o;
+ assign wbs16_bte_i = wbm_bte_o;
+ assign wbs_dat_o_mux_i[16] = wbs16_dat_o;
+ assign wbs_ack_o_mux_i[16] = wbs16_ack_o & wb_slave_sel[16];
+ assign wbs_err_o_mux_i[16] = wbs16_err_o & wb_slave_sel[16];
+ assign wbs_rty_o_mux_i[16] = wbs16_rty_o & wb_slave_sel[16];
+
+
+ // Slave 17 inputs
+ assign wbs17_adr_i = wbm_adr_o;
+ assign wbs17_dat_i = wbm_dat_o;
+ assign wbs17_cyc_i = wbm_cyc_o & wb_slave_sel[17];
+ assign wbs17_stb_i = wbm_stb_o & wb_slave_sel[17];
+ assign wbs17_we_i = wbm_we_o;
+ assign wbs17_cti_i = wbm_cti_o;
+ assign wbs17_bte_i = wbm_bte_o;
+ assign wbs_dat_o_mux_i[17] = wbs17_dat_o;
+ assign wbs_ack_o_mux_i[17] = wbs17_ack_o & wb_slave_sel[17];
+ assign wbs_err_o_mux_i[17] = wbs17_err_o & wb_slave_sel[17];
+ assign wbs_rty_o_mux_i[17] = wbs17_rty_o & wb_slave_sel[17];
+
+ // Slave 18 inputs
+ assign wbs18_adr_i = wbm_adr_o;
+ assign wbs18_dat_i = wbm_dat_o;
+ assign wbs18_cyc_i = wbm_cyc_o & wb_slave_sel[18];
+ assign wbs18_stb_i = wbm_stb_o & wb_slave_sel[18];
+ assign wbs18_we_i = wbm_we_o;
+ assign wbs18_cti_i = wbm_cti_o;
+ assign wbs18_bte_i = wbm_bte_o;
+ assign wbs_dat_o_mux_i[18] = wbs18_dat_o;
+ assign wbs_ack_o_mux_i[18] = wbs18_ack_o & wb_slave_sel[18];
+ assign wbs_err_o_mux_i[18] = wbs18_err_o & wb_slave_sel[18];
+ assign wbs_rty_o_mux_i[18] = wbs18_rty_o & wb_slave_sel[18];
+
+ // Slave 19 inputs
+ assign wbs19_adr_i = wbm_adr_o;
+ assign wbs19_dat_i = wbm_dat_o;
+ assign wbs19_cyc_i = wbm_cyc_o & wb_slave_sel[19];
+ assign wbs19_stb_i = wbm_stb_o & wb_slave_sel[19];
+ assign wbs19_we_i = wbm_we_o;
+ assign wbs19_cti_i = wbm_cti_o;
+ assign wbs19_bte_i = wbm_bte_o;
+ assign wbs_dat_o_mux_i[19] = wbs19_dat_o;
+ assign wbs_ack_o_mux_i[19] = wbs19_ack_o & wb_slave_sel[19];
+ assign wbs_err_o_mux_i[19] = wbs19_err_o & wb_slave_sel[19];
+ assign wbs_rty_o_mux_i[19] = wbs19_rty_o & wb_slave_sel[19];
+
+*/
+
+
+
+ // Master out mux from slave in data
+ assign wbm_dat_byte_i = wb_slave_sel[0] ? wbs_dat_o_mux_i[0] :
+/*
+ wb_slave_sel[1] ? wbs_dat_o_mux_i[1] :
+ wb_slave_sel[2] ? wbs_dat_o_mux_i[2] :
+ wb_slave_sel[3] ? wbs_dat_o_mux_i[3] :
+ wb_slave_sel[4] ? wbs_dat_o_mux_i[4] :
+ wb_slave_sel[5] ? wbs_dat_o_mux_i[5] :
+ wb_slave_sel[6] ? wbs_dat_o_mux_i[6] :
+ wb_slave_sel[7] ? wbs_dat_o_mux_i[7] :
+ wb_slave_sel[8] ? wbs_dat_o_mux_i[8] :
+ wb_slave_sel[9] ? wbs_dat_o_mux_i[9] :
+ wb_slave_sel[10] ? wbs_dat_o_mux_i[10] :
+ wb_slave_sel[11] ? wbs_dat_o_mux_i[11] :
+ wb_slave_sel[12] ? wbs_dat_o_mux_i[12] :
+ wb_slave_sel[13] ? wbs_dat_o_mux_i[13] :
+ wb_slave_sel[14] ? wbs_dat_o_mux_i[14] :
+ wb_slave_sel[15] ? wbs_dat_o_mux_i[15] :
+ wb_slave_sel[16] ? wbs_dat_o_mux_i[16] :
+ wb_slave_sel[17] ? wbs_dat_o_mux_i[17] :
+ wb_slave_sel[18] ? wbs_dat_o_mux_i[18] :
+ wb_slave_sel[19] ? wbs_dat_o_mux_i[19] :
+*/
+ wbs_dat_o_mux_i[0];
+ // Master out acks, or together
+ assign wbm_ack_i = wbs_ack_o_mux_i[0] /* |
+ wbs_ack_o_mux_i[1] |
+ wbs_ack_o_mux_i[2] |
+ wbs_ack_o_mux_i[3] |
+ wbs_ack_o_mux_i[4] |
+ wbs_ack_o_mux_i[5] |
+ wbs_ack_o_mux_i[6] |
+ wbs_ack_o_mux_i[7] |
+ wbs_ack_o_mux_i[8] |
+ wbs_ack_o_mux_i[9] |
+ wbs_ack_o_mux_i[10] |
+ wbs_ack_o_mux_i[11] |
+ wbs_ack_o_mux_i[12] |
+ wbs_ack_o_mux_i[13] |
+ wbs_ack_o_mux_i[14] |
+ wbs_ack_o_mux_i[15] |
+ wbs_ack_o_mux_i[16] |
+ wbs_ack_o_mux_i[17] |
+ wbs_ack_o_mux_i[18] |
+ wbs_ack_o_mux_i[19]
+ */
+ ;
+
+
+ assign wbm_err_i = wbs_err_o_mux_i[0] |/*
+ wbs_err_o_mux_i[1] |
+ wbs_err_o_mux_i[2] |
+ wbs_err_o_mux_i[3] |
+ wbs_err_o_mux_i[4] |
+ wbs_err_o_mux_i[5] |
+ wbs_err_o_mux_i[6] |
+ wbs_err_o_mux_i[7] |
+ wbs_err_o_mux_i[8] |
+ wbs_err_o_mux_i[9] |
+ wbs_err_o_mux_i[10] |
+ wbs_err_o_mux_i[11] |
+ wbs_err_o_mux_i[12] |
+ wbs_err_o_mux_i[13] |
+ wbs_err_o_mux_i[14] |
+ wbs_err_o_mux_i[15] |
+ wbs_err_o_mux_i[16] |
+ wbs_err_o_mux_i[17] |
+ wbs_err_o_mux_i[18] |
+ wbs_err_o_mux_i[19] |
+ */
+ watchdog_err ;
+
+
+ assign wbm_rty_i = wbs_rty_o_mux_i[0] /*|
+ wbs_rty_o_mux_i[1] |
+ wbs_rty_o_mux_i[2] |
+ wbs_rty_o_mux_i[3] |
+ wbs_rty_o_mux_i[4] |
+ wbs_rty_o_mux_i[5] |
+ wbs_rty_o_mux_i[6] |
+ wbs_rty_o_mux_i[7] |
+ wbs_rty_o_mux_i[8] |
+ wbs_rty_o_mux_i[9] |
+ wbs_rty_o_mux_i[10] |
+ wbs_rty_o_mux_i[11] |
+ wbs_rty_o_mux_i[12] |
+ wbs_rty_o_mux_i[13] |
+ wbs_rty_o_mux_i[14] |
+ wbs_rty_o_mux_i[15] |
+ wbs_rty_o_mux_i[16] |
+ wbs_rty_o_mux_i[17] |
+ wbs_rty_o_mux_i[18] |
+ wbs_rty_o_mux_i[19]
+ */
+ ;
+
+endmodule // arbiter_bytebus
Index: boards/generic/ft/rtl/verilog/arbiter/arbiter_dbus.v
===================================================================
--- boards/generic/ft/rtl/verilog/arbiter/arbiter_dbus.v (nonexistent)
+++ boards/generic/ft/rtl/verilog/arbiter/arbiter_dbus.v (revision 483)
@@ -0,0 +1,1267 @@
+//////////////////////////////////////////////////////////////////////
+/// ////
+/// Wishbone arbiter, burst-compatible ////
+/// ////
+/// Simple arbiter, multi-master, multi-slave with default slave ////
+/// for chaining with peripheral arbiter ////
+/// ////
+/// Julius Baxter, julius@opencores.org ////
+/// ////
+//////////////////////////////////////////////////////////////////////
+//// ////
+//// Copyright (C) 2009, 2010 Authors and OPENCORES.ORG ////
+//// ////
+//// This source file may be used and distributed without ////
+//// restriction provided that this copyright statement is not ////
+//// removed from the file and that any derivative work contains ////
+//// the original copyright notice and the associated disclaimer. ////
+//// ////
+//// This source file is free software; you can redistribute it ////
+//// and/or modify it under the terms of the GNU Lesser General ////
+//// Public License as published by the Free Software Foundation; ////
+//// either version 2.1 of the License, or (at your option) any ////
+//// later version. ////
+//// ////
+//// This source is distributed in the hope that it will be ////
+//// useful, but WITHOUT ANY WARRANTY; without even the implied ////
+//// warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR ////
+//// PURPOSE. See the GNU Lesser General Public License for more ////
+//// details. ////
+//// ////
+//// You should have received a copy of the GNU Lesser General ////
+//// Public License along with this source; if not, download it ////
+//// from http://www.opencores.org/lgpl.shtml ////
+//// ////
+//////////////////////////////////////////////////////////////////////
+`include "orpsoc-defines.v"
+// 2 Masters, a few slaves
+module arbiter_dbus
+ (
+ // or1200 data master
+ // Wishbone Master interface
+ wbm0_adr_o,
+ wbm0_dat_o,
+ wbm0_sel_o,
+ wbm0_we_o,
+ wbm0_cyc_o,
+ wbm0_stb_o,
+ wbm0_cti_o,
+ wbm0_bte_o,
+
+ wbm0_dat_i,
+ wbm0_ack_i,
+ wbm0_err_i,
+ wbm0_rty_i,
+
+ // or1200 debug master
+ // Wishbone Master interface
+ wbm1_adr_o,
+ wbm1_dat_o,
+ wbm1_sel_o,
+ wbm1_we_o,
+ wbm1_cyc_o,
+ wbm1_stb_o,
+ wbm1_cti_o,
+ wbm1_bte_o,
+
+ wbm1_dat_i,
+ wbm1_ack_i,
+ wbm1_err_i,
+ wbm1_rty_i,
+
+ // Slave one
+ // Wishbone Slave interface
+ wbs0_adr_i,
+ wbs0_dat_i,
+ wbs0_sel_i,
+ wbs0_we_i,
+ wbs0_cyc_i,
+ wbs0_stb_i,
+ wbs0_cti_i,
+ wbs0_bte_i,
+
+ wbs0_dat_o,
+ wbs0_ack_o,
+ wbs0_err_o,
+ wbs0_rty_o,
+
+ // Slave two
+ // Wishbone Slave interface
+ wbs1_adr_i,
+ wbs1_dat_i,
+ wbs1_sel_i,
+ wbs1_we_i,
+ wbs1_cyc_i,
+ wbs1_stb_i,
+ wbs1_cti_i,
+ wbs1_bte_i,
+
+ wbs1_dat_o,
+ wbs1_ack_o,
+ wbs1_err_o,
+ wbs1_rty_o,
+
+ /*
+ // Slave three
+ // Wishbone Slave interface
+ wbs2_adr_i,
+ wbs2_dat_i,
+ wbs2_sel_i,
+ wbs2_we_i,
+ wbs2_cyc_i,
+ wbs2_stb_i,
+ wbs2_cti_i,
+ wbs2_bte_i,
+
+ wbs2_dat_o,
+ wbs2_ack_o,
+ wbs2_err_o,
+ wbs2_rty_o,
+
+ // Slave four
+ // Wishbone Slave interface
+ wbs3_adr_i,
+ wbs3_dat_i,
+ wbs3_sel_i,
+ wbs3_we_i,
+ wbs3_cyc_i,
+ wbs3_stb_i,
+ wbs3_cti_i,
+ wbs3_bte_i,
+
+ wbs3_dat_o,
+ wbs3_ack_o,
+ wbs3_err_o,
+ wbs3_rty_o,
+
+ // Slave five
+ // Wishbone Slave interface
+ wbs4_adr_i,
+ wbs4_dat_i,
+ wbs4_sel_i,
+ wbs4_we_i,
+ wbs4_cyc_i,
+ wbs4_stb_i,
+ wbs4_cti_i,
+ wbs4_bte_i,
+
+ wbs4_dat_o,
+ wbs4_ack_o,
+ wbs4_err_o,
+ wbs4_rty_o,
+
+ // Slave six
+ // Wishbone Slave interface
+ wbs5_adr_i,
+ wbs5_dat_i,
+ wbs5_sel_i,
+ wbs5_we_i,
+ wbs5_cyc_i,
+ wbs5_stb_i,
+ wbs5_cti_i,
+ wbs5_bte_i,
+
+ wbs5_dat_o,
+ wbs5_ack_o,
+ wbs5_err_o,
+ wbs5_rty_o,
+
+ // Slave seven
+ // Wishbone Slave interface
+ wbs6_adr_i,
+ wbs6_dat_i,
+ wbs6_sel_i,
+ wbs6_we_i,
+ wbs6_cyc_i,
+ wbs6_stb_i,
+ wbs6_cti_i,
+ wbs6_bte_i,
+
+ wbs6_dat_o,
+ wbs6_ack_o,
+ wbs6_err_o,
+ wbs6_rty_o,
+
+ // Slave eight
+ // Wishbone Slave interface
+ wbs7_adr_i,
+ wbs7_dat_i,
+ wbs7_sel_i,
+ wbs7_we_i,
+ wbs7_cyc_i,
+ wbs7_stb_i,
+ wbs7_cti_i,
+ wbs7_bte_i,
+
+ wbs7_dat_o,
+ wbs7_ack_o,
+ wbs7_err_o,
+ wbs7_rty_o,
+
+ // Slave nine
+ // Wishbone Slave interface
+ wbs8_adr_i,
+ wbs8_dat_i,
+ wbs8_sel_i,
+ wbs8_we_i,
+ wbs8_cyc_i,
+ wbs8_stb_i,
+ wbs8_cti_i,
+ wbs8_bte_i,
+
+ wbs8_dat_o,
+ wbs8_ack_o,
+ wbs8_err_o,
+ wbs8_rty_o,
+
+ // Slave ten
+ // Wishbone Slave interface
+ wbs9_adr_i,
+ wbs9_dat_i,
+ wbs9_sel_i,
+ wbs9_we_i,
+ wbs9_cyc_i,
+ wbs9_stb_i,
+ wbs9_cti_i,
+ wbs9_bte_i,
+
+ wbs9_dat_o,
+ wbs9_ack_o,
+ wbs9_err_o,
+ wbs9_rty_o,
+
+ // Slave eleven
+ // Wishbone Slave interface
+ wbs10_adr_i,
+ wbs10_dat_i,
+ wbs10_sel_i,
+ wbs10_we_i,
+ wbs10_cyc_i,
+ wbs10_stb_i,
+ wbs10_cti_i,
+ wbs10_bte_i,
+
+ wbs10_dat_o,
+ wbs10_ack_o,
+ wbs10_err_o,
+ wbs10_rty_o,
+
+ // Slave twelve
+ // Wishbone Slave interface
+ wbs11_adr_i,
+ wbs11_dat_i,
+ wbs11_sel_i,
+ wbs11_we_i,
+ wbs11_cyc_i,
+ wbs11_stb_i,
+ wbs11_cti_i,
+ wbs11_bte_i,
+
+ wbs11_dat_o,
+ wbs11_ack_o,
+ wbs11_err_o,
+ wbs11_rty_o,
+
+ // Slave thirteen
+ // Wishbone Slave interface
+ wbs12_adr_i,
+ wbs12_dat_i,
+ wbs12_sel_i,
+ wbs12_we_i,
+ wbs12_cyc_i,
+ wbs12_stb_i,
+ wbs12_cti_i,
+ wbs12_bte_i,
+
+ wbs12_dat_o,
+ wbs12_ack_o,
+ wbs12_err_o,
+ wbs12_rty_o,
+
+ // Slave fourteen
+ // Wishbone Slave interface
+ wbs13_adr_i,
+ wbs13_dat_i,
+ wbs13_sel_i,
+ wbs13_we_i,
+ wbs13_cyc_i,
+ wbs13_stb_i,
+ wbs13_cti_i,
+ wbs13_bte_i,
+
+ wbs13_dat_o,
+ wbs13_ack_o,
+ wbs13_err_o,
+ wbs13_rty_o,
+
+ // Slave fifteen
+ // Wishbone Slave interface
+ wbs14_adr_i,
+ wbs14_dat_i,
+ wbs14_sel_i,
+ wbs14_we_i,
+ wbs14_cyc_i,
+ wbs14_stb_i,
+ wbs14_cti_i,
+ wbs14_bte_i,
+
+ wbs14_dat_o,
+ wbs14_ack_o,
+ wbs14_err_o,
+ wbs14_rty_o,
+
+ // Slave sixteen
+ // Wishbone Slave interface
+ wbs15_adr_i,
+ wbs15_dat_i,
+ wbs15_sel_i,
+ wbs15_we_i,
+ wbs15_cyc_i,
+ wbs15_stb_i,
+ wbs15_cti_i,
+ wbs15_bte_i,
+
+ wbs15_dat_o,
+ wbs15_ack_o,
+ wbs15_err_o,
+ wbs15_rty_o,
+
+ // Slave seventeen
+ // Wishbone Slave interface
+ wbs16_adr_i,
+ wbs16_dat_i,
+ wbs16_sel_i,
+ wbs16_we_i,
+ wbs16_cyc_i,
+ wbs16_stb_i,
+ wbs16_cti_i,
+ wbs16_bte_i,
+
+ wbs16_dat_o,
+ wbs16_ack_o,
+ wbs16_err_o,
+ wbs16_rty_o,
+ */
+
+ wb_clk,
+ wb_rst
+ );
+
+ parameter wb_dat_width = 32;
+ parameter wb_adr_width = 32;
+
+ parameter wb_addr_match_width = 8;
+
+ parameter wb_num_slaves = 2; // must also (un)comment things if changing
+
+ // Slave addresses - these should be defparam'd from top level
+ // Declare them as you need them
+ parameter slave0_adr = 0;
+ parameter slave1_adr = 0;
+ parameter slave2_adr = 0;
+ parameter slave3_adr = 0;
+ parameter slave4_adr = 0;
+ parameter slave5_adr = 0;
+ parameter slave6_adr = 0;
+ parameter slave7_adr = 0;
+ parameter slave8_adr = 0;
+ parameter slave9_adr = 0;
+ parameter slave10_adr = 0;
+ parameter slave11_adr = 0;
+ parameter slave12_adr = 0;
+
+ // Select for slave 0
+`define WB_ARB_ADDR_MATCH_SEL_SLAVE0 wb_adr_width-1:wb_adr_width-4
+`define WB_ARB_ADDR_MATCH_SEL wb_adr_width-1:wb_adr_width-wb_addr_match_width
+
+ input wb_clk;
+ input wb_rst;
+
+ // WB Master one
+ input [wb_adr_width-1:0] wbm0_adr_o;
+ input [wb_dat_width-1:0] wbm0_dat_o;
+ input [3:0] wbm0_sel_o;
+ input wbm0_we_o;
+ input wbm0_cyc_o;
+ input wbm0_stb_o;
+ input [2:0] wbm0_cti_o;
+ input [1:0] wbm0_bte_o;
+ output [wb_dat_width-1:0] wbm0_dat_i;
+ output wbm0_ack_i;
+ output wbm0_err_i;
+ output wbm0_rty_i;
+
+
+ input [wb_adr_width-1:0] wbm1_adr_o;
+ input [wb_dat_width-1:0] wbm1_dat_o;
+ input [3:0] wbm1_sel_o;
+ input wbm1_we_o;
+ input wbm1_cyc_o;
+ input wbm1_stb_o;
+ input [2:0] wbm1_cti_o;
+ input [1:0] wbm1_bte_o;
+ output [wb_dat_width-1:0] wbm1_dat_i;
+ output wbm1_ack_i;
+ output wbm1_err_i;
+ output wbm1_rty_i;
+
+
+ // Slave one
+ // Wishbone Slave interface
+ output [wb_adr_width-1:0] wbs0_adr_i;
+ output [wb_dat_width-1:0] wbs0_dat_i;
+ output [3:0] wbs0_sel_i;
+ output wbs0_we_i;
+ output wbs0_cyc_i;
+ output wbs0_stb_i;
+ output [2:0] wbs0_cti_i;
+ output [1:0] wbs0_bte_i;
+ input [wb_dat_width-1:0] wbs0_dat_o;
+ input wbs0_ack_o;
+ input wbs0_err_o;
+ input wbs0_rty_o;
+
+
+ // Wishbone Slave interface
+ output [wb_adr_width-1:0] wbs1_adr_i;
+ output [wb_dat_width-1:0] wbs1_dat_i;
+ output [3:0] wbs1_sel_i;
+ output wbs1_we_i;
+ output wbs1_cyc_i;
+ output wbs1_stb_i;
+ output [2:0] wbs1_cti_i;
+ output [1:0] wbs1_bte_i;
+ input [wb_dat_width-1:0] wbs1_dat_o;
+ input wbs1_ack_o;
+ input wbs1_err_o;
+ input wbs1_rty_o;
+
+/*
+ // Wishbone Slave interface
+ output [wb_adr_width-1:0] wbs2_adr_i;
+ output [wb_dat_width-1:0] wbs2_dat_i;
+ output [3:0] wbs2_sel_i;
+ output wbs2_we_i;
+ output wbs2_cyc_i;
+ output wbs2_stb_i;
+ output [2:0] wbs2_cti_i;
+ output [1:0] wbs2_bte_i;
+ input [wb_dat_width-1:0] wbs2_dat_o;
+ input wbs2_ack_o;
+ input wbs2_err_o;
+ input wbs2_rty_o;
+
+
+ // Wishbone Slave interface
+ output [wb_adr_width-1:0] wbs3_adr_i;
+ output [wb_dat_width-1:0] wbs3_dat_i;
+ output [3:0] wbs3_sel_i;
+ output wbs3_we_i;
+ output wbs3_cyc_i;
+ output wbs3_stb_i;
+ output [2:0] wbs3_cti_i;
+ output [1:0] wbs3_bte_i;
+ input [wb_dat_width-1:0] wbs3_dat_o;
+ input wbs3_ack_o;
+ input wbs3_err_o;
+ input wbs3_rty_o;
+
+
+ // Wishbone Slave interface
+ output [wb_adr_width-1:0] wbs4_adr_i;
+ output [wb_dat_width-1:0] wbs4_dat_i;
+ output [3:0] wbs4_sel_i;
+ output wbs4_we_i;
+ output wbs4_cyc_i;
+ output wbs4_stb_i;
+ output [2:0] wbs4_cti_i;
+ output [1:0] wbs4_bte_i;
+ input [wb_dat_width-1:0] wbs4_dat_o;
+ input wbs4_ack_o;
+ input wbs4_err_o;
+ input wbs4_rty_o;
+
+
+ // Wishbone Slave interface
+ output [wb_adr_width-1:0] wbs5_adr_i;
+ output [wb_dat_width-1:0] wbs5_dat_i;
+ output [3:0] wbs5_sel_i;
+ output wbs5_we_i;
+ output wbs5_cyc_i;
+ output wbs5_stb_i;
+ output [2:0] wbs5_cti_i;
+ output [1:0] wbs5_bte_i;
+ input [wb_dat_width-1:0] wbs5_dat_o;
+ input wbs5_ack_o;
+ input wbs5_err_o;
+ input wbs5_rty_o;
+
+
+ // Wishbone Slave interface
+ output [wb_adr_width-1:0] wbs6_adr_i;
+ output [wb_dat_width-1:0] wbs6_dat_i;
+ output [3:0] wbs6_sel_i;
+ output wbs6_we_i;
+ output wbs6_cyc_i;
+ output wbs6_stb_i;
+ output [2:0] wbs6_cti_i;
+ output [1:0] wbs6_bte_i;
+ input [wb_dat_width-1:0] wbs6_dat_o;
+ input wbs6_ack_o;
+ input wbs6_err_o;
+ input wbs6_rty_o;
+
+
+ // Wishbone Slave interface
+ output [wb_adr_width-1:0] wbs7_adr_i;
+ output [wb_dat_width-1:0] wbs7_dat_i;
+ output [3:0] wbs7_sel_i;
+ output wbs7_we_i;
+ output wbs7_cyc_i;
+ output wbs7_stb_i;
+ output [2:0] wbs7_cti_i;
+ output [1:0] wbs7_bte_i;
+ input [wb_dat_width-1:0] wbs7_dat_o;
+ input wbs7_ack_o;
+ input wbs7_err_o;
+ input wbs7_rty_o;
+
+
+ // Wishbone Slave interface
+ output [wb_adr_width-1:0] wbs8_adr_i;
+ output [wb_dat_width-1:0] wbs8_dat_i;
+ output [3:0] wbs8_sel_i;
+ output wbs8_we_i;
+ output wbs8_cyc_i;
+ output wbs8_stb_i;
+ output [2:0] wbs8_cti_i;
+ output [1:0] wbs8_bte_i;
+ input [wb_dat_width-1:0] wbs8_dat_o;
+ input wbs8_ack_o;
+ input wbs8_err_o;
+ input wbs8_rty_o;
+
+
+ // Wishbone Slave interface
+ output [wb_adr_width-1:0] wbs9_adr_i;
+ output [wb_dat_width-1:0] wbs9_dat_i;
+ output [3:0] wbs9_sel_i;
+ output wbs9_we_i;
+ output wbs9_cyc_i;
+ output wbs9_stb_i;
+ output [2:0] wbs9_cti_i;
+ output [1:0] wbs9_bte_i;
+ input [wb_dat_width-1:0] wbs9_dat_o;
+ input wbs9_ack_o;
+ input wbs9_err_o;
+ input wbs9_rty_o;
+
+
+ // Wishbone Slave interface
+ output [wb_adr_width-1:0] wbs10_adr_i;
+ output [wb_dat_width-1:0] wbs10_dat_i;
+ output [3:0] wbs10_sel_i;
+ output wbs10_we_i;
+ output wbs10_cyc_i;
+ output wbs10_stb_i;
+ output [2:0] wbs10_cti_i;
+ output [1:0] wbs10_bte_i;
+ input [wb_dat_width-1:0] wbs10_dat_o;
+ input wbs10_ack_o;
+ input wbs10_err_o;
+ input wbs10_rty_o;
+
+
+ // Wishbone Slave interface
+ output [wb_adr_width-1:0] wbs11_adr_i;
+ output [wb_dat_width-1:0] wbs11_dat_i;
+ output [3:0] wbs11_sel_i;
+ output wbs11_we_i;
+ output wbs11_cyc_i;
+ output wbs11_stb_i;
+ output [2:0] wbs11_cti_i;
+ output [1:0] wbs11_bte_i;
+ input [wb_dat_width-1:0] wbs11_dat_o;
+ input wbs11_ack_o;
+ input wbs11_err_o;
+ input wbs11_rty_o;
+
+
+ // Wishbone Slave interface
+ output [wb_adr_width-1:0] wbs12_adr_i;
+ output [wb_dat_width-1:0] wbs12_dat_i;
+ output [3:0] wbs12_sel_i;
+ output wbs12_we_i;
+ output wbs12_cyc_i;
+ output wbs12_stb_i;
+ output [2:0] wbs12_cti_i;
+ output [1:0] wbs12_bte_i;
+ input [wb_dat_width-1:0] wbs12_dat_o;
+ input wbs12_ack_o;
+ input wbs12_err_o;
+ input wbs12_rty_o;
+
+
+ // Wishbone Slave interface
+ output [wb_adr_width-1:0] wbs13_adr_i;
+ output [wb_dat_width-1:0] wbs13_dat_i;
+ output [3:0] wbs13_sel_i;
+ output wbs13_we_i;
+ output wbs13_cyc_i;
+ output wbs13_stb_i;
+ output [2:0] wbs13_cti_i;
+ output [1:0] wbs13_bte_i;
+ input [wb_dat_width-1:0] wbs13_dat_o;
+ input wbs13_ack_o;
+ input wbs13_err_o;
+ input wbs13_rty_o;
+
+
+ // Wishbone Slave interface
+ output [wb_adr_width-1:0] wbs14_adr_i;
+ output [wb_dat_width-1:0] wbs14_dat_i;
+ output [3:0] wbs14_sel_i;
+ output wbs14_we_i;
+ output wbs14_cyc_i;
+ output wbs14_stb_i;
+ output [2:0] wbs14_cti_i;
+ output [1:0] wbs14_bte_i;
+ input [wb_dat_width-1:0] wbs14_dat_o;
+ input wbs14_ack_o;
+ input wbs14_err_o;
+ input wbs14_rty_o;
+
+
+ // Wishbone Slave interface
+ output [wb_adr_width-1:0] wbs15_adr_i;
+ output [wb_dat_width-1:0] wbs15_dat_i;
+ output [3:0] wbs15_sel_i;
+ output wbs15_we_i;
+ output wbs15_cyc_i;
+ output wbs15_stb_i;
+ output [2:0] wbs15_cti_i;
+ output [1:0] wbs15_bte_i;
+ input [wb_dat_width-1:0] wbs15_dat_o;
+ input wbs15_ack_o;
+ input wbs15_err_o;
+ input wbs15_rty_o;
+
+
+ // Wishbone Slave interface
+ output [wb_adr_width-1:0] wbs16_adr_i;
+ output [wb_dat_width-1:0] wbs16_dat_i;
+ output [3:0] wbs16_sel_i;
+ output wbs16_we_i;
+ output wbs16_cyc_i;
+ output wbs16_stb_i;
+ output [2:0] wbs16_cti_i;
+ output [1:0] wbs16_bte_i;
+ input [wb_dat_width-1:0] wbs16_dat_o;
+ input wbs16_ack_o;
+ input wbs16_err_o;
+ input wbs16_rty_o;
+
+*/
+
+ reg watchdog_err;
+
+`ifdef ARBITER_DBUS_REGISTERING
+
+
+ // Registering setup:
+ // Masters typically register their outputs, so do the master selection and
+ // muxing before registering in the arbiter. Keep the common parts outside
+ // for code brevity.
+
+ // Master ins -> |MUX> -> these wires
+ wire [wb_adr_width-1:0] wbm_adr_o_w;
+ wire [wb_dat_width-1:0] wbm_dat_o_w;
+ wire [3:0] wbm_sel_o_w;
+ wire wbm_we_o_w;
+ wire wbm_cyc_o_w;
+ wire wbm_stb_o_w;
+ wire [2:0] wbm_cti_o_w;
+ wire [1:0] wbm_bte_o_w;
+ // Slave ins -> |MUX> -> these wires
+ wire [wb_dat_width-1:0] wbm_dat_i;
+ wire wbm_ack_i;
+ wire wbm_err_i;
+ wire wbm_rty_i;
+
+ // Registers after masters input mux
+ reg [wb_adr_width-1:0] wbm_adr_o_r;
+ reg [wb_dat_width-1:0] wbm_dat_o_r;
+ reg [3:0] wbm_sel_o_r;
+ reg wbm_we_o_r;
+ reg wbm_cyc_o_r;
+ reg wbm_stb_o_r;
+ reg [2:0] wbm_cti_o_r;
+ reg [1:0] wbm_bte_o_r;
+
+ // Master input mux register wires
+ wire [wb_adr_width-1:0] wbm_adr_o;
+ wire [wb_dat_width-1:0] wbm_dat_o;
+ wire [3:0] wbm_sel_o;
+ wire wbm_we_o;
+ wire wbm_cyc_o;
+ wire wbm_stb_o;
+ wire [2:0] wbm_cti_o;
+ wire [1:0] wbm_bte_o;
+
+ // Registers after slaves input mux
+ reg [wb_dat_width-1:0] wbm_dat_i_r;
+ reg wbm_ack_i_r;
+ reg wbm_err_i_r;
+ reg wbm_rty_i_r;
+
+ // Master select (MUX controls)
+ wire [1:0] master_sel;
+ // priority to wbm1, the debug master
+ assign master_sel[0] = wbm0_cyc_o & !wbm1_cyc_o;
+ assign master_sel[1] = wbm1_cyc_o;
+
+
+ // Master input mux, priority to debug master
+ assign wbm_adr_o_w = master_sel[1] ? wbm1_adr_o :
+ wbm0_adr_o;
+
+ assign wbm_dat_o_w = master_sel[1] ? wbm1_dat_o :
+ wbm0_dat_o;
+
+ assign wbm_sel_o_w = master_sel[1] ? wbm1_sel_o :
+ wbm0_sel_o;
+
+ assign wbm_we_o_w = master_sel[1] ? wbm1_we_o :
+ wbm0_we_o;
+
+ assign wbm_cyc_o_w = master_sel[1] ? wbm1_cyc_o :
+ wbm0_cyc_o;
+
+ assign wbm_stb_o_w = master_sel[1] ? wbm1_stb_o :
+ wbm0_stb_o;
+
+ assign wbm_cti_o_w = master_sel[1] ? wbm1_cti_o :
+ wbm0_cti_o;
+
+ assign wbm_bte_o_w = master_sel[1] ? wbm1_bte_o :
+ wbm0_bte_o;
+
+
+ // Register muxed master signals
+ always @(posedge wb_clk)
+ begin
+ wbm_adr_o_r <= wbm_adr_o_w;
+ wbm_dat_o_r <= wbm_dat_o_w;
+ wbm_sel_o_r <= wbm_sel_o_w;
+ wbm_we_o_r <= wbm_we_o_w;
+ wbm_cyc_o_r <= wbm_cyc_o_w;
+ wbm_stb_o_r <= wbm_stb_o_w & !wbm_ack_i & !wbm_ack_i_r;
+ wbm_cti_o_r <= wbm_cti_o_w;
+ wbm_bte_o_r <= wbm_bte_o_w;
+
+ wbm_dat_i_r <= wbm_dat_i;
+ wbm_ack_i_r <= wbm_ack_i;
+ wbm_err_i_r <= wbm_err_i;
+ wbm_rty_i_r <= wbm_rty_i;
+ end // always @ (posedge wb_clk)
+
+
+ assign wbm_adr_o = wbm_adr_o_r;
+ assign wbm_dat_o = wbm_dat_o_r;
+ assign wbm_sel_o = wbm_sel_o_r;
+ assign wbm_we_o = wbm_we_o_r;
+ assign wbm_cyc_o = wbm_cyc_o_r;
+ assign wbm_stb_o = wbm_stb_o_r;
+ assign wbm_cti_o = wbm_cti_o_r;
+ assign wbm_bte_o = wbm_bte_o_r;
+
+ // Master input mux, priority to debug master
+ assign wbm0_dat_i = wbm_dat_i_r;
+ assign wbm0_ack_i = wbm_ack_i_r & master_sel[0];
+ assign wbm0_err_i = wbm_err_i_r & master_sel[0];
+ assign wbm0_rty_i = wbm_rty_i_r & master_sel[0];
+
+ assign wbm1_dat_i = wbm_dat_i_r;
+ assign wbm1_ack_i = wbm_ack_i_r & master_sel[1];
+ assign wbm1_err_i = wbm_err_i_r & master_sel[1];
+ assign wbm1_rty_i = wbm_rty_i_r & master_sel[1];
+
+`else // !`ifdef ARBITER_DBUS_REGISTERING
+
+ // Master input mux output wires
+ wire [wb_adr_width-1:0] wbm_adr_o;
+ wire [wb_dat_width-1:0] wbm_dat_o;
+ wire [3:0] wbm_sel_o;
+ wire wbm_we_o;
+ wire wbm_cyc_o;
+ wire wbm_stb_o;
+ wire [2:0] wbm_cti_o;
+ wire [1:0] wbm_bte_o;
+
+ // Master select
+ wire [1:0] master_sel;
+ // priority to wbm1, the debug master
+ assign master_sel[0] = wbm0_cyc_o & !wbm1_cyc_o;
+ assign master_sel[1] = wbm1_cyc_o;
+
+
+ // Master input mux, priority to debug master
+ assign wbm_adr_o = master_sel[1] ? wbm1_adr_o :
+ wbm0_adr_o;
+
+ assign wbm_dat_o = master_sel[1] ? wbm1_dat_o :
+ wbm0_dat_o;
+
+ assign wbm_sel_o = master_sel[1] ? wbm1_sel_o :
+ wbm0_sel_o;
+
+ assign wbm_we_o = master_sel[1] ? wbm1_we_o :
+ wbm0_we_o;
+
+ assign wbm_cyc_o = master_sel[1] ? wbm1_cyc_o :
+ wbm0_cyc_o;
+
+ assign wbm_stb_o = master_sel[1] ? wbm1_stb_o :
+ wbm0_stb_o;
+
+ assign wbm_cti_o = master_sel[1] ? wbm1_cti_o :
+ wbm0_cti_o;
+
+ assign wbm_bte_o = master_sel[1] ? wbm1_bte_o :
+ wbm0_bte_o;
+
+
+ wire [wb_dat_width-1:0] wbm_dat_i;
+ wire wbm_ack_i;
+ wire wbm_err_i;
+ wire wbm_rty_i;
+
+
+ assign wbm0_dat_i = wbm_dat_i;
+ assign wbm0_ack_i = wbm_ack_i & master_sel[0];
+ assign wbm0_err_i = wbm_err_i & master_sel[0];
+ assign wbm0_rty_i = wbm_rty_i & master_sel[0];
+
+ assign wbm1_dat_i = wbm_dat_i;
+ assign wbm1_ack_i = wbm_ack_i & master_sel[1];
+ assign wbm1_err_i = wbm_err_i & master_sel[1];
+ assign wbm1_rty_i = wbm_rty_i & master_sel[1];
+
+
+
+`endif // !`ifdef ARBITER_DBUS_REGISTERING
+
+
+ // Slave select wire
+ wire [wb_num_slaves-1:0] wb_slave_sel;
+ reg [wb_num_slaves-1:0] wb_slave_sel_r;
+
+ // Register wb_slave_sel_r to break combinatorial loop when selecting default
+ // slave
+ always @(posedge wb_clk)
+ wb_slave_sel_r <= wb_slave_sel;
+
+ // Slave out mux in wires
+ wire [wb_dat_width-1:0] wbs_dat_o_mux_i [0:wb_num_slaves-1];
+ wire wbs_ack_o_mux_i [0:wb_num_slaves-1];
+ wire wbs_err_o_mux_i [0:wb_num_slaves-1];
+ wire wbs_rty_o_mux_i [0:wb_num_slaves-1];
+
+ //
+ // Slave selects
+ //
+ assign wb_slave_sel[0] = wbm_adr_o[31:28] == slave0_adr | wbm_adr_o[31:28] == 4'hf; // Special case, point all reads to ROM address to here
+
+ // Auto select last slave when others are not selected
+ assign wb_slave_sel[1] = !(wb_slave_sel_r[0]);
+
+/*
+ assign wb_slave_sel[1] = wbm_adr_o[`WB_ARB_ADDR_MATCH_SEL] == slave1_adr;
+ assign wb_slave_sel[2] = wbm_adr_o[`WB_ARB_ADDR_MATCH_SEL] == slave2_adr;
+ assign wb_slave_sel[3] = wbm_adr_o[`WB_ARB_ADDR_MATCH_SEL] == slave3_adr;
+ assign wb_slave_sel[4] = wbm_adr_o[`WB_ARB_ADDR_MATCH_SEL] == slave4_adr;
+ assign wb_slave_sel[5] = wbm_adr_o[`WB_ARB_ADDR_MATCH_SEL] == slave5_adr;
+ assign wb_slave_sel[6] = wbm_adr_o[`WB_ARB_ADDR_MATCH_SEL] == slave6_adr;
+ assign wb_slave_sel[7] = wbm_adr_o[`WB_ARB_ADDR_MATCH_SEL] == slave7_adr;
+ assign wb_slave_sel[8] = wbm_adr_o[`WB_ARB_ADDR_MATCH_SEL] == slave8_adr;
+ assign wb_slave_sel[9] = wbm_adr_o[`WB_ARB_ADDR_MATCH_SEL] == slave9_adr;
+ assign wb_slave_sel[10] = wbm_adr_o[`WB_ARB_ADDR_MATCH_SEL] == slave10_adr;
+ assign wb_slave_sel[11] = wbm_adr_o[`WB_ARB_ADDR_MATCH_SEL] == slave11_adr;
+ assign wb_slave_sel[12] = wbm_adr_o[`WB_ARB_ADDR_MATCH_SEL] == slave12_adr;
+ assign wb_slave_sel[13] = wbm_adr_o[`WB_ARB_ADDR_MATCH_SEL] == slave13_adr;
+ assign wb_slave_sel[14] = wbm_adr_o[`WB_ARB_ADDR_MATCH_SEL] == slave14_adr;
+ assign wb_slave_sel[15] = wbm_adr_o[`WB_ARB_ADDR_MATCH_SEL] == slave15_adr;
+ assign wb_slave_sel[16] = wbm_adr_o[`WB_ARB_ADDR_MATCH_SEL] == slave16_adr;
+*/
+
+`ifdef ARBITER_DBUS_WATCHDOG
+ reg [`ARBITER_DBUS_WATCHDOG_TIMER_WIDTH:0] watchdog_timer;
+ reg wbm_stb_r; // Register strobe
+ wire wbm_stb_edge; // Detect its edge
+
+ always @(posedge wb_clk)
+ wbm_stb_r <= wbm_stb_o;
+
+ assign wbm_stb_edge = (wbm_stb_o & !wbm_stb_r);
+
+ // Counter logic
+ always @(posedge wb_clk)
+ if (wb_rst) watchdog_timer <= 0;
+ else if (wbm_ack_i) // When we see an ack, turn off timer
+ watchdog_timer <= 0;
+ else if (wbm_stb_edge) // New access means start timer again
+ watchdog_timer <= 1;
+ else if (|watchdog_timer) // Continue counting if counter > 0
+ watchdog_timer <= watchdog_timer + 1;
+
+ always @(posedge wb_clk)
+ watchdog_err <= (&watchdog_timer);
+
+
+`else // !`ifdef ARBITER_DBUS_WATCHDOG
+
+ always @(posedge wb_clk)
+ watchdog_err <= 0;
+
+`endif // !`ifdef ARBITER_DBUS_WATCHDOG
+
+
+
+ // Slave 0 inputs
+ assign wbs0_adr_i = wbm_adr_o;
+ assign wbs0_dat_i = wbm_dat_o;
+ assign wbs0_sel_i = wbm_sel_o;
+ assign wbs0_cyc_i = wbm_cyc_o & wb_slave_sel_r[0];
+ assign wbs0_stb_i = wbm_stb_o & wb_slave_sel_r[0];
+ assign wbs0_we_i = wbm_we_o;
+ assign wbs0_cti_i = wbm_cti_o;
+ assign wbs0_bte_i = wbm_bte_o;
+ assign wbs_dat_o_mux_i[0] = wbs0_dat_o;
+ assign wbs_ack_o_mux_i[0] = wbs0_ack_o & wb_slave_sel_r[0];
+ assign wbs_err_o_mux_i[0] = wbs0_err_o & wb_slave_sel_r[0];
+ assign wbs_rty_o_mux_i[0] = wbs0_rty_o & wb_slave_sel_r[0];
+
+
+ // Slave 1 inputs
+ assign wbs1_adr_i = wbm_adr_o;
+ assign wbs1_dat_i = wbm_dat_o;
+ assign wbs1_sel_i = wbm_sel_o;
+ assign wbs1_cyc_i = wbm_cyc_o & wb_slave_sel_r[1];
+ assign wbs1_stb_i = wbm_stb_o & wb_slave_sel_r[1];
+ assign wbs1_we_i = wbm_we_o;
+ assign wbs1_cti_i = wbm_cti_o;
+ assign wbs1_bte_i = wbm_bte_o;
+ assign wbs_dat_o_mux_i[1] = wbs1_dat_o;
+ assign wbs_ack_o_mux_i[1] = wbs1_ack_o & wb_slave_sel_r[1];
+ assign wbs_err_o_mux_i[1] = wbs1_err_o & wb_slave_sel_r[1];
+ assign wbs_rty_o_mux_i[1] = wbs1_rty_o & wb_slave_sel_r[1];
+
+/*
+ // Slave 2 inputs
+ assign wbs2_adr_i = wbm_adr_o;
+ assign wbs2_dat_i = wbm_dat_o;
+ assign wbs2_sel_i = wbm_sel_o;
+ assign wbs2_cyc_i = wbm_cyc_o & wb_slave_sel_r[2];
+ assign wbs2_stb_i = wbm_stb_o & wb_slave_sel_r[2];
+ assign wbs2_we_i = wbm_we_o;
+ assign wbs2_cti_i = wbm_cti_o;
+ assign wbs2_bte_i = wbm_bte_o;
+ assign wbs_dat_o_mux_i[2] = wbs2_dat_o;
+ assign wbs_ack_o_mux_i[2] = wbs2_ack_o & wb_slave_sel_r[2];
+ assign wbs_err_o_mux_i[2] = wbs2_err_o & wb_slave_sel_r[2];
+ assign wbs_rty_o_mux_i[2] = wbs2_rty_o & wb_slave_sel_r[2];
+
+
+ // Slave 3 inputs
+ assign wbs3_adr_i = wbm_adr_o;
+ assign wbs3_dat_i = wbm_dat_o;
+ assign wbs3_sel_i = wbm_sel_o;
+ assign wbs3_cyc_i = wbm_cyc_o & wb_slave_sel_r[3];
+ assign wbs3_stb_i = wbm_stb_o & wb_slave_sel_r[3];
+ assign wbs3_we_i = wbm_we_o;
+ assign wbs3_cti_i = wbm_cti_o;
+ assign wbs3_bte_i = wbm_bte_o;
+ assign wbs_dat_o_mux_i[3] = wbs3_dat_o;
+ assign wbs_ack_o_mux_i[3] = wbs3_ack_o & wb_slave_sel_r[3];
+ assign wbs_err_o_mux_i[3] = wbs3_err_o & wb_slave_sel_r[3];
+ assign wbs_rty_o_mux_i[3] = wbs3_rty_o & wb_slave_sel_r[3];
+
+ // Slave 4 inputs
+ assign wbs4_adr_i = wbm_adr_o;
+ assign wbs4_dat_i = wbm_dat_o;
+ assign wbs4_sel_i = wbm_sel_o;
+ assign wbs4_cyc_i = wbm_cyc_o & wb_slave_sel_r[4];
+ assign wbs4_stb_i = wbm_stb_o & wb_slave_sel_r[4];
+ assign wbs4_we_i = wbm_we_o;
+ assign wbs4_cti_i = wbm_cti_o;
+ assign wbs4_bte_i = wbm_bte_o;
+ assign wbs_dat_o_mux_i[4] = wbs4_dat_o;
+ assign wbs_ack_o_mux_i[4] = wbs4_ack_o & wb_slave_sel_r[4];
+ assign wbs_err_o_mux_i[4] = wbs4_err_o & wb_slave_sel_r[4];
+ assign wbs_rty_o_mux_i[4] = wbs4_rty_o & wb_slave_sel_r[4];
+
+
+ // Slave 5 inputs
+ assign wbs5_adr_i = wbm_adr_o;
+ assign wbs5_dat_i = wbm_dat_o;
+ assign wbs5_sel_i = wbm_sel_o;
+ assign wbs5_cyc_i = wbm_cyc_o & wb_slave_sel_r[5];
+ assign wbs5_stb_i = wbm_stb_o & wb_slave_sel_r[5];
+ assign wbs5_we_i = wbm_we_o;
+ assign wbs5_cti_i = wbm_cti_o;
+ assign wbs5_bte_i = wbm_bte_o;
+ assign wbs_dat_o_mux_i[5] = wbs5_dat_o;
+ assign wbs_ack_o_mux_i[5] = wbs5_ack_o & wb_slave_sel_r[5];
+ assign wbs_err_o_mux_i[5] = wbs5_err_o & wb_slave_sel_r[5];
+ assign wbs_rty_o_mux_i[5] = wbs5_rty_o & wb_slave_sel_r[5];
+
+
+ // Slave 6 inputs
+ assign wbs6_adr_i = wbm_adr_o;
+ assign wbs6_dat_i = wbm_dat_o;
+ assign wbs6_sel_i = wbm_sel_o;
+ assign wbs6_cyc_i = wbm_cyc_o & wb_slave_sel_r[6];
+ assign wbs6_stb_i = wbm_stb_o & wb_slave_sel_r[6];
+ assign wbs6_we_i = wbm_we_o;
+ assign wbs6_cti_i = wbm_cti_o;
+ assign wbs6_bte_i = wbm_bte_o;
+ assign wbs_dat_o_mux_i[6] = wbs6_dat_o;
+ assign wbs_ack_o_mux_i[6] = wbs6_ack_o & wb_slave_sel_r[6];
+ assign wbs_err_o_mux_i[6] = wbs6_err_o & wb_slave_sel_r[6];
+ assign wbs_rty_o_mux_i[6] = wbs6_rty_o & wb_slave_sel_r[6];
+
+
+ // Slave 7 inputs
+ assign wbs7_adr_i = wbm_adr_o;
+ assign wbs7_dat_i = wbm_dat_o;
+ assign wbs7_sel_i = wbm_sel_o;
+ assign wbs7_cyc_i = wbm_cyc_o & wb_slave_sel_r[7];
+ assign wbs7_stb_i = wbm_stb_o & wb_slave_sel_r[7];
+ assign wbs7_we_i = wbm_we_o;
+ assign wbs7_cti_i = wbm_cti_o;
+ assign wbs7_bte_i = wbm_bte_o;
+ assign wbs_dat_o_mux_i[7] = wbs7_dat_o;
+ assign wbs_ack_o_mux_i[7] = wbs7_ack_o & wb_slave_sel_r[7];
+ assign wbs_err_o_mux_i[7] = wbs7_err_o & wb_slave_sel_r[7];
+ assign wbs_rty_o_mux_i[7] = wbs7_rty_o & wb_slave_sel_r[7];
+
+
+ // Slave 8 inputs
+ assign wbs8_adr_i = wbm_adr_o;
+ assign wbs8_dat_i = wbm_dat_o;
+ assign wbs8_sel_i = wbm_sel_o;
+ assign wbs8_cyc_i = wbm_cyc_o & wb_slave_sel_r[8];
+ assign wbs8_stb_i = wbm_stb_o & wb_slave_sel_r[8];
+ assign wbs8_we_i = wbm_we_o;
+ assign wbs8_cti_i = wbm_cti_o;
+ assign wbs8_bte_i = wbm_bte_o;
+ assign wbs_dat_o_mux_i[8] = wbs8_dat_o;
+ assign wbs_ack_o_mux_i[8] = wbs8_ack_o & wb_slave_sel_r[8];
+ assign wbs_err_o_mux_i[8] = wbs8_err_o & wb_slave_sel_r[8];
+ assign wbs_rty_o_mux_i[8] = wbs8_rty_o & wb_slave_sel_r[8];
+
+
+ // Slave 9 inputs
+ assign wbs9_adr_i = wbm_adr_o;
+ assign wbs9_dat_i = wbm_dat_o;
+ assign wbs9_sel_i = wbm_sel_o;
+ assign wbs9_cyc_i = wbm_cyc_o & wb_slave_sel_r[9];
+ assign wbs9_stb_i = wbm_stb_o & wb_slave_sel_r[9];
+ assign wbs9_we_i = wbm_we_o;
+ assign wbs9_cti_i = wbm_cti_o;
+ assign wbs9_bte_i = wbm_bte_o;
+ assign wbs_dat_o_mux_i[9] = wbs9_dat_o;
+ assign wbs_ack_o_mux_i[9] = wbs9_ack_o & wb_slave_sel_r[9];
+ assign wbs_err_o_mux_i[9] = wbs9_err_o & wb_slave_sel_r[9];
+ assign wbs_rty_o_mux_i[9] = wbs9_rty_o & wb_slave_sel_r[9];
+
+
+ // Slave 10 inputs
+ assign wbs10_adr_i = wbm_adr_o;
+ assign wbs10_dat_i = wbm_dat_o;
+ assign wbs10_sel_i = wbm_sel_o;
+ assign wbs10_cyc_i = wbm_cyc_o & wb_slave_sel_r[10];
+ assign wbs10_stb_i = wbm_stb_o & wb_slave_sel_r[10];
+ assign wbs10_we_i = wbm_we_o;
+ assign wbs10_cti_i = wbm_cti_o;
+ assign wbs10_bte_i = wbm_bte_o;
+ assign wbs_dat_o_mux_i[10] = wbs10_dat_o;
+ assign wbs_ack_o_mux_i[10] = wbs10_ack_o & wb_slave_sel_r[10];
+ assign wbs_err_o_mux_i[10] = wbs10_err_o & wb_slave_sel_r[10];
+ assign wbs_rty_o_mux_i[10] = wbs10_rty_o & wb_slave_sel_r[10];
+
+
+ // Slave 11 inputs
+ assign wbs11_adr_i = wbm_adr_o;
+ assign wbs11_dat_i = wbm_dat_o;
+ assign wbs11_sel_i = wbm_sel_o;
+ assign wbs11_cyc_i = wbm_cyc_o & wb_slave_sel_r[11];
+ assign wbs11_stb_i = wbm_stb_o & wb_slave_sel_r[11];
+ assign wbs11_we_i = wbm_we_o;
+ assign wbs11_cti_i = wbm_cti_o;
+ assign wbs11_bte_i = wbm_bte_o;
+ assign wbs_dat_o_mux_i[11] = wbs11_dat_o;
+ assign wbs_ack_o_mux_i[11] = wbs11_ack_o & wb_slave_sel_r[11];
+ assign wbs_err_o_mux_i[11] = wbs11_err_o & wb_slave_sel_r[11];
+ assign wbs_rty_o_mux_i[11] = wbs11_rty_o & wb_slave_sel_r[11];
+
+
+ // Slave 12 inputs
+ assign wbs12_adr_i = wbm_adr_o;
+ assign wbs12_dat_i = wbm_dat_o;
+ assign wbs12_sel_i = wbm_sel_o;
+ assign wbs12_cyc_i = wbm_cyc_o & wb_slave_sel_r[12];
+ assign wbs12_stb_i = wbm_stb_o & wb_slave_sel_r[12];
+ assign wbs12_we_i = wbm_we_o;
+ assign wbs12_cti_i = wbm_cti_o;
+ assign wbs12_bte_i = wbm_bte_o;
+ assign wbs_dat_o_mux_i[12] = wbs12_dat_o;
+ assign wbs_ack_o_mux_i[12] = wbs12_ack_o & wb_slave_sel_r[12];
+ assign wbs_err_o_mux_i[12] = wbs12_err_o & wb_slave_sel_r[12];
+ assign wbs_rty_o_mux_i[12] = wbs12_rty_o & wb_slave_sel_r[12];
+
+
+ // Slave 13 inputs
+ assign wbs13_adr_i = wbm_adr_o;
+ assign wbs13_dat_i = wbm_dat_o;
+ assign wbs13_sel_i = wbm_sel_o;
+ assign wbs13_cyc_i = wbm_cyc_o & wb_slave_sel_r[13];
+ assign wbs13_stb_i = wbm_stb_o & wb_slave_sel_r[13];
+ assign wbs13_we_i = wbm_we_o;
+ assign wbs13_cti_i = wbm_cti_o;
+ assign wbs13_bte_i = wbm_bte_o;
+ assign wbs_dat_o_mux_i[13] = wbs13_dat_o;
+ assign wbs_ack_o_mux_i[13] = wbs13_ack_o & wb_slave_sel_r[13];
+ assign wbs_err_o_mux_i[13] = wbs13_err_o & wb_slave_sel_r[13];
+ assign wbs_rty_o_mux_i[13] = wbs13_rty_o & wb_slave_sel_r[13];
+
+
+ // Slave 14 inputs
+ assign wbs14_adr_i = wbm_adr_o;
+ assign wbs14_dat_i = wbm_dat_o;
+ assign wbs14_sel_i = wbm_sel_o;
+ assign wbs14_cyc_i = wbm_cyc_o & wb_slave_sel_r[14];
+ assign wbs14_stb_i = wbm_stb_o & wb_slave_sel_r[14];
+ assign wbs14_we_i = wbm_we_o;
+ assign wbs14_cti_i = wbm_cti_o;
+ assign wbs14_bte_i = wbm_bte_o;
+ assign wbs_dat_o_mux_i[14] = wbs14_dat_o;
+ assign wbs_ack_o_mux_i[14] = wbs14_ack_o & wb_slave_sel_r[14];
+ assign wbs_err_o_mux_i[14] = wbs14_err_o & wb_slave_sel_r[14];
+ assign wbs_rty_o_mux_i[14] = wbs14_rty_o & wb_slave_sel_r[14];
+
+
+ // Slave 15 inputs
+ assign wbs15_adr_i = wbm_adr_o;
+ assign wbs15_dat_i = wbm_dat_o;
+ assign wbs15_sel_i = wbm_sel_o;
+ assign wbs15_cyc_i = wbm_cyc_o & wb_slave_sel_r[15];
+ assign wbs15_stb_i = wbm_stb_o & wb_slave_sel_r[15];
+ assign wbs15_we_i = wbm_we_o;
+ assign wbs15_cti_i = wbm_cti_o;
+ assign wbs15_bte_i = wbm_bte_o;
+ assign wbs_dat_o_mux_i[15] = wbs15_dat_o;
+ assign wbs_ack_o_mux_i[15] = wbs15_ack_o & wb_slave_sel_r[15];
+ assign wbs_err_o_mux_i[15] = wbs15_err_o & wb_slave_sel_r[15];
+ assign wbs_rty_o_mux_i[15] = wbs15_rty_o & wb_slave_sel_r[15];
+
+
+ // Slave 16 inputs
+ assign wbs16_adr_i = wbm_adr_o;
+ assign wbs16_dat_i = wbm_dat_o;
+ assign wbs16_sel_i = wbm_sel_o;
+ assign wbs16_cyc_i = wbm_cyc_o & wb_slave_sel_r[16];
+ assign wbs16_stb_i = wbm_stb_o & wb_slave_sel_r[16];
+ assign wbs16_we_i = wbm_we_o;
+ assign wbs16_cti_i = wbm_cti_o;
+ assign wbs16_bte_i = wbm_bte_o;
+ assign wbs_dat_o_mux_i[16] = wbs16_dat_o;
+ assign wbs_ack_o_mux_i[16] = wbs16_ack_o & wb_slave_sel_r[16];
+ assign wbs_err_o_mux_i[16] = wbs16_err_o & wb_slave_sel_r[16];
+ assign wbs_rty_o_mux_i[16] = wbs16_rty_o & wb_slave_sel_r[16];
+
+*/
+
+
+
+ // Master out mux from slave in data
+ assign wbm_dat_i = wb_slave_sel_r[0] ? wbs_dat_o_mux_i[0] :
+ wb_slave_sel_r[1] ? wbs_dat_o_mux_i[1] :
+/* wb_slave_sel_r[2] ? wbs_dat_o_mux_i[2] :
+ wb_slave_sel_r[3] ? wbs_dat_o_mux_i[3] :
+ wb_slave_sel_r[4] ? wbs_dat_o_mux_i[4] :
+ wb_slave_sel_r[5] ? wbs_dat_o_mux_i[5] :
+ wb_slave_sel_r[6] ? wbs_dat_o_mux_i[6] :
+ wb_slave_sel_r[7] ? wbs_dat_o_mux_i[7] :
+ wb_slave_sel_r[8] ? wbs_dat_o_mux_i[8] :
+ wb_slave_sel_r[9] ? wbs_dat_o_mux_i[9] :
+ wb_slave_sel_r[10] ? wbs_dat_o_mux_i[10] :
+ wb_slave_sel_r[11] ? wbs_dat_o_mux_i[11] :
+ wb_slave_sel_r[12] ? wbs_dat_o_mux_i[12] :
+ wb_slave_sel_r[13] ? wbs_dat_o_mux_i[13] :
+ wb_slave_sel_r[14] ? wbs_dat_o_mux_i[14] :
+ wb_slave_sel_r[15] ? wbs_dat_o_mux_i[15] :
+ wb_slave_sel_r[16] ? wbs_dat_o_mux_i[16] :
+*/
+ wbs_dat_o_mux_i[0];
+ // Master out acks, or together
+ assign wbm_ack_i = wbs_ack_o_mux_i[0] |
+ wbs_ack_o_mux_i[1] /*|
+ wbs_ack_o_mux_i[2] |
+ wbs_ack_o_mux_i[3] |
+ wbs_ack_o_mux_i[4] |
+ wbs_ack_o_mux_i[5] |
+ wbs_ack_o_mux_i[6] |
+ wbs_ack_o_mux_i[7] |
+ wbs_ack_o_mux_i[8] |
+ wbs_ack_o_mux_i[9] |
+ wbs_ack_o_mux_i[10] |
+ wbs_ack_o_mux_i[11] |
+ wbs_ack_o_mux_i[12] |
+ wbs_ack_o_mux_i[13] |
+ wbs_ack_o_mux_i[14] |
+ wbs_ack_o_mux_i[15] |
+ wbs_ack_o_mux_i[16] */
+ ;
+
+
+ assign wbm_err_i = wbs_err_o_mux_i[0] |
+ wbs_err_o_mux_i[1] |/*
+ wbs_err_o_mux_i[2] |
+ wbs_err_o_mux_i[3] |
+ wbs_err_o_mux_i[4] |
+ wbs_err_o_mux_i[5] |
+ wbs_err_o_mux_i[6] |
+ wbs_err_o_mux_i[7] |
+ wbs_err_o_mux_i[8] |
+ wbs_err_o_mux_i[9] |
+ wbs_err_o_mux_i[10] |
+ wbs_err_o_mux_i[11] |
+ wbs_err_o_mux_i[12] |
+ wbs_err_o_mux_i[13] |
+ wbs_err_o_mux_i[14] |
+ wbs_err_o_mux_i[15] |
+ wbs_err_o_mux_i[16] |*/
+ watchdog_err ;
+
+
+ assign wbm_rty_i = wbs_rty_o_mux_i[0] |
+ wbs_rty_o_mux_i[1]/*|
+ wbs_rty_o_mux_i[2] |
+ wbs_rty_o_mux_i[3] |
+ wbs_rty_o_mux_i[4] |
+ wbs_rty_o_mux_i[5] |
+ wbs_rty_o_mux_i[6] |
+ wbs_rty_o_mux_i[7] |
+ wbs_rty_o_mux_i[8] |
+ wbs_rty_o_mux_i[9] |
+ wbs_rty_o_mux_i[10] |
+ wbs_rty_o_mux_i[11] |
+ wbs_rty_o_mux_i[12] |
+ wbs_rty_o_mux_i[13] |
+ wbs_rty_o_mux_i[14] |
+ wbs_rty_o_mux_i[15] |
+ wbs_rty_o_mux_i[16]*/;
+
+endmodule // arbiter_dbus
+
Index: boards/generic/ft/rtl/verilog/arbiter/arbiter_ibus.v
===================================================================
--- boards/generic/ft/rtl/verilog/arbiter/arbiter_ibus.v (nonexistent)
+++ boards/generic/ft/rtl/verilog/arbiter/arbiter_ibus.v (revision 483)
@@ -0,0 +1,337 @@
+//////////////////////////////////////////////////////////////////////
+/// ////
+/// Wishbone arbiter, burst-compatible ////
+/// ////
+/// Simple arbiter, single master, dual slave, primarily for ////
+/// processor instruction bus, providing access to one main ////
+/// memory server and one ROM ////
+/// ////
+/// Julius Baxter, julius@opencores.org ////
+/// ////
+//////////////////////////////////////////////////////////////////////
+//// ////
+//// Copyright (C) 2009, 2010 Authors and OPENCORES.ORG ////
+//// ////
+//// This source file may be used and distributed without ////
+//// restriction provided that this copyright statement is not ////
+//// removed from the file and that any derivative work contains ////
+//// the original copyright notice and the associated disclaimer. ////
+//// ////
+//// This source file is free software; you can redistribute it ////
+//// and/or modify it under the terms of the GNU Lesser General ////
+//// Public License as published by the Free Software Foundation; ////
+//// either version 2.1 of the License, or (at your option) any ////
+//// later version. ////
+//// ////
+//// This source is distributed in the hope that it will be ////
+//// useful, but WITHOUT ANY WARRANTY; without even the implied ////
+//// warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR ////
+//// PURPOSE. See the GNU Lesser General Public License for more ////
+//// details. ////
+//// ////
+//// You should have received a copy of the GNU Lesser General ////
+//// Public License along with this source; if not, download it ////
+//// from http://www.opencores.org/lgpl.shtml ////
+//// ////
+//////////////////////////////////////////////////////////////////////
+`include "orpsoc-defines.v"
+// One master, 2 slaves.
+module arbiter_ibus
+ (
+ // instruction bus in
+ // Wishbone Master interface
+ wbm_adr_o,
+ wbm_dat_o,
+ wbm_sel_o,
+ wbm_we_o,
+ wbm_cyc_o,
+ wbm_stb_o,
+ wbm_cti_o,
+ wbm_bte_o,
+
+ wbm_dat_i,
+ wbm_ack_i,
+ wbm_err_i,
+ wbm_rty_i,
+
+
+ // Slave one
+ // Wishbone Slave interface
+ wbs0_adr_i,
+ wbs0_dat_i,
+ wbs0_sel_i,
+ wbs0_we_i,
+ wbs0_cyc_i,
+ wbs0_stb_i,
+ wbs0_cti_i,
+ wbs0_bte_i,
+
+ wbs0_dat_o,
+ wbs0_ack_o,
+ wbs0_err_o,
+ wbs0_rty_o,
+
+ // Slave two
+ // Wishbone Slave interface
+ wbs1_adr_i,
+ wbs1_dat_i,
+ wbs1_sel_i,
+ wbs1_we_i,
+ wbs1_cyc_i,
+ wbs1_stb_i,
+ wbs1_cti_i,
+ wbs1_bte_i,
+
+ wbs1_dat_o,
+ wbs1_ack_o,
+ wbs1_err_o,
+ wbs1_rty_o,
+
+ wb_clk,
+ wb_rst
+ );
+
+
+ parameter wb_dat_width = 32;
+ parameter wb_adr_width = 32;
+
+ parameter wb_addr_match_width = 8;
+
+ parameter slave0_adr = 8'hf0; // FLASH ROM
+ parameter slave1_adr = 8'h00; // Main memory (SDRAM/FPGA SRAM)
+
+`define WB_ARB_ADDR_MATCH_SEL wb_adr_width-1:wb_adr_width-wb_addr_match_width
+
+ input wb_clk;
+ input wb_rst;
+
+
+ // WB Master
+ input [wb_adr_width-1:0] wbm_adr_o;
+ input [wb_dat_width-1:0] wbm_dat_o;
+ input [3:0] wbm_sel_o;
+ input wbm_we_o;
+ input wbm_cyc_o;
+ input wbm_stb_o;
+ input [2:0] wbm_cti_o;
+ input [1:0] wbm_bte_o;
+ output [wb_dat_width-1:0] wbm_dat_i;
+ output wbm_ack_i;
+ output wbm_err_i;
+ output wbm_rty_i;
+
+ // WB Slave 0
+ output [wb_adr_width-1:0] wbs0_adr_i;
+ output [wb_dat_width-1:0] wbs0_dat_i;
+ output [3:0] wbs0_sel_i;
+ output wbs0_we_i;
+ output wbs0_cyc_i;
+ output wbs0_stb_i;
+ output [2:0] wbs0_cti_i;
+ output [1:0] wbs0_bte_i;
+ input [wb_dat_width-1:0] wbs0_dat_o;
+ input wbs0_ack_o;
+ input wbs0_err_o;
+ input wbs0_rty_o;
+
+ // WB Slave 1
+ output [wb_adr_width-1:0] wbs1_adr_i;
+ output [wb_dat_width-1:0] wbs1_dat_i;
+ output [3:0] wbs1_sel_i;
+ output wbs1_we_i;
+ output wbs1_cyc_i;
+ output wbs1_stb_i;
+ output [2:0] wbs1_cti_i;
+ output [1:0] wbs1_bte_i;
+ input [wb_dat_width-1:0] wbs1_dat_o;
+ input wbs1_ack_o;
+ input wbs1_err_o;
+ input wbs1_rty_o;
+
+ wire [1:0] slave_sel; // One bit per slave
+
+ reg watchdog_err;
+
+`ifdef ARBITER_IBUS_WATCHDOG
+ reg [`ARBITER_IBUS_WATCHDOG_TIMER_WIDTH:0] watchdog_timer;
+ reg wbm_stb_r; // Register strobe
+ wire wbm_stb_edge; // Detect its edge
+ reg wbm_stb_edge_r, wbm_ack_i_r; // Reg these, better timing
+
+ always @(posedge wb_clk)
+ wbm_stb_r <= wbm_stb_o;
+
+ assign wbm_stb_edge = (wbm_stb_o & !wbm_stb_r);
+
+ always @(posedge wb_clk)
+ wbm_stb_edge_r <= wbm_stb_edge;
+
+ always @(posedge wb_clk)
+ wbm_ack_i_r <= wbm_ack_i;
+
+
+ // Counter logic
+ always @(posedge wb_clk)
+ if (wb_rst) watchdog_timer <= 0;
+ else if (wbm_ack_i_r) // When we see an ack, turn off timer
+ watchdog_timer <= 0;
+ else if (wbm_stb_edge_r) // New access means start timer again
+ watchdog_timer <= 1;
+ else if (|watchdog_timer) // Continue counting if counter > 0
+ watchdog_timer <= watchdog_timer + 1;
+
+ always @(posedge wb_clk)
+ watchdog_err <= (&watchdog_timer);
+
+`else // !`ifdef ARBITER_IBUS_WATCHDOG
+
+ always @(posedge wb_clk)
+ watchdog_err <= 0;
+
+`endif // !`ifdef ARBITER_IBUS_WATCHDOG
+
+
+
+`ifdef ARBITER_IBUS_REGISTERING
+
+ // Master input registers
+ reg [wb_adr_width-1:0] wbm_adr_o_r;
+ reg [wb_dat_width-1:0] wbm_dat_o_r;
+ reg [3:0] wbm_sel_o_r;
+ reg wbm_we_o_r;
+ reg wbm_cyc_o_r;
+ reg wbm_stb_o_r;
+ reg [2:0] wbm_cti_o_r;
+ reg [1:0] wbm_bte_o_r;
+ // Slave output registers
+ reg [wb_dat_width-1:0] wbs0_dat_o_r;
+ reg wbs0_ack_o_r;
+ reg wbs0_err_o_r;
+ reg wbs0_rty_o_r;
+ reg [wb_dat_width-1:0] wbs1_dat_o_r;
+ reg wbs1_ack_o_r;
+ reg wbs1_err_o_r;
+ reg wbs1_rty_o_r;
+
+ wire wbm_ack_i_pre_reg;
+
+
+
+ // Register master input signals
+ always @(posedge wb_clk)
+ begin
+ wbm_adr_o_r <= wbm_adr_o;
+ wbm_dat_o_r <= wbm_dat_o;
+ wbm_sel_o_r <= wbm_sel_o;
+ wbm_we_o_r <= wbm_we_o;
+ wbm_cyc_o_r <= wbm_cyc_o;
+ wbm_stb_o_r <= wbm_stb_o & !wbm_ack_i_pre_reg & !wbm_ack_i;//classic
+ wbm_cti_o_r <= wbm_cti_o;
+ wbm_bte_o_r <= wbm_bte_o;
+
+ // Slave signals
+ wbs0_dat_o_r <= wbs0_dat_o;
+ wbs0_ack_o_r <= wbs0_ack_o;
+ wbs0_err_o_r <= wbs0_err_o;
+ wbs0_rty_o_r <= wbs0_rty_o;
+ wbs1_dat_o_r <= wbs1_dat_o;
+ wbs1_ack_o_r <= wbs1_ack_o;
+ wbs1_err_o_r <= wbs1_err_o;
+ wbs1_rty_o_r <= wbs1_rty_o;
+
+ end // always @ (posedge wb_clk)
+
+ // Slave select
+ assign slave_sel[0] = wbm_adr_o_r[`WB_ARB_ADDR_MATCH_SEL] ==
+ slave0_adr;
+
+ assign slave_sel[1] = wbm_adr_o_r[`WB_ARB_ADDR_MATCH_SEL] ==
+ slave1_adr;
+
+ // Slave out assigns
+ assign wbs0_adr_i = wbm_adr_o_r;
+ assign wbs0_dat_i = wbm_dat_o_r;
+ assign wbs0_we_i = wbm_dat_o_r;
+ assign wbs0_sel_i = wbm_sel_o_r;
+ assign wbs0_cti_i = wbm_cti_o_r;
+ assign wbs0_bte_i = wbm_bte_o_r;
+ assign wbs0_cyc_i = wbm_cyc_o_r & slave_sel[0];
+ assign wbs0_stb_i = wbm_stb_o_r & slave_sel[0];
+
+ assign wbs1_adr_i = wbm_adr_o_r;
+ assign wbs1_dat_i = wbm_dat_o_r;
+ assign wbs1_we_i = wbm_dat_o_r;
+ assign wbs1_sel_i = wbm_sel_o_r;
+ assign wbs1_cti_i = wbm_cti_o_r;
+ assign wbs1_bte_i = wbm_bte_o_r;
+ assign wbs1_cyc_i = wbm_cyc_o_r & slave_sel[1];
+ assign wbs1_stb_i = wbm_stb_o_r & slave_sel[1];
+
+ // Master out assigns
+ // Don't care about none selected...
+ assign wbm_dat_i = slave_sel[1] ? wbs1_dat_o_r :
+ wbs0_dat_o_r ;
+
+ assign wbm_ack_i = (slave_sel[0] & wbs0_ack_o_r) |
+ (slave_sel[1] & wbs1_ack_o_r)
+ ;
+
+ assign wbm_err_i = (slave_sel[0] & wbs0_err_o_r) |
+ (slave_sel[1] & wbs1_err_o_r) |
+ watchdog_err;
+
+ assign wbm_rty_i = (slave_sel[0] & wbs0_rty_o_r) |
+ (slave_sel[1] & wbs1_rty_o_r);
+
+ // Non-registered ack
+ assign wbm_ack_i_pre_reg = (slave_sel[0] & wbs0_ack_o) |
+ (slave_sel[1] & wbs1_ack_o);
+
+`else // !`ifdef ARBITER_IBUS_REGISTERING
+
+ // Slave select
+ assign slave_sel[0] = wbm_adr_o[`WB_ARB_ADDR_MATCH_SEL] ==
+ slave0_adr;
+
+ assign slave_sel[1] = wbm_adr_o[`WB_ARB_ADDR_MATCH_SEL] ==
+ slave1_adr;
+
+ // Slave out assigns
+ assign wbs0_adr_i = wbm_adr_o;
+ assign wbs0_dat_i = wbm_dat_o;
+ assign wbs0_we_i = wbm_we_o;
+ assign wbs0_sel_i = wbm_sel_o;
+ assign wbs0_cti_i = wbm_cti_o;
+ assign wbs0_bte_i = wbm_bte_o;
+ assign wbs0_cyc_i = wbm_cyc_o & slave_sel[0];
+ assign wbs0_stb_i = wbm_stb_o & slave_sel[0];
+
+ assign wbs1_adr_i = wbm_adr_o;
+ assign wbs1_dat_i = wbm_dat_o;
+ assign wbs1_we_i = wbm_we_o;
+ assign wbs1_sel_i = wbm_sel_o;
+ assign wbs1_cti_i = wbm_cti_o;
+ assign wbs1_bte_i = wbm_bte_o;
+ assign wbs1_cyc_i = wbm_cyc_o & slave_sel[1];
+ assign wbs1_stb_i = wbm_stb_o & slave_sel[1];
+
+ // Master out assigns
+ // Don't care about none selected...
+ assign wbm_dat_i = slave_sel[1] ? wbs1_dat_o :
+ wbs0_dat_o ;
+
+ assign wbm_ack_i = (slave_sel[0] & wbs0_ack_o) |
+ (slave_sel[1] & wbs1_ack_o);
+
+
+ assign wbm_err_i = (slave_sel[0] & wbs0_err_o) |
+ (slave_sel[1] & wbs1_err_o) |
+ watchdog_err;
+
+ assign wbm_rty_i = (slave_sel[0] & wbs0_rty_o) |
+ (slave_sel[1] & wbs1_rty_o);
+
+
+`endif
+endmodule // arbiter_ibus
+
Index: boards/generic/ft/rtl/verilog/parity_err_handler/parity_err_handler.v
===================================================================
--- boards/generic/ft/rtl/verilog/parity_err_handler/parity_err_handler.v (nonexistent)
+++ boards/generic/ft/rtl/verilog/parity_err_handler/parity_err_handler.v (revision 483)
@@ -0,0 +1,91 @@
+/*
+ Parity error handler
+
+ Vector of parity error indicating signals coming in.
+
+ We issue reset if certain errors are spotted, and interrupt in the case of
+ others.
+
+ This module is not intended to be synthesisable, rather to be used in
+ conjunction with the or1200_ft_stim testbench module.
+
+ */
+
+module parity_err_handler(
+ clk,
+ parity_err,
+ wb_rst,
+ reset,
+ interrupt,
+ wb_dat_o,
+ wb_ack_o,
+ wb_stb_i
+ );
+ parameter parity_vector_width = 9;
+ parameter parity_vector_resets = 1; // Signals at or below this we reset on
+
+ input clk;
+ input [parity_vector_width-1:0] parity_err;
+ input wb_rst;
+ output reset;
+ output reg interrupt;
+ output reg [7:0] wb_dat_o;
+ output wb_ack_o;
+ input wb_stb_i;
+
+ reg reset_r;
+
+ wire [parity_vector_width-1:0] parity_err_mask;
+
+ assign parity_err_mask = 9'b111100000;
+
+ // Signal a reset if signals up to the number indicated by
+ // parity_vector_resets go high.
+ always @(clk or wb_rst)
+ if (wb_rst)
+ reset_r <= 0;
+ else
+ casez(parity_err[parity_vector_width-1:0])
+ //9'b????1????: reset_r <= 1;
+ //9'b?????1???: reset_r <= 1;
+ //9'b??????1??: reset_r <= 1;
+ //9'b???????1?: reset_r <= 1;
+ 9'b????????1: reset_r <= 1;
+ default: reset_r <= 0;
+ endcase // casex (parity_err[parity_vector_resets-1:0])
+
+ assign reset = reset_r;
+
+ always @(posedge reset)
+ $display("%m: Reset due to parity error. Vect:%h",parity_err);
+
+
+ // Signal an interrupt if signals above number parity_vector_resets go high
+ always @(posedge clk)
+ begin
+ if (wb_rst)
+ interrupt <= 0;
+ // Simulate level sensitive interrupt - clear upon read
+ else if (parity_err[parity_vector_width-1:parity_vector_resets]
+ & ~parity_err_mask)
+ interrupt <= 1;
+ else if (wb_stb_i & wb_ack_o)
+ interrupt <= 0;
+ end
+
+ assign wb_ack_o = wb_stb_i;
+
+ // Data bus output to indicate which thing caused parity error
+ always @(posedge clk)
+ begin
+ if (wb_rst)
+ wb_dat_o <= 0;
+ else if (parity_err[parity_vector_width-1:parity_vector_resets])
+ wb_dat_o <= parity_err[parity_vector_width-1:parity_vector_resets];
+ else if (wb_ack_o) // Clear data after read
+ wb_dat_o <= 0;
+ end
+
+
+
+endmodule // parity_err_handler
Index: boards/generic/ft/doc/README
===================================================================
--- boards/generic/ft/doc/README (nonexistent)
+++ boards/generic/ft/doc/README (revision 483)
@@ -0,0 +1,114 @@
+ OR1200 with Fault Tolerance features
+ ====================================
+
+This technology-independent build tests the OR1200's fault tolerance features,
+primarily parity error detection and behavior on its various internal RAMs.
+
+OR1200 fault tolerance features
+===============================
+
+The OR1200's parity detection mechanisms are enabled by adding
+"`define OR1200_RAM_PARITY" in the or1200_defines.v file.
+
+This enables parity detection logic on the generic technology memory
+implementations (to be inerred as block RAMs by FPGA synthesis tools, ASIC flow
+will have to provide custom solution) throughout the processor.
+
+The 5 places special control logic is added is in the instruction and data
+cache modules, the instruction and data MMU TLB caches, and the register file.
+
+An output vector is added to the top level of the OR1200 to indicate when a
+parity error is detected.
+
+The following behavior is exhibited when a parity error is detected in these
+locations:
+
+Instruction cache instruction RAM: Cache line refill
+Instruction cache tag RAM: Cache line refill
+Data cache data RAM: Cache line refill
+Data cache tag RAM: Cache line refill
+
+Instruction MMU TLB match register RAM: ITLB miss exception
+Instruction MMU TLB translate register RAM: ITLB miss exception
+Data MMU TLB match register RAM: DTLB miss exception
+Data MMU TLB translate register RAM: DTLB miss exception
+
+Register file: Execution continues, however a parity error in the register
+ file is considered unrecoverable, and the OR1200 should be
+ reset. This is not done automatically and should be the job
+ of an external unit.
+
+
+Testing System
+==============
+
+A special test-bench set up is contained in this testbench. The software test,
+or1200ft-parity, communicates with a verilog module via some memory locations
+in the main RAM on the Wishbone bus, sending commands which will inject errors
+into various RAMs throughout the OR1200. The software then exercises these
+areas of the RAM to ensure the parity error is detected.
+
+ORPSoC Configuration
+====================
+
+ORPSoC is configured with no peripherals, just bus arbiters, and a 1MB RAM on
+the Wishbone bus.
+
+The only additional module is the parity error handler.
+
+Parity Error Handler Module
+===========================
+
+This module is in rtl/verilog/parity_err_handler of this build's path.
+
+It takes the wishbone clock, a reset and the OR1200's parity error indicator
+vector, and will issue a reset to the OR1200 on detection of a RF parity error,
+and assert its interrupt line (to IRQ5 of OR1200's PIC) on detection of any
+instruction cache parity errors.
+
+The interrupt is edge-triggered by the incoming parity error indicator vector
+but behaves as a level-triggered interrupt source, and reading from it (it is
+at address 0xe0000000 on the Wishbone data bus) will clear the pending
+interrupt.
+
+It can be configured to reset or interrupt on any incoming parity error vector.
+
+
+Verilog Testbench Stimulus
+==========================
+
+The additional verilog testbench module, or1200_ft_stim, is used to inject
+parity errors into specific bits and words of the various RAMs in the design,
+to a simulate single event upset (SUE).
+
+The stimulus is controlled by the software test running on the processor. It
+(the testbench) polls some unused memory locations in the RAM on the Wishbone
+data bus, and communicates via very simple protocol with the processor.
+
+It can inject errors into all cache, MMU TLB and register file memories for
+a generic technology configuration.
+
+See the file for more details.
+
+Software Test
+=============
+
+The software test configures the various memories to contain useful data before
+commanding the verilog or1200_ft_stim module to inject errors there and
+accessing them again. See the file sw/tests/or1200ft/or1200ft-parity.c for
+exact details.
+
+The software test checks every bit possible in an output word from the cache
+and TLB memories,and checks every word and every bit of the register file
+memories.
+
+Running The Test
+================
+
+To run the fault tolerance test, the Modelsim simulator is used by default,
+but to switch back to using Icarus Verilog, run:
+
+ boards/generic/ft/sim/run$ make rtl-test TEST=or1200ft-parity SIMULATOR=icarus
+
+Or to run with Modelsim, remove "SIMULATOR=icarus".
+
Index: boards/generic/ft/backend/rtl/verilog/dummy.v
===================================================================
Index: boards/generic/ft/sim/run/Makefile
===================================================================
--- boards/generic/ft/sim/run/Makefile (nonexistent)
+++ boards/generic/ft/sim/run/Makefile (revision 483)
@@ -0,0 +1 @@
+include ../bin/Makefile
Index: boards/generic/ft/sim/bin/Makefile
===================================================================
--- boards/generic/ft/sim/bin/Makefile (nonexistent)
+++ boards/generic/ft/sim/bin/Makefile (revision 483)
@@ -0,0 +1,571 @@
+######################################################################
+#### ####
+#### ORPSoCv2 Testbenches Makefile ####
+#### ####
+#### Description ####
+#### ORPSoCv2 Testbenches Makefile, containing rules for ####
+#### configuring and running different tests on the current ####
+#### ORPSoC(v2) design. ####
+#### ####
+#### To do: ####
+#### ####
+#### Author(s): ####
+#### - Julius Baxter, julius@opencores.org ####
+#### ####
+#### ####
+######################################################################
+#### ####
+#### Copyright (C) 2009,2010 Authors and OPENCORES.ORG ####
+#### ####
+#### This source file may be used and distributed without ####
+#### restriction provided that this copyright statement is not ####
+#### removed from the file and that any derivative work contains ####
+#### the original copyright notice and the associated disclaimer. ####
+#### ####
+#### This source file is free software; you can redistribute it ####
+#### and/or modify it under the terms of the GNU Lesser General ####
+#### Public License as published by the Free Software Foundation; ####
+#### either version 2.1 of the License, or (at your option) any ####
+#### later version. ####
+#### ####
+#### This source is distributed in the hope that it will be ####
+#### useful, but WITHOUT ANY WARRANTY; without even the implied ####
+#### warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR ####
+#### PURPOSE. See the GNU Lesser General Public License for more ####
+#### details. ####
+#### ####
+#### You should have received a copy of the GNU Lesser General ####
+#### Public License along with this source; if not, download it ####
+#### from http://www.opencores.org/lgpl.shtml ####
+#### ####
+######################################################################
+
+# Name of the directory we're currently in
+CUR_DIR=$(shell pwd)
+
+# The root path of the whole project
+PROJECT_ROOT ?=$(CUR_DIR)/../../../../..
+
+DESIGN_NAME=orpsoc
+RTL_TESTBENCH_TOP=$(DESIGN_NAME)_testbench
+
+# Hardset the board name, even though we could probably determine it
+FPGA_VENDOR=generic
+BOARD_NAME=ft
+BOARD_DIR=$(PROJECT_ROOT)/boards/$(FPGA_VENDOR)/$(BOARD_NAME)
+
+# Export BOARD_PATH for the software makefiles
+BOARD=$(FPGA_VENDOR)/$(BOARD_NAME)
+export BOARD
+
+# Paths to other important parts of this test suite
+COMMON_RTL_DIR = $(PROJECT_ROOT)/rtl
+COMMON_RTL_VERILOG_DIR = $(COMMON_RTL_DIR)/verilog
+#COMMON_RTL_VHDL_DIR = $(COMMON_RTL_DIR)/vhdl
+
+BOARD_RTL_DIR=$(BOARD_DIR)/rtl
+BOARD_RTL_VERILOG_DIR=$(BOARD_RTL_DIR)/verilog
+# Only 1 include path for board builds - their own!
+BOARD_RTL_VERILOG_INCLUDE_DIR=$(BOARD_RTL_VERILOG_DIR)/include
+
+BOARD_BENCH_DIR=$(BOARD_DIR)/bench
+BOARD_BENCH_VERILOG_DIR=$(BOARD_BENCH_DIR)/verilog
+BOARD_BENCH_VERILOG_INCLUDE_DIR=$(BOARD_BENCH_VERILOG_DIR)/include
+
+COMMON_BENCH_DIR=$(PROJECT_ROOT)
+COMMON_BENCH_VERILOG_DIR=$(COMMON_BENCH_DIR)/verilog
+COMMON_BENCH_VERILOG_INCLUDE_DIR=$(COMMON_BENCH_VERILOG_DIR)/include
+
+# Top level files for DUT and testbench
+DUT_TOP=$(BOARD_RTL_VERILOG_DIR)/$(DESIGN_NAME)_top/$(DESIGN_NAME)_top.v
+BENCH_TOP=$(BOARD_BENCH_VERILOG_DIR)/$(DESIGN_NAME)_testbench.v
+
+# Software tests we'll run
+
+# Need this for individual test variables to not break
+TEST ?= or1200-simple
+
+TESTS ?= or1200-simple or1200-cbasic or1200-dctest or1200-float or1200-mmu or1200-basic or1200-except or1200-tick or1200-ticksyscall or1200ft-parity
+
+# Gets turned into verilog `define
+SIM_TYPE=RTL
+
+# Main defines file is from board include path
+PROJECT_VERILOG_DEFINES=$(BOARD_RTL_VERILOG_INCLUDE_DIR)/$(DESIGN_NAME)-defines.v
+
+# Detect technology to use for the simulation
+DESIGN_DEFINES=$(shell cat $(PROJECT_VERILOG_DEFINES) | sed s://.*::g | sed s:\`:\#:g | sed 's:^[ ]*::' | awk '{print};/^\#define/{printf "_%s=%s\n",$$2,$$2}' | grep -v PERIOD | cpp -P | sed s:^_::g | sed s:=$$::g )
+
+# Rule to look at what defines are being extracted from main file
+print-defines:
+ @echo echo; echo "\t### Design defines ###"; echo;
+ @echo "\tParsing "$(PROJECT_VERILOG_DEFINES)" and exporting:"
+ @echo $(DESIGN_DEFINES)
+
+print-tests:
+ @echo; echo; echo "\t### Software tests to be run ###"; echo;
+ @echo $(TESTS)
+ @echo
+
+# Simulation directories
+SIM_DIR ?=$(BOARD_DIR)/sim
+RTL_SIM_DIR=$(SIM_DIR)
+RTL_SIM_RUN_DIR=$(RTL_SIM_DIR)/run
+RTL_SIM_BIN_DIR=$(RTL_SIM_DIR)/bin
+RTL_SIM_RESULTS_DIR=$(RTL_SIM_DIR)/out
+
+# Testbench paths
+BOARD_BENCH_DIR=$(BOARD_DIR)/bench
+BOARD_BENCH_VERILOG_DIR=$(BOARD_BENCH_DIR)/verilog
+COMMON_BENCH_DIR=$(PROJECT_ROOT)/bench
+COMMON_BENCH_VERILOG_DIR=$(COMMON_BENCH_DIR)/verilog
+
+#BENCH_VHDL_DIR=$(BENCH_DIR)/vhdl
+# No SystemC or Verilator support for this build
+#BENCH_SYSC_DIR=$(BENCH_DIR)/sysc
+#BENCH_SYSC_SRC_DIR=$(BENCH_SYSC_DIR)/src
+#BENCH_SYSC_INCLUDE_DIR=$(BENCH_SYSC_DIR)/include
+
+# Backend directories
+# This one is the board build's backend dir.
+BOARD_BACKEND_DIR=$(BOARD_DIR)/backend
+BOARD_BACKEND_VERILOG_DIR=$(BOARD_BACKEND_DIR)/rtl/verilog
+TECHNOLOGY_BACKEND_DIR=$(BOARD_DIR)/../backend
+# This path is for the technology library
+TECHNOLOGY_BACKEND_VERILOG_DIR=$(TECHNOLOGY_BACKEND_DIR)/rtl/verilog
+
+# Synthesis directory for board
+BOARD_SYN_DIR=$(BOARD_DIR)/syn/synplify
+BOARD_SYN_OUT_DIR=$(BOARD_SYN_DIR)/out
+
+# System software dir
+COMMON_SW_DIR=$(PROJECT_ROOT)/sw
+BOARD_SW_DIR=$(BOARD_DIR)/sw
+
+
+# Suffix of file to check after each test for the string
+TEST_OUT_FILE_SUFFIX=-general.log
+TEST_OK_STRING=8000000d
+
+# Dynamically generated verilog file defining configuration for various things
+# Rule actually generating this is found in definesgen.inc file.
+TEST_DEFINES_VLG=test-defines.v
+# Set V=1 when calling make to enable verbose output
+# mainly for debugging purposes.
+ifeq ($(V), 1)
+Q=
+QUIET=
+else
+Q ?=@
+QUIET=-quiet
+endif
+
+# Modelsim variables
+MGC_VSIM=vsim
+MGC_VLOG_COMP=vlog
+MGC_VHDL_COMP=vcom
+MODELSIM=modelsim
+
+# Icarus variables
+ICARUS_COMPILE=iverilog
+ICARUS_RUN=vvp
+ICARUS_SCRIPT=icarus.scr
+ICARUS_SIM_EXE=vlogsim.elf
+ICARUS=icarus
+
+
+# Default simulator is Modelsim here as we're using the ProASIC3
+# libraries which are not compilable with Icarus.
+# Set SIMULATOR=modelsim to use Modelsim (Default)
+# Set SIMULATOR=ncverilog to use Cadence's NC-Verilog - TODO
+# Set SIMULATOR=icarus to use Icarus Verilog (Not supported for this board)
+
+SIMULATOR ?= $(MODELSIM)
+
+#
+# Modelsim-specific settings
+#
+VOPT_ARGS=$(QUIET) -suppress 2241
+# If VCD dump is desired, tell Modelsim not to optimise
+# away everything.
+ifeq ($(VCD), 1)
+#VOPT_ARGS=-voptargs="+acc=rnp"
+VOPT_ARGS=+acc=rnpqv
+endif
+# VSIM commands
+# Suppressed warnings - 3009: Failed to open $readmemh() file
+# Suppressed warnings - 3009: Module 'blah' does not have a `timescale directive in effect, but previous modules do.
+# Suppressed warnings - 8598: Non-positive replication multiplier inside concat. Replication will be ignored
+VSIM_ARGS= -suppress 7 -suppress 3009 -suppress 8598 -c $(QUIET) -do "set StdArithNoWarnings 1; run -all; exit"
+# Modelsim VPI settings
+ifeq ($(VPI), 1)
+VPI_LIBS=$(VPI_SRC_C_DIR)/$(MODELTECH_VPILIB)
+VSIM_ARGS += -pli $(VPI_SRC_C_DIR)/$(MODELTECH_VPILIB)
+endif
+# Rule to make the VPI library for modelsim
+$(VPI_SRC_C_DIR)/$(MODELTECH_VPILIB): $(VPI_SRCS)
+ $(MAKE) -C $(VPI_SRC_C_DIR) $(MODELTECH_VPILIB)
+
+#
+# Verilog DUT source variables
+#
+
+# First consider any modules we'll use gatelevel descriptions of.
+# These will have to be set on the command line
+GATELEVEL_MODULES ?=
+
+# First we get a list of modules in the RTL path of the board's path.
+# Next we check which modules not in the board's RTL path are in the root RTL
+# path (modules which can be commonly instantiated, but over which board
+# build-specific versions take precedence.)
+
+# Paths under board/***/rtl/verilog we wish to exclude when getting modules
+BOARD_VERILOG_MODULES_EXCLUDE= include $(GATELEVEL_MODULES)
+BOARD_VERILOG_MODULES_DIR_LIST=$(shell ls $(BOARD_RTL_VERILOG_DIR))
+# Apply exclude to list of modules
+BOARD_RTL_VERILOG_MODULES=$(filter-out $(BOARD_VERILOG_MODULES_EXCLUDE),$(BOARD_VERILOG_MODULES_DIR_LIST))
+
+# Rule for debugging this script
+print-board-modules:
+ @echo echo; echo "\t### Board verilog modules ###"; echo
+ @echo $(BOARD_RTL_VERILOG_MODULES)
+
+# Now get list of modules that we don't have a version of in the board path
+COMMON_VERILOG_MODULES_EXCLUDE= include
+COMMON_VERILOG_MODULES_EXCLUDE += $(BOARD_RTL_VERILOG_MODULES)
+COMMON_VERILOG_MODULES_EXCLUDE += $(GATELEVEL_MODULES)
+
+COMMON_RTL_VERILOG_MODULES_DIR_LIST=$(shell ls $(COMMON_RTL_VERILOG_DIR))
+COMMON_RTL_VERILOG_MODULES=$(filter-out $(COMMON_VERILOG_MODULES_EXCLUDE), $(COMMON_RTL_VERILOG_MODULES_DIR_LIST))
+
+
+# Add these to exclude their RTL directories from being included in scripts
+
+
+
+# Rule for debugging this script
+print-common-modules-exclude:
+ @echo echo; echo "\t### Common verilog modules being excluded due to board versions ###"; echo
+ @echo "$(COMMON_VERILOG_MODULES_EXCLUDE)"
+
+print-common-modules:
+ @echo echo; echo "\t### Verilog modules from common RTL dir ###"; echo
+ @echo $(COMMON_RTL_VERILOG_MODULES)
+
+# List of verilog source files (only .v files!)
+# Board RTL modules first
+RTL_VERILOG_SRC=$(shell for module in $(BOARD_RTL_VERILOG_MODULES); do if [ -d $(BOARD_RTL_VERILOG_DIR)/$$module ]; then ls $(BOARD_RTL_VERILOG_DIR)/$$module/*.v; fi; done)
+# Common RTL module source
+RTL_VERILOG_SRC +=$(shell for module in $(COMMON_RTL_VERILOG_MODULES); do if [ -d $(COMMON_RTL_VERILOG_DIR)/$$module ]; then ls $(COMMON_RTL_VERILOG_DIR)/$$module/*.v; fi; done)
+
+# List of verilog includes from board RTL path - only for rule sensitivity
+RTL_VERILOG_INCLUDES=$(shell ls $(BOARD_RTL_VERILOG_INCLUDE_DIR)/*.*)
+
+print-verilog-src:
+ @echo echo; echo "\t### Verilog source ###"; echo
+ @echo $(RTL_VERILOG_SRC)
+
+# Rules to make RTL we might need
+# Expects modules, if they need making, to have their top verilog file to
+# correspond to their module name, and the directory should have a make file
+# and rule which works for this command.
+# Add name of module to this list, currently only does verilog ones.
+# Rule 'rtl' is called just before generating DUT modelsim compilation script
+RTL_TO_CHECK=
+rtl:
+ $(Q)for module in $(RTL_TO_CHECK); do \
+ $(MAKE) -C $(RTL_VERILOG_DIR)/$$module $$module.v; \
+ done
+
+#
+# VHDL DUT source variables
+#
+# VHDL modules
+#RTL_VHDL_MODULES=$(shell ls $(RTL_VHDL_DIR))
+# VHDL sources
+#RTL_VHDL_SRC=$(shell for module in $(RTL_VHDL_MODULES); do if [ -d $(RTL_VHDL_DIR)/$$module ]; then ls $(RTL_VHDL_DIR)/$$module/*.vhd; fi; done)
+#print-vhdl-src:
+# @echo echo; echo "\t### VHDL modules and source ###"; echo
+# @echo "modules: "; echo $(RTL_VHDL_MODULES); echo
+# @echo "source: "$(RTL_VHDL_SRC)
+
+#
+# Testbench source
+#
+BOARD_BENCH_VERILOG_SRC=$(shell ls $(BOARD_BENCH_VERILOG_DIR)/*.v | grep -v $(DESIGN_NAME)_testbench )
+BOARD_BENCH_VERILOG_SRC_FILES=$(notdir $(BOARD_BENCH_VERILOG_SRC))
+
+# Now only take the source from the common path that we don't already have in
+# our board's
+COMMON_BENCH_VERILOG_DIR_LS=$(shell ls $(COMMON_BENCH_VERILOG_DIR)/*.v)
+COMMON_BENCH_VERILOG_SRC_FILES=$(notdir $(COMMON_BENCH_VERILOG_DIR_LS))
+COMMON_BENCH_VERILOG_SRC_FILTERED=$(filter-out $(BOARD_BENCH_VERILOG_SRC_FILES) $(DESIGN_NAME)_testbench.v,$(COMMON_BENCH_VERILOG_SRC_FILES))
+COMMON_BENCH_VERILOG_SRC=$(addprefix $(COMMON_BENCH_VERILOG_DIR)/, $(COMMON_BENCH_VERILOG_SRC_FILTERED))
+
+print-board-bench-src:
+ $(Q)echo "\tBoard bench verilog source"; \
+ echo $(BOARD_BENCH_VERILOG_SRC)
+
+print-common-bench-src:
+ $(Q)echo "\Common bench verilog source"; \
+ echo $(COMMON_BENCH_VERILOG_SRC)
+
+# Testbench source subdirectory detection (exclude include, we always use
+# board bench include directory!)
+BOARD_BENCH_VERILOG_SUBDIRS=$(shell cd $(BOARD_BENCH_VERILOG_DIR) && ls -d */ | grep -v include)
+COMMON_BENCH_VERILOG_SUBDIRS=$(shell cd $(COMMON_BENCH_VERILOG_DIR) && ls -d */ | grep -v include)
+
+# Get rid of ones we have a copy of locally
+COMMON_BENCH_VERILOG_SUBDIRS_EXCLUDE_BOARDS=$(filter-out $(BOARD_BENCH_VERILOG_SUBDIRS),$(COMMON_BENCH_VERILOG_SUBDIRS))
+
+# Construct list of paths we will want to include
+BENCH_VERILOG_SUBDIRS=$(addprefix $(COMMON_BENCH_VERILOG_DIR)/,$(COMMON_BENCH_VERILOG_SUBDIRS_EXCLUDE_BOARDS))
+BENCH_VERILOG_SUBDIRS += $(addprefix $(BOARD_BENCH_VERILOG_DIR)/,$(BOARD_BENCH_VERILOG_SUBDIRS))
+
+# Finally, add include path from local bench path
+BENCH_VERILOG_SUBDIRS += $(BOARD_BENCH_VERILOG_DIR)/include
+
+print-board-bench-subdirs:
+ $(Q)echo "\tBoard bench subdirectories"; \
+ echo $(BOARD_BENCH_VERILOG_SUBDIRS)
+
+print-common-bench-subdirs:
+ $(Q)echo "\tCommon bench subdirectories"; \
+ echo $(COMMON_BENCH_VERILOG_SUBDIRS)
+
+print-bench-subdirs:
+ $(Q)echo "\tBench subdirectories"; \
+ echo $(BENCH_VERILOG_SUBDIRS)
+
+
+# Backend technology library files
+# We don't do this for the board backend stuff - that should all be properly
+# named, and so we only need to pass the "-y" option for that path.
+BACKEND_TECHNOLOGY_VERILOG_SRC=$(shell ls $(TECHNOLOGY_BACKEND_VERILOG_DIR)/*.v )
+BOARD_BACKEND_VERILOG_SRC=$(shell ls $(BOARD_BACKEND_VERILOG_DIR)/*.v )
+
+#
+# Compile script generation rules:
+#
+
+# Modelsim library compilation rules
+
+# Backend script generation - make these rules sensitive to source and includes
+modelsim_backend.scr: $(BOARD_BACKEND_VERILOG_SRC)
+ $(Q)echo "+incdir+"$(TECHNOLOGY_BACKEND_VERILOG_DIR) > $@;
+ $(Q)echo "-y " $(BOARD_BACKEND_VERILOG_DIR) >> $@
+ $(Q)echo "+libext+.v" >> $@;
+ $(Q)for vsrc in $(BACKEND_TECHNOLOGY_VERILOG_SRC); do echo $$vsrc >> $@; done
+ $(Q)echo >> $@;
+
+# DUT compile script
+modelsim_dut.scr: rtl $(RTL_VERILOG_SRC) $(RTL_VERILOG_INCLUDES)
+ $(Q)echo "+incdir+"$(BOARD_RTL_VERILOG_INCLUDE_DIR) > $@;
+ $(Q)echo "+incdir+"$(BOARD_BENCH_VERILOG_INCLUDE_DIR) >> $@;
+ $(Q)echo "+libext+.v" >> $@;
+ $(Q)for module in $(BOARD_RTL_VERILOG_MODULES); do if [ -d $(BOARD_RTL_VERILOG_DIR)/$$module ]; then echo "-y " $(BOARD_RTL_VERILOG_DIR)/$$module >> $@; fi; done
+ $(Q)for module in $(COMMON_RTL_VERILOG_MODULES); do if [ -d $(COMMON_RTL_VERILOG_DIR)/$$module ]; then echo "-y " $(COMMON_RTL_VERILOG_DIR)/$$module >> $@; fi; done
+ $(Q)echo "-y " $(BOARD_BACKEND_VERILOG_DIR) >> $@;
+ $(Q)if [ ! -z "$$GATELEVEL_MODULES" ]; \
+ then echo "-y " $(BOARD_SYN_OUT_DIR) >> $@; \
+ echo "+libext+.vm" >> $@; \
+ fi
+ $(Q)echo >> $@
+
+modelsim_bench.scr: $(BOARD_BENCH_VERILOG_SRC) $(COMMON_BENCH_VERILOG_SRC)
+ $(Q)echo "+incdir+"$(BOARD_BENCH_VERILOG_INCLUDE_DIR) > $@;
+ $(Q)echo "+incdir+"$(COMMON_BENCH_VERILOG_INCLUDE_DIR) >> $@;
+ $(Q)for path in $(BENCH_VERILOG_SUBDIRS); do echo "+incdir+"$$path >> $@; done
+ $(Q)for path in $(BENCH_VERILOG_SUBDIRS); do echo "-y "$$path >> $@; done
+ $(Q)echo "+incdir+"$(BOARD_RTL_VERILOG_INCLUDE_DIR) >> $@;
+ $(Q)echo "+libext+.v" >> $@;
+ $(Q)for vsrc in $(BOARD_BENCH_VERILOG_SRC); do echo $$vsrc >> $@; done
+ $(Q)for vsrc in $(COMMON_BENCH_VERILOG_SRC); do echo $$vsrc >> $@; done
+ $(Q)echo >> $@
+
+# Modelsim library compilation rules
+#BACKEND_LIB=lib_backend
+BACKEND_LIB=
+#$(BACKEND_LIB): modelsim_backend.scr
+# $(Q)if [ ! -e $@ ]; then vlib $@; fi
+# $(Q)echo; echo "\t### Compiling backend library ###"; echo
+# $(Q)vlog -nologo $(QUIET) -work $@ -f $<
+
+# Compile DUT into "work" library
+work: modelsim_dut.scr
+ $(Q)if [ ! -e $@ ]; then vlib $@; fi
+ $(Q)echo; echo "\t### Compiling Verilog design library ###"; echo
+ $(Q)vlog $(QUIET) -f $< $(DUT_TOP)
+
+# Single compile rule
+.PHONY : $(MODELSIM)
+$(MODELSIM): modelsim_bench.scr $(TEST_DEFINES_VLG) $(BACKEND_LIB) $(VPI_LIBS) \
+ work
+ $(Q)echo; echo "\t### Compiling testbench ###"; echo
+ $(Q)vlog $(QUIET) -nologo -incr $(BENCH_TOP) -f $<
+# $(Q)vopt $(QUIET) $(RTL_TESTBENCH_TOP) $(VOPT_ARGS) -L $(BACKEND_LIB) \
+ -o tb
+ $(Q)vopt $(QUIET) $(RTL_TESTBENCH_TOP) $(VOPT_ARGS) -o tb
+ $(Q)echo; echo "\t### Launching simulation ###"; echo
+ $(Q)vsim $(VSIM_ARGS) tb
+
+#
+# Icarus Verilog simulator build and run rules
+#
+.PHONY: $(ICARUS_SCRIPT)
+$(ICARUS_SCRIPT): $(BOARD_BENCH_VERILOG_SRC) $(COMMON_BENCH_VERILOG_SRC) \
+ $(RTL_VERILOG_SRC) $(RTL_VERILOG_INCLUDES)
+ $(Q)echo "# Icarus Verilog simulation script" > $@
+ $(Q)echo "# Auto generated. Any alterations will be written over!" >> $@
+ $(Q)echo "+incdir+"$(BOARD_RTL_VERILOG_INCLUDE_DIR) >> $@;
+ $(Q)echo "+libext+.v" >> $@;
+ $(Q)for module in $(BOARD_RTL_VERILOG_MODULES); do if [ -d $(BOARD_RTL_VERILOG_DIR)/$$module ]; then echo "-y " $(BOARD_RTL_VERILOG_DIR)/$$module >> $@; fi; done
+ $(Q)for module in $(COMMON_RTL_VERILOG_MODULES); do if [ -d $(COMMON_RTL_VERILOG_DIR)/$$module ]; then echo "-y " $(COMMON_RTL_VERILOG_DIR)/$$module >> $@; fi; done
+ $(Q)echo "-y " $(BOARD_BACKEND_VERILOG_DIR) >> $@;
+ $(Q)echo "+incdir+"$(BOARD_BENCH_VERILOG_INCLUDE_DIR) >> $@;
+ $(Q)echo "+incdir+"$(COMMON_BENCH_VERILOG_INCLUDE_DIR) >> $@;
+ $(Q)for path in $(BENCH_VERILOG_SUBDIRS); do echo "+incdir+"$$path >> $@; done
+ $(Q)for path in $(BENCH_VERILOG_SUBDIRS); do echo "-y "$$path >> $@; done
+ $(Q)for vsrc in $(BOARD_BENCH_VERILOG_SRC); do echo $$vsrc >> $@; done
+ $(Q)for vsrc in $(COMMON_BENCH_VERILOG_SRC); do echo $$vsrc >> $@; done
+ $(Q)echo $(BENCH_TOP) >> $@;
+ $(Q) echo >> $@
+
+# Icarus design compilation rule
+$(ICARUS_SIM_EXE): $(ICARUS_SCRIPT) $(TEST_DEFINES_VLG)
+ $(Q)echo; echo "\t### Compiling ###"; echo
+ $(Q) $(ICARUS_COMPILE) -s$(RTL_TESTBENCH_TOP) -c $< -o $@
+
+# Icarus simulation run rule
+$(ICARUS): $(ICARUS_SIM_EXE) $(ICARUS_VPI_LIB)
+ $(Q)echo; echo "\t### Launching simulation ###"; echo
+ $(Q) $(ICARUS_RUN) $(ICARUS_VPI_ARGS) -l ../out/$(ICARUS_RUN).log $<
+
+
+.PHONY: rtl-test
+rtl-test: clean-sim-test-sw sw clean-test-defines $(TEST_DEFINES_VLG) \
+ $(SIMULATOR)
+
+# Run an RTL test followed by checking of generated results
+rtl-test-with-check: rtl-test
+ $(Q)$(MAKE) check-test-log; \
+ if [ $$? -ne 0 ]; then \
+ echo; echo "\t### "$(TEST)" test FAIL ###"; echo; \
+ else \
+ echo; echo "\t### "$(TEST)" test OK ###"; echo; \
+ fi
+
+# Do check, don't print anything out
+rtl-test-with-check-no-print: rtl-test check-test-log
+
+# Main RTL test loop
+rtl-tests:
+ $(Q)for test in $(TESTS); do \
+ export TEST=$$test; \
+ $(MAKE) rtl-test-with-check-no-print; \
+ if [ $$? -ne 0 ]; then break; fi; \
+ echo; echo "\t### $$test test OK ###"; echo; \
+ done
+
+
+.PHONY: check-test-log
+check-test-log:
+ $(Q)echo "#!/bin/bash" > $@
+ $(Q)echo "function check-test-log { if [ \`grep -c -i "$(TEST_OK_STRING)" "$(RTL_SIM_RESULTS_DIR)"/"$(TEST)$(TEST_OUT_FILE_SUFFIX)"\` -gt 0 ]; then return 0; else return 1; fi; }" >> $@
+ $(Q)echo "check-test-log" >> $@
+ $(Q)chmod +x $@
+ $(Q) echo; echo "\t### Checking simulation results for "$(TEST)" test ###"; echo;
+ $(Q)./$@
+
+# Include the test-defines.v generation rule
+include $(PROJECT_ROOT)/sim/bin/definesgen.inc
+
+#
+# Software make rules (called recursively)
+#
+
+# Path for the current test
+# First check for a local copy of the test. If it doesn't exist then we
+# default to the software tests in the root directory
+TEST_MODULE=$(shell echo $(TEST) | cut -d "-" -f 1)
+BOARD_SW_TEST_DIR=$(BOARD_SW_DIR)/tests/$(TEST_MODULE)/sim
+COMMON_SW_TEST_DIR=$(COMMON_SW_DIR)/tests/$(TEST_MODULE)/sim
+# Do this by testing for the file's existence
+SW_TEST_DIR=$(shell if [ -e $(BOARD_SW_TEST_DIR)/$(TEST).[cS] ]; then echo $(BOARD_SW_TEST_DIR); else echo $(COMMON_SW_TEST_DIR); fi)
+
+print-test-sw-dir:
+ @echo; echo "\tTest software is in the following path"; echo;
+ @echo $(BOARD_SW_DIR); echo;
+ @echo $(BOARD_SW_TEST_DIR); echo;
+ @echo $(SW_TEST_DIR); echo;
+
+print-sw-tests:
+ $(Q) $(MAKE) -C $(COMMON_SW_DIR)/lib print-sw-tests
+ $(Q) $(MAKE) -C $(COMMON_SW_DIR)/lib print-sw-tests-subdirs
+
+
+# Name of the image the RAM model will attempt to load via Verilog $readmemh
+# system function.
+
+SIM_SW_IMAGE ?=sram.vmem
+
+.PHONY : sw
+sw: $(SIM_SW_IMAGE)
+
+sram.vmem: $(SW_TEST_DIR)/$(TEST).vmem
+ $(Q)if [ -L $@ ]; then unlink $@; fi
+ $(Q)ln -s $< $@
+
+.PHONY: $(SW_TEST_DIR)/$(TEST).flashin
+$(SW_TEST_DIR)/$(TEST).flashin:
+ $(Q) echo; echo "\t### Compiling software ###"; echo;
+ $(Q)$(MAKE) -C $(SW_TEST_DIR) $(TEST).flashin
+
+.PHONY: $(SW_TEST_DIR)/$(TEST).vmem
+$(SW_TEST_DIR)/$(TEST).vmem:
+ $(Q) echo; echo "\t### Compiling software ###"; echo;
+ $(Q)$(MAKE) -C $(SW_TEST_DIR) $(TEST).vmem
+
+# Create test software disassembly
+
+sw-dis: $(SW_TEST_DIR)/$(TEST).dis
+ $(Q)cp -v $< .
+
+$(SW_TEST_DIR)/$(TEST).dis:
+ $(Q)$(MAKE) -C $(SW_TEST_DIR) $(TEST).dis
+
+#
+# Cleaning rules
+#
+clean: clean-sim clean-sim-test-sw clean-out clean-sw
+
+clean-sim:
+ $(Q) echo; echo "\t### Cleaning simulation run directory ###"; echo;
+ $(Q)rm -rf *.* lib_* work transcript check-test-log
+# No VPI support for now. $(Q) if [ -e $(VPI_SRC_C_DIR) ]; then $(MAKE) -C $(VPI_SRC_C_DIR) clean; fi
+
+clean-out:
+ $(Q)rm -rf $(RTL_SIM_RESULTS_DIR)/*.*
+
+clean-test-defines:
+ $(Q)rm -f $(TEST_DEFINES_VLG)
+
+clean-sim-test-sw:
+ $(Q)if [ -e $(SIM_SW_IMAGE) ]; then unlink $(SIM_SW_IMAGE); fi
+
+clean-sw:
+ $(Q) echo; echo "\t### Cleaning simulation sw directories ###"; echo;
+ $(Q) $(MAKE) -C $(COMMON_SW_DIR)/lib distclean
+
+clean-rtl:
+ $(Q) echo; echo "\t### Cleaning generated verilog RTL ###"; echo;
+ for module in $(RTL_TO_CHECK); do \
+ $(MAKE) -C $(RTL_VERILOG_DIR)/$$module clean; \
+ done
+
+# Removes any checked out RTL
+distclean: clean
+ $(Q) echo; echo "\t### Cleaning generated verilog RTL ###"; echo;
+ $(Q)for module in $(RTL_TO_CHECK); do \
+ $(MAKE) -C $(RTL_VERILOG_DIR)/$$module distclean; \
+ done
Index: boards/generic/ft/sw/tests/or1200ft/sim/or1200ft-parity.c
===================================================================
--- boards/generic/ft/sw/tests/or1200ft/sim/or1200ft-parity.c (nonexistent)
+++ boards/generic/ft/sw/tests/or1200ft/sim/or1200ft-parity.c (revision 483)
@@ -0,0 +1,1035 @@
+/*
+ *
+ * Communicate with the verilog testbench via memory, send commands for it to
+ * inject errors to I/D cache content RAM and tag RAM, I/D MMU translate and
+ * match RAMs, and the register file RAM.
+ *
+ * On instruction/data cache parity error we should receive an interrupt.
+ *
+ * On I/MMU parity error we should get an TLB miss exception, causing a software
+ * flush before continuing.
+ *
+ * On register file parity error we reset via assertion of reset signal to
+ * OR1200.
+ *
+ * To allow some variables to maintain their values between resets, we store
+ * them in #defined memory locations.
+ *
+ * The interrupt and exception vector routines contain important code allowing
+ * the test to proceed, so if they don't fire (due to parity errors not being
+ * injected, exercised or detected properly) then the test will repeat itself
+ * over and over with the same values, and should be stopped by the user and
+ * investigated.
+ *
+ * The ft_state pointer points to the overall state of the test.
+ *
+ * Julius Baxter, julius@opencores.org
+ *
+ */
+
+
+#include "cpu-utils.h"
+#include "spr-defs.h"
+#include "printf.h"
+#include "board.h"
+
+// define to jump to a certain test immediately
+//#define JUMP_TO_TEST 3
+
+#define FT_MEM 0x4
+#define FT_GO_COMMAND 0x88000000
+
+#define FT_STIM_CMD_OFF 24
+
+#define FT_STIM_CMD_IC_RAM_FAULT 0x1
+#define FT_STIM_CMD_IC_TAG_FAULT 0x2
+#define FT_STIM_CMD_DC_RAM_FAULT 0x3
+#define FT_STIM_CMD_DC_TAG_FAULT 0x4
+
+#define FT_STIM_CMD_DMMU_MR_FAULT 0x5
+#define FT_STIM_CMD_DMMU_TR_FAULT 0x6
+#define FT_STIM_CMD_IMMU_MR_FAULT 0x7
+#define FT_STIM_CMD_IMMU_TR_FAULT 0x8
+#define FT_STIM_CMD_RF_FAULT 0x9
+
+#define FT_STIM_CMD_DEBUG_ON (0xff<> SPR_DMMUCFGR_NTS_OFF);
+
+
+
+ // Initialise all match/translate register pairs, set 1-1 mapping
+ for (i = 0; i < ways; i++)
+ for (j = 0; j < sets; j++){
+ mtspr (SPR_DTLBMR_BASE(i) + j, (j*PAGE_SIZE) |
+ SPR_DTLBMR_V);
+ mtspr (SPR_DTLBTR_BASE(i) + j, (j*PAGE_SIZE) |
+ DTLB_PR_NOLIMIT);
+ }
+
+ // Set cache inhibit for first page
+ mtspr (SPR_DTLBTR_BASE(0), 0 | DTLB_PR_NOLIMIT | SPR_DTLBTR_CI);
+
+}
+
+
+// If DC is present, init DMMU to disable cache on first page, which we'll
+// use to communicate to the fault injection testbench.
+int
+dmmu_init(void)
+{
+
+ unsigned long upr;
+
+ // Only do this if DMMU and DC are here
+
+ // Get the unit present register
+ upr = mfspr(SPR_UPR);
+ if ((upr & SPR_UPR_DCP) && !(upr & SPR_UPR_DMP))
+ // Cannot do the test
+ exit(1);
+
+ if (!(upr & SPR_UPR_DCP))
+ // No need to config MMU - no data cache
+ return 1;
+
+ dmmu_tlb_one_to_one_reset();
+
+ /* Enable DMMU */
+ lo_dmmu_en ();
+
+ return 0;
+
+}
+
+// Initialise iMMU
+void
+immu_tlb_one_to_one_reset(void)
+{
+
+ int i, j, sets, ways;
+ unsigned long immucfgr;
+
+ // Determine number of TLB sets
+ immucfgr = mfspr(SPR_IMMUCFGR);
+
+ ways = (immucfgr & SPR_IMMUCFGR_NTW) + 1;
+ sets = 1 << ((immucfgr & SPR_IMMUCFGR_NTS)>> SPR_IMMUCFGR_NTS_OFF);
+
+ // Initialise all match/translate register pairs, set 1-1 mapping
+ for (i = 0; i < ways; i++)
+ for (j = 0; j < sets; j++){
+ mtspr (SPR_ITLBMR_BASE(i) + j, (j*PAGE_SIZE) |
+ SPR_ITLBMR_V);
+ mtspr (SPR_ITLBTR_BASE(i) + j, (j*PAGE_SIZE) |
+ ITLB_PR_NOLIMIT);
+ }
+}
+
+void
+test_state_update(void)
+{
+ volatile int * test_state1 = (volatile int*)FT_STATE_TEST_STATE1_MEM;
+ volatile int * test_state2 = (volatile int*)FT_STATE_TEST_STATE2_MEM;
+ volatile int * test_state3 = (volatile int*)FT_STATE_TEST_STATE3_MEM;
+ volatile int * ft_state = (volatile int*)FT_STATE_RECORD_MEM;
+
+ // Disable DC here
+ mtspr(SPR_SR, (mfspr(SPR_SR) & ~SPR_SR_DCE));
+ // Flush line of test state
+ mtspr(SPR_DCBIR, (unsigned long) test_state1);
+
+ (*test_state1)++;
+
+ if (*test_state1 == *test_state2)
+ (*ft_state)++;
+
+}
+
+// Initialise TLB contents and enable iMMU
+int
+immu_init(void)
+{
+
+ int i, j, sets, ways;
+ unsigned long upr;
+ unsigned long immucfgr;
+
+ // Only do this if iMMU here
+
+ // Get the unit present register
+ upr = mfspr(SPR_UPR);
+ if (!(upr & SPR_UPR_IMP))
+ return 1;
+
+ immu_tlb_one_to_one_reset();
+
+ /* Enable IMMU */
+ lo_immu_en ();
+
+ return 0;
+}
+
+void
+itlb_miss_handler (void)
+{
+ // This was probably cause by injection of parity error
+ // We just reset iTLB in event of miss
+ printf("iTLB miss handler resetting iTLB\n");
+
+ immu_tlb_one_to_one_reset();
+
+ test_state_update();
+
+}
+
+void
+dtlb_miss_handler (void)
+{
+ // This was probably cause by injection of parity error
+ // We just reset iTLB in event of miss
+ printf("dTLB miss handler resetting iTLB\n");
+
+ dmmu_tlb_one_to_one_reset();
+
+ test_state_update();
+
+}
+
+
+unsigned long
+inline inline_mfspr(unsigned long spr)
+{
+ unsigned long value;
+ asm("l.mfspr\t\t%0,%1,0" : "=r" (value) : "r" (spr));
+ return value;
+}
+
+void
+parity_error_interrupt(void)
+{
+ // Read parity error indicator. Reading also clears interrupt line.
+ char parerr = REG8(PARERR_BASE);
+
+ printf("Parity error interrupt: 0x%02x\n",parerr);
+
+ test_state_update();
+
+ // Clear iTLB
+ //immu_tlb_one_to_one_reset();
+
+ return;
+}
+
+
+void
+dummy_function()
+{
+ volatile int i;
+
+ report(0xdfdfdfdf);
+
+ for(i=0;i<64;i++);
+
+ return;
+}
+
+void
+copy_function(void *insn_area, void* dummy_function, int nwords)
+{
+ int i;
+ unsigned long *p1 = (unsigned long *)insn_area;
+ unsigned long *p2 = (unsigned long *)dummy_function;
+ for (i = 0; i < nwords; i++)
+ p1[i] = p2[i];
+}
+
+
+void
+ic_test_setup()
+{
+ //Initialise handler vector
+ int_init();
+ int_add(PARERR_IRQ, parity_error_interrupt, 0);
+
+ // Enable interrupts in supervisor register
+ cpu_enable_user_interrupts();
+}
+
+
+void
+dc_test_setup()
+{
+ //Initialise handler vector
+ int_init();
+ int_add(PARERR_IRQ, parity_error_interrupt, 0);
+
+ // Enable interrupts in supervisor register
+ cpu_enable_user_interrupts();
+}
+
+
+int
+dmmu_test_setup(unsigned long data_location)
+{
+ unsigned long mmucfgr;
+ int mmu_tlb_reg, mmusets;
+
+ // Determine number of mmusets
+ mmucfgr = mfspr (SPR_DMMUCFGR);
+ mmusets = 1 << ((mmucfgr & SPR_DMMUCFGR_NTS)>>
+ SPR_DMMUCFGR_NTS_OFF);
+ // Now get TLB register that will be used when matching/translating
+ // VA for page dummy_function() is in.
+
+ mmu_tlb_reg = (data_location / PAGE_SIZE) % mmusets;
+ report (data_location);
+ report (mmu_tlb_reg);
+
+ // Enable interrupts and install handler. Error will trigger
+ // an interrupt.
+
+ //Initialise handler vector
+ int_init();
+ int_add(PARERR_IRQ, parity_error_interrupt, 0);
+
+ // Add handler for dTLB miss (parity error may show up as
+ // miss.)
+ add_handler(0x9, dtlb_miss_handler);
+
+ // Enable interrupts in supervisor register
+ cpu_enable_user_interrupts();
+
+ return mmu_tlb_reg;
+
+}
+
+
+
+int
+immu_test_setup(void)
+{
+ unsigned long mmucfgr;
+ int mmu_tlb_reg, mmusets;
+
+ // Determine number of mmusets
+ mmucfgr = mfspr(SPR_IMMUCFGR);
+ mmusets = 1 << ((mmucfgr & SPR_IMMUCFGR_NTS)>>
+ SPR_IMMUCFGR_NTS_OFF);
+ // Now get TLB register that will be used when matching/translating
+ // VA for page dummy_function() is in.
+
+ mmu_tlb_reg = ((unsigned long)dummy_function / PAGE_SIZE) % mmusets;
+
+ report(mmu_tlb_reg);
+
+ // Enable interrupts and install handler. Error will trigger
+ // an interrupt.
+
+ // iMMU parity errors trigger both a miss and the parity interrupt, but
+ // for now we'll just have the miss vector do the handling
+
+ //Initialise handler vector
+ //int_init();
+ //int_add(PARERR_IRQ, parity_error_interrupt, 0);
+ // Enable interrupts in supervisor register
+ //cpu_enable_user_interrupts();
+
+ // Add handler for iTLB miss (parity error may show up as
+ // miss.)
+ add_handler(0xa, itlb_miss_handler);
+
+
+ return mmu_tlb_reg;
+}
+
+
+void
+gpr_test(int reg, int bit_number)
+{
+
+ switch(reg)
+ {
+ case 0:
+ FT_STIM_WRITE_FAULT_CMD(FT_STIM_CMD_RF_FAULT,bit_number, reg);
+ FT_STIM_WAIT_ACK;
+ __asm__ ("l.add r23, r24, r0");
+
+ break;
+
+ case 1:
+ FT_STIM_WRITE_FAULT_CMD(FT_STIM_CMD_RF_FAULT,bit_number, reg);
+ FT_STIM_WAIT_ACK;
+ __asm__ ("l.add r23, r24, r1");
+
+ break;
+
+ case 2:
+ FT_STIM_WRITE_FAULT_CMD(FT_STIM_CMD_RF_FAULT,bit_number, reg);
+ FT_STIM_WAIT_ACK;
+ __asm__ ("l.add r23, r24, r2");
+
+ break;
+
+ case 3:
+ FT_STIM_WRITE_FAULT_CMD(FT_STIM_CMD_RF_FAULT,bit_number, reg);
+ FT_STIM_WAIT_ACK;
+ __asm__ ("l.add r23, r24, r3");
+
+ break;
+
+ case 4:
+ FT_STIM_WRITE_FAULT_CMD(FT_STIM_CMD_RF_FAULT,bit_number, reg);
+ FT_STIM_WAIT_ACK;
+ __asm__ ("l.add r23, r24, r4");
+
+ break;
+
+ case 5:
+ FT_STIM_WRITE_FAULT_CMD(FT_STIM_CMD_RF_FAULT,bit_number, reg);
+ FT_STIM_WAIT_ACK;
+ __asm__ ("l.add r23, r24, r5");
+
+ break;
+
+ case 6:
+ FT_STIM_WRITE_FAULT_CMD(FT_STIM_CMD_RF_FAULT,bit_number, reg);
+ FT_STIM_WAIT_ACK;
+ __asm__ ("l.add r23, r24, r6");
+
+ break;
+
+ case 7:
+ FT_STIM_WRITE_FAULT_CMD(FT_STIM_CMD_RF_FAULT,bit_number, reg);
+ FT_STIM_WAIT_ACK;
+ __asm__ ("l.add r23, r24, r7");
+
+ break;
+
+ case 8:
+ FT_STIM_WRITE_FAULT_CMD(FT_STIM_CMD_RF_FAULT,bit_number, reg);
+ FT_STIM_WAIT_ACK;
+ __asm__ ("l.add r23, r24, r8");
+
+ break;
+
+ case 9:
+ FT_STIM_WRITE_FAULT_CMD(FT_STIM_CMD_RF_FAULT,bit_number, reg);
+ FT_STIM_WAIT_ACK;
+ __asm__ ("l.add r23, r24, r9");
+
+ break;
+
+ case 10:
+ FT_STIM_WRITE_FAULT_CMD(FT_STIM_CMD_RF_FAULT,bit_number, reg);
+ FT_STIM_WAIT_ACK;
+ __asm__ ("l.add r23, r24, r10");
+
+ break;
+
+ case 11:
+ FT_STIM_WRITE_FAULT_CMD(FT_STIM_CMD_RF_FAULT,bit_number, reg);
+ FT_STIM_WAIT_ACK;
+ __asm__ ("l.add r23, r24, r11");
+
+ break;
+
+ case 12:
+ FT_STIM_WRITE_FAULT_CMD(FT_STIM_CMD_RF_FAULT,bit_number, reg);
+ FT_STIM_WAIT_ACK;
+ __asm__ ("l.add r23, r24, r12");
+
+ break;
+
+ case 13:
+ FT_STIM_WRITE_FAULT_CMD(FT_STIM_CMD_RF_FAULT,bit_number, reg);
+ FT_STIM_WAIT_ACK;
+ __asm__ ("l.add r23, r24, r13");
+
+ break;
+
+ case 14:
+ FT_STIM_WRITE_FAULT_CMD(FT_STIM_CMD_RF_FAULT,bit_number, reg);
+ FT_STIM_WAIT_ACK;
+ __asm__ ("l.add r23, r24, r14");
+
+ break;
+
+ case 15:
+ FT_STIM_WRITE_FAULT_CMD(FT_STIM_CMD_RF_FAULT,bit_number, reg);
+ FT_STIM_WAIT_ACK;
+ __asm__ ("l.add r23, r24, r15");
+
+ break;
+
+ case 16:
+ FT_STIM_WRITE_FAULT_CMD(FT_STIM_CMD_RF_FAULT,bit_number, reg);
+ FT_STIM_WAIT_ACK;
+ __asm__ ("l.add r23, r24, r16");
+
+ break;
+
+ case 17:
+ FT_STIM_WRITE_FAULT_CMD(FT_STIM_CMD_RF_FAULT,bit_number, reg);
+ FT_STIM_WAIT_ACK;
+ __asm__ ("l.add r23, r24, r17");
+
+ break;
+
+ case 18:
+ FT_STIM_WRITE_FAULT_CMD(FT_STIM_CMD_RF_FAULT,bit_number, reg);
+ FT_STIM_WAIT_ACK;
+ __asm__ ("l.add r23, r24, r18");
+
+ break;
+
+ case 19:
+ FT_STIM_WRITE_FAULT_CMD(FT_STIM_CMD_RF_FAULT,bit_number, reg);
+ FT_STIM_WAIT_ACK;
+ __asm__ ("l.add r23, r24, r19");
+
+ break;
+
+ case 20:
+ FT_STIM_WRITE_FAULT_CMD(FT_STIM_CMD_RF_FAULT,bit_number, reg);
+ FT_STIM_WAIT_ACK;
+ __asm__ ("l.add r23, r24, r20");
+
+ break;
+
+ case 21:
+ FT_STIM_WRITE_FAULT_CMD(FT_STIM_CMD_RF_FAULT,bit_number, reg);
+ FT_STIM_WAIT_ACK;
+ __asm__ ("l.add r23, r24, r21");
+
+ break;
+
+ case 22:
+ FT_STIM_WRITE_FAULT_CMD(FT_STIM_CMD_RF_FAULT,bit_number, reg);
+ FT_STIM_WAIT_ACK;
+ __asm__ ("l.add r23, r24, r22");
+
+ break;
+
+ case 23:
+ FT_STIM_WRITE_FAULT_CMD(FT_STIM_CMD_RF_FAULT,bit_number, reg);
+ FT_STIM_WAIT_ACK;
+ __asm__ ("l.add r23, r24, r23");
+
+ break;
+
+ case 24:
+ FT_STIM_WRITE_FAULT_CMD(FT_STIM_CMD_RF_FAULT,bit_number, reg);
+ FT_STIM_WAIT_ACK;
+ __asm__ ("l.add r23, r24, r24");
+
+ break;
+
+ case 25:
+ FT_STIM_WRITE_FAULT_CMD(FT_STIM_CMD_RF_FAULT,bit_number, reg);
+ FT_STIM_WAIT_ACK;
+ __asm__ ("l.add r23, r24, r25");
+
+ break;
+
+ case 26:
+ FT_STIM_WRITE_FAULT_CMD(FT_STIM_CMD_RF_FAULT,bit_number, reg);
+ FT_STIM_WAIT_ACK;
+ __asm__ ("l.add r23, r24, r26");
+
+ break;
+
+ case 27:
+ FT_STIM_WRITE_FAULT_CMD(FT_STIM_CMD_RF_FAULT,bit_number, reg);
+ FT_STIM_WAIT_ACK;
+ __asm__ ("l.add r23, r24, r27");
+
+ break;
+
+ case 28:
+ FT_STIM_WRITE_FAULT_CMD(FT_STIM_CMD_RF_FAULT,bit_number, reg);
+ FT_STIM_WAIT_ACK;
+ __asm__ ("l.add r23, r24, r28");
+
+ break;
+
+ case 29:
+ FT_STIM_WRITE_FAULT_CMD(FT_STIM_CMD_RF_FAULT,bit_number, reg);
+ FT_STIM_WAIT_ACK;
+ __asm__ ("l.add r23, r24, r29");
+
+ break;
+
+ case 30:
+ FT_STIM_WRITE_FAULT_CMD(FT_STIM_CMD_RF_FAULT,bit_number, reg);
+ FT_STIM_WAIT_ACK;
+ __asm__ ("l.add r23, r24, r30");
+
+ break;
+
+ case 31:
+ FT_STIM_WRITE_FAULT_CMD(FT_STIM_CMD_RF_FAULT,bit_number, reg);
+ FT_STIM_WAIT_ACK;
+ __asm__ ("l.add r23, r24, r31");
+ break;
+ }
+}
+
+
+int main(void)
+{
+
+ unsigned long cachecfgr, mmucfgr;
+ int cachebs, cachesets, cachesize;
+ int mmusets;
+ unsigned long * stack_ptr;
+ unsigned long * data_area;
+ unsigned long * insn_area;
+ int mmu_mr, mmu_tr;
+ int bit_number, word_number;
+
+ printf("\nParity Error Test Restart\n");
+
+ // Setup DMMU with cache disable on first page
+ dmmu_init();
+
+ // This ft_state variable should retain its value between resets, as
+ // we'll always store it back to its memory location when accessing it.
+ volatile int * ft_state = (volatile int*)FT_STATE_RECORD_MEM;
+
+ volatile int * test_state1 = (volatile int*)FT_STATE_TEST_STATE1_MEM;
+ volatile int * test_state2 = (volatile int*)FT_STATE_TEST_STATE2_MEM;
+
+
+ printf("Test state %d\n",*ft_state);
+
+restart_tests:
+
+ switch(*ft_state)
+ {
+ case 0:
+ printf("State %d: Test initialisation\n", *ft_state);
+
+ // Kickoff - tell testbench stimulus to start
+ printf("Writing GO command\n");
+ FT_STIM_WRITE(FT_GO_COMMAND);
+ (*ft_state)++;
+ FT_STIM_WAIT_ACK;
+
+#ifdef JUMP_TO_TEST
+ *ft_state = JUMP_TO_TEST;
+ goto restart_tests;
+#endif
+
+ // No break, fall through to case 1
+ case 1:
+ printf("\nState %d: IC instruction memory test\n", *ft_state);
+
+ // IC instruction RAM fault injection.
+
+ ic_test_setup();
+
+ // Determine cache configuration
+ cachecfgr = inline_mfspr(SPR_ICCFGR);
+ // What is block size
+ cachebs = (cachecfgr & SPR_ICCFGR_CBS) ? 32 : 16;
+
+ cachesets = (1 << ((cachecfgr & SPR_ICCFGR_NCS)>>
+ SPR_ICCFGR_NCS_OFF));
+
+ // *ft_state increments when *test_state1 == *test_state2
+ *test_state1 = 0;
+ *test_state2 = 32;
+
+ word_number = (((unsigned long)dummy_function >> 2) %
+ cachesets);
+ report((unsigned long) dummy_function);
+ report(word_number);
+
+ // Call a function, so it's cached, inject an error into
+ // the cache instruction RAM location where the first
+ // instruction of that function is located, and call it again.
+ // This should trip the parity error, and the interrupt.
+
+ while(*ft_state == 1)
+ {
+ dummy_function();
+
+ bit_number = *test_state1;
+ FT_STIM_WRITE_FAULT_CMD(FT_STIM_CMD_IC_RAM_FAULT,
+ bit_number, word_number);
+
+ FT_STIM_WAIT_ACK;
+
+ dummy_function();
+
+ }
+ case 2:
+ printf("\nState %d: IC tag memory test\n", *ft_state);
+ // IC tag RAM fault injection.
+
+ ic_test_setup();
+
+ // Determine cache configuration
+ cachecfgr = inline_mfspr(SPR_ICCFGR);
+ // What is block size
+ cachebs = (cachecfgr & SPR_ICCFGR_CBS) ? 32 : 16;
+
+ cachesets = (1 << ((cachecfgr & SPR_ICCFGR_NCS)>>
+ SPR_ICCFGR_NCS_OFF));
+
+ cachesize = cachebs * cachesets;
+
+ // Same as above, but this time for the tag RAM.
+
+ // *ft_state increments when *test_state1 == *test_state2
+ *test_state1 = 0;
+ *test_state2 = 24;
+
+ // Calculate word in tag RAM
+ word_number = (((unsigned long)dummy_function %
+ cachesize ) / cachebs) ;
+
+ while(*ft_state == 2)
+ {
+ dummy_function();
+ bit_number = *test_state1;
+ FT_STIM_WRITE_FAULT_CMD(FT_STIM_CMD_IC_TAG_FAULT,
+ bit_number, word_number);
+
+ FT_STIM_WAIT_ACK;
+
+ dummy_function();
+
+ }
+ case 3:
+ // DC data RAM fault injection
+ printf("\nState %d: DC data memory test\n", *ft_state);
+
+ dc_test_setup();
+
+ // Read a far off data address (outside first MMU page, at
+ // least), determine it's cache line, inject a fault and read
+ // it again.
+ // Set up stack pointer variable, so we know where top of
+ // stack is.
+ stack_ptr = (unsigned long*)&_stack;
+
+ // Put test area one page past it:
+ data_area = stack_ptr;
+ data_area += PAGE_SIZE;
+
+ // Report address
+ report((unsigned long)data_area);
+ // Write a test variable there
+ *data_area = 0xea5ecafe;
+
+ // Determine cache set up
+ cachecfgr = inline_mfspr(SPR_DCCFGR);
+ // What is block size
+ cachebs = (cachecfgr & SPR_DCCFGR_CBS) ? 32 : 16;
+
+ cachesets = (1 << ((cachecfgr & SPR_DCCFGR_NCS)>>
+ SPR_DCCFGR_NCS_OFF));
+
+ cachesize = cachebs * cachesets;
+
+ // Calculate address of word in DC RAM
+ word_number = (((unsigned long)data_area % cachesize) >> 2);
+
+ // *ft_state increments when *test_state1 == *test_state2
+ *test_state1 = 0;
+ *test_state2 = 32;
+
+ while(*ft_state == 3)
+ {
+
+ // Read the location, to cache it, or trigger read
+ // from cache
+ report(*data_area);
+ bit_number = *test_state1;
+ FT_STIM_WRITE_FAULT_CMD(FT_STIM_CMD_DC_RAM_FAULT,
+ bit_number, word_number);
+
+ FT_STIM_WAIT_ACK;
+
+ //report(*data_area);
+
+
+ }
+ case 4:
+ printf("\nState %d: DC tag memory test\n", *ft_state);
+
+ dc_test_setup();
+
+ // Same set up as data cache RAM test.
+ stack_ptr = (unsigned long*)&_stack;
+
+ // Put test area one page past it:
+ data_area = stack_ptr;
+ data_area += PAGE_SIZE;
+
+ // Report address
+ report((unsigned long)data_area);
+ // Write a test variable there
+ *data_area = 0xea5ecafe;
+
+ // Determine cache set up
+ cachecfgr = inline_mfspr(SPR_DCCFGR);
+ // What is block size
+ cachebs = (cachecfgr & SPR_DCCFGR_CBS) ? 32 : 16;
+
+ cachesets = (1 << ((cachecfgr & SPR_DCCFGR_NCS)>>
+ SPR_DCCFGR_NCS_OFF));
+
+ cachesize = cachebs * cachesets;
+
+ // Calculate address of word in DC RAM
+ word_number = (((unsigned long)data_area % cachesize)/cachebs);
+
+ // *ft_state increments when *test_state1 == *test_state2
+ *test_state1 = 0;
+ *test_state2 = 24;
+
+ while(*ft_state == 4)
+ {
+
+ // Read the location, to cache it, or trigger read
+ // from cache
+ report(*data_area);
+ bit_number = *test_state1;
+ FT_STIM_WRITE_FAULT_CMD(FT_STIM_CMD_DC_TAG_FAULT,
+ bit_number, word_number);
+ FT_STIM_WAIT_ACK;
+
+ report(*data_area);
+
+ }
+ case 5:
+ // Instruction MMU TLB match register corruption test
+ // Parity error should just trigger an interrupt, not
+ // reset the system
+ printf("\nState %d: IMMU match register memory test\n",
+ *ft_state);
+
+ if (immu_init())
+ {
+
+ printf("\nSkipping test %d - no iMMU present\n",
+ *ft_state);
+ (*ft_state)++;
+ goto restart_tests;
+ }
+
+ mmu_mr = immu_test_setup();
+
+ *test_state1 = 0;
+ *test_state2 = 16;
+
+ while (*ft_state==5)
+ {
+ bit_number = *test_state1;
+ FT_STIM_WRITE_FAULT_CMD(FT_STIM_CMD_IMMU_MR_FAULT,
+ bit_number, mmu_mr);
+ FT_STIM_WAIT_ACK;
+
+ dummy_function();
+ }
+
+
+
+ case 6:
+ // Instruction MMU TLB match register corruption test
+ // Should just trigger interrupt, not reset.
+ printf("\nState %d: IMMU translate register memory test\n",
+ *ft_state);
+ if (immu_init())
+ {
+
+ printf("\nSkipping test %d - no iMMU present\n",
+ *ft_state);
+ (*ft_state)++;
+ goto restart_tests;
+ }
+
+ mmu_tr = immu_test_setup();
+
+ *test_state1 = 0;
+ *test_state2 = 24;
+
+ while (*ft_state==6)
+ {
+ bit_number = *test_state1;
+ FT_STIM_WRITE_FAULT_CMD(FT_STIM_CMD_IMMU_TR_FAULT,
+ bit_number, mmu_mr );
+ FT_STIM_WAIT_ACK;
+
+ dummy_function();
+ }
+
+ case 7:
+ // Data MMU TLB match register corruption test
+ // Parity error should just trigger an interrupt, not
+ // reset the system
+ printf("\nState %d: DMMU match register memory test\n",
+ *ft_state);
+
+ if (dmmu_init())
+ {
+
+ printf("\nSkipping test %d - no dMMU present\n",
+ *ft_state);
+ (*ft_state)++;
+ goto restart_tests;
+ }
+
+ // Choose address for test
+ data_area = stack_ptr;
+ data_area += PAGE_SIZE;
+
+ *data_area = 0xeaaaa51e;
+
+ mmu_mr = dmmu_test_setup((unsigned long) data_area);
+
+ *test_state1 = 0;
+ *test_state2 = 16;
+
+ while (*ft_state==7)
+ {
+ bit_number = *test_state1;
+ FT_STIM_WRITE_FAULT_CMD(FT_STIM_CMD_DMMU_MR_FAULT,
+ bit_number, mmu_mr );
+ FT_STIM_WAIT_ACK;
+
+ report (*data_area);
+ }
+
+ case 8:
+ // Data MMU TLB translate register corruption test
+ // Parity error should just trigger an interrupt, not
+ // reset the system
+ printf("\nState %d: DMMU translate register memory test\n",
+ *ft_state);
+
+ if (dmmu_init())
+ {
+
+ printf("\nSkipping test %d - no dMMU present\n",
+ *ft_state);
+ (*ft_state)++;
+ goto restart_tests;
+ }
+
+ // Choose address for test
+ data_area = stack_ptr;
+ data_area += (PAGE_SIZE<<2);
+
+ *data_area = 0xdeadc0de;
+
+ mmu_tr = dmmu_test_setup((unsigned long) data_area);
+
+ *test_state1 = 0;
+ *test_state2 = 24;
+
+ while (*ft_state==8)
+ {
+ bit_number = *test_state1;
+ FT_STIM_WRITE_FAULT_CMD(FT_STIM_CMD_DMMU_TR_FAULT,
+ bit_number, mmu_tr );
+ FT_STIM_WAIT_ACK;
+
+ report (*data_area);
+ }
+
+ // Sometimes the interrupt triggers twice here, meaning
+ // ft_state was incremented twice. So manually put it back,
+ // just in case.
+ *ft_state = 9;
+
+ case 9:
+ printf("\nState %d: Register file memory test\n",
+ *ft_state);
+
+ // Inject an error into a reg, then schedule an instruction to
+ // read it.
+ (*ft_state)++;
+
+ // initialise variables here
+ *test_state1 = -1; // Bit number
+ *test_state2 = 0; // GPR number
+
+ case 10:
+ // Sit in this state to do the tests
+ (*test_state1)++;
+
+ if (*test_state1 == 32)
+ {
+ (*test_state2)++;
+ *test_state1 = 0;
+
+ if (*test_state2 == 32)
+ (*ft_state)++;
+ }
+
+ bit_number = *test_state1;
+
+ while (*ft_state==10)
+ {
+ gpr_test(*test_state2,bit_number);
+ }
+
+ case 11:
+ printf("Tests done\n");
+ report(0x8000000d);
+ return 0;
+ default:
+ // Shouldn't be here. ft_state somhow got corrupted.
+ exit(1);
+ break;
+ }
+
+ return 0;
+}
Index: boards/generic/ft/sw/tests/or1200ft/sim/Makefile
===================================================================
--- boards/generic/ft/sw/tests/or1200ft/sim/Makefile (nonexistent)
+++ boards/generic/ft/sw/tests/or1200ft/sim/Makefile (revision 483)
@@ -0,0 +1,14 @@
+
+BOARD_SW_ROOT=../../..
+
+include $(BOARD_SW_ROOT)/Makefile.inc
+
+%.dis: %.elf
+ $(Q)$(OR32_OBJDUMP) -d $< > $@
+
+%.bin: %.elf
+ $(Q)$(OR32_OBJCOPY) -O binary $< $@
+
+clean:
+ $(Q)rm -f *.elf *.bin *.vmem *.flashin *.dis
+
Index: boards/generic/ft/sw/Makefile.inc
===================================================================
--- boards/generic/ft/sw/Makefile.inc (nonexistent)
+++ boards/generic/ft/sw/Makefile.inc (revision 483)
@@ -0,0 +1,24 @@
+
+# Expecting BOARD_SW_ROOT already set to indicate how far below directory we're
+# in the board's software root path is.
+
+# Root from the board's sw/ path
+PROJ_ROOT=../../../..
+
+# Figure out actual path the common software directory
+SW_ROOT=$(BOARD_SW_ROOT)/$(PROJ_ROOT)/sw
+
+# Set the BOARD
+BOARD=generic/ft
+
+# Set RTL_VERILOG_INCLUDE_DIR so software
+RTL_VERILOG_INCLUDE_DIR=$(shell pwd)/$(BOARD_SW_ROOT)/../rtl/verilog/include
+
+# Set the processor capability flags
+#MARCH_FLAGS =-mhard-mul -mhard-div -msoft-float
+MARCH_FLAGS =-mhard-mul -msoft-div -msoft-float
+export MARCH_FLAGS
+
+# Finally include the main software include file
+
+include $(SW_ROOT)/Makefile.inc
Index: boards/generic/ft/sw/board/include/board.h
===================================================================
--- boards/generic/ft/sw/board/include/board.h (nonexistent)
+++ boards/generic/ft/sw/board/include/board.h (revision 483)
@@ -0,0 +1,26 @@
+#ifndef _BOARD_H_
+#define _BOARD_H_
+
+#define IN_CLK 50000000 // Hz
+
+
+//
+// Defines for each core (memory map base, OR1200 interrupt line number, etc.)
+//
+#define RAM_BASE 0x00000000
+#define RAM_SIZE 0x00100000
+
+
+// Parity error indicator module. Simple one for this build
+#define PARERR_BASE 0xe0000000
+// Parity error generator IRQ - just for this test design
+#define PARERR_IRQ 5
+
+
+
+//
+// OR1200 tick timer period define
+//
+#define TICKS_PER_SEC 100
+
+#endif