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

Subversion Repositories openrisc

Compare Revisions

  • This comparison shows the changes necessary to convert path
    /openrisc/trunk/or1200/rtl/verilog
    from Rev 401 to Rev 481
    Reverse comparison

Rev 401 → Rev 481

/or1200_defines.v
163,8 → 163,12
//`define OR1200_IC_1W_512B
//`define OR1200_IC_1W_4KB
`define OR1200_IC_1W_8KB
//`define OR1200_IC_1W_16KB
//`define OR1200_IC_1W_32KB
//`define OR1200_DC_1W_4KB
`define OR1200_DC_1W_8KB
//`define OR1200_DC_1W_16KB
//`define OR1200_DC_1W_32KB
 
`endif
 
360,39 → 364,38
// Implement multiply-and-accumulate
//
// By default MAC is implemented. To
// implement MAC, multiplier needs to be
// implement MAC, multiplier (non-serial) needs to be
// implemented.
//
`define OR1200_MAC_IMPLEMENTED
//`define OR1200_MAC_IMPLEMENTED
 
//
// Implement optional l.div/l.divu instructions
//
// By default divide instructions are not implemented
// to save area and increase clock frequency. or32 C/C++
// compiler can use soft library for division.
// to save area.
//
// To implement divide, both multiplier and MAC needs to be implemented.
//
`define OR1200_DIV_IMPLEMENTED
 
//
// Low power, slower multiplier
// Serial multiplier.
//
// Select between low-power (larger) multiplier
// and faster multiplier. The actual difference
// is only AND logic that prevents distribution
// of operands into the multiplier when instruction
// in execution is not multiply instruction
//`define OR1200_MULT_SERIAL
 
//
//`define OR1200_LOWPWR_MULT
// Serial divider.
// Uncomment to use a serial divider, otherwise will
// be a generic parallel implementation.
//
`define OR1200_DIV_SERIAL
 
//
// Implement HW Single Precision FPU
//
//`define OR1200_FPU_IMPLEMENTED
//
 
 
//
// Clock ratio RISC clock versus WB clock
//
464,8 → 467,8
`define OR1200_ALUOP_SHROT 4'd8
`define OR1200_ALUOP_DIV 4'd9
`define OR1200_ALUOP_DIVU 4'd10
/* Order not specifically defined. */
`define OR1200_ALUOP_IMM 4'd11
`define OR1200_ALUOP_MULU 4'd11
/* Values sent to ALU from decode unit - not strictly defined by ISA */
`define OR1200_ALUOP_MOVHI 4'd12
`define OR1200_ALUOP_COMP 4'd13
`define OR1200_ALUOP_MTSR 4'd14
1025,7 → 1028,7
`define OR1200_PIC_IMPLEMENTED
 
// Define number of interrupt inputs (2-31)
`define OR1200_PIC_INTS 31
`define OR1200_PIC_INTS 20
 
// Address offsets of PIC registers inside PIC group
`define OR1200_PIC_OFS_PICMR 2'd0
1220,19 → 1223,23
// Insn cache (IC)
//
 
// 3 for 8 bytes, 4 for 16 bytes etc
`define OR1200_ICLS 4
// 4 for 16 byte line, 5 for 32 byte lines.
`ifdef OR1200_IC_1W_32KB
`define OR1200_ICLS 5
`else
`define OR1200_ICLS 4
`endif
 
//
// IC configurations
//
`ifdef OR1200_IC_1W_512B
`define OR1200_ICSIZE 9 // 512
`define OR1200_ICINDX `OR1200_ICSIZE-2 // 7
`define OR1200_ICINDXH `OR1200_ICSIZE-1 // 8
`define OR1200_ICTAGL `OR1200_ICINDXH+1 // 9
`define OR1200_ICTAG `OR1200_ICSIZE-`OR1200_ICLS // 5
`define OR1200_ICTAG_W 24
`define OR1200_ICSIZE 9 // 512
`define OR1200_ICINDX `OR1200_ICSIZE-2 // 7
`define OR1200_ICINDXH `OR1200_ICSIZE-1 // 8
`define OR1200_ICTAGL `OR1200_ICINDXH+1 // 9
`define OR1200_ICTAG `OR1200_ICSIZE-`OR1200_ICLS // 5
`define OR1200_ICTAG_W 24
`endif
`ifdef OR1200_IC_1W_4KB
`define OR1200_ICSIZE 12 // 4096
1250,6 → 1257,22
`define OR1200_ICTAG `OR1200_ICSIZE-`OR1200_ICLS // 9
`define OR1200_ICTAG_W 20
`endif
`ifdef OR1200_IC_1W_16KB
`define OR1200_ICSIZE 14 // 16384
`define OR1200_ICINDX `OR1200_ICSIZE-2 // 12
`define OR1200_ICINDXH `OR1200_ICSIZE-1 // 13
`define OR1200_ICTAGL `OR1200_ICINDXH+1 // 14
`define OR1200_ICTAG `OR1200_ICSIZE-`OR1200_ICLS // 10
`define OR1200_ICTAG_W 19
`endif
`ifdef OR1200_IC_1W_32KB
`define OR1200_ICSIZE 15 // 32768
`define OR1200_ICINDX `OR1200_ICSIZE-2 // 13
`define OR1200_ICINDXH `OR1200_ICSIZE-1 // 14
`define OR1200_ICTAGL `OR1200_ICINDXH+1 // 14
`define OR1200_ICTAG `OR1200_ICSIZE-`OR1200_ICLS // 10
`define OR1200_ICTAG_W 18
`endif
 
 
/////////////////////////////////////////////////
1257,8 → 1280,12
// Data cache (DC)
//
 
// 3 for 8 bytes, 4 for 16 bytes etc
`define OR1200_DCLS 4
// 4 for 16 bytes, 5 for 32 bytes
`ifdef OR1200_DC_1W_32KB
`define OR1200_DCLS 5
`else
`define OR1200_DCLS 4
`endif
 
// Define to enable default behavior of cache as write through
// Turning this off enabled write back statergy
1298,6 → 1325,22
`define OR1200_DCTAG `OR1200_DCSIZE-`OR1200_DCLS // 9
`define OR1200_DCTAG_W 20
`endif
`ifdef OR1200_DC_1W_16KB
`define OR1200_DCSIZE 14 // 16384
`define OR1200_DCINDX `OR1200_DCSIZE-2 // 12
`define OR1200_DCINDXH `OR1200_DCSIZE-1 // 13
`define OR1200_DCTAGL `OR1200_DCINDXH+1 // 14
`define OR1200_DCTAG `OR1200_DCSIZE-`OR1200_DCLS // 10
`define OR1200_DCTAG_W 19
`endif
`ifdef OR1200_DC_1W_32KB
`define OR1200_DCSIZE 15 // 32768
`define OR1200_DCINDX `OR1200_DCSIZE-2 // 13
`define OR1200_DCINDXH `OR1200_DCSIZE-1 // 14
`define OR1200_DCTAGL `OR1200_DCINDXH+1 // 15
`define OR1200_DCTAG `OR1200_DCSIZE-`OR1200_DCLS // 10
`define OR1200_DCTAG_W 18
`endif
 
 
/////////////////////////////////////////////////
1721,10 → 1764,18
 
///////////////////////////////////////////////////////////////////////////////
// Boot Address Selection //
// This only changes where the initial reset occurs. EPH setting is still //
// used to determine where vectors are located. //
// //
// Allows a definable boot address, potentially different to the usual reset //
// vector to allow for power-on code to be run, if desired. //
// //
// OR1200_BOOT_ADR should be the 32-bit address of the boot location //
// OR1200_BOOT_PCREG_DEFAULT should be ((OR1200_BOOT_ADR-4)>>2) //
// //
// For default reset behavior uncomment the settings under the "Boot 0x100" //
// comment below. //
// //
///////////////////////////////////////////////////////////////////////////////
// Boot from 0xf0000100
// Boot from 0xf0000100
//`define OR1200_BOOT_PCREG_DEFAULT 30'h3c00003f
//`define OR1200_BOOT_ADR 32'hf0000100
// Boot from 0x100
/or1200_alu.v
195,9 → 195,6
`OR1200_ALUOP_OR : begin
result = a | b;
end
`OR1200_ALUOP_IMM : begin
result = b;
end
`OR1200_ALUOP_MOVHI : begin
if (macrc_op) begin
result = mult_mac_result;
211,7 → 208,8
`OR1200_ALUOP_DIV,
`OR1200_ALUOP_DIVU,
`endif
`OR1200_ALUOP_MUL : begin
`OR1200_ALUOP_MUL,
`OR1200_ALUOP_MULU : begin
result = mult_mac_result;
end
`endif
/or1200_tt.v
41,49 → 41,6
//// ////
//////////////////////////////////////////////////////////////////////
//
// CVS Revision History
//
// $Log: or1200_tt.v,v $
// Revision 2.0 2010/06/30 11:00:00 ORSoC
// No update
//
// Revision 1.5 2004/06/08 18:17:36 lampret
// Non-functional changes. Coding style fixes.
//
// Revision 1.4 2002/03/29 15:16:56 lampret
// Some of the warnings fixed.
//
// Revision 1.3 2002/02/12 01:33:47 lampret
// No longer using async rst as sync reset for the counter.
//
// Revision 1.2 2002/01/28 01:16:00 lampret
// Changed 'void' nop-ops instead of insn[0] to use insn[16]. Debug unit stalls the tick timer. Prepared new flag generation for add and and insns. Blocked DC/IC while they are turned off. Fixed I/D MMU SPRs layout except WAYs. TODO: smart IC invalidate, l.j 2 and TLB ways.
//
// Revision 1.1 2002/01/03 08:16:15 lampret
// New prefixes for RTL files, prefixed module names. Updated cache controllers and MMUs.
//
// Revision 1.10 2001/11/13 10:00:49 lampret
// Fixed tick timer interrupt reporting by using TTCR[IP] bit.
//
// Revision 1.9 2001/11/10 03:43:57 lampret
// Fixed exceptions.
//
// Revision 1.8 2001/10/21 17:57:16 lampret
// Removed params from generic_XX.v. Added translate_off/on in sprs.v and id.v. Removed spr_addr from dc.v and ic.v. Fixed CR+LF.
//
// Revision 1.7 2001/10/14 13:12:10 lampret
// MP3 version.
//
// Revision 1.1.1.1 2001/10/06 10:18:35 igorm
// no message
//
// Revision 1.2 2001/08/09 13:39:33 lampret
// Major clean-up.
//
// Revision 1.1 2001/07/20 00:46:23 lampret
// Development version of RTL. Libraries are missing.
//
//
 
// synopsys translate_off
`include "timescale.v"
/or1200_sprs.v
52,311 → 52,369
`include "or1200_defines.v"
 
module or1200_sprs(
// Clk & Rst
clk, rst,
// Clk & Rst
clk, rst,
 
// Internal CPU interface
flagforw, flag_we, flag, cyforw, cy_we, carry,
addrbase, addrofs, dat_i, branch_op, ex_spr_read, ex_spr_write,
epcr, eear, esr, except_started,
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,
boot_adr_sel_i,
// Floating point SPR input
fpcsr, fpcsr_we, spr_dat_fpu,
// Internal CPU interface
flagforw, flag_we, flag, cyforw, cy_we, carry,
addrbase, addrofs, dat_i, branch_op, ex_spr_read,
ex_spr_write,
epcr, eear, esr, except_started,
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,
boot_adr_sel_i,
 
// From/to other RISC units
spr_dat_pic, spr_dat_tt, spr_dat_pm,
spr_dat_dmmu, spr_dat_immu, spr_dat_du,
spr_addr, spr_dat_o, spr_cs, spr_we,
// Floating point SPR input
fpcsr, fpcsr_we, spr_dat_fpu,
 
du_addr, du_dat_du, du_read,
du_write, du_dat_cpu
// From/to other RISC units
spr_dat_pic, spr_dat_tt, spr_dat_pm,
spr_dat_dmmu, spr_dat_immu, spr_dat_du,
spr_addr, spr_dat_o, spr_cs, spr_we,
 
);
du_addr, du_dat_du, du_read,
du_write, du_dat_cpu
 
