Line 64... |
Line 64... |
|
|
// Internal CPU interface
|
// Internal CPU interface
|
flag, addrbase, addrofs, dat_i, alu_op, branch_op,
|
flag, addrbase, addrofs, dat_i, alu_op, branch_op,
|
epcr, eear, esr, except_start, except_started,
|
epcr, eear, esr, except_start, except_started,
|
to_wbmux, epcr_we, eear_we, esr_we, sr,
|
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
|
// From/to other RISC units
|
spr_dat_pic, spr_dat_tt, spr_dat_pm,
|
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;
|
parameter width = `OPERAND_WIDTH;
|
|
|
//
|
//
|
Line 99... |
Line 104... |
output epcr_we; // EPCR0 write enable
|
output epcr_we; // EPCR0 write enable
|
output eear_we; // EEAR0 write enable
|
output eear_we; // EEAR0 write enable
|
output esr_we; // ESR0 write enable
|
output esr_we; // ESR0 write enable
|
output [`SR_WIDTH-1:0] sr; // SR
|
output [`SR_WIDTH-1:0] sr; // SR
|
input [31:0] spr_dat_cfgr; // Data from CFGR
|
input [31:0] spr_dat_cfgr; // Data from CFGR
|
|
input [31:0] spr_dat_rf; // Data from RF
|
|
|
//
|
//
|
// To/from other RISC units
|
// To/from other RISC units
|
//
|
//
|
input [31:0] spr_dat_pic; // Data from PIC
|
input [31:0] spr_dat_pic; // Data from PIC
|
input [31:0] spr_dat_tt; // Data from TT
|
input [31:0] spr_dat_tt; // Data from TT
|
input [31:0] spr_dat_pm; // Data from PM
|
input [31:0] spr_dat_pm; // Data from PM
|
input [31:0] spr_dat_dmmu; // Data from DMMU
|
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_addr; // SPR Address
|
output [31:0] spr_dataout; // Data to unit
|
output [31:0] spr_dataout; // Data to unit
|
output [31:0] spr_cs; // Unit select
|
output [31:0] spr_cs; // Unit select
|
output spr_we; // SPR write enable
|
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
|
// Internal regs & wires
|
//
|
//
|
reg [`SR_WIDTH-1:0] sr; // SR
|
reg [`SR_WIDTH-1:0] sr; // SR
|
reg write_spr; // Write SPR
|
reg write_spr; // Write SPR
|
reg read_spr; // Read SPR
|
reg read_spr; // Read SPR
|
reg [width-1:0] to_wbmux; // For l.mfspr
|
reg [width-1:0] to_wbmux; // For l.mfspr
|
reg [31:0] spr_cs; // Group selects
|
|
wire sr_we; // Write enable SR
|
wire sr_we; // Write enable SR
|
wire cfgr_sel; // Select for cfg regs
|
wire cfgr_sel; // Select for cfg regs
|
|
wire rf_sel; // Select for RF
|
wire sr_sel; // Select for SR
|
wire sr_sel; // Select for SR
|
wire epcr_sel; // Select for EPCR0
|
wire epcr_sel; // Select for EPCR0
|
wire eear_sel; // Select for EEAR0
|
wire eear_sel; // Select for EEAR0
|
wire esr_sel; // Select for ESR0
|
wire esr_sel; // Select for ESR0
|
wire [31:0] sys_data; // Read data from system SPRs
|
wire [31:0] sys_data; // Read data from system SPRs
|
wire [`SR_WIDTH-1:0] to_sr; // Data to SR
|
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
|
// 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
|
// 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
|
// Decoding of groups
|
//
|
//
|
always @(spr_addr)
|
always @(spr_addr)
|
case (spr_addr[`SPR_GROUP_BITS]) // synopsys parallel_case
|
case (spr_addr[`SPR_GROUP_BITS]) // synopsys parallel_case
|
`SPR_GROUP_WIDTH'd00: spr_cs = 32'b00000000_00000000_00000000_00000001;
|
`SPR_GROUP_WIDTH'd00: unqualified_cs = 32'b00000000_00000000_00000000_00000001;
|
`SPR_GROUP_WIDTH'd01: spr_cs = 32'b00000000_00000000_00000000_00000010;
|
`SPR_GROUP_WIDTH'd01: unqualified_cs = 32'b00000000_00000000_00000000_00000010;
|
`SPR_GROUP_WIDTH'd02: spr_cs = 32'b00000000_00000000_00000000_00000100;
|
`SPR_GROUP_WIDTH'd02: unqualified_cs = 32'b00000000_00000000_00000000_00000100;
|
`SPR_GROUP_WIDTH'd03: spr_cs = 32'b00000000_00000000_00000000_00001000;
|
`SPR_GROUP_WIDTH'd03: unqualified_cs = 32'b00000000_00000000_00000000_00001000;
|
`SPR_GROUP_WIDTH'd04: spr_cs = 32'b00000000_00000000_00000000_00010000;
|
`SPR_GROUP_WIDTH'd04: unqualified_cs = 32'b00000000_00000000_00000000_00010000;
|
`SPR_GROUP_WIDTH'd05: spr_cs = 32'b00000000_00000000_00000000_00100000;
|
`SPR_GROUP_WIDTH'd05: unqualified_cs = 32'b00000000_00000000_00000000_00100000;
|
`SPR_GROUP_WIDTH'd06: spr_cs = 32'b00000000_00000000_00000000_01000000;
|
`SPR_GROUP_WIDTH'd06: unqualified_cs = 32'b00000000_00000000_00000000_01000000;
|
`SPR_GROUP_WIDTH'd07: spr_cs = 32'b00000000_00000000_00000000_10000000;
|
`SPR_GROUP_WIDTH'd07: unqualified_cs = 32'b00000000_00000000_00000000_10000000;
|
`SPR_GROUP_WIDTH'd08: spr_cs = 32'b00000000_00000000_00000001_00000000;
|
`SPR_GROUP_WIDTH'd08: unqualified_cs = 32'b00000000_00000000_00000001_00000000;
|
`SPR_GROUP_WIDTH'd09: spr_cs = 32'b00000000_00000000_00000010_00000000;
|
`SPR_GROUP_WIDTH'd09: unqualified_cs = 32'b00000000_00000000_00000010_00000000;
|
`SPR_GROUP_WIDTH'd10: spr_cs = 32'b00000000_00000000_00000100_00000000;
|
`SPR_GROUP_WIDTH'd10: unqualified_cs = 32'b00000000_00000000_00000100_00000000;
|
`SPR_GROUP_WIDTH'd11: spr_cs = 32'b00000000_00000000_00001000_00000000;
|
`SPR_GROUP_WIDTH'd11: unqualified_cs = 32'b00000000_00000000_00001000_00000000;
|
`SPR_GROUP_WIDTH'd12: spr_cs = 32'b00000000_00000000_00010000_00000000;
|
`SPR_GROUP_WIDTH'd12: unqualified_cs = 32'b00000000_00000000_00010000_00000000;
|
`SPR_GROUP_WIDTH'd13: spr_cs = 32'b00000000_00000000_00100000_00000000;
|
`SPR_GROUP_WIDTH'd13: unqualified_cs = 32'b00000000_00000000_00100000_00000000;
|
`SPR_GROUP_WIDTH'd14: spr_cs = 32'b00000000_00000000_01000000_00000000;
|
`SPR_GROUP_WIDTH'd14: unqualified_cs = 32'b00000000_00000000_01000000_00000000;
|
`SPR_GROUP_WIDTH'd15: spr_cs = 32'b00000000_00000000_10000000_00000000;
|
`SPR_GROUP_WIDTH'd15: unqualified_cs = 32'b00000000_00000000_10000000_00000000;
|
`SPR_GROUP_WIDTH'd16: spr_cs = 32'b00000000_00000001_00000000_00000000;
|
`SPR_GROUP_WIDTH'd16: unqualified_cs = 32'b00000000_00000001_00000000_00000000;
|
`SPR_GROUP_WIDTH'd17: spr_cs = 32'b00000000_00000010_00000000_00000000;
|
`SPR_GROUP_WIDTH'd17: unqualified_cs = 32'b00000000_00000010_00000000_00000000;
|
`SPR_GROUP_WIDTH'd18: spr_cs = 32'b00000000_00000100_00000000_00000000;
|
`SPR_GROUP_WIDTH'd18: unqualified_cs = 32'b00000000_00000100_00000000_00000000;
|
`SPR_GROUP_WIDTH'd19: spr_cs = 32'b00000000_00001000_00000000_00000000;
|
`SPR_GROUP_WIDTH'd19: unqualified_cs = 32'b00000000_00001000_00000000_00000000;
|
`SPR_GROUP_WIDTH'd20: spr_cs = 32'b00000000_00010000_00000000_00000000;
|
`SPR_GROUP_WIDTH'd20: unqualified_cs = 32'b00000000_00010000_00000000_00000000;
|
`SPR_GROUP_WIDTH'd21: spr_cs = 32'b00000000_00100000_00000000_00000000;
|
`SPR_GROUP_WIDTH'd21: unqualified_cs = 32'b00000000_00100000_00000000_00000000;
|
`SPR_GROUP_WIDTH'd22: spr_cs = 32'b00000000_01000000_00000000_00000000;
|
`SPR_GROUP_WIDTH'd22: unqualified_cs = 32'b00000000_01000000_00000000_00000000;
|
`SPR_GROUP_WIDTH'd23: spr_cs = 32'b00000000_10000000_00000000_00000000;
|
`SPR_GROUP_WIDTH'd23: unqualified_cs = 32'b00000000_10000000_00000000_00000000;
|
`SPR_GROUP_WIDTH'd24: spr_cs = 32'b00000001_00000000_00000000_00000000;
|
`SPR_GROUP_WIDTH'd24: unqualified_cs = 32'b00000001_00000000_00000000_00000000;
|
`SPR_GROUP_WIDTH'd25: spr_cs = 32'b00000010_00000000_00000000_00000000;
|
`SPR_GROUP_WIDTH'd25: unqualified_cs = 32'b00000010_00000000_00000000_00000000;
|
`SPR_GROUP_WIDTH'd26: spr_cs = 32'b00000100_00000000_00000000_00000000;
|
`SPR_GROUP_WIDTH'd26: unqualified_cs = 32'b00000100_00000000_00000000_00000000;
|
`SPR_GROUP_WIDTH'd27: spr_cs = 32'b00001000_00000000_00000000_00000000;
|
`SPR_GROUP_WIDTH'd27: unqualified_cs = 32'b00001000_00000000_00000000_00000000;
|
`SPR_GROUP_WIDTH'd28: spr_cs = 32'b00010000_00000000_00000000_00000000;
|
`SPR_GROUP_WIDTH'd28: unqualified_cs = 32'b00010000_00000000_00000000_00000000;
|
`SPR_GROUP_WIDTH'd29: spr_cs = 32'b00100000_00000000_00000000_00000000;
|
`SPR_GROUP_WIDTH'd29: unqualified_cs = 32'b00100000_00000000_00000000_00000000;
|
`SPR_GROUP_WIDTH'd30: spr_cs = 32'b01000000_00000000_00000000_00000000;
|
`SPR_GROUP_WIDTH'd30: unqualified_cs = 32'b01000000_00000000_00000000_00000000;
|
`SPR_GROUP_WIDTH'd31: spr_cs = 32'b10000000_00000000_00000000_00000000;
|
`SPR_GROUP_WIDTH'd31: unqualified_cs = 32'b10000000_00000000_00000000_00000000;
|
endcase
|
endcase
|
|
|
//
|
//
|
// SPRs System Group
|
// SPRs System Group
|
//
|
//
|
|
|
//
|
//
|
// What to write into SR
|
// 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
|
// Selects for system SPRs
|
//
|
//
|
assign cfgr_sel = (spr_cs[`SPR_GROUP_SYS] && (spr_addr[6:4] == `SPR_CFGR));
|
assign cfgr_sel = (spr_cs[`SPR_GROUP_SYS] && (spr_addr[10:4] == `SPR_CFGR));
|
assign sr_sel = (spr_cs[`SPR_GROUP_SYS] && (spr_addr[6:0] == `SPR_SR));
|
assign rf_sel = (spr_cs[`SPR_GROUP_SYS] && (spr_addr[10:5] == `SPR_RF));
|
assign epcr_sel = (spr_cs[`SPR_GROUP_SYS] && (spr_addr[6:0] == `SPR_EPCR));
|
assign sr_sel = (spr_cs[`SPR_GROUP_SYS] && (spr_addr[10:0] == `SPR_SR));
|
assign eear_sel = (spr_cs[`SPR_GROUP_SYS] && (spr_addr[6:0] == `SPR_EEAR));
|
assign epcr_sel = (spr_cs[`SPR_GROUP_SYS] && (spr_addr[10:0] == `SPR_EPCR));
|
assign esr_sel = (spr_cs[`SPR_GROUP_SYS] && (spr_addr[6:0] == `SPR_ESR));
|
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
|
// Write enables for system SPRs
|
//
|
//
|
assign sr_we = (write_spr && sr_sel) | (branch_op == `BRANCHOP_RFE);
|
assign sr_we = (write_spr && sr_sel) | (branch_op == `BRANCHOP_RFE);
|
Line 213... |
Line 250... |
|
|
//
|
//
|
// Output from system SPRs
|
// Output from system SPRs
|
//
|
//
|
assign sys_data = (spr_dat_cfgr & {32{read_spr & cfgr_sel}}) |
|
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}}) |
|
(epcr & {32{read_spr & epcr_sel}}) |
|
(eear & {32{read_spr & eear_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
|
// Supervision register
|
//
|
//
|
always @(posedge clk or posedge rst)
|
always @(posedge clk or posedge rst)
|
Line 232... |
Line 270... |
$display(" INFO: exception started. SR[SUPV] set and SR[EXR] cleared.");
|
$display(" INFO: exception started. SR[SUPV] set and SR[EXR] cleared.");
|
// synopsys translate_on
|
// synopsys translate_on
|
`endif
|
`endif
|
sr[`SR_SUPV] <= #1 1'b1;
|
sr[`SR_SUPV] <= #1 1'b1;
|
sr[`SR_EXR] <= #1 1'b0;
|
sr[`SR_EXR] <= #1 1'b0;
|
|
sr[`SR_WIDTH:2] <= #1 {`SR_WIDTH-2{1'b0}};
|
end
|
end
|
else if (sr_we) begin
|
else if (sr_we) begin
|
`ifdef OR1200_VERBOSE
|
`ifdef OR1200_VERBOSE
|
// synopsys translate_off
|
// synopsys translate_off
|
$display(" INFO: writing into SR register: %h", dat_i);
|
$display(" INFO: writing into SR register: %h", spr_dataout);
|
// synopsys translate_on
|
// synopsys translate_on
|
`endif
|
`endif
|
sr <= #1 to_sr;
|
sr <= #1 to_sr;
|
end
|
end
|
|
|
//
|
//
|
// MTSPR/MFSPR interface
|
// 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
|
always @(sprs_op or spr_addr or spr_dataout or sys_data or spr_dat_pic or spr_dat_pm or
|
case (alu_op) // synopsys full_case parallel_case
|
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
|
`ALUOP_MTSR : begin
|
`ifdef OR1200_VERBOSE
|
`ifdef OR1200_VERBOSE
|
// synopsys translate_off
|
// 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
|
// synopsys translate_on
|
`endif
|
`endif
|
write_spr = 1'b1;
|
write_spr = 1'b1;
|
read_spr = 1'b0;
|
read_spr = 1'b0;
|
to_wbmux = 32'b0;
|
to_wbmux = 32'b0;
|
Line 267... |
Line 307... |
to_wbmux = spr_dat_pic;
|
to_wbmux = spr_dat_pic;
|
`SPR_GROUP_PM:
|
`SPR_GROUP_PM:
|
to_wbmux = spr_dat_pm;
|
to_wbmux = spr_dat_pm;
|
`SPR_GROUP_DMMU:
|
`SPR_GROUP_DMMU:
|
to_wbmux = spr_dat_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:
|
`SPR_GROUP_SYS:
|
to_wbmux = sys_data;
|
to_wbmux = sys_data;
|
default:
|
default:
|
to_wbmux = 32'b0;
|
to_wbmux = 32'b0;
|
endcase
|
endcase
|