Line 41... |
Line 41... |
//// ////
|
//// ////
|
//////////////////////////////////////////////////////////////////////
|
//////////////////////////////////////////////////////////////////////
|
//
|
//
|
// CVS Revision History
|
// CVS Revision History
|
//
|
//
|
// $Log: not supported by cvs2svn $
|
// $Log: or1200_sprs.v,v $
|
|
// Revision 2.0 2010/06/30 11:00:00 ORSoC
|
|
// Major update:
|
|
// Structure reordered and bugs fixed.
|
|
//
|
|
// Revision 1.11 2004/04/05 08:29:57 lampret
|
|
// Merged branch_qmem into main tree.
|
|
//
|
// Revision 1.9.4.1 2003/12/17 13:43:38 simons
|
// Revision 1.9.4.1 2003/12/17 13:43:38 simons
|
// Exception prefix configuration changed.
|
// Exception prefix configuration changed.
|
//
|
//
|
// Revision 1.9 2002/09/07 05:42:02 lampret
|
// Revision 1.9 2002/09/07 05:42:02 lampret
|
// Added optional SR[CY]. Added define to enable additional (compare) flag modifiers. Defines are OR1200_IMPL_ADDC and OR1200_ADDITIONAL_FLAG_MODIFIERS.
|
// Added optional SR[CY]. Added define to enable additional (compare) flag modifiers. Defines are OR1200_IMPL_ADDC and OR1200_ADDITIONAL_FLAG_MODIFIERS.
|
Line 112... |
Line 119... |
// Clk & Rst
|
// Clk & Rst
|
clk, rst,
|
clk, rst,
|
|
|
// Internal CPU interface
|
// Internal CPU interface
|
flagforw, flag_we, flag, cyforw, cy_we, carry,
|
flagforw, flag_we, flag, cyforw, cy_we, carry,
|
addrbase, addrofs, dat_i, alu_op, branch_op,
|
addrbase, addrofs, dat_i, branch_op, ex_spr_read, ex_spr_write,
|
epcr, eear, esr, except_started,
|
epcr, eear, esr, except_started,
|
to_wbmux, epcr_we, eear_we, esr_we, pc_we, sr_we, to_sr, sr,
|
to_wbmux, epcr_we, eear_we, esr_we, pc_we, sr_we, to_sr, sr,
|
spr_dat_cfgr, spr_dat_rf, spr_dat_npc, spr_dat_ppc, spr_dat_mac,
|
spr_dat_cfgr, spr_dat_rf, spr_dat_npc, spr_dat_ppc, spr_dat_mac,
|
|
boot_adr_sel_i,
|
|
|
// 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_dat_dmmu, spr_dat_immu, spr_dat_du,
|
spr_dat_dmmu, spr_dat_immu, spr_dat_du,
|
spr_addr, spr_dat_o, spr_cs, spr_we,
|
spr_addr, spr_dat_o, spr_cs, spr_we,
|
Line 147... |
Line 155... |
input cy_we; // From ALU
|
input cy_we; // From ALU
|
output carry; // SR[CY]
|
output carry; // SR[CY]
|
input [width-1:0] addrbase; // SPR base address
|
input [width-1:0] addrbase; // SPR base address
|
input [15:0] addrofs; // SPR offset
|
input [15:0] addrofs; // SPR offset
|
input [width-1:0] dat_i; // SPR write data
|
input [width-1:0] dat_i; // SPR write data
|
input [`OR1200_ALUOP_WIDTH-1:0] alu_op; // ALU operation
|
input ex_spr_read; // l.mfspr in EX
|
|
input ex_spr_write; // l.mtspr in EX
|
input [`OR1200_BRANCHOP_WIDTH-1:0] branch_op; // Branch operation
|
input [`OR1200_BRANCHOP_WIDTH-1:0] branch_op; // Branch operation
|
input [width-1:0] epcr; // EPCR0
|
input [width-1:0] epcr; // EPCR0
|
input [width-1:0] eear; // EEAR0
|
input [width-1:0] eear; // EEAR0
|
input [`OR1200_SR_WIDTH-1:0] esr; // ESR0
|
input [`OR1200_SR_WIDTH-1:0] esr; // ESR0
|
input except_started; // Exception was started
|
input except_started; // Exception was started
|
Line 166... |
Line 175... |
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
|
input [31:0] spr_dat_rf; // Data from RF
|
input [31:0] spr_dat_npc; // Data from NPC
|
input [31:0] spr_dat_npc; // Data from NPC
|
input [31:0] spr_dat_ppc; // Data from PPC
|
input [31:0] spr_dat_ppc; // Data from PPC
|
input [31:0] spr_dat_mac; // Data from MAC
|
input [31:0] spr_dat_mac; // Data from MAC
|
|
input boot_adr_sel_i;
|
|
|
//
|
//
|
// 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
|
Line 193... |
Line 203... |
output [width-1:0] du_dat_cpu; // Data from SPRS to DU
|
output [width-1:0] du_dat_cpu; // Data from SPRS to DU
|
|
|
//
|
//
|
// Internal regs & wires
|
// Internal regs & wires
|
//
|
//
|
|
reg [`OR1200_SR_WIDTH-1:0] sr_reg; // SR
|
|
reg sr_reg_bit_eph; // SR_EPH bit
|
|
reg sr_reg_bit_eph_select; // SR_EPH select
|
|
wire sr_reg_bit_eph_muxed; // SR_EPH muxed bit
|
reg [`OR1200_SR_WIDTH-1:0] sr; // SR
|
reg [`OR1200_SR_WIDTH-1:0] sr; // SR
|
reg write_spr; // Write SPR
|
|
reg read_spr; // Read SPR
|
|
reg [width-1:0] to_wbmux; // For l.mfspr
|
reg [width-1:0] to_wbmux; // For l.mfspr
|
wire cfgr_sel; // Select for cfg regs
|
wire cfgr_sel; // Select for cfg regs
|
wire rf_sel; // Select for RF
|
wire rf_sel; // Select for RF
|
wire npc_sel; // Select for NPC
|
wire npc_sel; // Select for NPC
|
wire ppc_sel; // Select for PPC
|
wire ppc_sel; // Select for PPC
|
Line 207... |
Line 219... |
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 du_access; // Debug unit access
|
wire du_access; // Debug unit access
|
wire [`OR1200_ALUOP_WIDTH-1:0] sprs_op; // ALU operation
|
|
reg [31:0] unqualified_cs; // Unqualified chip selects
|
reg [31:0] unqualified_cs; // Unqualified chip selects
|
|
wire ex_spr_write; // jb
|
|
|
//
|
//
|
// Decide if it is debug unit access
|
// Decide if it is debug unit access
|
//
|
//
|
assign du_access = du_read | du_write;
|
assign du_access = du_read | du_write;
|
|
|
//
|
//
|
// Generate sprs opcode
|
|
//
|
|
assign sprs_op = du_write ? `OR1200_ALUOP_MTSR : du_read ? `OR1200_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
|
// OR from debug unit address
|
//
|
//
|
assign spr_addr = du_access ? du_addr : addrbase | {16'h0000, addrofs};
|
assign spr_addr = du_access ? du_addr : (addrbase | {16'h0000, addrofs});
|
|
|
//
|
//
|
// SPR is written by debug unit or by l.mtspr
|
// SPR is written by debug unit or by l.mtspr
|
//
|
//
|
assign spr_dat_o = du_write ? du_dat_du : dat_i;
|
assign spr_dat_o = du_write ? du_dat_du : dat_i;
|
|
|
//
|
//
|
// debug unit data input:
|
// debug unit data input:
|
// - write into debug unit SPRs by debug unit itself
|
|
// - read of SPRS by debug unit
|
// - read of SPRS by debug unit
|
|
// - write into debug unit SPRs by debug unit itself
|
// - write into debug unit SPRs by l.mtspr
|
// - write into debug unit SPRs by l.mtspr
|
//
|
//
|
assign du_dat_cpu = du_write ? du_dat_du : du_read ? to_wbmux : dat_i;
|
assign du_dat_cpu = du_read ? to_wbmux : du_write ? du_dat_du : dat_i;
|
|
|
//
|
//
|
// Write into SPRs when l.mtspr
|
// Write into SPRs when DU or l.mtspr
|
//
|
//
|
assign spr_we = du_write | write_spr;
|
assign spr_we = du_write | ex_spr_write;
|
|
|
//
|
//
|
// Qualify chip selects
|
// Qualify chip selects
|
//
|
//
|
assign spr_cs = unqualified_cs & {32{read_spr | write_spr}};
|
assign spr_cs = unqualified_cs & {32{du_read | du_write | ex_spr_read | (ex_spr_write & sr[`OR1200_SR_SM])}};
|
|
|
//
|
//
|
// Decoding of groups
|
// Decoding of groups
|
//
|
//
|
always @(spr_addr)
|
always @(spr_addr)
|
Line 296... |
Line 303... |
|
|
//
|
//
|
// What to write into SR
|
// What to write into SR
|
//
|
//
|
assign to_sr[`OR1200_SR_FO:`OR1200_SR_OV] =
|
assign to_sr[`OR1200_SR_FO:`OR1200_SR_OV] =
|
|
(except_started) ? sr[`OR1200_SR_FO:`OR1200_SR_OV] :
|
(branch_op == `OR1200_BRANCHOP_RFE) ? esr[`OR1200_SR_FO:`OR1200_SR_OV] :
|
(branch_op == `OR1200_BRANCHOP_RFE) ? esr[`OR1200_SR_FO:`OR1200_SR_OV] :
|
(write_spr && sr_sel) ? {1'b1, spr_dat_o[`OR1200_SR_FO-1:`OR1200_SR_OV]}:
|
(spr_we && sr_sel) ? {1'b1, spr_dat_o[`OR1200_SR_FO-1:`OR1200_SR_OV]}:
|
sr[`OR1200_SR_FO:`OR1200_SR_OV];
|
sr[`OR1200_SR_FO:`OR1200_SR_OV];
|
|
assign to_sr[`OR1200_SR_TED] =
|
|
(except_started) ? 1'b1 :
|
|
(branch_op == `OR1200_BRANCHOP_RFE) ? esr[`OR1200_SR_TED] :
|
|
(spr_we && sr_sel) ? spr_dat_o[`OR1200_SR_TED]:
|
|
sr[`OR1200_SR_TED];
|
assign to_sr[`OR1200_SR_CY] =
|
assign to_sr[`OR1200_SR_CY] =
|
|
(except_started) ? sr[`OR1200_SR_CY] :
|
(branch_op == `OR1200_BRANCHOP_RFE) ? esr[`OR1200_SR_CY] :
|
(branch_op == `OR1200_BRANCHOP_RFE) ? esr[`OR1200_SR_CY] :
|
cy_we ? cyforw :
|
cy_we ? cyforw :
|
(write_spr && sr_sel) ? spr_dat_o[`OR1200_SR_CY] :
|
(spr_we && sr_sel) ? spr_dat_o[`OR1200_SR_CY] :
|
sr[`OR1200_SR_CY];
|
sr[`OR1200_SR_CY];
|
assign to_sr[`OR1200_SR_F] =
|
assign to_sr[`OR1200_SR_F] =
|
|
(except_started) ? sr[`OR1200_SR_F] :
|
(branch_op == `OR1200_BRANCHOP_RFE) ? esr[`OR1200_SR_F] :
|
(branch_op == `OR1200_BRANCHOP_RFE) ? esr[`OR1200_SR_F] :
|
flag_we ? flagforw :
|
flag_we ? flagforw :
|
(write_spr && sr_sel) ? spr_dat_o[`OR1200_SR_F] :
|
(spr_we && sr_sel) ? spr_dat_o[`OR1200_SR_F] :
|
sr[`OR1200_SR_F];
|
sr[`OR1200_SR_F];
|
assign to_sr[`OR1200_SR_CE:`OR1200_SR_SM] =
|
assign to_sr[`OR1200_SR_CE:`OR1200_SR_SM] =
|
|
(except_started) ? {sr[`OR1200_SR_CE:`OR1200_SR_LEE], 2'b00, sr[`OR1200_SR_ICE:`OR1200_SR_DCE], 3'b001} :
|
(branch_op == `OR1200_BRANCHOP_RFE) ? esr[`OR1200_SR_CE:`OR1200_SR_SM] :
|
(branch_op == `OR1200_BRANCHOP_RFE) ? esr[`OR1200_SR_CE:`OR1200_SR_SM] :
|
(write_spr && sr_sel) ? spr_dat_o[`OR1200_SR_CE:`OR1200_SR_SM]:
|
(spr_we && sr_sel) ? spr_dat_o[`OR1200_SR_CE:`OR1200_SR_SM]:
|
sr[`OR1200_SR_CE:`OR1200_SR_SM];
|
sr[`OR1200_SR_CE:`OR1200_SR_SM];
|
|
|
//
|
//
|
// Selects for system SPRs
|
// Selects for system SPRs
|
//
|
//
|
Line 329... |
Line 345... |
assign esr_sel = (spr_cs[`OR1200_SPR_GROUP_SYS] && (spr_addr[10:0] == `OR1200_SPR_ESR));
|
assign esr_sel = (spr_cs[`OR1200_SPR_GROUP_SYS] && (spr_addr[10:0] == `OR1200_SPR_ESR));
|
|
|
//
|
//
|
// Write enables for system SPRs
|
// Write enables for system SPRs
|
//
|
//
|
assign sr_we = (write_spr && sr_sel) | (branch_op == `OR1200_BRANCHOP_RFE) | flag_we | cy_we;
|
assign sr_we = (spr_we && sr_sel) | (branch_op == `OR1200_BRANCHOP_RFE) | flag_we | cy_we;
|
assign pc_we = (write_spr && (npc_sel | ppc_sel));
|
assign pc_we = (du_write && (npc_sel | ppc_sel));
|
assign epcr_we = (write_spr && epcr_sel);
|
assign epcr_we = (spr_we && epcr_sel);
|
assign eear_we = (write_spr && eear_sel);
|
assign eear_we = (spr_we && eear_sel);
|
assign esr_we = (write_spr && esr_sel);
|
assign esr_we = (spr_we && esr_sel);
|
|
|
//
|
//
|
// 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{cfgr_sel}}) |
|
(spr_dat_rf & {32{read_spr & rf_sel}}) |
|
(spr_dat_rf & {32{rf_sel}}) |
|
(spr_dat_npc & {32{read_spr & npc_sel}}) |
|
(spr_dat_npc & {32{npc_sel}}) |
|
(spr_dat_ppc & {32{read_spr & ppc_sel}}) |
|
(spr_dat_ppc & {32{ppc_sel}}) |
|
({{32-`OR1200_SR_WIDTH{1'b0}},sr} & {32{read_spr & sr_sel}}) |
|
({{32-`OR1200_SR_WIDTH{1'b0}},sr} & {32{sr_sel}}) |
|
(epcr & {32{read_spr & epcr_sel}}) |
|
(epcr & {32{epcr_sel}}) |
|
(eear & {32{read_spr & eear_sel}}) |
|
(eear & {32{eear_sel}}) |
|
({{32-`OR1200_SR_WIDTH{1'b0}},esr} & {32{read_spr & esr_sel}});
|
({{32-`OR1200_SR_WIDTH{1'b0}},esr} & {32{esr_sel}});
|
|
|
//
|
//
|
// Flag alias
|
// Flag alias
|
//
|
//
|
assign flag = sr[`OR1200_SR_F];
|
assign flag = sr[`OR1200_SR_F];
|
Line 362... |
Line 378... |
//
|
//
|
// Supervision register
|
// Supervision register
|
//
|
//
|
always @(posedge clk or posedge rst)
|
always @(posedge clk or posedge rst)
|
if (rst)
|
if (rst)
|
sr <= #1 {1'b1, `OR1200_SR_EPH_DEF, {`OR1200_SR_WIDTH-3{1'b0}}, 1'b1};
|
sr_reg <= #1 {2'h1, `OR1200_SR_EPH_DEF, {`OR1200_SR_WIDTH-4{1'b0}}, 1'b1};
|
else if (except_started) begin
|
else if (except_started)
|
sr[`OR1200_SR_SM] <= #1 1'b1;
|
sr_reg <= #1 to_sr[`OR1200_SR_WIDTH-1:0];
|
sr[`OR1200_SR_TEE] <= #1 1'b0;
|
|
sr[`OR1200_SR_IEE] <= #1 1'b0;
|
|
sr[`OR1200_SR_DME] <= #1 1'b0;
|
|
sr[`OR1200_SR_IME] <= #1 1'b0;
|
|
end
|
|
else if (sr_we)
|
else if (sr_we)
|
sr <= #1 to_sr[`OR1200_SR_WIDTH-1:0];
|
sr_reg <= #1 to_sr[`OR1200_SR_WIDTH-1:0];
|
|
|
|
// EPH part of Supervision register
|
|
always @(posedge clk or posedge rst)
|
|
// default value
|
|
if (rst) begin
|
|
sr_reg_bit_eph <= #1 `OR1200_SR_EPH_DEF;
|
|
sr_reg_bit_eph_select <= #1 1'b1; // select async. value due to reset state
|
|
end
|
|
// selected value (different from default) is written into FF after reset state
|
|
else if (sr_reg_bit_eph_select) begin
|
|
sr_reg_bit_eph <= #1 boot_adr_sel_i; // dynamic value can only be assigned to FF out of reset!
|
|
sr_reg_bit_eph_select <= #1 1'b0; // select FF value
|
|
end
|
|
else if (sr_we) begin
|
|
sr_reg_bit_eph <= #1 to_sr[`OR1200_SR_EPH];
|
|
end
|
|
|
|
// select async. value of EPH bit after reset
|
|
assign sr_reg_bit_eph_muxed = (sr_reg_bit_eph_select) ? boot_adr_sel_i : sr_reg_bit_eph;
|
|
|
|
// EPH part joined together with rest of Supervision register
|
|
always @(sr_reg or sr_reg_bit_eph_muxed)
|
|
sr = {sr_reg[`OR1200_SR_WIDTH-1:`OR1200_SR_WIDTH-2], sr_reg_bit_eph_muxed, sr_reg[`OR1200_SR_WIDTH-4:0]};
|
|
|
//
|
//
|
// MTSPR/MFSPR interface
|
// MTSPR/MFSPR interface
|
//
|
//
|
always @(sprs_op or spr_addr or sys_data or spr_dat_mac or spr_dat_pic or spr_dat_pm or
|
always @(spr_addr or sys_data or spr_dat_mac 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
|
spr_dat_dmmu or spr_dat_immu or spr_dat_du or spr_dat_tt) begin
|
case (sprs_op) // synopsys parallel_case
|
|
`OR1200_ALUOP_MTSR : begin
|
|
write_spr = 1'b1;
|
|
read_spr = 1'b0;
|
|
to_wbmux = 32'b0;
|
|
end
|
|
`OR1200_ALUOP_MFSR : begin
|
|
casex (spr_addr[`OR1200_SPR_GROUP_BITS]) // synopsys parallel_case
|
casex (spr_addr[`OR1200_SPR_GROUP_BITS]) // synopsys parallel_case
|
|
`OR1200_SPR_GROUP_SYS:
|
|
to_wbmux = sys_data;
|
`OR1200_SPR_GROUP_TT:
|
`OR1200_SPR_GROUP_TT:
|
to_wbmux = spr_dat_tt;
|
to_wbmux = spr_dat_tt;
|
`OR1200_SPR_GROUP_PIC:
|
`OR1200_SPR_GROUP_PIC:
|
to_wbmux = spr_dat_pic;
|
to_wbmux = spr_dat_pic;
|
`OR1200_SPR_GROUP_PM:
|
`OR1200_SPR_GROUP_PM:
|
Line 398... |
Line 427... |
to_wbmux = spr_dat_dmmu;
|
to_wbmux = spr_dat_dmmu;
|
`OR1200_SPR_GROUP_IMMU:
|
`OR1200_SPR_GROUP_IMMU:
|
to_wbmux = spr_dat_immu;
|
to_wbmux = spr_dat_immu;
|
`OR1200_SPR_GROUP_MAC:
|
`OR1200_SPR_GROUP_MAC:
|
to_wbmux = spr_dat_mac;
|
to_wbmux = spr_dat_mac;
|
`OR1200_SPR_GROUP_DU:
|
default: //`OR1200_SPR_GROUP_DU:
|
to_wbmux = spr_dat_du;
|
to_wbmux = spr_dat_du;
|
`OR1200_SPR_GROUP_SYS:
|
|
to_wbmux = sys_data;
|
|
default:
|
|
to_wbmux = 32'b0;
|
|
endcase
|
|
write_spr = 1'b0;
|
|
read_spr = 1'b1;
|
|
end
|
|
default : begin
|
|
write_spr = 1'b0;
|
|
read_spr = 1'b0;
|
|
to_wbmux = 32'b0;
|
|
end
|
|
endcase
|
endcase
|
end
|
end
|
|
|
endmodule
|
endmodule
|
|
|
No newline at end of file
|
No newline at end of file
|