parameter width = `OR1200_OPERAND_WIDTH;
);
 
//
// I/O Ports
//
parameter width = `OR1200_OPERAND_WIDTH;
 
//
// Internal CPU interface
//
input clk; // Clock
input rst; // Reset
input flagforw; // From ALU
input flag_we; // From ALU
output flag; // SR[F]
input cyforw; // From ALU
input cy_we; // From ALU
output carry; // SR[CY]
input [width-1:0] addrbase; // SPR base address
input [15:0] addrofs; // SPR offset
input [width-1:0] dat_i; // SPR write data
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 [width-1:0] epcr /* verilator public */; // EPCR0
input [width-1:0] eear /* verilator public */; // EEAR0
input [`OR1200_SR_WIDTH-1:0] esr /* verilator public */; // ESR0
input except_started; // Exception was started
output [width-1:0] to_wbmux; // For l.mfspr
output epcr_we; // EPCR0 write enable
output eear_we; // EEAR0 write enable
output esr_we; // ESR0 write enable
output pc_we; // PC write enable
output sr_we; // Write enable SR
output [`OR1200_SR_WIDTH-1:0] to_sr; // Data to SR
output [`OR1200_SR_WIDTH-1:0] sr /* verilator public */; // SR
input [31:0] spr_dat_cfgr; // Data from CFGR
input [31:0] spr_dat_rf; // Data from RF
input [31:0] spr_dat_npc; // Data from NPC
input [31:0] spr_dat_ppc; // Data from PPC
input [31:0] spr_dat_mac; // Data from MAC
input boot_adr_sel_i;
//
// I/O Ports
//
 
input [`OR1200_FPCSR_WIDTH-1:0] fpcsr; // FPCSR
output fpcsr_we; // Write enable FPCSR
input [31:0] spr_dat_fpu; // Data from FPU
//
// Internal CPU interface
//
input clk; // Clock
input rst; // Reset
input flagforw; // From ALU
input flag_we; // From ALU
output flag; // SR[F]
input cyforw; // From ALU
input cy_we; // From ALU
output carry; // SR[CY]
input [width-1:0] addrbase; // SPR base address
input [15:0] addrofs; // SPR offset
input [width-1:0] dat_i; // SPR write data
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 [width-1:0] epcr /* verilator public */;// EPCR0
input [width-1:0] eear /* verilator public */;// EEAR0
input [`OR1200_SR_WIDTH-1:0] esr /* verilator public */; // ESR0
input except_started; // Exception was started
output [width-1:0] to_wbmux; // For l.mfspr
output epcr_we; // EPCR0 write enable
output eear_we; // EEAR0 write enable
output esr_we; // ESR0 write enable
output pc_we; // PC write enable
output sr_we; // Write enable SR
output [`OR1200_SR_WIDTH-1:0] to_sr; // Data to SR
output [`OR1200_SR_WIDTH-1:0] sr /* verilator public */;// SR
input [31:0] spr_dat_cfgr; // Data from CFGR
input [31:0] spr_dat_rf; // Data from RF
input [31:0] spr_dat_npc; // Data from NPC
input [31:0] spr_dat_ppc; // Data from PPC
input [31:0] spr_dat_mac; // Data from MAC
input boot_adr_sel_i;
 
input [`OR1200_FPCSR_WIDTH-1:0] fpcsr; // FPCSR
output fpcsr_we; // Write enable FPCSR
input [31:0] spr_dat_fpu; // Data from FPU
//
// To/from other RISC units
//
input [31:0] spr_dat_pic; // Data from PIC
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_dat_o; // Data to unit
output [31:0] spr_cs; // Unit select
output spr_we; // SPR write enable
//
// To/from other RISC units
//
input [31:0] spr_dat_pic; // Data from PIC
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_dat_o; // Data to unit
output [31:0] spr_cs; // Unit select
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
output [width-1:0] du_dat_cpu; // Data from SPRS to DU
//
// 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
output [width-1:0] du_dat_cpu; // Data from SPRS to DU
 
//
// 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 [width-1:0] to_wbmux; // For l.mfspr
wire cfgr_sel; // Select for cfg regs
wire rf_sel; // Select for RF
wire npc_sel; // Select for NPC
wire ppc_sel; // Select for PPC
wire sr_sel; // Select for SR
wire epcr_sel; // Select for EPCR0
wire eear_sel; // Select for EEAR0
wire esr_sel; // Select for ESR0
wire fpcsr_sel; // Select for FPCSR
wire [31:0] sys_data; // Read data from system SPRs
wire du_access; // Debug unit access
reg [31:0] unqualified_cs; // Unqualified chip selects
wire ex_spr_write; // jb
//
// 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 [width-1:0] to_wbmux; // For l.mfspr
wire cfgr_sel; // Select for cfg regs
wire rf_sel; // Select for RF
wire npc_sel; // Select for NPC
wire ppc_sel; // Select for PPC
wire sr_sel; // Select for SR
wire epcr_sel; // Select for EPCR0
wire eear_sel; // Select for EEAR0
wire esr_sel; // Select for ESR0
wire fpcsr_sel; // Select for FPCSR
wire [31:0] sys_data;// Read data from system SPRs
wire du_access;// Debug unit access
reg [31:0] unqualified_cs; // Unqualified selects
wire ex_spr_write; // jb
//
// Decide if it is debug unit access
//
assign du_access = du_read | du_write;
//
// Decide if it is debug unit access
//
assign du_access = du_read | du_write;
 
