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

Subversion Repositories or1k

Compare Revisions

  • This comparison shows the changes necessary to convert path
    /
    from Rev 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()
);
 

powered by: WebSVN 2.1.0

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