URL
https://opencores.org/ocsvn/or1k/or1k/trunk
Subversion Repositories or1k
Compare Revisions
- This comparison shows the changes necessary to convert path
/
- from Rev 208 to Rev 209
- ↔ Reverse comparison
Rev 208 → Rev 209
/trunk/or1200/rtl/verilog/pic.v
138,7 → 138,7
`ifdef PIC_PICMR |
always @(posedge clk or posedge rst) |
if (rst) |
picmr <= `PIC_INTS-2'b0; |
picmr <= {`PIC_INTS-2{1'b0}}; |
else if (picmr_sel && spr_write) begin |
picmr <= #1 spr_dat_i[`PIC_INTS-1:2]; |
end |
152,7 → 152,7
`ifdef PIC_PICPR |
always @(posedge clk or posedge rst) |
if (rst) |
picpr <= `PIC_INTS-2'b0; |
picpr <= {`PIC_INTS-2{1'b0}}; |
else if (picpr_sel && spr_write) begin |
picpr <= #1 spr_dat_i[`PIC_INTS-1:2]; |
end |
166,9 → 166,9
`ifdef PIC_PICSR |
always @(posedge clk or posedge rst) |
if (rst) |
picsr <= `PIC_INTS-2'b0; |
picsr <= {`PIC_INTS-2{1'b0}}; |
else if (picsr_sel && spr_write) begin |
picsr <= #1 spr_dat_i[`PIC_INTS-1:2] | um_ints; |
picsr <= #1 spr_dat_i[`PIC_INTS-1:0] | um_ints; |
end else |
picsr <= #1 picsr | um_ints; |
`else |
178,26 → 178,26
// |
// Read PIC registers |
// |
always @(spr_addr or picmr or picmr_sel or picpr or picpr_sel or picsr or picsr_sel) |
always @(spr_addr or picmr or picpr or picsr) |
case (spr_addr[`PICOFS_BITS]) // synopsys full_case parallel_case |
`ifdef PIC_READREGS |
`PIC_OFS_PICMR: begin |
spr_dat_o[`PIC_INTS-1:0] <= {picmr, 2'b0}; |
spr_dat_o[`PIC_INTS-1:0] = {picmr, 2'b0}; |
`ifdef PIC_UNUSED_ZERO |
spr_dat_o[31:`PIC_INTS] <= 32-`PIC_INTS'b0; |
spr_dat_o[31:`PIC_INTS] = {32-`PIC_INTS{1'b0}}; |
`endif |
end |
`PIC_OFS_PICPR: begin |
spr_dat_o[`PIC_INTS-1:0] <= {picpr, 2'b0}; |
spr_dat_o[`PIC_INTS-1:0] = {picpr, 2'b0}; |
`ifdef PIC_UNUSED_ZERO |
spr_dat_o[31:`PIC_INTS] <= 32-`PIC_INTS'b0; |
spr_dat_o[31:`PIC_INTS] = {32-`PIC_INTS{1'b0}}; |
`endif |
end |
`endif |
default: begin |
spr_dat_o[`PIC_INTS-1:0] <= picsr; |
spr_dat_o[`PIC_INTS-1:0] = picsr; |
`ifdef PIC_UNUSED_ZERO |
spr_dat_o[31:`PIC_INTS] <= 32-`PIC_INTS'b0; |
spr_dat_o[31:`PIC_INTS] = {32-`PIC_INTS{1'b0}}; |
`endif |
end |
endcase |
/trunk/or1200/rtl/verilog/pm.v
81,7 → 81,7
// Power Management Interface |
// |
input pm_cpustall; // Stall the CPU |
output pm_clksd; // Clock Slowdown factor |
output [3:0] pm_clksd; // Clock Slowdown factor |
output pm_dc_gate; // Gate DCache clock |
output pm_ic_gate; // Gate ICache clock |
output pm_dmmu_gate; // Gate DMMU clock |
124,7 → 124,7
always @(posedge clk or posedge rst) |
if (rst) |
{dcge, sme, dme, sdf} <= 7'b0; |
else if (pmr_sel && pmr_we) begin |
else if (pmr_sel && spr_write) begin |
sdf <= #1 spr_dat_i[`PM_PMR_SDF]; |
dme <= #1 spr_dat_i[`PM_PMR_DME]; |
sme <= #1 spr_dat_i[`PM_PMR_SME]; |
/trunk/or1200/rtl/verilog/frz_logic.v
71,7 → 71,9
clk, rst, |
|
// Internal i/f |
multicycle, except_flushpipe, lsu_stall, if_stall, dclsu_unstall, branch_stall, force_dslot_fetch, |
multicycle, except_flushpipe, lsu_stall, if_stall, |
dclsu_unstall, branch_stall, du_stall, mac_stall, |
force_dslot_fetch, |
if_freeze, id_freeze, ex_freeze, wb_freeze |
); |
|
87,6 → 89,8
input dclsu_unstall; |
input branch_stall; |
input force_dslot_fetch; |
input du_stall; |
input mac_stall; |
output if_freeze; |
output id_freeze; |
output ex_freeze; |
96,7 → 100,6
// Internal wires and regs |
// |
reg multicycle_freeze; |
reg [1:0] state; |
reg [2:0] state2; |
reg [2:0] multicycle_cnt; |
reg done_once; |
104,30 → 107,20
// |
// Pipeline freeze |
// |
assign if_freeze = id_freeze; |
assign id_freeze = (lsu_stall | (~dclsu_unstall & if_stall) | multicycle_freeze | force_dslot_fetch) & ~except_flushpipe; |
assign ex_freeze = (lsu_stall | (~dclsu_unstall & if_stall) | multicycle_freeze) & ~except_flushpipe; |
assign wb_freeze = (lsu_stall | (~dclsu_unstall & if_stall) | multicycle_freeze) & ~except_flushpipe; |
|
// Rules how to create freeze signals: |
// 1. Not overwriting pipeline stages: |
// Frreze signals at the beginning of pipeline (such as if_freeze) can be asserted more |
// often than freeze signals at the of pipeline (such as wb_freeze). In other words, wb_freeze must never |
// be asserted when ex_freeze is not. ex_freeze must never be asserted when id_freeze is not etc. |
// |
// Freeze FSM1 |
// 2. Inserting NOPs in the middle of pipeline only if supported: |
// At this time, only ex_freeze (and wb_freeze) can be deassrted when id_freeze (and if_freeze) are asserted. |
// This way NOP is asserted from stage ID into EX stage. |
// |
always @(posedge clk or posedge rst) begin |
if (rst) begin |
state <= #1 `NO_FREEZE; |
end |
else |
case (state) // synopsys full_case parallel_case |
`NO_FREEZE : |
if (lsu_stall) begin |
state <= #1 `FREEZE_BYDC; |
end |
`FREEZE_BYDC : |
if (!lsu_stall) begin |
state <= #1 `NO_FREEZE; |
end |
endcase |
end |
assign if_freeze = id_freeze; |
assign id_freeze = (lsu_stall | (~dclsu_unstall & if_stall) | multicycle_freeze | force_dslot_fetch) & ~except_flushpipe | du_stall; |
assign ex_freeze = wb_freeze; |
assign wb_freeze = (lsu_stall | (~dclsu_unstall & if_stall) | multicycle_freeze) & ~except_flushpipe | du_stall | mac_stall; |
|
// |
// Freeze FSM2 |
171,10 → 164,10
multicycle_freeze <= #1 1'b0; |
end |
`WAIT_LSU_TO_FINISH: |
if (!lsu_stall && !multicycle) begin |
if (!lsu_stall && !(|multicycle)) begin |
state2 <= #1 `NO_FREEZE; |
end |
else if (!lsu_stall && multicycle) begin |
else if (!lsu_stall & (|multicycle)) begin |
state2 <= #1 `FREEZE_BYMULTICYCLE; |
multicycle_freeze <= #1 1'b1; |
multicycle_cnt <= #1 multicycle - 'd1; |
/trunk/or1200/rtl/verilog/dc_tag.v
85,7 → 85,7
// |
// Data cache not implemented |
// |
assign tag = {dw{1'b0}}; |
assign tag = {dw-1{1'b0}}; |
assign tag_v = 1'b0; |
|
`else |
/trunk/or1200/rtl/verilog/or1200.v
151,7 → 151,7
// Power Management |
// |
input pm_cpustall; |
output pm_clksd; |
output [3:0] pm_clksd; |
output pm_dc_gate; |
output pm_ic_gate; |
output pm_dmmu_gate; |
264,8 → 264,12
// |
// Trace port and caches/MMUs |
// |
wire [`TP2W_WIDTH-1:0] tp2w; |
wire [`TP3W_WIDTH-1:0] tp3w; |
wire [dw-1:0] spr_dat_du; |
wire du_stall; |
wire [dw-1:0] du_addr; |
wire [dw-1:0] du_dat_du; |
wire du_read; |
wire du_write; |
|
// |
// Assignments |
402,10 → 406,11
.ic_en(ic_en), |
|
// Connection CPU to external Trace port |
.tp_dir_in(1'b0), |
.tp_sel(2'b00), |
.tp_in(32'h00000000), |
.tp_out(), |
.du_stall(du_stall), |
.du_addr(du_addr), |
.du_dat_du(du_dat_du), |
.du_read(du_read), |
.du_write(du_write), |
|
// Connection IMMU and CPU internally |
.immu_en(immu_en), |
438,12 → 443,9
.spr_dat_tt(spr_dat_tt), |
.spr_dat_pm(spr_dat_pm), |
.spr_dat_dmmu(spr_dat_dmmu), |
.spr_dat_immu(spr_dat_immu), |
.spr_cs(spr_cs), |
.spr_we(spr_we), |
|
// These connect trace port to caches and MMUs |
.tp2w(tp2w), |
.tp3w(tp3w) |
.spr_we(spr_we) |
); |
|
// |
506,10 → 508,7
.dcbiu_addr(dcbiu_addr), |
.dcbiu_read(dcbiu_read), |
.dcbiu_write(dcbiu_write), |
.dcbiu_sel(dcbiu_sel), |
|
// Trace port |
.tp2w(tp2w) |
.dcbiu_sel(dcbiu_sel) |
); |
|
// |
523,12 → 522,12
.icfetch_op(icfetch_op), |
|
// DU's access to SPR unit |
.du_stall(), |
.du_addr(), |
.du_dat_i(32'h00000000), |
.du_dat_o(), |
.du_read(), |
.du_write(), |
.du_stall(du_stall), |
.du_addr(du_addr), |
.du_dat_i(spr_dat_cpu), |
.du_dat_o(du_dat_du), |
.du_read(du_read), |
.du_write(du_write), |
|
// Access to DU's SPRs |
.spr_cs(spr_cs[`SPR_GROUP_DU]), |
535,7 → 534,7
.spr_write(spr_we), |
.spr_addr(spr_addr), |
.spr_dat_i(spr_dat_cpu), |
.spr_dat_o(), |
.spr_dat_o(spr_dat_du), |
|
// External Debug Interface |
.dbg_stall_i(dbg_stall_i), |
/trunk/or1200/rtl/verilog/generic_spram_64x14.v
101,8 → 101,8
// |
// Internal wires and registers |
// |
wire [1:0] unconnected; |
|
|
`ifdef ARTISAN_SSP |
|
// |
196,10 → 196,10
.CLK(clk), |
.RST(rst), |
.ADDR({2'b00, addr}), |
.DI(di[13:0]), |
.DI({unconnected, di[13:0]}), |
.EN(ce), |
.WE(we), |
.DO(do[13:0]) |
.DO({unconnected, do[13:0]}) |
); |
|
`else |
/trunk/or1200/rtl/verilog/multp2_32x32.v
787,7 → 787,7
reg DOUT_reg; |
always @ ( posedge RST or posedge CLK ) begin |
if (RST) |
DOUT_reg <= DIN; |
DOUT_reg <= 1'b0; |
else |
DOUT_reg <= #1 DIN; |
end |
/trunk/or1200/rtl/verilog/sprs.v
66,11 → 66,16
flag, addrbase, addrofs, dat_i, alu_op, branch_op, |
epcr, eear, esr, except_start, except_started, |
to_wbmux, epcr_we, eear_we, esr_we, sr, |
spr_dat_cfgr, spr_dat_dmmu, |
spr_dat_cfgr, spr_dat_rf, |
|
// From/to other RISC units |
spr_dat_pic, spr_dat_tt, spr_dat_pm, |
spr_addr, spr_dataout, spr_cs, spr_we |
spr_dat_dmmu, spr_dat_immu, spr_dat_du, |
spr_addr, spr_dataout, spr_cs, spr_we, |
|
du_addr, du_dat_du, du_read, |
du_write |
|
); |
|
parameter width = `OPERAND_WIDTH; |
101,6 → 106,7
output esr_we; // ESR0 write enable |
output [`SR_WIDTH-1:0] sr; // SR |
input [31:0] spr_dat_cfgr; // Data from CFGR |
input [31:0] spr_dat_rf; // Data from RF |
|
// |
// To/from other RISC units |
109,6 → 115,8
input [31:0] spr_dat_tt; // Data from TT |
input [31:0] spr_dat_pm; // Data from PM |
input [31:0] spr_dat_dmmu; // Data from DMMU |
input [31:0] spr_dat_immu; // Data from IMMU |
input [31:0] spr_dat_du; // Data from DU |
output [31:0] spr_addr; // SPR Address |
output [31:0] spr_dataout; // Data to unit |
output [31:0] spr_cs; // Unit select |
115,6 → 123,14
output spr_we; // SPR write enable |
|
// |
// To/from Debug Unit |
// |
input [width-1:0] du_addr; // Address |
input [width-1:0] du_dat_du; // Data from DU to SPRS |
input du_read; // Read qualifier |
input du_write; // Write qualifier |
|
// |
// Internal regs & wires |
// |
reg [`SR_WIDTH-1:0] sr; // SR |
121,9 → 137,9
reg write_spr; // Write SPR |
reg read_spr; // Read SPR |
reg [width-1:0] to_wbmux; // For l.mfspr |
reg [31:0] spr_cs; // Group selects |
wire sr_we; // Write enable SR |
wire cfgr_sel; // Select for cfg regs |
wire rf_sel; // Select for RF |
wire sr_sel; // Select for SR |
wire epcr_sel; // Select for EPCR0 |
wire eear_sel; // Select for EEAR0 |
130,59 → 146,79
wire esr_sel; // Select for ESR0 |
wire [31:0] sys_data; // Read data from system SPRs |
wire [`SR_WIDTH-1:0] to_sr; // Data to SR |
wire du_access; // Debug unit access |
wire [`ALUOP_WIDTH-1:0] sprs_op; // ALU operation |
reg [31:0] unqualified_cs; // Unqualified chip selects |
|
// |
// Decide if it is debug unit access |
// |
assign du_access = du_read | du_write; |
|
// |
// Generate sprs opcode |
// |
assign sprs_op = du_write ? `ALUOP_MTSR : du_read ? `ALUOP_MFSR : alu_op; |
|
// |
// Generate SPR address from base address and offset |
// OR from debug unit address |
// |
assign spr_addr = addrbase + addrofs; |
assign spr_addr = du_access ? du_addr : addrbase + {16'h0000, addrofs}; |
|
// |
// SPR is written with dat_i |
// SPR is written with dat_i from l.mtspr |
// OR by debug unit |
// |
assign spr_dataout = dat_i; |
assign spr_dataout = du_access ? du_dat_du : dat_i; |
|
// |
// Write into SPRs when l.mtspr |
// |
assign spr_we = write_spr; |
assign spr_we = du_write | write_spr; |
|
// |
// Qualify chip selects |
// |
assign spr_cs = unqualified_cs & {32{read_spr | write_spr}}; |
|
// |
// Decoding of groups |
// |
always @(spr_addr) |
case (spr_addr[`SPR_GROUP_BITS]) // synopsys parallel_case |
`SPR_GROUP_WIDTH'd00: spr_cs = 32'b00000000_00000000_00000000_00000001; |
`SPR_GROUP_WIDTH'd01: spr_cs = 32'b00000000_00000000_00000000_00000010; |
`SPR_GROUP_WIDTH'd02: spr_cs = 32'b00000000_00000000_00000000_00000100; |
`SPR_GROUP_WIDTH'd03: spr_cs = 32'b00000000_00000000_00000000_00001000; |
`SPR_GROUP_WIDTH'd04: spr_cs = 32'b00000000_00000000_00000000_00010000; |
`SPR_GROUP_WIDTH'd05: spr_cs = 32'b00000000_00000000_00000000_00100000; |
`SPR_GROUP_WIDTH'd06: spr_cs = 32'b00000000_00000000_00000000_01000000; |
`SPR_GROUP_WIDTH'd07: spr_cs = 32'b00000000_00000000_00000000_10000000; |
`SPR_GROUP_WIDTH'd08: spr_cs = 32'b00000000_00000000_00000001_00000000; |
`SPR_GROUP_WIDTH'd09: spr_cs = 32'b00000000_00000000_00000010_00000000; |
`SPR_GROUP_WIDTH'd10: spr_cs = 32'b00000000_00000000_00000100_00000000; |
`SPR_GROUP_WIDTH'd11: spr_cs = 32'b00000000_00000000_00001000_00000000; |
`SPR_GROUP_WIDTH'd12: spr_cs = 32'b00000000_00000000_00010000_00000000; |
`SPR_GROUP_WIDTH'd13: spr_cs = 32'b00000000_00000000_00100000_00000000; |
`SPR_GROUP_WIDTH'd14: spr_cs = 32'b00000000_00000000_01000000_00000000; |
`SPR_GROUP_WIDTH'd15: spr_cs = 32'b00000000_00000000_10000000_00000000; |
`SPR_GROUP_WIDTH'd16: spr_cs = 32'b00000000_00000001_00000000_00000000; |
`SPR_GROUP_WIDTH'd17: spr_cs = 32'b00000000_00000010_00000000_00000000; |
`SPR_GROUP_WIDTH'd18: spr_cs = 32'b00000000_00000100_00000000_00000000; |
`SPR_GROUP_WIDTH'd19: spr_cs = 32'b00000000_00001000_00000000_00000000; |
`SPR_GROUP_WIDTH'd20: spr_cs = 32'b00000000_00010000_00000000_00000000; |
`SPR_GROUP_WIDTH'd21: spr_cs = 32'b00000000_00100000_00000000_00000000; |
`SPR_GROUP_WIDTH'd22: spr_cs = 32'b00000000_01000000_00000000_00000000; |
`SPR_GROUP_WIDTH'd23: spr_cs = 32'b00000000_10000000_00000000_00000000; |
`SPR_GROUP_WIDTH'd24: spr_cs = 32'b00000001_00000000_00000000_00000000; |
`SPR_GROUP_WIDTH'd25: spr_cs = 32'b00000010_00000000_00000000_00000000; |
`SPR_GROUP_WIDTH'd26: spr_cs = 32'b00000100_00000000_00000000_00000000; |
`SPR_GROUP_WIDTH'd27: spr_cs = 32'b00001000_00000000_00000000_00000000; |
`SPR_GROUP_WIDTH'd28: spr_cs = 32'b00010000_00000000_00000000_00000000; |
`SPR_GROUP_WIDTH'd29: spr_cs = 32'b00100000_00000000_00000000_00000000; |
`SPR_GROUP_WIDTH'd30: spr_cs = 32'b01000000_00000000_00000000_00000000; |
`SPR_GROUP_WIDTH'd31: spr_cs = 32'b10000000_00000000_00000000_00000000; |
`SPR_GROUP_WIDTH'd00: unqualified_cs = 32'b00000000_00000000_00000000_00000001; |
`SPR_GROUP_WIDTH'd01: unqualified_cs = 32'b00000000_00000000_00000000_00000010; |
`SPR_GROUP_WIDTH'd02: unqualified_cs = 32'b00000000_00000000_00000000_00000100; |
`SPR_GROUP_WIDTH'd03: unqualified_cs = 32'b00000000_00000000_00000000_00001000; |
`SPR_GROUP_WIDTH'd04: unqualified_cs = 32'b00000000_00000000_00000000_00010000; |
`SPR_GROUP_WIDTH'd05: unqualified_cs = 32'b00000000_00000000_00000000_00100000; |
`SPR_GROUP_WIDTH'd06: unqualified_cs = 32'b00000000_00000000_00000000_01000000; |
`SPR_GROUP_WIDTH'd07: unqualified_cs = 32'b00000000_00000000_00000000_10000000; |
`SPR_GROUP_WIDTH'd08: unqualified_cs = 32'b00000000_00000000_00000001_00000000; |
`SPR_GROUP_WIDTH'd09: unqualified_cs = 32'b00000000_00000000_00000010_00000000; |
`SPR_GROUP_WIDTH'd10: unqualified_cs = 32'b00000000_00000000_00000100_00000000; |
`SPR_GROUP_WIDTH'd11: unqualified_cs = 32'b00000000_00000000_00001000_00000000; |
`SPR_GROUP_WIDTH'd12: unqualified_cs = 32'b00000000_00000000_00010000_00000000; |
`SPR_GROUP_WIDTH'd13: unqualified_cs = 32'b00000000_00000000_00100000_00000000; |
`SPR_GROUP_WIDTH'd14: unqualified_cs = 32'b00000000_00000000_01000000_00000000; |
`SPR_GROUP_WIDTH'd15: unqualified_cs = 32'b00000000_00000000_10000000_00000000; |
`SPR_GROUP_WIDTH'd16: unqualified_cs = 32'b00000000_00000001_00000000_00000000; |
`SPR_GROUP_WIDTH'd17: unqualified_cs = 32'b00000000_00000010_00000000_00000000; |
`SPR_GROUP_WIDTH'd18: unqualified_cs = 32'b00000000_00000100_00000000_00000000; |
`SPR_GROUP_WIDTH'd19: unqualified_cs = 32'b00000000_00001000_00000000_00000000; |
`SPR_GROUP_WIDTH'd20: unqualified_cs = 32'b00000000_00010000_00000000_00000000; |
`SPR_GROUP_WIDTH'd21: unqualified_cs = 32'b00000000_00100000_00000000_00000000; |
`SPR_GROUP_WIDTH'd22: unqualified_cs = 32'b00000000_01000000_00000000_00000000; |
`SPR_GROUP_WIDTH'd23: unqualified_cs = 32'b00000000_10000000_00000000_00000000; |
`SPR_GROUP_WIDTH'd24: unqualified_cs = 32'b00000001_00000000_00000000_00000000; |
`SPR_GROUP_WIDTH'd25: unqualified_cs = 32'b00000010_00000000_00000000_00000000; |
`SPR_GROUP_WIDTH'd26: unqualified_cs = 32'b00000100_00000000_00000000_00000000; |
`SPR_GROUP_WIDTH'd27: unqualified_cs = 32'b00001000_00000000_00000000_00000000; |
`SPR_GROUP_WIDTH'd28: unqualified_cs = 32'b00010000_00000000_00000000_00000000; |
`SPR_GROUP_WIDTH'd29: unqualified_cs = 32'b00100000_00000000_00000000_00000000; |
`SPR_GROUP_WIDTH'd30: unqualified_cs = 32'b01000000_00000000_00000000_00000000; |
`SPR_GROUP_WIDTH'd31: unqualified_cs = 32'b10000000_00000000_00000000_00000000; |
endcase |
|
// |
192,16 → 228,17
// |
// What to write into SR |
// |
assign to_sr = (branch_op == `BRANCHOP_RFE) ? esr : dat_i[`SR_WIDTH-1:0]; |
assign to_sr = (branch_op == `BRANCHOP_RFE) ? esr : spr_dataout[`SR_WIDTH-1:0]; |
|
// |
// Selects for system SPRs |
// |
assign cfgr_sel = (spr_cs[`SPR_GROUP_SYS] && (spr_addr[6:4] == `SPR_CFGR)); |
assign sr_sel = (spr_cs[`SPR_GROUP_SYS] && (spr_addr[6:0] == `SPR_SR)); |
assign epcr_sel = (spr_cs[`SPR_GROUP_SYS] && (spr_addr[6:0] == `SPR_EPCR)); |
assign eear_sel = (spr_cs[`SPR_GROUP_SYS] && (spr_addr[6:0] == `SPR_EEAR)); |
assign esr_sel = (spr_cs[`SPR_GROUP_SYS] && (spr_addr[6:0] == `SPR_ESR)); |
assign cfgr_sel = (spr_cs[`SPR_GROUP_SYS] && (spr_addr[10:4] == `SPR_CFGR)); |
assign rf_sel = (spr_cs[`SPR_GROUP_SYS] && (spr_addr[10:5] == `SPR_RF)); |
assign sr_sel = (spr_cs[`SPR_GROUP_SYS] && (spr_addr[10:0] == `SPR_SR)); |
assign epcr_sel = (spr_cs[`SPR_GROUP_SYS] && (spr_addr[10:0] == `SPR_EPCR)); |
assign eear_sel = (spr_cs[`SPR_GROUP_SYS] && (spr_addr[10:0] == `SPR_EEAR)); |
assign esr_sel = (spr_cs[`SPR_GROUP_SYS] && (spr_addr[10:0] == `SPR_ESR)); |
|
// |
// Write enables for system SPRs |
215,10 → 252,11
// Output from system SPRs |
// |
assign sys_data = (spr_dat_cfgr & {32{read_spr & cfgr_sel}}) | |
(sr & {32{read_spr & sr_sel}}) | |
(spr_dat_rf & {32{read_spr & rf_sel}}) | |
({{32-`SR_WIDTH{1'b0}},sr} & {32{read_spr & sr_sel}}) | |
(epcr & {32{read_spr & epcr_sel}}) | |
(eear & {32{read_spr & eear_sel}}) | |
(esr & {32{read_spr & esr_sel}}); |
({{32-`SR_WIDTH{1'b0}},esr} & {32{read_spr & esr_sel}}); |
|
// |
// Supervision register |
234,11 → 272,12
`endif |
sr[`SR_SUPV] <= #1 1'b1; |
sr[`SR_EXR] <= #1 1'b0; |
sr[`SR_WIDTH:2] <= #1 {`SR_WIDTH-2{1'b0}}; |
end |
else if (sr_we) begin |
`ifdef OR1200_VERBOSE |
// synopsys translate_off |
$display(" INFO: writing into SR register: %h", dat_i); |
$display(" INFO: writing into SR register: %h", spr_dataout); |
// synopsys translate_on |
`endif |
sr <= #1 to_sr; |
247,12 → 286,13
// |
// MTSPR/MFSPR interface |
// |
always @(alu_op or spr_addr or dat_i or sys_data or spr_dat_pic or spr_dat_pm or spr_dat_dmmu or spr_dat_tt) begin |
case (alu_op) // synopsys full_case parallel_case |
always @(sprs_op or spr_addr or spr_dataout or sys_data or spr_dat_pic or spr_dat_pm or |
spr_dat_dmmu or spr_dat_immu or spr_dat_du or spr_dat_tt) begin |
case (sprs_op) // synopsys full_case parallel_case |
`ALUOP_MTSR : begin |
`ifdef OR1200_VERBOSE |
// synopsys translate_off |
$display("%t: SPRS: mtspr (%h) <- %h", $time, spr_addr, dat_i); |
$display("%t: SPRS: mtspr (%h) <- %h", $time, spr_addr, spr_dataout); |
// synopsys translate_on |
`endif |
write_spr = 1'b1; |
269,6 → 309,10
to_wbmux = spr_dat_pm; |
`SPR_GROUP_DMMU: |
to_wbmux = spr_dat_dmmu; |
`SPR_GROUP_IMMU: |
to_wbmux = spr_dat_immu; |
`SPR_GROUP_DU: |
to_wbmux = spr_dat_du; |
`SPR_GROUP_SYS: |
to_wbmux = sys_data; |
default: |
/trunk/or1200/rtl/verilog/tt.v
145,12 → 145,12
// |
// Read TT registers |
// |
always @(spr_addr or ttmr or ttmr_sel or ttcr or ttcr_sel) |
always @(spr_addr or ttmr or ttcr) |
case (spr_addr[`TTOFS_BITS]) // synopsys full_case parallel_case |
`ifdef TT_READREGS |
`TT_OFS_TTMR: spr_dat_o <= ttmr; |
`TT_OFS_TTMR: spr_dat_o = ttmr; |
`endif |
default: spr_dat_o <= ttcr; |
default: spr_dat_o = ttcr; |
endcase |
|
// |
/trunk/or1200/rtl/verilog/ic.v
171,7 → 171,7
else if (icbiu_rdy) |
bypass_wait <= #1 2'b0; |
else if (icbiu_read) |
bypass_wait <= #1 {bypass_wait, 1'b1}; |
bypass_wait <= #1 {bypass_wait[0], 1'b1}; |
else |
bypass_wait <= #1 2'b00; |
|
207,9 → 207,9
// |
always @(tag or saved_addr) begin |
if ((tag == saved_addr[31:`ICTAGL]) && tag_v) |
hit <= #1 1'b1; |
hit = 1'b1; |
else |
hit <= #1 1'b0; |
hit = 1'b0; |
end |
|
// |
/trunk/or1200/rtl/verilog/dc_fsm.v
119,19 → 119,19
always @(refill_first or refill or biudata_valid or lsu_op or start_addr or biu_write) begin |
if (refill_first || !refill) |
casex({lsu_op, start_addr[1:0]}) |
{`LSUOP_SB, 2'b00} : dcram_we <= #1 4'b1000 ^ {4{refill_first}}; |
{`LSUOP_SB, 2'b01} : dcram_we <= #1 4'b0100 ^ {4{refill_first}}; |
{`LSUOP_SB, 2'b10} : dcram_we <= #1 4'b0010 ^ {4{refill_first}}; |
{`LSUOP_SB, 2'b11} : dcram_we <= #1 4'b0001 ^ {4{refill_first}}; |
{`LSUOP_SH, 2'b00} : dcram_we <= #1 4'b1100 ^ {4{refill_first}}; |
{`LSUOP_SH, 2'b10} : dcram_we <= #1 4'b0011 ^ {4{refill_first}}; |
{`LSUOP_SW, 2'b00} : dcram_we <= #1 4'b1111 ^ {4{refill_first}}; |
{`LSUOP_SB, 2'b00} : dcram_we = 4'b1000 ^ {4{refill_first}}; |
{`LSUOP_SB, 2'b01} : dcram_we = 4'b0100 ^ {4{refill_first}}; |
{`LSUOP_SB, 2'b10} : dcram_we = 4'b0010 ^ {4{refill_first}}; |
{`LSUOP_SB, 2'b11} : dcram_we = 4'b0001 ^ {4{refill_first}}; |
{`LSUOP_SH, 2'b00} : dcram_we = 4'b1100 ^ {4{refill_first}}; |
{`LSUOP_SH, 2'b10} : dcram_we = 4'b0011 ^ {4{refill_first}}; |
{`LSUOP_SW, 2'b00} : dcram_we = 4'b1111 ^ {4{refill_first}}; |
{`LSUOP_LWZ, 2'bxx}, {`LSUOP_LHZ, 2'bxx}, {`LSUOP_LHS, 2'bxx}, |
{`LSUOP_LBS, 2'bxx}, {`LSUOP_LBZ, 2'bxx} : dcram_we <= #1 4'b0000 ^ {4{refill_first}}; |
default : dcram_we <= #1 4'b0000; |
{`LSUOP_LBS, 2'bxx}, {`LSUOP_LBZ, 2'bxx} : dcram_we = 4'b0000 ^ {4{refill_first}}; |
default : dcram_we = 4'b0000; |
endcase |
else |
dcram_we <= #1 {4{refill & biudata_valid & ~biu_write}}; |
dcram_we = {4{refill & biudata_valid & ~biu_write}}; |
end |
|
// |
242,7 → 242,7
cntrbusy <= #1 (lsu_op) ? 1'b1 : 1'b0; |
end |
`DCFSM_LREFILL3 : begin |
if (biudata_valid && cnt) begin |
if (biudata_valid && (|cnt)) begin |
`ifdef OR1200_VERBOSE |
// synopsys translate_off |
$display("%t: DC_FSM Load refill %d", $time, cnt); |
294,7 → 294,7
biu_read <= #1 1'b0; |
end |
`DCFSM_SREFILL3 : begin |
if (biudata_valid && cnt) begin |
if (biudata_valid && (|cnt)) begin |
`ifdef OR1200_VERBOSE |
// synopsys translate_off |
$display("%t: DC_FSM Store refill %d", $time, cnt); |
/trunk/or1200/rtl/verilog/id.v
64,7 → 64,7
rf_addra, rf_addrb, alu_op, shrot_op, comp_op, rf_addrw, rfwb_op, |
wb_insn, simm, branch_addrofs, lsu_addrofs, sel_a, sel_b, lsu_op, |
multicycle, spr_addrimm, wbforw_valid, sig_syscall, |
force_dslot_fetch |
force_dslot_fetch, id_macrc_op, ex_macrc_op |
); |
|
// |
97,6 → 97,8
input wbforw_valid; |
output sig_syscall; |
output force_dslot_fetch; |
output id_macrc_op; |
output ex_macrc_op; |
|
// |
// Internal wires and regs |
122,6 → 124,7
reg [15:0] spr_addrimm; |
reg sig_syscall; |
wire rst_or_except_flushpipe; |
reg ex_macrc_op; |
|
// |
// Register file read addresses |
133,7 → 136,7
// Force fetch of delay slot instruction when jump/branch is preceeded by load/store |
// instructions |
// |
assign force_dslot_fetch = (pre_branch_op && lsu_op); |
assign force_dslot_fetch = ((|pre_branch_op) & (|lsu_op)); |
|
// |
// Sign/Zero extension of immediates |
151,30 → 154,47
assign rst_or_except_flushpipe = rst | except_flushpipe; |
|
// |
// l.macrc in ID stage |
// |
assign id_macrc_op = (id_insn[31:26] == 6'b00_0110) & id_insn[16]; |
|
// |
// Generation of sel_a |
// |
always @(rf_addrw or wb_insn or id_insn or rfwb_op or wbforw_valid or wb_rfaddrw) |
always @(rf_addrw or id_insn or rfwb_op or wbforw_valid or wb_rfaddrw) |
if ((id_insn[20:16] == rf_addrw) && rfwb_op[0]) |
sel_a <= #1 `SEL_EX_FORW; |
sel_a = `SEL_EX_FORW; |
else if ((id_insn[20:16] == wb_rfaddrw) && wbforw_valid) |
sel_a <= #1 `SEL_WB_FORW; |
sel_a = `SEL_WB_FORW; |
else |
sel_a <= #1 `SEL_RF; |
sel_a = `SEL_RF; |
|
// |
// Generation of sel_b |
// |
always @(rf_addrw or wb_insn or sel_imm or id_insn or rfwb_op or wbforw_valid or wb_rfaddrw) |
always @(rf_addrw or sel_imm or id_insn or rfwb_op or wbforw_valid or wb_rfaddrw) |
if (sel_imm) |
sel_b <= #1 `SEL_IMM; |
sel_b = `SEL_IMM; |
else if ((id_insn[15:11] == rf_addrw) && rfwb_op[0]) |
sel_b <= #1 `SEL_EX_FORW; |
sel_b = `SEL_EX_FORW; |
else if ((id_insn[15:11] == wb_rfaddrw) && wbforw_valid) |
sel_b <= #1 `SEL_WB_FORW; |
sel_b = `SEL_WB_FORW; |
else |
sel_b <= #1 `SEL_RF; |
sel_b = `SEL_RF; |
|
// |
// l.macrc in EX stage |
// |
always @(posedge clk or posedge rst_or_except_flushpipe) begin |
if (rst_or_except_flushpipe) |
ex_macrc_op <= #1 1'b0; |
else if (!ex_freeze & id_freeze) |
ex_macrc_op <= #1 1'b0; |
else if (!ex_freeze) |
ex_macrc_op <= #1 id_macrc_op; |
end |
|
// |
// Decode of spr_addrimm |
// |
always @(posedge clk or posedge rst_or_except_flushpipe) begin |
202,43 → 222,43
|
// l.lwz |
`OR32_LWZ: |
multicycle <= #1 `TWO_CYCLES; |
multicycle = `TWO_CYCLES; |
|
// l.lbz |
`OR32_LBZ: |
multicycle <= #1 `TWO_CYCLES; |
multicycle = `TWO_CYCLES; |
|
// l.lbs |
`OR32_LBS: |
multicycle <= #1 `TWO_CYCLES; |
multicycle = `TWO_CYCLES; |
|
// l.lhz |
`OR32_LHZ: |
multicycle <= #1 `TWO_CYCLES; |
multicycle = `TWO_CYCLES; |
|
// l.lhs |
`OR32_LHS: |
multicycle <= #1 `TWO_CYCLES; |
multicycle = `TWO_CYCLES; |
|
// l.sw |
`OR32_SW: |
multicycle <= #1 `TWO_CYCLES; |
multicycle = `TWO_CYCLES; |
|
// l.sb |
`OR32_SB: |
multicycle <= #1 `TWO_CYCLES; |
multicycle = `TWO_CYCLES; |
|
// l.sh |
`OR32_SH: |
multicycle <= #1 `TWO_CYCLES; |
multicycle = `TWO_CYCLES; |
|
// ALU instructions except the one with immediate |
`OR32_ALU: |
multicycle <= #1 id_insn[`ALUMCYC_POS]; |
multicycle = id_insn[`ALUMCYC_POS]; |
|
// Single cycle instructions |
default: begin |
multicycle <= #1 `ONE_CYCLE; |
multicycle = `ONE_CYCLE; |
end |
|
endcase |
253,31 → 273,31
|
// l.addi |
`OR32_ADDI: |
imm_signextend <= #1 `on; |
imm_signextend = `on; |
|
// l.addic |
`OR32_ADDIC: |
imm_signextend <= #1 `on; |
imm_signextend = `on; |
|
// l.xori |
`OR32_XORI: |
imm_signextend <= #1 `on; |
imm_signextend = `on; |
|
// l.muli |
`OR32_MULI: |
imm_signextend <= #1 `on; |
imm_signextend = `on; |
|
// l.maci |
`OR32_MACI: |
imm_signextend <= #1 `on; |
imm_signextend = `on; |
|
// SFXX insns with immediate |
`OR32_SFXXI: |
imm_signextend <= #1 `on; |
imm_signextend = `on; |
|
// Instructions with no or zero extended immediate |
default: begin |
imm_signextend <= #1 `off; |
imm_signextend = `off; |
end |
|
endcase |
288,12 → 308,12
// LSU addr offset |
// |
always @(lsu_op or ex_insn) begin |
lsu_addrofs[10:0] <= #1 ex_insn[10:0]; |
lsu_addrofs[10:0] = ex_insn[10:0]; |
case(lsu_op) // synopsys parallel_case full_case |
`LSUOP_SW, `LSUOP_SH, `LSUOP_SB : |
lsu_addrofs[31:11] <= #1 {{16{ex_insn[25]}}, ex_insn[25:21]}; |
lsu_addrofs[31:11] = {{16{ex_insn[25]}}, ex_insn[25:21]}; |
default : |
lsu_addrofs[31:11] <= #1 {{16{ex_insn[15]}}, ex_insn[15:11]}; |
lsu_addrofs[31:11] = {{16{ex_insn[15]}}, ex_insn[15:11]}; |
endcase |
end |
|
/trunk/or1200/rtl/verilog/defines.v
63,7 → 63,7
|
//`define XILINX_RAMB4 |
//`define XILINX_RAM32X1D |
`define ARTISAN_SSP |
//`define ARTISAN_SSP |
//`define ARTISAN_SDP |
//`define ARTISAN_STP |
|
76,12 → 76,12
// |
// Data cache not implemented |
// |
//`define OR1200_NO_DC |
`define OR1200_NO_DC |
|
// |
// Insn cache not implemented |
// |
//`define OR1200_NO_IC |
`define OR1200_NO_IC |
|
// |
// Register OR1200 outputs |
151,8 → 151,8
|
`define OPERAND_WIDTH 32 |
`define REGFILE_ADDR_WIDTH 5 |
`define off 0 |
`define on 1 |
`define off 1'b0 |
`define on 1'b1 |
|
// Use fast (and bigger) version of mem2reg aligner |
`define MEM2REG_FAST |
217,13 → 217,13
`define RFWBOP_LR 3'b111 |
|
// Compare instructions |
`define COP_SFEQ 'b000 |
`define COP_SFNE 'b001 |
`define COP_SFGT 'b010 |
`define COP_SFGE 'b011 |
`define COP_SFLT 'b100 |
`define COP_SFLE 'b101 |
`define COP_X 'b0111 |
`define COP_SFEQ 3'b000 |
`define COP_SFNE 3'b001 |
`define COP_SFGT 3'b010 |
`define COP_SFGE 3'b011 |
`define COP_SFLT 3'b100 |
`define COP_SFLE 3'b101 |
`define COP_X 3'b0111 |
`define SIGNED_COMPARE 'd3 |
`define COMPOP_WIDTH 4 |
|
426,11 → 426,12
`define SPR_GROUP_MODA 5'd29 |
`define SPR_GROUP_MODD 5'd30 |
|
`define SPR_CFGR 3'd0 |
`define SPR_SR 7'd16 |
`define SPR_EPCR 7'd32 |
`define SPR_EEAR 7'd48 |
`define SPR_ESR 7'd64 |
`define SPR_CFGR 7'd0 |
`define SPR_RF 6'd32 // 1024 >> 5 |
`define SPR_SR 11'd16 |
`define SPR_EPCR 11'd32 |
`define SPR_EEAR 11'd48 |
`define SPR_ESR 11'd64 |
|
|
// Bits that define the group |
/trunk/or1200/rtl/verilog/alu.v
57,7 → 57,7
// synopsys translate_on |
`include "defines.v" |
|
module alu(clk, rst, a, b, alu_op, shrot_op, comp_op, result, flag); |
module alu(clk, rst, a, b, mult_mac_result, macrc_op, alu_op, shrot_op, comp_op, result, flag); |
|
parameter width = `OPERAND_WIDTH; |
|
68,6 → 68,8
input rst; |
input [width-1:0] a; |
input [width-1:0] b; |
input [width-1:0] mult_mac_result; |
input macrc_op; |
input [`ALUOP_WIDTH-1:0] alu_op; |
input [`SHROTOP_WIDTH-1:0] shrot_op; |
input [`COMPOP_WIDTH-1:0] comp_op; |
82,7 → 84,6
reg flagforw; |
reg flag_we; |
reg flag; |
reg [width-1:0] mul_prod; |
integer d1; |
integer d2; |
wire [width-1:0] comp_a; |
89,9 → 90,6
wire [width-1:0] comp_b; |
wire a_eq_b; |
wire a_lt_b; |
wire [width-1:0] mul_a; |
wire [width-1:0] mul_b; |
wire [2*width-1:0] tmp_prod; |
|
// |
// Combinatorial logic |
100,8 → 98,6
assign comp_b = {b[width-1] ^ comp_op[3] , b[width-2:0]}; |
assign a_eq_b = (comp_a == comp_b); |
assign a_lt_b = (comp_a < comp_b); |
assign mul_a = a; |
assign mul_b = b; |
|
// |
// Simulation check for bad ALU behavior |
118,7 → 114,7
// |
// Central part of the ALU |
// |
always @(alu_op or a or b or shifted_rotated or mul_prod) begin |
always @(alu_op or a or b or macrc_op or shifted_rotated or mult_mac_result) begin |
casex (alu_op) // synopsys parallel_case full_case |
`ALUOP_SHROT : begin |
result = shifted_rotated; |
149,14 → 145,20
flag_we = 1'b0; |
end |
`ALUOP_MOVHI : begin |
result = b << 16; |
flag_we = 1'b0; |
if (macrc_op) begin |
result = mult_mac_result; |
flag_we = 1'b0; |
end |
else begin |
result = b << 16; |
flag_we = 1'b0; |
end |
end |
`ALUOP_MUL : begin |
result = mul_prod; |
result = mult_mac_result; |
`ifdef OR1200_VERBOSE |
// synopsys translate_off |
$display("%t: MUL operation: %h * %h = %h", $time, a, b, mul_prod); |
$display("%t: MUL operation: %h * %h = %h", $time, a, b, mult_mac_result); |
// synopsys translate_on |
`endif |
flag_we = 1'b0; |
202,10 → 204,10
shifted_rotated = (a >> b[4:0]); |
`ifdef IMPL_ALU_ROTATE |
`SHROTOP_ROR : |
shifted_rotated = (a << (6'd32-b[4:0])) | (a >> b[4:0]); |
shifted_rotated = (a << (6'd32-{1'b0, b[4:0]})) | (a >> b[4:0]); |
`endif |
default: |
shifted_rotated = ({32{a[31]}} << (6'd32-b[4:0])) | a >> b[4:0]; |
shifted_rotated = ({32{a[31]}} << (6'd32-{1'b0, b[4:0]})) | a >> b[4:0]; |
endcase |
end |
|
277,25 → 279,4
end |
end |
|
// |
// Instantiation of the multiplier |
// |
multp2_32x32 multp2_32x32( |
.X(mul_a), |
.Y(mul_b), |
.RST(rst), |
.CLK(clk), |
.P(tmp_prod) |
); |
|
// |
// Registered output from the multiplier |
// |
always @(posedge rst or posedge clk) |
if (rst) |
mul_prod <= #1 32'b0; |
else |
mul_prod <= #1 tmp_prod[31:0]; |
// mul_prod <= #1 mul_a[31:0]; |
|
endmodule |
/trunk/or1200/rtl/verilog/generic_spram_64x21.v
101,8 → 101,8
// |
// Internal wires and registers |
// |
wire [10:0] unconnected; |
|
|
`ifdef ARTISAN_SSP |
|
// |
209,10 → 209,10
.CLK(clk), |
.RST(rst), |
.ADDR({2'b00, addr}), |
.DI(di[20:16]), |
.DI({unconnected, di[20:16]}), |
.EN(ce), |
.WE(we), |
.DO(do[20:16]) |
.DO({unconnected, do[20:16]}) |
); |
|
`else |
/trunk/or1200/rtl/verilog/generic_spram_64x23.v
101,8 → 101,8
// |
// Internal wires and registers |
// |
wire [8:0] unconnected; |
|
|
`ifdef ARTISAN_SSP |
|
// |
209,10 → 209,10
.CLK(clk), |
.RST(rst), |
.ADDR({2'b00, addr}), |
.DI(di[22:16]), |
.DI({unconnected, di[22:16]}), |
.EN(ce), |
.WE(we), |
.DO(do[22:16]) |
.DO({unconnected, do[22:16]}) |
); |
|
`else |
/trunk/or1200/rtl/verilog/ic_tag.v
93,7 → 93,7
// |
// Insn cache not implemented |
// |
assign tag = {dw{1'b0}}; |
assign tag = {dw-1{1'b0}}; |
assign tag_v = 1'b0; |
`else |
|
/trunk/or1200/rtl/verilog/dc.v
78,10 → 78,7
dc_en, dclsu_addr, dclsu_lsuop, dclsu_datain, dclsu_dataout, dclsu_stall, dclsu_unstall, |
|
// SPRs |
spr_cs, spr_write, spr_addr, spr_dat_i, |
|
// Trace |
tp2w |
spr_cs, spr_write, spr_addr, spr_dat_i |
); |
|
parameter dw = `OPERAND_WIDTH; |
128,11 → 125,6
input [31:0] spr_dat_i; |
|
// |
// Trace |
// |
input [`TP2W_WIDTH-1:0] tp2w; |
|
// |
// Internal wires and regs |
// |
wire tag_v; |
187,26 → 179,26
// Bypases of the DC when DC is disabled |
// |
assign dcfsm_lsuop = (dc_en) ? dclsu_lsuop : `LSUOP_NOP; |
assign dcbiu_read = (dc_en) ? dcfsm_read : (dclsu_lsuop && ~dclsu_lsuop[3]); |
assign dcbiu_write = (dc_en) ? dcfsm_write : (dclsu_lsuop && dclsu_lsuop[3]); |
assign dcbiu_read = (dc_en) ? dcfsm_read : ((|dclsu_lsuop) && ~dclsu_lsuop[3]); |
assign dcbiu_write = (dc_en) ? dcfsm_write : ((|dclsu_lsuop) && dclsu_lsuop[3]); |
always @(dc_en or dclsu_lsuop or dclsu_addr) |
casex({dc_en, dclsu_lsuop, dclsu_addr[1:0]}) |
{1'b0, `LSUOP_SB, 2'b00} : dcbiu_sel <= #1 4'b1000; |
{1'b0, `LSUOP_SB, 2'b01} : dcbiu_sel <= #1 4'b0100; |
{1'b0, `LSUOP_SB, 2'b10} : dcbiu_sel <= #1 4'b0010; |
{1'b0, `LSUOP_SB, 2'b11} : dcbiu_sel <= #1 4'b0001; |
{1'b0, `LSUOP_SH, 2'b00} : dcbiu_sel <= #1 4'b1100; |
{1'b0, `LSUOP_SH, 2'b10} : dcbiu_sel <= #1 4'b0011; |
{1'b0, `LSUOP_SW, 2'b00} : dcbiu_sel <= #1 4'b1111; |
{1'b0, `LSUOP_LBZ, 2'b00}, {1'b0, `LSUOP_LBS, 2'b00} : dcbiu_sel <= #1 4'b1000; |
{1'b0, `LSUOP_LBZ, 2'b01}, {1'b0, `LSUOP_LBS, 2'b01} : dcbiu_sel <= #1 4'b0100; |
{1'b0, `LSUOP_LBZ, 2'b10}, {1'b0, `LSUOP_LBS, 2'b10} : dcbiu_sel <= #1 4'b0010; |
{1'b0, `LSUOP_LBZ, 2'b11}, {1'b0, `LSUOP_LBS, 2'b11} : dcbiu_sel <= #1 4'b0001; |
{1'b0, `LSUOP_LHZ, 2'b00}, {1'b0, `LSUOP_LHS, 2'b00} : dcbiu_sel <= #1 4'b1100; |
{1'b0, `LSUOP_LHZ, 2'b10}, {1'b0, `LSUOP_LHS, 2'b10} : dcbiu_sel <= #1 4'b0011; |
{1'b0, `LSUOP_LWZ, 2'b00}, {1'b0, `LSUOP_LWS, 2'b00} : dcbiu_sel <= #1 4'b1111; |
7'b1xxxxxx : dcbiu_sel <= #1 4'b1111; |
default : dcbiu_sel <= #1 4'b0000; |
{1'b0, `LSUOP_SB, 2'b00} : dcbiu_sel = 4'b1000; |
{1'b0, `LSUOP_SB, 2'b01} : dcbiu_sel = 4'b0100; |
{1'b0, `LSUOP_SB, 2'b10} : dcbiu_sel = 4'b0010; |
{1'b0, `LSUOP_SB, 2'b11} : dcbiu_sel = 4'b0001; |
{1'b0, `LSUOP_SH, 2'b00} : dcbiu_sel = 4'b1100; |
{1'b0, `LSUOP_SH, 2'b10} : dcbiu_sel = 4'b0011; |
{1'b0, `LSUOP_SW, 2'b00} : dcbiu_sel = 4'b1111; |
{1'b0, `LSUOP_LBZ, 2'b00}, {1'b0, `LSUOP_LBS, 2'b00} : dcbiu_sel = 4'b1000; |
{1'b0, `LSUOP_LBZ, 2'b01}, {1'b0, `LSUOP_LBS, 2'b01} : dcbiu_sel = 4'b0100; |
{1'b0, `LSUOP_LBZ, 2'b10}, {1'b0, `LSUOP_LBS, 2'b10} : dcbiu_sel = 4'b0010; |
{1'b0, `LSUOP_LBZ, 2'b11}, {1'b0, `LSUOP_LBS, 2'b11} : dcbiu_sel = 4'b0001; |
{1'b0, `LSUOP_LHZ, 2'b00}, {1'b0, `LSUOP_LHS, 2'b00} : dcbiu_sel = 4'b1100; |
{1'b0, `LSUOP_LHZ, 2'b10}, {1'b0, `LSUOP_LHS, 2'b10} : dcbiu_sel = 4'b0011; |
{1'b0, `LSUOP_LWZ, 2'b00}, {1'b0, `LSUOP_LWS, 2'b00} : dcbiu_sel = 4'b1111; |
7'b1xxxxxx : dcbiu_sel = 4'b1111; |
default : dcbiu_sel = 4'b0000; |
endcase |
|
assign mem2reg_addr = (dc_en) ? saved_addr[1:0] : dclsu_addr[1:0]; |
216,11 → 208,11
// |
always @(posedge rst or posedge clk) |
if (rst) |
bypass_wait <= #1 2'b0; |
bypass_wait <= #1 2'b00; |
else if (dcbiu_valid) |
bypass_wait <= #1 2'b0; |
bypass_wait <= #1 2'b00; |
else if (dcbiu_read | dcbiu_write) |
bypass_wait <= #1 {bypass_wait, 1'b1}; |
bypass_wait <= #1 {bypass_wait[0], 1'b1}; |
else |
bypass_wait <= #1 2'b00; |
|
227,7 → 219,7
// |
// Queue |
// |
assign queue = (refill && dcfsm_lsuop && !refill_first & !refill_rest) ? 1'b1 : 1'b0; |
assign queue = (refill && (|dcfsm_lsuop) && !refill_first && !refill_rest) ? 1'b1 : 1'b0; |
|
// |
// DC/LSU stall |
255,9 → 247,9
// |
always @(tag or saved_addr) begin |
if ((tag == saved_addr[31:13]) && tag_v) |
hit <= #1 1'b1; |
hit = 1'b1; |
else |
hit <= #1 1'b0; |
hit = 1'b0; |
end |
|
// |
/trunk/or1200/rtl/verilog/cpu.v
72,8 → 72,8
ic_insn, ic_addr, ic_stall, ic_fetchop, ic_en, |
immu_en, immuexcept_miss, immuexcept_fault, |
|
// Trace port |
tp_dir_in, tp_sel, tp_in, tp_out, |
// Debug unit |
du_stall, du_addr, du_dat_du, du_read, du_write, |
|
// Data interface |
dclsu_stall, dclsu_unstall, dclsu_addr, dclsu_datain, dclsu_dataout, dclsu_lsuop, dc_en, |
83,10 → 83,8
int_high, int_low, |
|
// SPR interface |
supv, spr_addr, spr_dataout, spr_dat_pic, spr_dat_tt, spr_dat_pm, spr_dat_dmmu, spr_cs, spr_we, |
|
// Trace port |
tp2w, tp3w |
supv, spr_addr, spr_dataout, spr_dat_pic, spr_dat_tt, spr_dat_pm, |
spr_dat_dmmu, spr_dat_immu, spr_dat_du, spr_cs, spr_we |
); |
|
parameter dw = `OPERAND_WIDTH; |
119,14 → 117,13
output immu_en; |
|
// |
// Trace |
// Debug interface |
// |
input tp_dir_in; |
input [1:0] tp_sel; |
input [31:0] tp_in; |
output [31:0] tp_out; |
output [`TP2W_WIDTH-1:0] tp2w; |
output [`TP3W_WIDTH-1:0] tp3w; |
input du_stall; |
input [dw-1:0] du_addr; |
input [dw-1:0] du_dat_du; |
input du_read; |
input du_write; |
|
// |
// Data (DC) interface |
149,11 → 146,13
// |
// SPR interface |
// |
input supv; |
output supv; |
input [dw-1:0] spr_dat_pic; |
input [dw-1:0] spr_dat_tt; |
input [dw-1:0] spr_dat_pm; |
input [dw-1:0] spr_dat_dmmu; |
input [dw-1:0] spr_dat_immu; |
input [dw-1:0] spr_dat_du; |
output [dw-1:0] spr_addr; |
output [dw-1:0] spr_dataout; |
output [31:0] spr_cs; |
218,24 → 217,18
wire except_started; |
wire [31:0] wb_pc; |
wire [31:0] wb_insn; |
wire [31:0] tp_insn; |
wire tp_wr_insn; |
wire [15:0] spr_addrimm; |
wire sig_syscall; |
wire [31:0] spr_dat_cfgr; |
wire [31:0] spr_dat_rf; |
wire force_dslot_fetch; |
wire if_stall; |
wire id_macrc_op; |
wire ex_macrc_op; |
wire [31:0] mult_mac_result; |
wire mac_stall; |
|
// |
// Trace port |
// |
wire [31:0] rfa_tqa; |
wire [31:0] rfb_tqa; |
wire [`TP1R_WIDTH-1:0] rfa_tmuxed; |
wire [`TP1R_WIDTH-1:0] rfb_tmuxed; |
wire [`TP1W_WIDTH-1:0] tp1w; |
|
// |
// Data cache enable |
// |
assign dc_en = sr[`SR_DCE]; |
309,9 → 302,7
.ic_addr(ic_addr), |
.ic_stall(ic_stall), |
.ic_fetchop(ic_fetchop), |
.tp_insn(tp_insn), |
.tp_wr_insn(tp_wr_insn), |
.if_freeze(id_freeze), |
.if_freeze(if_freeze), |
.if_insn(insn), |
.if_pc(if_pc), |
.branch_op(branch_op), |
358,7 → 349,9
.spr_addrimm(spr_addrimm), |
.wbforw_valid(wbforw_valid), |
.sig_syscall(sig_syscall), |
.force_dslot_fetch(force_dslot_fetch) |
.force_dslot_fetch(force_dslot_fetch), |
.id_macrc_op(id_macrc_op), |
.ex_macrc_op(ex_macrc_op) |
); |
|
// |
392,11 → 385,12
.dataa(rf_dataa), |
.addrb(rf_addrb), |
.datab(rf_datab), |
.rfa_tqa(rfa_tqa), |
.rfb_tqa(rfb_tqa), |
.rfa_tmuxed(rfa_tmuxed), |
.rfb_tmuxed(rfb_tmuxed), |
.tp1w(tp1w) |
.spr_cs(spr_cs[`SPR_GROUP_SYS]), |
.spr_write(spr_we), |
.spr_addr(spr_addr), |
.spr_dat_i(spr_dataout), |
.spr_dat_o(spr_dat_rf) |
|
); |
|
// |
426,6 → 420,8
.rst(rst), |
.a(operand_a), |
.b(operand_b), |
.mult_mac_result(mult_mac_result), |
.macrc_op(ex_macrc_op), |
.alu_op(alu_op), |
.shrot_op(shrot_op), |
.comp_op(comp_op), |
434,6 → 430,21
); |
|
// |
// Instantiation of CPU's ALU |
// |
mult_mac mult_mac( |
.clk(clk), |
.rst(rst), |
.id_macrc_op(id_macrc_op), |
.macrc_op(ex_macrc_op), |
.a(operand_a), |
.b(operand_b), |
.alu_op(alu_op), |
.result(mult_mac_result), |
.mac_stall_r(mac_stall) |
); |
|
// |
// Instantiation of CPU's SPRS block |
// |
sprs sprs( |
446,12 → 457,20
.flag(flag), |
.to_wbmux(sprs_dataout), |
|
.du_addr(du_addr), |
.du_dat_du(du_dat_du), |
.du_read(du_read), |
.du_write(du_write), |
|
.spr_addr(spr_addr), |
.spr_dat_pic(spr_dat_pic), |
.spr_dat_tt(spr_dat_tt), |
.spr_dat_pm(spr_dat_pm), |
.spr_dat_cfgr(spr_dat_cfgr), |
.spr_dat_rf(spr_dat_rf), |
.spr_dat_dmmu(spr_dat_dmmu), |
.spr_dat_immu(spr_dat_immu), |
.spr_dat_du(spr_dat_du), |
.spr_dataout(spr_dataout), |
.spr_cs(spr_cs), |
.spr_we(spr_we), |
501,6 → 520,8
.dclsu_unstall(dclsu_unstall), |
.branch_stall(branch_stall), |
.force_dslot_fetch(force_dslot_fetch), |
.du_stall(du_stall), |
.mac_stall(mac_stall), |
.if_freeze(if_freeze), |
.id_freeze(id_freeze), |
.ex_freeze(ex_freeze), |
517,36 → 538,4
.spr_dat_o(spr_dat_cfgr) |
); |
|
// |
// Instantiation of Trace port |
// |
traceport traceport( |
// Trace port connection to outside world |
.tp_dir_in(tp_dir_in), |
.tp_sel(tp_sel), |
.tp_in(tp_in), |
.tp_out(tp_out), |
|
// Trace sources coming from RISC core |
.rst(rst), |
.rfa_tqa(rfa_tqa), |
.rfb_tqa(rfb_tqa), |
.rfa_tmuxed(rfa_tmuxed), |
.rfb_tmuxed(rfb_tmuxed), |
.wb_pc(wb_pc), |
.wb_insn(wb_insn), |
.wb_forw(wb_forw), |
|
// To RISC core |
.wr_insn(tp_wr_insn), |
.insn(tp_insn), |
.tp1w(tp1w), |
.tp2w(tp2w), |
.tp3w(tp3w), |
.tp4w(), |
.tpdw() |
); |
|
endmodule |
|
|
/trunk/or1200/rtl/verilog/except.v
208,7 → 208,7
// 1. Asserted for 3 clock cycles |
// 2. Don't execute any instruction that is still in pipeline and is not part of exception handler |
// |
assign except_flushpipe = (sr[`SR_EXR] & (sig_dtlbmiss | sig_dmmufault | sig_inthigh | sig_syscall | ex_exceptflags) |
assign except_flushpipe = (sr[`SR_EXR] & (sig_dtlbmiss | sig_dmmufault | sig_inthigh | sig_syscall | (|ex_exceptflags)) |
| extend_flush); |
|
// |
291,7 → 291,7
if (eear_we) |
eear <= #1 datain; |
if (esr_we) |
esr <= #1 datain; |
esr <= #1 datain[`SR_WIDTH-1:0]; |
end |
`EXCEPTFSM_FLU1: |
if (!if_stall && !id_freeze) |
/trunk/or1200/rtl/verilog/itlb.v
172,7 → 172,7
// |
// Assign to Translate registers inputs |
// |
assign tlb_tr_ram_in = {spr_dat_i[31:13], spr_dat_i[9:6]}; |
assign tlb_tr_ram_in = {spr_dat_i[31:13], spr_dat_i[7:6]}; |
|
// |
// Generate hit |
/trunk/or1200/rtl/verilog/ic_fsm.v
116,11 → 116,11
always @(refill_first or refill or biudata_valid or fetch_op or start_addr) begin |
if (refill_first || !refill) |
case(fetch_op) |
`FETCHOP_LW : icram_we <= #1 4'b0000 ^ {4{refill_first}}; |
default : icram_we <= #1 4'b0000; |
`FETCHOP_LW : icram_we = 4'b0000 ^ {4{refill_first}}; |
default : icram_we = 4'b0000; |
endcase |
else |
icram_we <= #1 {4{refill & biudata_valid}}; |
icram_we = {4{refill & biudata_valid}}; |
end |
|
// |
/trunk/or1200/rtl/verilog/ifetch.v
59,7 → 59,7
clk, rst, |
|
// External i/f to IC |
ic_insn, ic_addr, ic_stall, ic_fetchop, tp_insn, tp_wr_insn, |
ic_insn, ic_addr, ic_stall, ic_fetchop, |
|
// Internal i/f |
if_freeze, if_insn, if_pc, branch_op, except_type, |
84,8 → 84,6
output [31:0] ic_addr; |
output [`FETCHOP_WIDTH-1:0] ic_fetchop; |
input ic_stall; |
input [31:0] tp_insn; |
input tp_wr_insn; |
|
// |
// Internal i/f |
116,9 → 114,6
reg [31:0] pc_saved; |
reg taken; /* Set to in case of jump or taken branch */ |
|
// Selection between insn from IC or Trace port |
wire [31:0] ic_tp_insn = (tp_wr_insn) ? tp_insn : ic_insn; |
|
// |
// Current registered PC (corresponds to fetched instruction) |
// |
137,7 → 132,7
// |
// Just fetched instruction |
// |
assign if_insn = (if_saved[32]) ? if_saved[31:0] : (ic_stall) ? 32'h1500FFFF : ic_tp_insn; |
assign if_insn = (if_saved[32]) ? if_saved[31:0] : (ic_stall) ? 32'h1500FFFF : ic_insn; |
|
// |
// Delay slot PC saved |
240,7 → 235,7
$display("Starting exception: %h.", except_type); |
// synopsys translate_on |
`endif |
pcaddr = { 21'h0, except_type, 8'h00}; |
pcaddr = { 20'h0_0000, except_type, 8'h00}; |
taken = 1'b1; |
end |
endcase |
270,10 → 265,10
if_saved <= #1 33'b0; |
end |
else if (if_freeze && !if_saved[32] && !ic_stall) begin // && !taken |
if_saved <= #1 {1'b1, ic_tp_insn}; |
if_saved <= #1 {1'b1, ic_insn}; |
`ifdef OR1200_VERBOSE |
// synopsys translate_off |
$display("%t: if_saved <= %h", $time, {1'b1, ic_tp_insn}); |
$display("%t: if_saved <= %h", $time, {1'b1, ic_insn}); |
// synopsys translate_on |
`endif |
end |
/trunk/or1200/rtl/verilog/dmmu.v
192,7 → 192,7
// |
// Page fault exception logic |
// |
assign dmmuexcept_fault = dmmulsu_lsuop && dmmu_en && |
assign dmmuexcept_fault = (|dmmulsu_lsuop) && dmmu_en && |
( (!dmmulsu_lsuop[3] & !supv & !dtlb_ure) // Load in user mode not enabled |
|| (!dmmulsu_lsuop[3] & supv & !dtlb_sre) // Load in supv mode not enabled |
|| (dmmulsu_lsuop[3] & !supv & !dtlb_uwe) // Store in user mode not enabled |
201,7 → 201,7
// |
// TLB Miss exception logic |
// |
assign dmmuexcept_miss = dmmulsu_lsuop && dmmu_en && !dtlb_hit; |
assign dmmuexcept_miss = (|dmmulsu_lsuop) && dmmu_en && !dtlb_hit; |
|
// |
// Instantiation of DTLB |
/trunk/or1200/rtl/verilog/wbmux.v
118,29 → 118,29
// |
always @(muxin_a or muxin_b or muxin_c or muxin_d or rfwb_op) begin |
case(rfwb_op[`RFWBOP_WIDTH-1:1]) // synopsys full_case parallel_case infer_mux |
'b00: muxout = muxin_a; |
'b01: begin |
2'b00: muxout = muxin_a; |
2'b01: begin |
muxout = muxin_b; |
`ifdef OR1200_VERBOSE |
// synopsys translate_off |
$display(" WBMUX: muxin_b %h", muxin_b); |
// translate_on |
// synopsys translate_on |
`endif |
end |
'b10: begin |
2'b10: begin |
muxout = muxin_c; |
`ifdef OR1200_VERBOSE |
// synopsys translate_off |
$display(" WBMUX: muxin_c %h", muxin_c); |
// translate_on |
// synopsys translate_on |
`endif |
end |
'b11: begin |
2'b11: begin |
muxout = muxin_d + 4'h8; |
`ifdef OR1200_VERBOSE |
// synopsys translate_off |
$display(" WBMUX: muxin_d %h", muxin_d + 4'h8); |
// translate_on |
// synopsys translate_on |
`endif |
end |
endcase |
/trunk/or1200/rtl/verilog/rf.v
71,7 → 71,7
id_freeze, addra, addrb, dataa, datab, |
|
// Debug |
rfa_tqa, rfb_tqa, rfa_tmuxed, rfb_tmuxed, tp1w |
spr_cs, spr_write, spr_addr, spr_dat_i, spr_dat_o |
); |
|
parameter dw = `OPERAND_WIDTH; |
104,13 → 104,13
output [dw-1:0] datab; |
|
// |
// Debug |
// SPR access for debugging purposes |
// |
output [31:0] rfa_tqa; |
output [31:0] rfb_tqa; |
output [`TP1R_WIDTH-1:0] rfa_tmuxed; |
output [`TP1R_WIDTH-1:0] rfb_tmuxed; |
input [`TP1W_WIDTH-1:0] tp1w; |
input spr_cs; |
input spr_write; |
input [31:0] spr_addr; |
input [31:0] spr_dat_i; |
output [31:0] spr_dat_o; |
|
// |
// Internal wires and regs |
117,22 → 117,26
// |
wire [dw-1:0] from_rfa; |
wire [dw-1:0] from_rfb; |
wire [dw-1:0] t_dataw; // for test port |
wire [aw-1:0] t_addrw; // for test port |
wire [aw-1:0] t_addra; // for test port |
wire [aw-1:0] t_addrb; // for test port |
reg [dw:0] dataa_saved; |
reg [dw:0] datab_saved; |
wire [aw-1:0] rf_addra; |
wire [aw-1:0] rf_addrw; |
wire [dw-1:0] rf_dataw; |
wire rf_we; |
wire spr_valid; |
|
// |
// Simple assignments |
// SPR access is valid when spr_cs is asserted and |
// SPR address matches GPR addresses |
// |
assign rfa_tqa = 32'b0; |
assign rfb_tqa = 32'b0; |
assign rfa_tmuxed = `TP1R_WIDTH'b0; |
assign rfb_tmuxed = `TP1R_WIDTH'b0; |
assign spr_valid = spr_cs & (spr_addr[10:5] == `SPR_RF); |
|
// |
// SPR data output is always from RF A |
// |
assign spr_dat_o = from_rfa; |
|
// |
// Operand A comes from RF or from saved A register |
// |
assign dataa = (dataa_saved[32]) ? dataa_saved[31:0] : from_rfa; |
143,6 → 147,26
assign datab = (datab_saved[32]) ? datab_saved[31:0] : from_rfb; |
|
// |
// RF A read address is either from SPRS or normal from CPU control |
// |
assign rf_addra = (spr_valid & !spr_write) ? spr_addr[4:0] : addra; |
|
// |
// RF write address is either from SPRS or normal from CPU control |
// |
assign rf_addrw = (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; |
|
// |
// RF write enable is either from SPRS or normal from CPU control |
// |
assign rf_we = (spr_valid & spr_write) | we; |
|
// |
// Stores operand from RF_A into temp reg when pipeline is frozen |
// |
always @(posedge clk or posedge rst) |
178,7 → 202,7
.ce_a(1'b1), |
.we_a(1'b0), |
.oe_a(1'b1), |
.addr_a(addra), |
.addr_a(rf_addra), |
.di_a(32'h0000_0000), |
.do_a(from_rfa), |
|
185,11 → 209,11
// Port B |
.clk_b(clk), |
.rst_b(rst), |
.ce_b(we), |
.we_b(we), |
.ce_b(rf_we), |
.we_b(rf_we), |
.oe_b(1'b0), |
.addr_b(addrw), |
.di_b(dataw), |
.addr_b(rf_addrw), |
.di_b(rf_dataw), |
.do_b() |
); |
|
210,11 → 234,11
// Port B |
.clk_b(clk), |
.rst_b(rst), |
.ce_b(we), |
.we_b(we), |
.ce_b(rf_we), |
.we_b(rf_we), |
.oe_b(1'b0), |
.addr_b(addrw), |
.di_b(dataw), |
.addr_b(rf_addrw), |
.di_b(rf_dataw), |
.do_b() |
); |
|