//
// Generate SPR address from base address and offset
// OR from debug unit address
//
assign spr_addr = du_access ? du_addr : (addrbase | {16'h0000, addrofs});
//
// Generate SPR address from base address and offset
// OR from debug unit address
//
assign spr_addr = du_access ? du_addr : (addrbase | {16'h0000, addrofs});
 
//
// SPR is written by debug unit or by l.mtspr
//
assign spr_dat_o = du_write ? du_dat_du : dat_i;
//
// SPR is written by debug unit or by l.mtspr
//
assign spr_dat_o = du_write ? du_dat_du : dat_i;
 
//
// debug unit data input:
// - read of SPRS by debug unit
// - write into debug unit SPRs by debug unit itself
// - write into debug unit SPRs by l.mtspr
//
assign du_dat_cpu = du_read ? to_wbmux : du_write ? du_dat_du : dat_i;
//
// debug unit data input:
// - read of SPRS by debug unit
// - write into debug unit SPRs by debug unit itself
// - write into debug unit SPRs by l.mtspr
//
assign du_dat_cpu = du_read ? to_wbmux : du_write ? du_dat_du : dat_i;
 
//
// Write into SPRs when DU or l.mtspr
//
assign spr_we = du_write | ( ex_spr_write & !du_access );
//
// Write into SPRs when DU or l.mtspr
//
assign spr_we = du_write | ( ex_spr_write & !du_access );
 
 
//
// Qualify chip selects
//
assign spr_cs = unqualified_cs & {32{du_read | du_write | ex_spr_read | (ex_spr_write & sr[`OR1200_SR_SM])}};
//
// Qualify chip selects
//
assign spr_cs = unqualified_cs & {32{du_read | du_write | ex_spr_read |
(ex_spr_write & sr[`OR1200_SR_SM])}};
 
//
// Decoding of groups
//
always @(spr_addr)
case (spr_addr[`OR1200_SPR_GROUP_BITS]) // synopsys parallel_case
`OR1200_SPR_GROUP_WIDTH'd00: unqualified_cs = 32'b00000000_00000000_00000000_00000001;
`OR1200_SPR_GROUP_WIDTH'd01: unqualified_cs = 32'b00000000_00000000_00000000_00000010;
`OR1200_SPR_GROUP_WIDTH'd02: unqualified_cs = 32'b00000000_00000000_00000000_00000100;
`OR1200_SPR_GROUP_WIDTH'd03: unqualified_cs = 32'b00000000_00000000_00000000_00001000;
`OR1200_SPR_GROUP_WIDTH'd04: unqualified_cs = 32'b00000000_00000000_00000000_00010000;
`OR1200_SPR_GROUP_WIDTH'd05: unqualified_cs = 32'b00000000_00000000_00000000_00100000;
`OR1200_SPR_GROUP_WIDTH'd06: unqualified_cs = 32'b00000000_00000000_00000000_01000000;
`OR1200_SPR_GROUP_WIDTH'd07: unqualified_cs = 32'b00000000_00000000_00000000_10000000;
`OR1200_SPR_GROUP_WIDTH'd08: unqualified_cs = 32'b00000000_00000000_00000001_00000000;
`OR1200_SPR_GROUP_WIDTH'd09: unqualified_cs = 32'b00000000_00000000_00000010_00000000;
`OR1200_SPR_GROUP_WIDTH'd10: unqualified_cs = 32'b00000000_00000000_00000100_00000000;
`OR1200_SPR_GROUP_WIDTH'd11: unqualified_cs = 32'b00000000_00000000_00001000_00000000;
`OR1200_SPR_GROUP_WIDTH'd12: unqualified_cs = 32'b00000000_00000000_00010000_00000000;
`OR1200_SPR_GROUP_WIDTH'd13: unqualified_cs = 32'b00000000_00000000_00100000_00000000;
`OR1200_SPR_GROUP_WIDTH'd14: unqualified_cs = 32'b00000000_00000000_01000000_00000000;
`OR1200_SPR_GROUP_WIDTH'd15: unqualified_cs = 32'b00000000_00000000_10000000_00000000;
`OR1200_SPR_GROUP_WIDTH'd16: unqualified_cs = 32'b00000000_00000001_00000000_00000000;
`OR1200_SPR_GROUP_WIDTH'd17: unqualified_cs = 32'b00000000_00000010_00000000_00000000;
`OR1200_SPR_GROUP_WIDTH'd18: unqualified_cs = 32'b00000000_00000100_00000000_00000000;
`OR1200_SPR_GROUP_WIDTH'd19: unqualified_cs = 32'b00000000_00001000_00000000_00000000;
`OR1200_SPR_GROUP_WIDTH'd20: unqualified_cs = 32'b00000000_00010000_00000000_00000000;
`OR1200_SPR_GROUP_WIDTH'd21: unqualified_cs = 32'b00000000_00100000_00000000_00000000;
`OR1200_SPR_GROUP_WIDTH'd22: unqualified_cs = 32'b00000000_01000000_00000000_00000000;
`OR1200_SPR_GROUP_WIDTH'd23: unqualified_cs = 32'b00000000_10000000_00000000_00000000;
`OR1200_SPR_GROUP_WIDTH'd24: unqualified_cs = 32'b00000001_00000000_00000000_00000000;
`OR1200_SPR_GROUP_WIDTH'd25: unqualified_cs = 32'b00000010_00000000_00000000_00000000;
`OR1200_SPR_GROUP_WIDTH'd26: unqualified_cs = 32'b00000100_00000000_00000000_00000000;
`OR1200_SPR_GROUP_WIDTH'd27: unqualified_cs = 32'b00001000_00000000_00000000_00000000;
`OR1200_SPR_GROUP_WIDTH'd28: unqualified_cs = 32'b00010000_00000000_00000000_00000000;
`OR1200_SPR_GROUP_WIDTH'd29: unqualified_cs = 32'b00100000_00000000_00000000_00000000;
`OR1200_SPR_GROUP_WIDTH'd30: unqualified_cs = 32'b01000000_00000000_00000000_00000000;
`OR1200_SPR_GROUP_WIDTH'd31: unqualified_cs = 32'b10000000_00000000_00000000_00000000;
endcase
//
// Decoding of groups
//
always @(spr_addr)
case (spr_addr[`OR1200_SPR_GROUP_BITS]) // synopsys parallel_case
`OR1200_SPR_GROUP_WIDTH'd00: unqualified_cs
= 32'b00000000_00000000_00000000_00000001;
`OR1200_SPR_GROUP_WIDTH'd01: unqualified_cs
= 32'b00000000_00000000_00000000_00000010;
`OR1200_SPR_GROUP_WIDTH'd02: unqualified_cs
= 32'b00000000_00000000_00000000_00000100;
`OR1200_SPR_GROUP_WIDTH'd03: unqualified_cs
= 32'b00000000_00000000_00000000_00001000;
`OR1200_SPR_GROUP_WIDTH'd04: unqualified_cs
= 32'b00000000_00000000_00000000_00010000;
`OR1200_SPR_GROUP_WIDTH'd05: unqualified_cs
= 32'b00000000_00000000_00000000_00100000;
`OR1200_SPR_GROUP_WIDTH'd06: unqualified_cs
= 32'b00000000_00000000_00000000_01000000;
`OR1200_SPR_GROUP_WIDTH'd07: unqualified_cs
= 32'b00000000_00000000_00000000_10000000;
`OR1200_SPR_GROUP_WIDTH'd08: unqualified_cs
= 32'b00000000_00000000_00000001_00000000;
`OR1200_SPR_GROUP_WIDTH'd09: unqualified_cs
= 32'b00000000_00000000_00000010_00000000;
`OR1200_SPR_GROUP_WIDTH'd10: unqualified_cs
= 32'b00000000_00000000_00000100_00000000;
`OR1200_SPR_GROUP_WIDTH'd11: unqualified_cs
= 32'b00000000_00000000_00001000_00000000;
`OR1200_SPR_GROUP_WIDTH'd12: unqualified_cs
= 32'b00000000_00000000_00010000_00000000;
`OR1200_SPR_GROUP_WIDTH'd13: unqualified_cs
= 32'b00000000_00000000_00100000_00000000;
`OR1200_SPR_GROUP_WIDTH'd14: unqualified_cs
= 32'b00000000_00000000_01000000_00000000;
`OR1200_SPR_GROUP_WIDTH'd15: unqualified_cs
= 32'b00000000_00000000_10000000_00000000;
`OR1200_SPR_GROUP_WIDTH'd16: unqualified_cs
= 32'b00000000_00000001_00000000_00000000;
`OR1200_SPR_GROUP_WIDTH'd17: unqualified_cs
= 32'b00000000_00000010_00000000_00000000;
`OR1200_SPR_GROUP_WIDTH'd18: unqualified_cs
= 32'b00000000_00000100_00000000_00000000;
`OR1200_SPR_GROUP_WIDTH'd19: unqualified_cs
= 32'b00000000_00001000_00000000_00000000;
`OR1200_SPR_GROUP_WIDTH'd20: unqualified_cs
= 32'b00000000_00010000_00000000_00000000;
`OR1200_SPR_GROUP_WIDTH'd21: unqualified_cs
= 32'b00000000_00100000_00000000_00000000;
`OR1200_SPR_GROUP_WIDTH'd22: unqualified_cs
= 32'b00000000_01000000_00000000_00000000;
`OR1200_SPR_GROUP_WIDTH'd23: unqualified_cs
= 32'b00000000_10000000_00000000_00000000;
`OR1200_SPR_GROUP_WIDTH'd24: unqualified_cs
= 32'b00000001_00000000_00000000_00000000;
`OR1200_SPR_GROUP_WIDTH'd25: unqualified_cs
= 32'b00000010_00000000_00000000_00000000;
`OR1200_SPR_GROUP_WIDTH'd26: unqualified_cs
= 32'b00000100_00000000_00000000_00000000;
`OR1200_SPR_GROUP_WIDTH'd27: unqualified_cs
= 32'b00001000_00000000_00000000_00000000;
`OR1200_SPR_GROUP_WIDTH'd28: unqualified_cs
= 32'b00010000_00000000_00000000_00000000;
`OR1200_SPR_GROUP_WIDTH'd29: unqualified_cs
= 32'b00100000_00000000_00000000_00000000;
`OR1200_SPR_GROUP_WIDTH'd30: unqualified_cs
= 32'b01000000_00000000_00000000_00000000;
`OR1200_SPR_GROUP_WIDTH'd31: unqualified_cs
= 32'b10000000_00000000_00000000_00000000;
endcase
 
//
// SPRs System Group
//
//
// SPRs System Group
//
 
//
// What to write into SR
//
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] :
(spr_we && sr_sel) ? {1'b1, spr_dat_o[`OR1200_SR_FO-1:`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] =
(except_started) ? sr[`OR1200_SR_CY] :
(branch_op == `OR1200_BRANCHOP_RFE) ? esr[`OR1200_SR_CY] :
cy_we ? cyforw :
(spr_we && sr_sel) ? spr_dat_o[`OR1200_SR_CY] :
sr[`OR1200_SR_CY];
assign to_sr[`OR1200_SR_F] =
(except_started) ? sr[`OR1200_SR_F] :
(branch_op == `OR1200_BRANCHOP_RFE) ? esr[`OR1200_SR_F] :
flag_we ? flagforw :
(spr_we && sr_sel) ? spr_dat_o[`OR1200_SR_F] :
sr[`OR1200_SR_F];
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] :
(spr_we && sr_sel) ? spr_dat_o[`OR1200_SR_CE:`OR1200_SR_SM]:
sr[`OR1200_SR_CE:`OR1200_SR_SM];
//
// What to write into SR
//
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] : (spr_we && sr_sel) ?
{1'b1, spr_dat_o[`OR1200_SR_FO-1:`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]
= (except_started) ? sr[`OR1200_SR_CY] :
(branch_op == `OR1200_BRANCHOP_RFE) ? esr[`OR1200_SR_CY] :
cy_we ? cyforw :
(spr_we && sr_sel) ? spr_dat_o[`OR1200_SR_CY] :
sr[`OR1200_SR_CY];
assign to_sr[`OR1200_SR_F]
= (except_started) ? sr[`OR1200_SR_F] :
(branch_op == `OR1200_BRANCHOP_RFE) ? esr[`OR1200_SR_F] :
flag_we ? flagforw :
(spr_we && sr_sel) ? spr_dat_o[`OR1200_SR_F] :
sr[`OR1200_SR_F];
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] : (spr_we && sr_sel) ?
spr_dat_o[`OR1200_SR_CE:`OR1200_SR_SM] :
sr[`OR1200_SR_CE:`OR1200_SR_SM];
 
//
// Selects for system SPRs
//
assign cfgr_sel = (spr_cs[`OR1200_SPR_GROUP_SYS] && (spr_addr[10:4] == `OR1200_SPR_CFGR));
assign rf_sel = (spr_cs[`OR1200_SPR_GROUP_SYS] && (spr_addr[10:5] == `OR1200_SPR_RF));
assign npc_sel = (spr_cs[`OR1200_SPR_GROUP_SYS] && (spr_addr[10:0] == `OR1200_SPR_NPC));
assign ppc_sel = (spr_cs[`OR1200_SPR_GROUP_SYS] && (spr_addr[10:0] == `OR1200_SPR_PPC));
assign sr_sel = (spr_cs[`OR1200_SPR_GROUP_SYS] && (spr_addr[10:0] == `OR1200_SPR_SR));
assign epcr_sel = (spr_cs[`OR1200_SPR_GROUP_SYS] && (spr_addr[10:0] == `OR1200_SPR_EPCR));
assign eear_sel = (spr_cs[`OR1200_SPR_GROUP_SYS] && (spr_addr[10:0] == `OR1200_SPR_EEAR));
assign esr_sel = (spr_cs[`OR1200_SPR_GROUP_SYS] && (spr_addr[10:0] == `OR1200_SPR_ESR));
assign fpcsr_sel = (spr_cs[`OR1200_SPR_GROUP_SYS] && (spr_addr[10:0] == `OR1200_SPR_FPCSR));
//
// Selects for system SPRs
//
assign cfgr_sel = (spr_cs[`OR1200_SPR_GROUP_SYS] &&
(spr_addr[10:4] == `OR1200_SPR_CFGR));
assign rf_sel = (spr_cs[`OR1200_SPR_GROUP_SYS] &&
(spr_addr[10:5] == `OR1200_SPR_RF));
assign npc_sel = (spr_cs[`OR1200_SPR_GROUP_SYS] &&
(spr_addr[10:0] == `OR1200_SPR_NPC));
assign ppc_sel = (spr_cs[`OR1200_SPR_GROUP_SYS] &&
(spr_addr[10:0] == `OR1200_SPR_PPC));
assign sr_sel = (spr_cs[`OR1200_SPR_GROUP_SYS] &&
(spr_addr[10:0] == `OR1200_SPR_SR));
assign epcr_sel = (spr_cs[`OR1200_SPR_GROUP_SYS] &&
(spr_addr[10:0] == `OR1200_SPR_EPCR));
assign eear_sel = (spr_cs[`OR1200_SPR_GROUP_SYS] &&
(spr_addr[10:0] == `OR1200_SPR_EEAR));
assign esr_sel = (spr_cs[`OR1200_SPR_GROUP_SYS] &&
(spr_addr[10:0] == `OR1200_SPR_ESR));
assign fpcsr_sel = (spr_cs[`OR1200_SPR_GROUP_SYS] &&
(spr_addr[10:0] == `OR1200_SPR_FPCSR));
 
 
//
// Write enables for system SPRs
//
assign sr_we = (spr_we && sr_sel) | (branch_op == `OR1200_BRANCHOP_RFE) | flag_we | cy_we;
assign pc_we = (du_write && (npc_sel | ppc_sel));
assign epcr_we = (spr_we && epcr_sel);
assign eear_we = (spr_we && eear_sel);
assign esr_we = (spr_we && esr_sel);
assign fpcsr_we = (spr_we && fpcsr_sel);
//
// Write enables for system SPRs
//
assign sr_we = (spr_we && sr_sel) | (branch_op == `OR1200_BRANCHOP_RFE) |
flag_we | cy_we;
assign pc_we = (du_write && (npc_sel | ppc_sel));
assign epcr_we = (spr_we && epcr_sel);
assign eear_we = (spr_we && eear_sel);
assign esr_we = (spr_we && esr_sel);
assign fpcsr_we = (spr_we && fpcsr_sel);
//
// Output from system SPRs
//
assign sys_data = (spr_dat_cfgr & {32{cfgr_sel}}) |
(spr_dat_rf & {32{rf_sel}}) |
(spr_dat_npc & {32{npc_sel}}) |
(spr_dat_ppc & {32{ppc_sel}}) |
({{32-`OR1200_SR_WIDTH{1'b0}},sr} & {32{sr_sel}}) |
(epcr & {32{epcr_sel}}) |
(eear & {32{eear_sel}}) |
({{32-`OR1200_FPCSR_WIDTH{1'b0}},fpcsr} & {32{fpcsr_sel}}) |
({{32-`OR1200_SR_WIDTH{1'b0}},esr} & {32{esr_sel}});
//
// Output from system SPRs
//
assign sys_data = (spr_dat_cfgr & {32{cfgr_sel}}) |
(spr_dat_rf & {32{rf_sel}}) |
(spr_dat_npc & {32{npc_sel}}) |
(spr_dat_ppc & {32{ppc_sel}}) |
({{32-`OR1200_SR_WIDTH{1'b0}},sr} & {32{sr_sel}}) |
(epcr & {32{epcr_sel}}) |
(eear & {32{eear_sel}}) |
({{32-`OR1200_FPCSR_WIDTH{1'b0}},fpcsr} &
{32{fpcsr_sel}}) |
({{32-`OR1200_SR_WIDTH{1'b0}},esr} & {32{esr_sel}});
 
//
// Flag alias
//
assign flag = sr[`OR1200_SR_F];
//
// Flag alias
//
assign flag = sr[`OR1200_SR_F];
 
//
// Carry alias
//
assign carry = sr[`OR1200_SR_CY];
//
// Carry alias
//
assign carry = sr[`OR1200_SR_CY];
 
//
// Supervision register
//
always @(posedge clk or `OR1200_RST_EVENT rst)
if (rst == `OR1200_RST_VALUE)
sr_reg <= {2'h1, `OR1200_SR_EPH_DEF, {`OR1200_SR_WIDTH-4{1'b0}}, 1'b1};
else if (except_started)
sr_reg <= to_sr[`OR1200_SR_WIDTH-1:0];
else if (sr_we)
sr_reg <= to_sr[`OR1200_SR_WIDTH-1:0];
//
// Supervision register
//
always @(posedge clk or `OR1200_RST_EVENT rst)
if (rst == `OR1200_RST_VALUE)
sr_reg <= {2'b01, // Fixed one.
`OR1200_SR_EPH_DEF, {`OR1200_SR_WIDTH-4{1'b0}}, 1'b1};
else if (except_started)
sr_reg <= to_sr[`OR1200_SR_WIDTH-1:0];
else if (sr_we)
sr_reg <= to_sr[`OR1200_SR_WIDTH-1:0];
 
// EPH part of Supervision register
always @(posedge clk or `OR1200_RST_EVENT rst)
// default value
if (rst == `OR1200_RST_VALUE) begin
sr_reg_bit_eph <= `OR1200_SR_EPH_DEF;
sr_reg_bit_eph_select <= 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 <= boot_adr_sel_i; // dynamic value can only be assigned to FF out of reset!
sr_reg_bit_eph_select <= 1'b0; // select FF value
end
else if (sr_we) begin
sr_reg_bit_eph <= to_sr[`OR1200_SR_EPH];
end
// EPH part of Supervision register
always @(posedge clk or `OR1200_RST_EVENT rst)
// default value
if (rst == `OR1200_RST_VALUE) begin
sr_reg_bit_eph <= `OR1200_SR_EPH_DEF;
// select async. value due to reset state
sr_reg_bit_eph_select <= 1'b1;
end
// selected value (different from default) is written into FF after reset
// state
else if (sr_reg_bit_eph_select) begin
// dynamic value can only be assigned to FF out of reset!
sr_reg_bit_eph <= boot_adr_sel_i;
sr_reg_bit_eph_select <= 1'b0; // select FF value
end
else if (sr_we) begin
sr_reg_bit_eph <= 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;
// 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]};
// 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]};
 
`ifdef verilator
// Function to access various sprs (for Verilator). Have to hide this from
384,34 → 442,33
endfunction // get_esr
 
`endif
 
//
// MTSPR/MFSPR interface
//
always @(spr_addr or sys_data or spr_dat_mac or spr_dat_pic or spr_dat_pm or
spr_dat_fpu or
spr_dat_dmmu or spr_dat_immu or spr_dat_du or spr_dat_tt) begin
casez (spr_addr[`OR1200_SPR_GROUP_BITS]) // synopsys parallel_case
`OR1200_SPR_GROUP_SYS:
to_wbmux = sys_data;
`OR1200_SPR_GROUP_TT:
to_wbmux = spr_dat_tt;
`OR1200_SPR_GROUP_PIC:
to_wbmux = spr_dat_pic;
`OR1200_SPR_GROUP_PM:
to_wbmux = spr_dat_pm;
`OR1200_SPR_GROUP_DMMU:
to_wbmux = spr_dat_dmmu;
`OR1200_SPR_GROUP_IMMU:
to_wbmux = spr_dat_immu;
`OR1200_SPR_GROUP_MAC:
to_wbmux = spr_dat_mac;
`OR1200_SPR_GROUP_FPU:
to_wbmux = spr_dat_fpu;
default: //`OR1200_SPR_GROUP_DU:
to_wbmux = spr_dat_du;
endcase
end
//
// MTSPR/MFSPR interface
//
always @(spr_addr or sys_data or spr_dat_mac or spr_dat_pic or spr_dat_pm or
spr_dat_fpu or
spr_dat_dmmu or spr_dat_immu or spr_dat_du or spr_dat_tt) begin
casez (spr_addr[`OR1200_SPR_GROUP_BITS]) // synopsys parallel_case
`OR1200_SPR_GROUP_SYS:
to_wbmux = sys_data;
`OR1200_SPR_GROUP_TT:
to_wbmux = spr_dat_tt;
`OR1200_SPR_GROUP_PIC:
to_wbmux = spr_dat_pic;
`OR1200_SPR_GROUP_PM:
to_wbmux = spr_dat_pm;
`OR1200_SPR_GROUP_DMMU:
to_wbmux = spr_dat_dmmu;
`OR1200_SPR_GROUP_IMMU:
to_wbmux = spr_dat_immu;
`OR1200_SPR_GROUP_MAC:
to_wbmux = spr_dat_mac;
`OR1200_SPR_GROUP_FPU:
to_wbmux = spr_dat_fpu;
default: //`OR1200_SPR_GROUP_DU:
to_wbmux = spr_dat_du;
endcase
end
 
endmodule
/or1200_cpu.v
312,7 → 312,7
wire [`OR1200_MACOP_WIDTH-1:0] id_mac_op;
wire [`OR1200_MACOP_WIDTH-1:0] mac_op;
wire [31:0] mult_mac_result;
wire mac_stall;
wire mult_mac_stall;
wire [13:0] except_trig;
wire [13:0] except_stop;
wire genpc_refetch;
644,7 → 644,7
.mac_op(mac_op),
.alu_op(alu_op),
.result(mult_mac_result),
.mac_stall_r(mac_stall),
.mult_mac_stall(mult_mac_stall),
.spr_cs(spr_cs[`OR1200_SPR_GROUP_MAC]),
.spr_write(spr_we),
.spr_addr(spr_addr),
785,7 → 785,7
.force_dslot_fetch(force_dslot_fetch),
.abort_ex(abort_ex),
.du_stall(du_stall),
.mac_stall(mac_stall),
.mac_stall(mult_mac_stall),
.saving_if_insn(saving_if_insn),
.genpc_freeze(genpc_freeze),
.if_freeze(if_freeze),
/or1200_immu_top.v
3,7 → 3,7
//// OR1200's Instruction MMU top level ////
//// ////
//// This file is part of the OpenRISC 1200 project ////
//// http://www.opencores.org/cores/or1k/ ////
//// http://www.opencores.org/project,or1k ////
//// ////
//// Description ////
//// Instantiation of all IMMU blocks. ////
40,81 → 40,6
//// from http://www.opencores.org/lgpl.shtml ////
//// ////
//////////////////////////////////////////////////////////////////////
//
// CVS Revision History
//
// $Log: or1200_immu_top.v,v $
// Revision 2.0 2010/06/30 11:00:00 ORSoC
// Major update:
// Structure reordered and bugs fixed.
//
// Revision 1.15 2004/06/08 18:17:36 lampret
// Non-functional changes. Coding style fixes.
//
// Revision 1.14 2004/04/05 08:29:57 lampret
// Merged branch_qmem into main tree.
//
// Revision 1.12.4.2 2003/12/09 11:46:48 simons
// Mbist nameing changed, Artisan ram instance signal names fixed, some synthesis waning fixed.
//
// Revision 1.12.4.1 2003/07/08 15:36:37 lampret
// Added embedded memory QMEM.
//
// Revision 1.12 2003/06/06 02:54:47 lampret
// When OR1200_NO_IMMU and OR1200_NO_IC are not both defined or undefined at the same time, results in a IC bug. Fixed.
//
// Revision 1.11 2002/10/17 20:04:40 lampret
// Added BIST scan. Special VS RAMs need to be used to implement BIST.
//
// Revision 1.10 2002/09/16 03:08:56 lampret
// Disabled cache inhibit atttribute.
//
// Revision 1.9 2002/08/18 19:54:17 lampret
// Added store buffer.
//
// Revision 1.8 2002/08/14 06:23:50 lampret
// Disabled ITLB translation when 1) doing access to ITLB SPRs or 2) crossing page. This modification was tested only with parts of IMMU test - remaining test cases needs to be run.
//
// Revision 1.7 2002/08/12 05:31:30 lampret
// Delayed external access at page crossing.
//
// Revision 1.6 2002/03/29 15:16:56 lampret
// Some of the warnings fixed.
//
// Revision 1.5 2002/02/11 04:33:17 lampret
// Speed optimizations (removed duplicate _cyc_ and _stb_). Fixed D/IMMU cache-inhibit attr.
//
// Revision 1.4 2002/02/01 19:56:54 lampret
// Fixed combinational loops.
//
// Revision 1.3 2002/01/28 01:16:00 lampret
// Changed 'void' nop-ops instead of insn[0] to use insn[16]. Debug unit stalls the tick timer. Prepared new flag generation for add and and insns. Blocked DC/IC while they are turned off. Fixed I/D MMU SPRs layout except WAYs. TODO: smart IC invalidate, l.j 2 and TLB ways.
//
// Revision 1.2 2002/01/14 06:18:22 lampret
// Fixed mem2reg bug in FAST implementation. Updated debug unit to work with new genpc/if.
//
// Revision 1.1 2002/01/03 08:16:15 lampret
// New prefixes for RTL files, prefixed module names. Updated cache controllers and MMUs.
//
// Revision 1.6 2001/10/21 17:57:16 lampret
// Removed params from generic_XX.v. Added translate_off/on in sprs.v and id.v. Removed spr_addr from dc.v and ic.v. Fixed CR+LF.
//
// Revision 1.5 2001/10/14 13:12:09 lampret
// MP3 version.
//
// Revision 1.1.1.1 2001/10/06 10:18:36 igorm
// no message
//
// Revision 1.1 2001/08/17 08:03:35 lampret
// *** empty log message ***
//
// Revision 1.2 2001/07/22 03:31:53 lampret
// Fixed RAM's oen bug. Cache bypass under development.
//
// Revision 1.1 2001/07/20 00:46:03 lampret
// Development version of RTL. Libraries are missing.
//
//
 
// synopsys translate_off
`include "timescale.v"
254,27 → 179,35
always @(`OR1200_RST_EVENT rst or posedge clk)
// default value
if (rst == `OR1200_RST_VALUE) begin
// select async. value due to reset state
icpu_adr_default <= 32'h0000_0100;
icpu_adr_select <= 1'b1; // select async. value due to reset state
icpu_adr_select <= 1'b1;
end
// selected value (different from default) is written into FF after reset state
// selected value (different from default) is written
// into FF after reset state
else if (icpu_adr_select) begin
icpu_adr_default <= icpu_adr_boot; // dynamic value can only be assigned to FF out of reset!
icpu_adr_select <= 1'b0; // select FF value
// dynamic value can only be assigned to FF out of reset!
icpu_adr_default <= icpu_adr_boot;
// select FF value
icpu_adr_select <= 1'b0;
end
else begin
icpu_adr_default <= icpu_adr_i;
end
 
// select async. value for boot address after reset - PC jumps to the address selected after boot!
//assign icpu_adr_boot = {(boot_adr_sel_i ? `OR1200_EXCEPT_EPH1_P : `OR1200_EXCEPT_EPH0_P), 12'h100} ;
// select async. value for boot address after reset - PC jumps to the address
// selected after boot!
//assign icpu_adr_boot = {(boot_adr_sel_i ? `OR1200_EXCEPT_EPH1_P :
// `OR1200_EXCEPT_EPH0_P), 12'h100} ;
assign icpu_adr_boot = `OR1200_BOOT_ADR; // jb
 
always @(icpu_adr_boot or icpu_adr_default or icpu_adr_select)
if (icpu_adr_select)
icpu_adr_o = icpu_adr_boot ; // async. value is selected due to reset state
// async. value is selected due to reset state
icpu_adr_o = icpu_adr_boot ;
else
icpu_adr_o = icpu_adr_default ; // FF value is selected 2nd clock after reset state
// FF value is selected 2nd clock after reset state
icpu_adr_o = icpu_adr_default ;
`else
Unsupported !!!
`endif
/or1200_dc_fsm.v
125,7 → 125,7
//
reg [31:0] addr_r;
reg [2:0] state;
reg [2:0] cnt;
reg [`OR1200_DCLS-1:0] cnt;
reg hitmiss_eval;
reg store;
reg load;
150,7 → 150,7
wire tagram_dirty_bit_set;
wire writethrough;
wire cache_inhibit_with_eval;
wire [1:0] next_addr_word;
wire [(`OR1200_DCLS-1)-2:0] next_addr_word;
 
//
// Cache inhibit
268,8 → 268,9
// the line to memory. (1 selects DCRAM)
assign biu_do_sel = (state == `OR1200_DCFSM_LOOP2) & store;
 
// 2-bit wire for calculating next word of burst write
assign next_addr_word = addr_r[3:2] + 1;
// 3-bit wire for calculating next word of burst write, depending on
// line size of data cache.
assign next_addr_word = addr_r[`OR1200_DCLS-1:2] + 1;
// Address to cache RAM (tag address also derived from this)
assign dc_addr =
285,7 → 286,7
// to increment, but it's needed immediately for burst)
// otherwise, output our registered address.
(state==`OR1200_DCFSM_LOOP2 & biudata_valid & store ) ?
{addr_r[31:4], next_addr_word, 2'b00} : addr_r;
{addr_r[31:`OR1200_DCLS], next_addr_word, 2'b00} : addr_r;
`ifdef OR1200_DC_WRITETHROUGH
`ifdef OR1200_DC_NOSTACKWRITETHROUGH
342,9 → 343,9
// tell from value of cnt), and we're loading a line to read from it (not
// loading to write to it, in the case of a write without writethrough.)
assign load_miss_ack = ((state== `OR1200_DCFSM_LOOP2) & load &
(cnt==`OR1200_DCLS-1) & biudata_valid &
(cnt==((1 << `OR1200_DCLS) - 4)) & biudata_valid &
!(dcqmem_we_i & !writethrough));
 
assign load_inhibit_ack = (state == `OR1200_DCFSM_CLOADSTORE) &
load & cache_inhibit & biudata_valid;
362,11 → 363,11
always @(posedge clk or `OR1200_RST_EVENT rst) begin
if (rst == `OR1200_RST_VALUE) begin
state <= `OR1200_DCFSM_IDLE;
addr_r <= 32'b0;
addr_r <= 32'd0;
hitmiss_eval <= 1'b0;
store <= 1'b0;
load <= 1'b0;
cnt <= 3'd0;
cnt <= `OR1200_DCLS'd0;
cache_miss <= 1'b0;
cache_dirty_needs_writeback <= 1'b0;
cache_inhibit <= 1'b0;
430,7 → 431,7
end // else: !if(dirty)
state <= `OR1200_DCFSM_LOOP2;
// Set the counter for the burst accesses
cnt <= `OR1200_DCLS-1;
cnt <= ((1 << `OR1200_DCLS) - 4);
end
else if (// Strobe goes low
!dcqmem_cycstb_i |
453,11 → 454,11
state <= `OR1200_DCFSM_IDLE;
load <= 1'b0;
store <= 1'b0;
cnt <= 3'd0;
cnt <= `OR1200_DCLS'd0;
end
if (biudata_valid & (|cnt)) begin
cnt <= cnt - 3'd1;
addr_r[3:2] <= addr_r[3:2] + 1'b1;
cnt <= cnt - 4;
addr_r[`OR1200_DCLS-1:2] <= addr_r[`OR1200_DCLS-1:2] + 1;
end
else if (biudata_valid & !(|cnt)) begin
state <= `OR1200_DCFSM_LOOP3;
478,7 → 479,7
// Just did store of the dirty line so now load new one
load <= 1'b1;
// Set the counter for the burst accesses
cnt <= `OR1200_DCLS-1;
cnt <= ((1 << `OR1200_DCLS) - 4);
// Address of line to be loaded
addr_r <= lsu_addr;
cache_dirty_needs_writeback <= 1'b0;
526,7 → 527,7
`endif
state <= `OR1200_DCFSM_LOOP2;
// Set the counter for the burst accesses
cnt <= `OR1200_DCLS-1;
cnt <= ((1 << `OR1200_DCLS) - 4);
end
else if (cache_spr_block_flush & !dirty)
begin
/or1200_ic_tag.v
48,43 → 48,6
// Minor update:
// Coding style changed.
//
// Revision 1.7 2004/06/08 18:17:36 lampret
// Non-functional changes. Coding style fixes.
//
// Revision 1.6 2004/04/08 11:00:46 simont
// Add support for 512B instruction cache.
//
// Revision 1.5 2004/04/05 08:29:57 lampret
// Merged branch_qmem into main tree.
//
// Revision 1.3.4.1 2003/12/09 11:46:48 simons
// Mbist nameing changed, Artisan ram instance signal names fixed, some synthesis waning fixed.
//
// Revision 1.3 2002/10/24 22:19:04 mohor
// Signal scanb_eni renamed to scanb_en
//
// Revision 1.2 2002/10/17 20:04:40 lampret
// Added BIST scan. Special VS RAMs need to be used to implement BIST.
//
// Revision 1.1 2002/01/03 08:16:15 lampret
// New prefixes for RTL files, prefixed module names. Updated cache controllers and MMUs.
//
// Revision 1.8 2001/10/21 17:57:16 lampret
// Removed params from generic_XX.v. Added translate_off/on in sprs.v and id.v. Removed spr_addr from dc.v and ic.v. Fixed CR+LF.
//
// Revision 1.7 2001/10/14 13:12:09 lampret
// MP3 version.
//
// Revision 1.1.1.1 2001/10/06 10:18:36 igorm
// no message
//
// Revision 1.2 2001/08/09 13:39:33 lampret
// Major clean-up.
//
// Revision 1.1 2001/07/20 00:46:03 lampret
// Development version of RTL. Libraries are missing.
//
//
 
// synopsys translate_off
`include "timescale.v"
152,30 → 115,11
//
// Instantiation of TAG RAM block
//
`ifdef OR1200_IC_1W_512B
//or1200_spram_32x24 ic_tag0(
or1200_spram #
(
.aw(5),
.dw(24)
.aw(`OR1200_ICTAG),
.dw(`OR1200_ICTAG_W)
)
`endif
`ifdef OR1200_IC_1W_4KB
//or1200_spram_256x21 ic_tag0(
or1200_spram #
(
.aw(8),
.dw(21)
)
`endif
`ifdef OR1200_IC_1W_8KB
//or1200_spram_512x20 ic_tag0(
or1200_spram #
(
.aw(9),
.dw(20)
)
`endif
ic_tag0
(
`ifdef OR1200_BIST
/or1200_ic_ram.v
48,43 → 48,6
// Minor update:
// Coding style changed.
//
// Revision 1.6 2004/06/08 18:17:36 lampret
// Non-functional changes. Coding style fixes.
//
// Revision 1.5 2004/04/08 11:00:46 simont
// Add support for 512B instruction cache.
//
// Revision 1.4 2004/04/05 08:29:57 lampret
// Merged branch_qmem into main tree.
//
// Revision 1.2.4.1 2003/12/09 11:46:48 simons
// Mbist nameing changed, Artisan ram instance signal names fixed, some synthesis waning fixed.
//
// Revision 1.2 2002/10/17 20:04:40 lampret
// Added BIST scan. Special VS RAMs need to be used to implement BIST.
//
// Revision 1.1 2002/01/03 08:16:15 lampret
// New prefixes for RTL files, prefixed module names. Updated cache controllers and MMUs.
//
// Revision 1.9 2001/10/21 17:57:16 lampret
// Removed params from generic_XX.v. Added translate_off/on in sprs.v and id.v. Removed spr_addr from dc.v and ic.v. Fixed CR+LF.
//
// Revision 1.8 2001/10/14 13:12:09 lampret
// MP3 version.
//
// Revision 1.1.1.1 2001/10/06 10:18:36 igorm
// no message
//
// Revision 1.3 2001/08/09 13:39:33 lampret
// Major clean-up.
//
// Revision 1.2 2001/07/22 03:31:54 lampret
// Fixed RAM's oen bug. Cache bypass under development.
//
// Revision 1.1 2001/07/20 00:46:03 lampret
// Development version of RTL. Libraries are missing.
//
//
 
// synopsys translate_off
`include "timescale.v"
142,27 → 105,11
//
// Instantiation of IC RAM block
//
`ifdef OR1200_IC_1W_512B
or1200_spram #
(
.aw(9),
.aw(`OR1200_ICINDX),
.dw(32)
)
`endif
`ifdef OR1200_IC_1W_4KB
or1200_spram #
(
.aw(10),
.dw(32)
)
`endif
`ifdef OR1200_IC_1W_8KB
or1200_spram #
(
.aw(11),
.dw(32)
)
`endif
ic_ram0
(
`ifdef OR1200_BIST
/or1200_wb_biu.v
79,7 → 79,10
 
parameter dw = `OR1200_OPERAND_WIDTH;
parameter aw = `OR1200_OPERAND_WIDTH;
 
parameter bl = 4; /* Can currently be either 4 or 8 - the two optional line
sizes for the OR1200. */
//
// RISC clock, reset and clock control
//
153,7 → 156,7
assign retry_cnt = 1'b0;
`endif
`ifdef OR1200_WB_B3
reg [1:0] burst_len; // burst counter
reg [3:0] burst_len; // burst counter
`endif
 
reg biu_stb_reg; // WB strobe
197,14 → 200,14
//
always @(posedge wb_clk_i or `OR1200_RST_EVENT wb_rst_i) begin
if (wb_rst_i == `OR1200_RST_VALUE) begin
burst_len <= 2'h0;
burst_len <= 0;
end
else begin
// burst counter
if (wb_fsm_state_cur == wb_fsm_idle)
burst_len <= 2'h2;
burst_len <= bl[3:0] - 2;
else if (wb_stb_o & wb_ack)
burst_len <= burst_len - 1'b1;
burst_len <= burst_len - 1;
end
end
 
232,15 → 235,11
!(wb_ack & wb_cti_o == 3'b111);
wb_stb_nxt = !wb_stb_o | !wb_err_i & !wb_rty_i & !wb_ack |
!wb_err_i & !wb_rty_i & wb_cti_o == 3'b010 /*& !wb_we_o -- Removed to add burst write, JPB*/;
!wb_err_i & !wb_rty_i & wb_cti_o == 3'b010 ;
wb_cti_nxt[2] = wb_stb_o & wb_ack & burst_len == 'h0 | wb_cti_o[2];
wb_cti_nxt[1] = 1'b1 ;
wb_cti_nxt[0] = wb_stb_o & wb_ack & burst_len == 'h0 | wb_cti_o[0];
//if ((!biu_cyc_i | !biu_stb | !biu_cab_i) & wb_cti_o == 3'b010 |
// biu_sel_i != wb_sel_o | biu_we_i != wb_we_o)
 
if ((!biu_cyc_i | !biu_stb | !biu_cab_i | biu_sel_i != wb_sel_o |
biu_we_i != wb_we_o) & wb_cti_o == 3'b010)
wb_fsm_state_nxt = wb_fsm_last;
282,7 → 281,7
wb_cyc_o <= 1'b0;
wb_stb_o <= 1'b0;
wb_cti_o <= 3'b111;
wb_bte_o <= 2'b01; // 4-beat wrap burst = constant
wb_bte_o <= (bl==8) ? 2'b10 : (bl==4) ? 2'b01 : 2'b00;
`ifdef OR1200_WB_CAB
wb_cab_o <= 1'b0;
`endif
295,13 → 294,15
end
else begin
wb_cyc_o <= wb_cyc_nxt;
// wb_stb_o <= wb_stb_nxt;
 
if (wb_ack & wb_cti_o == 3'b111)
wb_stb_o <= 1'b0;
else
wb_stb_o <= wb_stb_nxt;
`ifndef OR1200_NO_BURSTS
wb_cti_o <= wb_cti_nxt;
wb_bte_o <= 2'b01; // 4-beat wrap burst = constant
`endif
wb_bte_o <= (bl==8) ? 2'b10 : (bl==4) ? 2'b01 : 2'b00;
`ifdef OR1200_WB_CAB
wb_cab_o <= biu_cab_i;
`endif
315,7 → 316,12
wb_adr_o <= biu_adr_i;
end
else if (wb_stb_o & wb_ack) begin
wb_adr_o[3:2] <= wb_adr_o[3:2] + 1'b1;
if (bl==4) begin
wb_adr_o[3:2] <= wb_adr_o[3:2] + 1;
end
if (bl==8) begin
wb_adr_o[4:2] <= wb_adr_o[4:2] + 1;
end
end
`ifdef OR1200_NO_DC
// dat - write data changed after avery subsequent write access
/or1200_ic_top.v
1,6 → 1,6
//////////////////////////////////////////////////////////////////////
//// ////
//// OR1200's Data Cache top level ////
//// OR1200's Instruction Cache top level ////
//// ////
//// This file is part of the OpenRISC 1200 project ////
//// http://opencores.org/project,or1k ////
51,7 → 51,7
`include "or1200_defines.v"
 
//
// Data cache
// Instruction cache top
//
module or1200_ic_top(
// Rst, clk and clock control
58,13 → 58,12
clk, rst,
 
// External i/f
icbiu_dat_o, icbiu_adr_o, icbiu_cyc_o, icbiu_stb_o, icbiu_we_o, icbiu_sel_o, icbiu_cab_o,
icbiu_dat_i, icbiu_ack_i, icbiu_err_i,
icbiu_dat_o, icbiu_adr_o, icbiu_cyc_o, icbiu_stb_o, icbiu_we_o,
icbiu_sel_o, icbiu_cab_o, icbiu_dat_i, icbiu_ack_i, icbiu_err_i,
 
// Internal i/f
ic_en,
icqmem_adr_i, icqmem_cycstb_i, icqmem_ci_i,
icqmem_sel_i, icqmem_tag_i,
icqmem_adr_i, icqmem_cycstb_i, icqmem_ci_i, icqmem_sel_i, icqmem_tag_i,
icqmem_dat_o, icqmem_ack_o, icqmem_rty_o, icqmem_err_o, icqmem_tag_o,
 
`ifdef OR1200_BIST
145,7 → 144,9
wire ictag_we;
wire [31:0] ic_addr;
wire icfsm_biu_read;
/* verilator lint_off UNOPTFLAT */
reg tagcomp_miss;
/* verilator lint_on UNOPTFLAT */
wire [`OR1200_ICINDXH:`OR1200_ICLS] ictag_addr;
wire ictag_en;
wire ictag_v;
155,6 → 156,8
wire icfsm_first_miss_err;
wire icfsm_burst;
wire icfsm_tag_we;
reg ic_inv_q;
`ifdef OR1200_BIST
//
// RAM BIST
217,13 → 220,24
assign icqmem_dat_o = icfsm_first_miss_ack | !ic_en ? icbiu_dat_i : from_icram;
 
//
// Detect falling edge of IC invalidate signal
//
always @(posedge clk or `OR1200_RST_EVENT rst)
if (rst==`OR1200_RST_VALUE)
ic_inv_q <= 1'b0;
else
ic_inv_q <= ic_inv;
//
// Tag comparison
//
// During line invalidate, ensure it stays the same
always @(tag or saved_addr or tag_v) begin
if ((tag != saved_addr[31:`OR1200_ICTAGL]) || !tag_v)
tagcomp_miss = 1'b1;
else
tagcomp_miss = 1'b0;
if ((tag != saved_addr[31:`OR1200_ICTAGL]) | !tag_v)
tagcomp_miss = 1'b1;
else
tagcomp_miss = 1'b0;
end
 
//
/or1200_dc_tag.v
107,20 → 107,12
//
// Instantiation of TAG RAM block
//
`ifdef OR1200_DC_1W_4KB
// Data widths are tag width plus one for valid
or1200_spram #
(
.aw(8),
.dw(21 + 1)
.aw(`OR1200_DCTAG),
.dw(`OR1200_DCTAG_W + 1)
)
`endif
`ifdef OR1200_DC_1W_8KB
or1200_spram #
(
.aw(9),
.dw(20 + 1)
)
`endif
dc_tag0
(
`ifdef OR1200_BIST
/or1200_dc_ram.v
104,20 → 104,11
//
// Instantiation of RAM block
//
`ifdef OR1200_DC_1W_4KB
or1200_spram_32_bw #
(
.aw(10),
.dw(32)
.aw(`OR1200_DCINDX),
.dw(dw)
)
`endif
`ifdef OR1200_DC_1W_8KB
or1200_spram_32_bw #
(
.aw(11),
.dw(32)
)
`endif
dc_ram
(
`ifdef OR1200_BIST
/or1200_gmultp2_32x32.v
3,7 → 3,7
//// Generic 32x32 multiplier ////
//// ////
//// This file is part of the OpenRISC 1200 project ////
//// http://www.opencores.org/cores/or1k/ ////
//// http://www.opencores.org/project,or1k ////
//// ////
//// Description ////
//// Generic 32x32 multiplier with pipeline stages. ////
47,31 → 47,6
// Revision 2.0 2010/06/30 11:00:00 ORSoC
// No update
//
// Revision 1.2 2002/07/31 02:04:35 lampret
// MAC now follows software convention (signed multiply instead of unsigned).
//
// Revision 1.1 2002/01/03 08:16:15 lampret
// New prefixes for RTL files, prefixed module names. Updated cache controllers and MMUs.
//
// Revision 1.4 2001/12/04 05:02:35 lampret
// Added OR1200_GENERIC_MULTP2_32X32 and OR1200_ASIC_MULTP2_32X32
//
// Revision 1.3 2001/10/21 17:57:16 lampret
// Removed params from generic_XX.v. Added translate_off/on in sprs.v and id.v. Removed spr_addr from dc.v and ic.v. Fixed CR+LF.
//
// Revision 1.2 2001/10/14 13:12:09 lampret
// MP3 version.
//
// Revision 1.1.1.1 2001/10/06 10:18:36 igorm
// no message
//
// Revision 1.2 2001/08/09 13:39:33 lampret
// Major clean-up.
//
// Revision 1.1 2001/07/20 00:46:03 lampret
// Development version of RTL. Libraries are missing.
//
//
 
// synopsys translate_off
`include "timescale.v"
/or1200_mult_mac.v
11,13 → 11,15
//// ////
//// To Do: ////
//// - make signed division better, w/o negating the operands ////
//// - implement non-serial divider that is synthesizable ////
//// ////
//// Author(s): ////
//// - Damjan Lampret, lampret@opencores.org ////
//// - Julius Baxter, julius@opencores.org ////
//// ////
//////////////////////////////////////////////////////////////////////
//// ////
//// Copyright (C) 2000 Authors and OPENCORES.ORG ////
//// Copyright (C) 2000, 2010 Authors and OPENCORES.ORG ////
//// ////
//// This source file may be used and distributed without ////
//// restriction provided that this copyright statement is not ////
56,278 → 58,391
`include "or1200_defines.v"
 
module or1200_mult_mac(
// Clock and reset
clk, rst,
// Clock and reset
clk, rst,
 
// Multiplier/MAC interface
ex_freeze, id_macrc_op, macrc_op, a, b, mac_op, alu_op, result, mac_stall_r,
// Multiplier/MAC interface
ex_freeze, id_macrc_op, macrc_op, a, b, mac_op, alu_op,
result, mult_mac_stall,
 
// SPR interface
spr_cs, spr_write, spr_addr, spr_dat_i, spr_dat_o
);
// SPR interface
spr_cs, spr_write, spr_addr, spr_dat_i, spr_dat_o
);
 
parameter width = `OR1200_OPERAND_WIDTH;
parameter width = `OR1200_OPERAND_WIDTH;
 
//
// I/O
//
//
// I/O
//
 
//
// Clock and reset
//
input clk;
input rst;
//
// Clock and reset
//
input clk;
input rst;
 
//
// Multiplier/MAC interface
//
input ex_freeze;
input id_macrc_op;
input macrc_op;
input [width-1:0] a;
input [width-1:0] b;
input [`OR1200_MACOP_WIDTH-1:0] mac_op;
input [`OR1200_ALUOP_WIDTH-1:0] alu_op;
output [width-1:0] result;
output mac_stall_r;
//
// Multiplier/MAC interface
//
input ex_freeze;
input id_macrc_op;
input macrc_op;
input [width-1:0] a;
input [width-1:0] b;
input [`OR1200_MACOP_WIDTH-1:0] mac_op;
input [`OR1200_ALUOP_WIDTH-1:0] alu_op;
output [width-1:0] result;
output mult_mac_stall;
 
//
// SPR interface
//
input spr_cs;
input spr_write;
input [31:0] spr_addr;
input [31:0] spr_dat_i;
output [31:0] spr_dat_o;
//
// SPR interface
//
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
//
//
// Internal wires and regs
//
reg [width-1:0] result;
`ifdef OR1200_MULT_IMPLEMENTED
reg [width-1:0] result;
reg [2*width-1:0] mul_prod_r;
reg [2*width-1:0] mul_prod_r;
wire alu_op_smul;
wire alu_op_umul;
wire alu_op_mul;
`ifdef OR1200_MULT_SERIAL
reg [5:0] serial_mul_cnt;
reg mul_free;
`endif
`else
wire [width-1:0] result;
wire [2*width-1:0] mul_prod_r;
wire [2*width-1:0] mul_prod_r;
`endif
wire [2*width-1:0] mul_prod;
wire [`OR1200_MACOP_WIDTH-1:0] mac_op;
wire [2*width-1:0] mul_prod;
wire mul_stall;
wire [`OR1200_MACOP_WIDTH-1:0] mac_op;
`ifdef OR1200_MAC_IMPLEMENTED
reg [`OR1200_MACOP_WIDTH-1:0] mac_op_r1;
reg [`OR1200_MACOP_WIDTH-1:0] mac_op_r2;
reg [`OR1200_MACOP_WIDTH-1:0] mac_op_r3;
reg mac_stall_r;
reg [63:0] mac_r;
reg [`OR1200_MACOP_WIDTH-1:0] mac_op_r1;
reg [`OR1200_MACOP_WIDTH-1:0] mac_op_r2;
reg [`OR1200_MACOP_WIDTH-1:0] mac_op_r3;
reg mac_stall_r;
reg [63:0] mac_r;
`else
wire [`OR1200_MACOP_WIDTH-1:0] mac_op_r1;
wire [`OR1200_MACOP_WIDTH-1:0] mac_op_r2;
wire [`OR1200_MACOP_WIDTH-1:0] mac_op_r3;
wire mac_stall_r;
wire [63:0] mac_r;
wire [`OR1200_MACOP_WIDTH-1:0] mac_op_r1;
wire [`OR1200_MACOP_WIDTH-1:0] mac_op_r2;
wire [`OR1200_MACOP_WIDTH-1:0] mac_op_r3;
wire mac_stall_r;
wire [63:0] mac_r;
`endif
wire [width-1:0] x;
wire [width-1:0] y;
wire spr_maclo_we;
wire spr_machi_we;
wire alu_op_div_divu;
wire alu_op_div;
reg div_free;
wire [width-1:0] x;
wire [width-1:0] y;
wire spr_maclo_we;
wire spr_machi_we;
wire alu_op_div;
wire alu_op_udiv;
wire alu_op_sdiv;
reg div_free;
wire div_stall;
`ifdef OR1200_DIV_IMPLEMENTED
wire [width-1:0] div_tmp;
reg [5:0] div_cntr;
`ifdef OR1200_DIV_SERIAL
reg [2*width-1:0] div_quot_r;
wire [width-1:0] div_tmp;
reg [5:0] div_cntr;
`else
reg [width-1:0] div_quot_r;
reg [width-1:0] div_quot_generic;
`endif
`endif
 
//
// Combinatorial logic
//
//
// Combinatorial logic
//
`ifdef OR1200_MULT_IMPLEMENTED
assign alu_op_smul = (alu_op == `OR1200_ALUOP_MUL);
assign alu_op_umul = (alu_op == `OR1200_ALUOP_MULU);
assign alu_op_mul = alu_op_smul | alu_op_umul;
`endif
`ifdef OR1200_MAC_IMPLEMENTED
assign spr_maclo_we = spr_cs & spr_write & spr_addr[`OR1200_MAC_ADDR];
assign spr_machi_we = spr_cs & spr_write & !spr_addr[`OR1200_MAC_ADDR];
assign spr_dat_o = spr_addr[`OR1200_MAC_ADDR] ? mac_r[31:0] : mac_r[63:32];
assign spr_maclo_we = spr_cs & spr_write & spr_addr[`OR1200_MAC_ADDR];
assign spr_machi_we = spr_cs & spr_write & !spr_addr[`OR1200_MAC_ADDR];
assign spr_dat_o = spr_addr[`OR1200_MAC_ADDR] ? mac_r[31:0] : mac_r[63:32];
`else
assign spr_maclo_we = 1'b0;
assign spr_machi_we = 1'b0;
assign spr_dat_o = 32'h0000_0000;
assign spr_maclo_we = 1'b0;
assign spr_machi_we = 1'b0;
assign spr_dat_o = 32'h0000_0000;
`endif
`ifdef OR1200_LOWPWR_MULT
assign x = (alu_op_div & a[31]) ? ~a + 1'b1 :
alu_op_div_divu | (alu_op == `OR1200_ALUOP_MUL) | (|mac_op) ?
a : 32'h0000_0000;
assign y = (alu_op_div & b[31]) ? ~b + 1'b1 :
alu_op_div_divu | (alu_op == `OR1200_ALUOP_MUL) | (|mac_op) ?
b : 32'h0000_0000;
`else
assign x = alu_op_div & a[31] ? ~a + 32'b1 : a;
assign y = alu_op_div & b[31] ? ~b + 32'b1 : b;
`endif
`ifdef OR1200_DIV_IMPLEMENTED
assign alu_op_div = (alu_op == `OR1200_ALUOP_DIV);
assign alu_op_div_divu = alu_op_div | (alu_op == `OR1200_ALUOP_DIVU);
assign div_tmp = mul_prod_r[63:32] - y;
assign alu_op_sdiv = (alu_op == `OR1200_ALUOP_DIV);
assign alu_op_udiv = (alu_op == `OR1200_ALUOP_DIVU);
assign alu_op_div = alu_op_sdiv | alu_op_udiv;
`else
assign alu_op_div = 1'b0;
assign alu_op_div_divu = 1'b0;
assign alu_op_udiv = 1'b0;
assign alu_op_sdiv = 1'b0;
assign alu_op_div = 1'b0;
`endif
 
`ifdef OR1200_MULT_IMPLEMENTED
assign x = (alu_op_sdiv | alu_op_smul) & a[31] ? ~a + 32'b1 :
alu_op_div | alu_op_mul | (|mac_op) ? a : 32'd0;
assign y = (alu_op_sdiv | alu_op_smul) & b[31] ? ~b + 32'b1 :
alu_op_div | alu_op_mul | (|mac_op) ? b : 32'd0;
 
//
// Select result of current ALU operation to be forwarded
// to next instruction and to WB stage
//
always @*
casez(alu_op) // synopsys parallel_case
`ifdef OR1200_DIV_IMPLEMENTED
`OR1200_ALUOP_DIV: begin
result = a[31] ^ b[31] ? ~mul_prod_r[31:0] + 32'd1 : mul_prod_r[31:0];
end
`OR1200_ALUOP_DIVU,
`endif
`OR1200_ALUOP_MUL: begin
result = mul_prod_r[31:0];
end
default:
//
// Select result of current ALU operation to be forwarded
// to next instruction and to WB stage
//
always @*
casez(alu_op) // synopsys parallel_case
`ifdef OR1200_DIV_IMPLEMENTED
`OR1200_ALUOP_DIV: begin
result = a[31] ^ b[31] ? ~div_quot_r[31:0] + 32'd1 : div_quot_r[31:0];
end
`OR1200_ALUOP_DIVU: begin
result = div_quot_r[31:0];
end
`endif
`ifdef OR1200_MULT_IMPLEMENTED
`OR1200_ALUOP_MUL: begin
result = a[31] ^ b[31] ? ~mul_prod_r[31:0] + 32'd1 : mul_prod_r[31:0];
end
`OR1200_ALUOP_MULU: begin
result = mul_prod_r[31:0];
end
`endif
default:
`ifdef OR1200_MAC_IMPLEMENTED
`ifdef OR1200_MAC_SHIFTBY
result = mac_r[`OR1200_MAC_SHIFTBY+31:`OR1200_MAC_SHIFTBY];
result = mac_r[`OR1200_MAC_SHIFTBY+31:`OR1200_MAC_SHIFTBY];
`else
result = mac_r[31:0];
result = mac_r[31:0];
`endif
endcase
`else
result = {width{1'b0}};
`endif
endcase
 
`ifdef OR1200_MULT_IMPLEMENTED
`ifdef OR1200_MULT_SERIAL
 
always @(`OR1200_RST_EVENT rst or posedge clk)
if (rst == `OR1200_RST_VALUE) begin
mul_prod_r <= 64'h0000_0000_0000_0000;
serial_mul_cnt <= 6'd0;
mul_free <= 1'b1;
end
else if (|serial_mul_cnt) begin
serial_mul_cnt <= serial_mul_cnt - 6'd1;
if (mul_prod_r[0])
mul_prod_r[(width*2)-1:width-1] <= mul_prod_r[(width*2)-1:width] + x;
else
mul_prod_r[(width*2)-1:width-1] <= {1'b0,mul_prod_r[(width*2)-1:
width]};
mul_prod_r[width-2:0] <= mul_prod_r[width-1:1];
end
else if (alu_op_mul && mul_free) begin
mul_prod_r <= {32'd0, y};
mul_free <= 0;
serial_mul_cnt <= 6'b10_0000;
end
else if (!ex_freeze | mul_free) begin
mul_free <= 1'b1;
end
 
assign mul_stall = (|serial_mul_cnt);
`else
//
// Instantiation of the multiplier
//
`ifdef OR1200_ASIC_MULTP2_32X32
or1200_amultp2_32x32 or1200_amultp2_32x32(
.X(x),
.Y(y),
.RST(rst),
.CLK(clk),
.P(mul_prod)
);
`else // OR1200_ASIC_MULTP2_32X32
or1200_gmultp2_32x32 or1200_gmultp2_32x32(
.X(x),
.Y(y),
.RST(rst),
.CLK(clk),
.P(mul_prod)
);
`endif // OR1200_ASIC_MULTP2_32X32
`ifdef OR1200_ASIC_MULTP2_32X32
or1200_amultp2_32x32 or1200_amultp2_32x32(
.X(x),
.Y(y),
.RST(rst),
.CLK(clk),
.P(mul_prod)
);
`else // OR1200_ASIC_MULTP2_32X32
or1200_gmultp2_32x32 or1200_gmultp2_32x32(
.X(x),
.Y(y),
.RST(rst),
.CLK(clk),
.P(mul_prod)
);
`endif // OR1200_ASIC_MULTP2_32X32
//
// Registered output from the multiplier
//
always @(`OR1200_RST_EVENT rst or posedge clk)
if (rst == `OR1200_RST_VALUE) begin
mul_prod_r <= 64'h0000_0000_0000_0000;
end
else begin
mul_prod_r <= mul_prod[63:0];
end
 
//
// Registered output from the multiplier and
// an optional divider
//
always @(`OR1200_RST_EVENT rst or posedge clk)
if (rst == `OR1200_RST_VALUE) begin
mul_prod_r <= 64'h0000_0000_0000_0000;
div_free <= 1'b1;
`ifdef OR1200_DIV_IMPLEMENTED
div_cntr <= 6'b00_0000;
`endif
end
`ifdef OR1200_DIV_IMPLEMENTED
else if (|div_cntr) begin
if (div_tmp[31])
mul_prod_r <= {mul_prod_r[62:0], 1'b0};
else
mul_prod_r <= {div_tmp[30:0], mul_prod_r[31:0], 1'b1};
div_cntr <= div_cntr - 6'd1;
end
else if (alu_op_div_divu && div_free) begin
mul_prod_r <= {31'b0, x[31:0], 1'b0};
div_cntr <= 6'b10_0000;
div_free <= 1'b0;
end
`endif // OR1200_DIV_IMPLEMENTED
else if (div_free | !ex_freeze) begin
mul_prod_r <= mul_prod[63:0];
div_free <= 1'b1;
end
 
assign mul_stall = 0;
`endif // !`ifdef OR1200_MULT_SERIAL
`else // OR1200_MULT_IMPLEMENTED
assign result = {width{1'b0}};
assign mul_prod = {2*width{1'b0}};
assign mul_prod_r = {2*width{1'b0}};
assign mul_prod = {2*width{1'b0}};
assign mul_prod_r = {2*width{1'b0}};
assign mul_stall = 0;
`endif // OR1200_MULT_IMPLEMENTED
 
`ifdef OR1200_MAC_IMPLEMENTED
// Signal to indicate when we should check for new MAC op
reg ex_freeze_r;
// Signal to indicate when we should check for new MAC op
reg ex_freeze_r;
always @(posedge clk or `OR1200_RST_EVENT rst)
if (rst == `OR1200_RST_VALUE)
ex_freeze_r <= 1'b1;
else
ex_freeze_r <= ex_freeze;
always @(posedge clk or `OR1200_RST_EVENT rst)
if (rst == `OR1200_RST_VALUE)
ex_freeze_r <= 1'b1;
else
ex_freeze_r <= ex_freeze;
//
// Propagation of l.mac opcode, only register it for one cycle
//
always @(posedge clk or `OR1200_RST_EVENT rst)
if (rst == `OR1200_RST_VALUE)
mac_op_r1 <= `OR1200_MACOP_WIDTH'b0;
else
mac_op_r1 <= !ex_freeze_r ? mac_op : `OR1200_MACOP_WIDTH'b0;
//
// Propagation of l.mac opcode, only register it for one cycle
//
always @(posedge clk or `OR1200_RST_EVENT rst)
if (rst == `OR1200_RST_VALUE)
mac_op_r1 <= `OR1200_MACOP_WIDTH'b0;
else
mac_op_r1 <= !ex_freeze_r ? mac_op : `OR1200_MACOP_WIDTH'b0;
 
//
// Propagation of l.mac opcode
//
always @(posedge clk or `OR1200_RST_EVENT rst)
if (rst == `OR1200_RST_VALUE)
mac_op_r2 <= `OR1200_MACOP_WIDTH'b0;
else
mac_op_r2 <= mac_op_r1;
//
// Propagation of l.mac opcode
//
always @(posedge clk or `OR1200_RST_EVENT rst)
if (rst == `OR1200_RST_VALUE)
mac_op_r2 <= `OR1200_MACOP_WIDTH'b0;
else
mac_op_r2 <= mac_op_r1;
 
//
// Propagation of l.mac opcode
//
always @(posedge clk or `OR1200_RST_EVENT rst)
if (rst == `OR1200_RST_VALUE)
mac_op_r3 <= `OR1200_MACOP_WIDTH'b0;
else
mac_op_r3 <= mac_op_r2;
//
// Propagation of l.mac opcode
//
always @(posedge clk or `OR1200_RST_EVENT rst)
if (rst == `OR1200_RST_VALUE)
mac_op_r3 <= `OR1200_MACOP_WIDTH'b0;
else
mac_op_r3 <= mac_op_r2;
 
//
// Implementation of MAC
//
always @(`OR1200_RST_EVENT rst or posedge clk)
if (rst == `OR1200_RST_VALUE)
mac_r <= 64'h0000_0000_0000_0000;
`ifdef OR1200_MAC_SPR_WE
else if (spr_maclo_we)
mac_r[31:0] <= spr_dat_i;
else if (spr_machi_we)
mac_r[63:32] <= spr_dat_i;
`endif
else if (mac_op_r3 == `OR1200_MACOP_MAC)
mac_r <= mac_r + mul_prod_r;
else if (mac_op_r3 == `OR1200_MACOP_MSB)
mac_r <= mac_r - mul_prod_r;
else if (macrc_op && !ex_freeze)
mac_r <= 64'h0000_0000_0000_0000;
//
// Implementation of MAC
//
always @(`OR1200_RST_EVENT rst or posedge clk)
if (rst == `OR1200_RST_VALUE)
mac_r <= 64'h0000_0000_0000_0000;
`ifdef OR1200_MAC_SPR_WE
else if (spr_maclo_we)
mac_r[31:0] <= spr_dat_i;
else if (spr_machi_we)
mac_r[63:32] <= spr_dat_i;
`endif
else if (mac_op_r3 == `OR1200_MACOP_MAC)
mac_r <= mac_r + mul_prod_r;
else if (mac_op_r3 == `OR1200_MACOP_MSB)
mac_r <= mac_r - mul_prod_r;
else if (macrc_op && !ex_freeze)
mac_r <= 64'h0000_0000_0000_0000;
 
//
// Stall CPU if l.macrc is in ID and MAC still has to process l.mac instructions
// in EX stage (e.g. inside multiplier)
// This stall signal is also used by the divider.
//
always @(`OR1200_RST_EVENT rst or posedge clk)
if (rst == `OR1200_RST_VALUE)
mac_stall_r <= 1'b0;
else
mac_stall_r <= (|mac_op | (|mac_op_r1) | (|mac_op_r2)) & (id_macrc_op | mac_stall_r)
`ifdef OR1200_DIV_IMPLEMENTED
| (|div_cntr)
`endif
;
//
// Stall CPU if l.macrc is in ID and MAC still has to process l.mac
// instructions in EX stage (e.g. inside multiplier)
// This stall signal is also used by the divider.
//
always @(`OR1200_RST_EVENT rst or posedge clk)
if (rst == `OR1200_RST_VALUE)
mac_stall_r <= 1'b0;
else
mac_stall_r <= (|mac_op | (|mac_op_r1) | (|mac_op_r2)) &
(id_macrc_op | mac_stall_r);
`else // OR1200_MAC_IMPLEMENTED
assign mac_stall_r = 1'b0;
assign mac_r = {2*width{1'b0}};
assign mac_op_r1 = `OR1200_MACOP_WIDTH'b0;
assign mac_op_r2 = `OR1200_MACOP_WIDTH'b0;
assign mac_op_r3 = `OR1200_MACOP_WIDTH'b0;
assign mac_stall_r = 1'b0;
assign mac_r = {2*width{1'b0}};
assign mac_op_r1 = `OR1200_MACOP_WIDTH'b0;
assign mac_op_r2 = `OR1200_MACOP_WIDTH'b0;
assign mac_op_r3 = `OR1200_MACOP_WIDTH'b0;
`endif // OR1200_MAC_IMPLEMENTED
 
`ifdef OR1200_DIV_IMPLEMENTED
//
// Serial division
//
`ifdef OR1200_DIV_SERIAL
assign div_tmp = div_quot_r[63:32] - y;
always @(`OR1200_RST_EVENT rst or posedge clk)
if (rst == `OR1200_RST_VALUE) begin
div_quot_r <= 64'h0000_0000_0000_0000;
div_free <= 1'b1;
div_cntr <= 6'b00_0000;
end
else if (|div_cntr) begin
if (div_tmp[31])
div_quot_r <= {div_quot_r[62:0], 1'b0};
else
div_quot_r <= {div_tmp[30:0], div_quot_r[31:0], 1'b1};
div_cntr <= div_cntr - 6'd1;
end
else if (alu_op_div && div_free) begin
div_quot_r <= {31'b0, x[31:0], 1'b0};
div_cntr <= 6'b10_0000;
div_free <= 1'b0;
end
else if (div_free | !ex_freeze) begin
//div_quot_r <= div_quot[63:0];
div_free <= 1'b1;
end
 
assign div_stall = (|div_cntr);
 
 
`else // !`ifdef OR1200_DIV_SERIAL
 
// Full divider
// TODO: Perhaps provide module that can be technology dependent.
always @(`OR1200_RST_EVENT rst or posedge clk) begin
if (rst == `OR1200_RST_VALUE) begin
div_quot_r <= 32'd0;
div_quot_generic <= 32'd0;
end
else begin
if (alu_op_udiv & !(|y)) // unsigned divide by 0 - force to MAX
div_quot_generic[31:0] <= 32'hffff_ffff;
else if (alu_op_div)
div_quot_generic[31:0] <= x / y;
end
 
// Add any additional statges of pipelining as required here. Ensure
// ends with div_quot_r.
// Then add logic to ensure div_stall stays high for as long as the
// division should take.
div_quot_r[31:0] <= div_quot_generic;
 
end
assign div_stall = 0;
`endif
 
`else // !`ifdef OR1200_DIV_IMPLEMENTED
 
assign div_stall = 0;
 
`endif // !`ifdef OR1200_DIV_IMPLEMENTED
//
// Stall output
//
assign mult_mac_stall = mac_stall_r | div_stall | mul_stall;
endmodule
/or1200_dc_top.v
284,7 → 284,6
// Select between data generated by DCRAM or passed by BIU
//
assign dcqmem_dat_o = dcfsm_first_miss_ack | !dc_en ? dcsb_dat_i : from_dcram;
//assign dcqmem_dat_o = !dc_en ? dcsb_dat_i : from_dcram;
 
//
// Tag comparison
/or1200_ic_fsm.v
58,7 → 58,7
`define OR1200_ICFSM_IFETCH 2'd3
 
//
// Data cache FSM for cache line of 16 bytes (4x singleword)
// Instruction cache FSM
//
 
module or1200_ic_fsm(
67,9 → 67,13
 
// Internal i/f to top level IC
ic_en, icqmem_cycstb_i, icqmem_ci_i,
tagcomp_miss, biudata_valid, biudata_error, start_addr, saved_addr,
icram_we, biu_read, first_hit_ack, first_miss_ack, first_miss_err,
burst, tag_we
tagcomp_miss,
biudata_valid, biudata_error,
start_addr, saved_addr,
icram_we, tag_we,
biu_read,
first_hit_ack, first_miss_ack, first_miss_err,
burst
);
 
//
98,11 → 102,12
//
reg [31:0] saved_addr_r;
reg [1:0] state;
reg [2:0] cnt;
reg [`OR1200_ICLS-1:0] cnt;
reg hitmiss_eval;
reg load;
reg cache_inhibit;
 
reg last_eval_miss; // JPB
//
// Generate of ICRAM write enables
//
142,8 → 147,10
saved_addr_r <= 32'b0;
hitmiss_eval <= 1'b0;
load <= 1'b0;
cnt <= 3'b000;
cnt <= `OR1200_ICLS'd0;
cache_inhibit <= 1'b0;
last_eval_miss <= 0; // JPB
end
else
case (state) // synopsys parallel_case
154,12 → 161,13
hitmiss_eval <= 1'b1;
load <= 1'b1;
cache_inhibit <= icqmem_ci_i;
last_eval_miss <= 0; // JPB
end
else begin // idle
hitmiss_eval <= 1'b0;
load <= 1'b0;
cache_inhibit <= 1'b0;
end
end
`OR1200_ICFSM_CFETCH: begin // fetch
if (icqmem_cycstb_i & icqmem_ci_i)
166,8 → 174,7
cache_inhibit <= 1'b1;
if (hitmiss_eval)
saved_addr_r[31:13] <= start_addr[31:13];
saved_addr_r[31:`OR1200_ICTAGL] <= start_addr[31:`OR1200_ICTAGL];
if ((!ic_en) ||
// fetch aborted (usually caused by IMMU)
(hitmiss_eval & !icqmem_cycstb_i) ||
179,28 → 186,35
load <= 1'b0;
cache_inhibit <= 1'b0;
end // if ((!ic_en) ||...
// fetch missed, finish current external fetch and refill
// fetch missed, wait for first fetch and continue filling line
else if (tagcomp_miss & biudata_valid) begin
state <= `OR1200_ICFSM_LREFILL3;
saved_addr_r[3:2] <= saved_addr_r[3:2] + 1'd1;
saved_addr_r[`OR1200_ICLS-1:2]
<= saved_addr_r[`OR1200_ICLS-1:2] + 1;
hitmiss_eval <= 1'b0;
cnt <= `OR1200_ICLS-2;
cnt <= ((1 << `OR1200_ICLS) - (2 * 4));
cache_inhibit <= 1'b0;
end
// fetch aborted (usually caused by exception)
else if (!icqmem_cycstb_i) begin
else if (!icqmem_cycstb_i
& !last_eval_miss // JPB
) begin
state <= `OR1200_ICFSM_IDLE;
hitmiss_eval <= 1'b0;
load <= 1'b0;
cache_inhibit <= 1'b0;
end
// fetch hit, finish immediately
else if (!tagcomp_miss & !icqmem_ci_i) begin
// fetch hit, wait in this state for now
else if (!tagcomp_miss & !icqmem_ci_i) begin
saved_addr_r <= start_addr;
cache_inhibit <= 1'b0;
end
else // fetch in-progress
hitmiss_eval <= 1'b0;
 
if (hitmiss_eval & !tagcomp_miss) // JPB
last_eval_miss <= 1; // JPB
end
`OR1200_ICFSM_LREFILL3 : begin
// abort because IC has just been turned off
213,8 → 227,9
end
// refill ack, more fetchs to come
else if (biudata_valid && (|cnt)) begin
cnt <= cnt - 3'd1;
saved_addr_r[3:2] <= saved_addr_r[3:2] + 1'd1;
cnt <= cnt - `OR1200_ICLS'd4;
saved_addr_r[`OR1200_ICLS-1:2]
<= saved_addr_r[`OR1200_ICLS-1:2] + 1;
end
// last fetch of line refill
else if (biudata_valid) begin
/or1200_top.v
432,7 → 432,9
//
// Instantiation of Instruction WISHBONE BIU
//
or1200_wb_biu iwb_biu(
or1200_wb_biu
#(.bl((1 << (`OR1200_ICLS-2))))
iwb_biu(
// RISC clk, rst and clock control
.clk(clk_i),
.rst(rst_i),
476,7 → 478,9
//
// Instantiation of Data WISHBONE BIU
//
or1200_wb_biu dwb_biu(
or1200_wb_biu
#(.bl((1 << (`OR1200_DCLS-2))))
dwb_biu(
// RISC clk, rst and clock control
.clk(clk_i),
.rst(rst_i),
/or1200_rfram_generic.v
126,6 → 126,7
reg [dw-1:0] do_a;
reg [dw-1:0] do_b;
 
`ifdef verilator
// Function to access GPRs (for use by Verilator). No need to hide this one
// from the simulator, since it has an input (as required by IEEE 1364-2001).
function [31:0] get_gpr;
151,6 → 152,51
endfunction // get_gpr
 
// Function to access GPRs (for use by Verilator). No need to hide this one
// from the simulator, since it has an input (as required by IEEE 1364-2001).
function [31:0] set_gpr;
// verilator public
input [aw-1:0] gpr_no;
input [dw-1:0] value;
 
mem[gpr_no*32 + 31] = value[31];
mem[gpr_no*32 + 30] = value[30];
mem[gpr_no*32 + 29] = value[29];
mem[gpr_no*32 + 28] = value[28];
mem[gpr_no*32 + 27] = value[27];
mem[gpr_no*32 + 26] = value[26];
mem[gpr_no*32 + 25] = value[25];
mem[gpr_no*32 + 24] = value[24];
mem[gpr_no*32 + 23] = value[23];
mem[gpr_no*32 + 22] = value[22];
mem[gpr_no*32 + 21] = value[21];
mem[gpr_no*32 + 20] = value[20];
mem[gpr_no*32 + 19] = value[19];
mem[gpr_no*32 + 18] = value[18];
mem[gpr_no*32 + 17] = value[17];
mem[gpr_no*32 + 16] = value[16];
mem[gpr_no*32 + 15] = value[15];
mem[gpr_no*32 + 14] = value[14];
mem[gpr_no*32 + 13] = value[13];
mem[gpr_no*32 + 12] = value[12];
mem[gpr_no*32 + 11] = value[11];
mem[gpr_no*32 + 10] = value[10];
mem[gpr_no*32 + 9] = value[ 9];
mem[gpr_no*32 + 8] = value[ 8];
mem[gpr_no*32 + 7] = value[ 7];
mem[gpr_no*32 + 6] = value[ 6];
mem[gpr_no*32 + 5] = value[ 5];
mem[gpr_no*32 + 4] = value[ 4];
mem[gpr_no*32 + 3] = value[ 3];
mem[gpr_no*32 + 2] = value[ 2];
mem[gpr_no*32 + 1] = value[ 1];
mem[gpr_no*32 + 0] = value[ 0];
 
set_gpr = 0;
endfunction // set_gpr
`endif // `ifdef verilator
//
// Write port
//
/or1200_dpram.v
107,6 → 107,15
get_gpr = mem[gpr_no];
endfunction // get_gpr
 
task set_gpr;
// verilator public
input [aw-1:0] gpr_no;
input [dw-1:0] value;
 
mem[gpr_no] = value;
endtask // get_gpr
//
// Data output drivers

powered by: WebSVN 2.1.0

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