//////////////////////////////////////////////////////////////////////
|
//////////////////////////////////////////////////////////////////////
|
//// ////
|
//// ////
|
//// OR1200's Instruction decode ////
|
//// OR1200's Instruction decode ////
|
//// ////
|
//// ////
|
//// This file is part of the OpenRISC 1200 project ////
|
//// This file is part of the OpenRISC 1200 project ////
|
//// http://www.opencores.org/cores/or1k/ ////
|
//// http://www.opencores.org/cores/or1k/ ////
|
//// ////
|
//// ////
|
//// Description ////
|
//// Description ////
|
//// Majority of instruction decoding is performed here. ////
|
//// Majority of instruction decoding is performed here. ////
|
//// ////
|
//// ////
|
//// To Do: ////
|
//// To Do: ////
|
//// - make it smaller and faster ////
|
//// - make it smaller and faster ////
|
//// ////
|
//// ////
|
//// Author(s): ////
|
//// Author(s): ////
|
//// - Damjan Lampret, lampret@opencores.org ////
|
//// - Damjan Lampret, lampret@opencores.org ////
|
//// ////
|
//// ////
|
//////////////////////////////////////////////////////////////////////
|
//////////////////////////////////////////////////////////////////////
|
//// ////
|
//// ////
|
//// Copyright (C) 2000 Authors and OPENCORES.ORG ////
|
//// Copyright (C) 2000 Authors and OPENCORES.ORG ////
|
//// ////
|
//// ////
|
//// This source file may be used and distributed without ////
|
//// This source file may be used and distributed without ////
|
//// restriction provided that this copyright statement is not ////
|
//// restriction provided that this copyright statement is not ////
|
//// removed from the file and that any derivative work contains ////
|
//// removed from the file and that any derivative work contains ////
|
//// the original copyright notice and the associated disclaimer. ////
|
//// the original copyright notice and the associated disclaimer. ////
|
//// ////
|
//// ////
|
//// This source file is free software; you can redistribute it ////
|
//// This source file is free software; you can redistribute it ////
|
//// and/or modify it under the terms of the GNU Lesser General ////
|
//// and/or modify it under the terms of the GNU Lesser General ////
|
//// Public License as published by the Free Software Foundation; ////
|
//// Public License as published by the Free Software Foundation; ////
|
//// either version 2.1 of the License, or (at your option) any ////
|
//// either version 2.1 of the License, or (at your option) any ////
|
//// later version. ////
|
//// later version. ////
|
//// ////
|
//// ////
|
//// This source is distributed in the hope that it will be ////
|
//// This source is distributed in the hope that it will be ////
|
//// useful, but WITHOUT ANY WARRANTY; without even the implied ////
|
//// useful, but WITHOUT ANY WARRANTY; without even the implied ////
|
//// warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR ////
|
//// warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR ////
|
//// PURPOSE. See the GNU Lesser General Public License for more ////
|
//// PURPOSE. See the GNU Lesser General Public License for more ////
|
//// details. ////
|
//// details. ////
|
//// ////
|
//// ////
|
//// You should have received a copy of the GNU Lesser General ////
|
//// You should have received a copy of the GNU Lesser General ////
|
//// Public License along with this source; if not, download it ////
|
//// Public License along with this source; if not, download it ////
|
//// from http://www.opencores.org/lgpl.shtml ////
|
//// from http://www.opencores.org/lgpl.shtml ////
|
//// ////
|
//// ////
|
//////////////////////////////////////////////////////////////////////
|
//////////////////////////////////////////////////////////////////////
|
//
|
//
|
// CVS Revision History
|
// CVS Revision History
|
//
|
//
|
// $Log: not supported by cvs2svn $
|
// $Log: not supported by cvs2svn $
|
// Revision 1.5 2002/02/01 19:56:54 lampret
|
// Revision 1.5 2002/02/01 19:56:54 lampret
|
// Fixed combinational loops.
|
// Fixed combinational loops.
|
//
|
//
|
// Revision 1.4 2002/01/28 01:15:59 lampret
|
// Revision 1.4 2002/01/28 01:15:59 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.
|
// 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.3 2002/01/18 14:21:43 lampret
|
// Revision 1.3 2002/01/18 14:21:43 lampret
|
// Fixed 'the NPC single-step fix'.
|
// Fixed 'the NPC single-step fix'.
|
//
|
//
|
// Revision 1.2 2002/01/14 06:18:22 lampret
|
// 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.
|
// 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
|
// Revision 1.1 2002/01/03 08:16:15 lampret
|
// New prefixes for RTL files, prefixed module names. Updated cache controllers and MMUs.
|
// New prefixes for RTL files, prefixed module names. Updated cache controllers and MMUs.
|
//
|
//
|
// Revision 1.14 2001/11/30 18:59:17 simons
|
// Revision 1.14 2001/11/30 18:59:17 simons
|
// force_dslot_fetch does not work - allways zero.
|
// force_dslot_fetch does not work - allways zero.
|
//
|
//
|
// Revision 1.13 2001/11/20 18:46:15 simons
|
// Revision 1.13 2001/11/20 18:46:15 simons
|
// Break point bug fixed
|
// Break point bug fixed
|
//
|
//
|
// Revision 1.12 2001/11/18 08:36:28 lampret
|
// Revision 1.12 2001/11/18 08:36:28 lampret
|
// For GDB changed single stepping and disabled trap exception.
|
// For GDB changed single stepping and disabled trap exception.
|
//
|
//
|
// Revision 1.11 2001/11/13 10:02:21 lampret
|
// Revision 1.11 2001/11/13 10:02:21 lampret
|
// Added 'setpc'. Renamed some signals (except_flushpipe into flushpipe etc)
|
// Added 'setpc'. Renamed some signals (except_flushpipe into flushpipe etc)
|
//
|
//
|
// Revision 1.10 2001/11/12 01:45:40 lampret
|
// Revision 1.10 2001/11/12 01:45:40 lampret
|
// Moved flag bit into SR. Changed RF enable from constant enable to dynamic enable for read ports.
|
// Moved flag bit into SR. Changed RF enable from constant enable to dynamic enable for read ports.
|
//
|
//
|
// Revision 1.9 2001/11/10 03:43:57 lampret
|
// Revision 1.9 2001/11/10 03:43:57 lampret
|
// Fixed exceptions.
|
// Fixed exceptions.
|
//
|
//
|
// Revision 1.8 2001/10/21 17:57:16 lampret
|
// 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.
|
// 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
|
// Revision 1.7 2001/10/14 13:12:09 lampret
|
// MP3 version.
|
// MP3 version.
|
//
|
//
|
// Revision 1.1.1.1 2001/10/06 10:18:36 igorm
|
// Revision 1.1.1.1 2001/10/06 10:18:36 igorm
|
// no message
|
// no message
|
//
|
//
|
// Revision 1.2 2001/08/13 03:36:20 lampret
|
// Revision 1.2 2001/08/13 03:36:20 lampret
|
// Added cfg regs. Moved all defines into one defines.v file. More cleanup.
|
// Added cfg regs. Moved all defines into one defines.v file. More cleanup.
|
//
|
//
|
// Revision 1.1 2001/08/09 13:39:33 lampret
|
// Revision 1.1 2001/08/09 13:39:33 lampret
|
// Major clean-up.
|
// Major clean-up.
|
//
|
//
|
//
|
//
|
|
|
// synopsys translate_off
|
// synopsys translate_off
|
`include "timescale.v"
|
`include "timescale.v"
|
// synopsys translate_on
|
// synopsys translate_on
|
`include "or1200_defines.v"
|
`include "or1200_defines.v"
|
|
|
module or1200_ctrl(
|
module or1200_ctrl(
|
// Clock and reset
|
// Clock and reset
|
clk, rst,
|
clk, rst,
|
|
|
// Internal i/f
|
// Internal i/f
|
id_freeze, ex_freeze, wb_freeze, flushpipe, if_insn, ex_insn, branch_op, branch_taken,
|
id_freeze, ex_freeze, wb_freeze, flushpipe, if_insn, ex_insn, branch_op, branch_taken,
|
rf_addra, rf_addrb, rf_rda, rf_rdb, alu_op, mac_op, shrot_op, comp_op, rf_addrw, rfwb_op,
|
rf_addra, rf_addrb, rf_rda, rf_rdb, alu_op, mac_op, shrot_op, comp_op, rf_addrw, rfwb_op,
|
wb_insn, simm, branch_addrofs, lsu_addrofs, sel_a, sel_b, lsu_op,
|
wb_insn, simm, branch_addrofs, lsu_addrofs, sel_a, sel_b, lsu_op,
|
multicycle, spr_addrimm, wbforw_valid, sig_syscall, sig_trap,
|
multicycle, spr_addrimm, wbforw_valid, sig_syscall, sig_trap,
|
force_dslot_fetch, no_more_dslot, ex_void, id_macrc_op, ex_macrc_op, rfe, except_illegal
|
force_dslot_fetch, no_more_dslot, ex_void, id_macrc_op, ex_macrc_op, rfe, except_illegal
|
);
|
);
|
|
|
//
|
//
|
// I/O
|
// I/O
|
//
|
//
|
input clk;
|
input clk;
|
input rst;
|
input rst;
|
input id_freeze;
|
input id_freeze;
|
input ex_freeze;
|
input ex_freeze;
|
input wb_freeze;
|
input wb_freeze;
|
input flushpipe;
|
input flushpipe;
|
input [31:0] if_insn;
|
input [31:0] if_insn;
|
output [31:0] ex_insn;
|
output [31:0] ex_insn;
|
output [`OR1200_BRANCHOP_WIDTH-1:0] branch_op;
|
output [`OR1200_BRANCHOP_WIDTH-1:0] branch_op;
|
input branch_taken;
|
input branch_taken;
|
output [`OR1200_REGFILE_ADDR_WIDTH-1:0] rf_addrw;
|
output [`OR1200_REGFILE_ADDR_WIDTH-1:0] rf_addrw;
|
output [`OR1200_REGFILE_ADDR_WIDTH-1:0] rf_addra;
|
output [`OR1200_REGFILE_ADDR_WIDTH-1:0] rf_addra;
|
output [`OR1200_REGFILE_ADDR_WIDTH-1:0] rf_addrb;
|
output [`OR1200_REGFILE_ADDR_WIDTH-1:0] rf_addrb;
|
output rf_rda;
|
output rf_rda;
|
output rf_rdb;
|
output rf_rdb;
|
output [`OR1200_ALUOP_WIDTH-1:0] alu_op;
|
output [`OR1200_ALUOP_WIDTH-1:0] alu_op;
|
output [`OR1200_MACOP_WIDTH-1:0] mac_op;
|
output [`OR1200_MACOP_WIDTH-1:0] mac_op;
|
output [`OR1200_SHROTOP_WIDTH-1:0] shrot_op;
|
output [`OR1200_SHROTOP_WIDTH-1:0] shrot_op;
|
output [`OR1200_RFWBOP_WIDTH-1:0] rfwb_op;
|
output [`OR1200_RFWBOP_WIDTH-1:0] rfwb_op;
|
output [31:0] wb_insn;
|
output [31:0] wb_insn;
|
output [31:0] simm;
|
output [31:0] simm;
|
output [31:2] branch_addrofs;
|
output [31:2] branch_addrofs;
|
output [31:0] lsu_addrofs;
|
output [31:0] lsu_addrofs;
|
output [`OR1200_SEL_WIDTH-1:0] sel_a;
|
output [`OR1200_SEL_WIDTH-1:0] sel_a;
|
output [`OR1200_SEL_WIDTH-1:0] sel_b;
|
output [`OR1200_SEL_WIDTH-1:0] sel_b;
|
output [`OR1200_LSUOP_WIDTH-1:0] lsu_op;
|
output [`OR1200_LSUOP_WIDTH-1:0] lsu_op;
|
output [`OR1200_COMPOP_WIDTH-1:0] comp_op;
|
output [`OR1200_COMPOP_WIDTH-1:0] comp_op;
|
output [`OR1200_MULTICYCLE_WIDTH-1:0] multicycle;
|
output [`OR1200_MULTICYCLE_WIDTH-1:0] multicycle;
|
output [15:0] spr_addrimm;
|
output [15:0] spr_addrimm;
|
input wbforw_valid;
|
input wbforw_valid;
|
output sig_syscall;
|
output sig_syscall;
|
output sig_trap;
|
output sig_trap;
|
output force_dslot_fetch;
|
output force_dslot_fetch;
|
output no_more_dslot;
|
output no_more_dslot;
|
output ex_void;
|
output ex_void;
|
output id_macrc_op;
|
output id_macrc_op;
|
output ex_macrc_op;
|
output ex_macrc_op;
|
output rfe;
|
output rfe;
|
output except_illegal;
|
output except_illegal;
|
|
|
//
|
//
|
// Internal wires and regs
|
// Internal wires and regs
|
//
|
//
|
reg [`OR1200_BRANCHOP_WIDTH-1:0] pre_branch_op;
|
reg [`OR1200_BRANCHOP_WIDTH-1:0] pre_branch_op;
|
reg [`OR1200_BRANCHOP_WIDTH-1:0] branch_op;
|
reg [`OR1200_BRANCHOP_WIDTH-1:0] branch_op;
|
reg [`OR1200_ALUOP_WIDTH-1:0] alu_op;
|
reg [`OR1200_ALUOP_WIDTH-1:0] alu_op;
|
reg [`OR1200_MACOP_WIDTH-1:0] mac_op;
|
reg [`OR1200_MACOP_WIDTH-1:0] mac_op;
|
reg [`OR1200_SHROTOP_WIDTH-1:0] shrot_op;
|
reg [`OR1200_SHROTOP_WIDTH-1:0] shrot_op;
|
reg [31:0] id_insn;
|
reg [31:0] id_insn;
|
reg [31:0] ex_insn;
|
reg [31:0] ex_insn;
|
reg [31:0] wb_insn;
|
reg [31:0] wb_insn;
|
reg [`OR1200_REGFILE_ADDR_WIDTH-1:0] rf_addrw;
|
reg [`OR1200_REGFILE_ADDR_WIDTH-1:0] rf_addrw;
|
reg [`OR1200_REGFILE_ADDR_WIDTH-1:0] wb_rfaddrw;
|
reg [`OR1200_REGFILE_ADDR_WIDTH-1:0] wb_rfaddrw;
|
reg [`OR1200_RFWBOP_WIDTH-1:0] rfwb_op;
|
reg [`OR1200_RFWBOP_WIDTH-1:0] rfwb_op;
|
reg [31:0] lsu_addrofs;
|
reg [31:0] lsu_addrofs;
|
reg [`OR1200_SEL_WIDTH-1:0] sel_a;
|
reg [`OR1200_SEL_WIDTH-1:0] sel_a;
|
reg [`OR1200_SEL_WIDTH-1:0] sel_b;
|
reg [`OR1200_SEL_WIDTH-1:0] sel_b;
|
reg sel_imm;
|
reg sel_imm;
|
reg [`OR1200_LSUOP_WIDTH-1:0] lsu_op;
|
reg [`OR1200_LSUOP_WIDTH-1:0] lsu_op;
|
reg [`OR1200_COMPOP_WIDTH-1:0] comp_op;
|
reg [`OR1200_COMPOP_WIDTH-1:0] comp_op;
|
reg [`OR1200_MULTICYCLE_WIDTH-1:0] multicycle;
|
reg [`OR1200_MULTICYCLE_WIDTH-1:0] multicycle;
|
reg imm_signextend;
|
reg imm_signextend;
|
reg [15:0] spr_addrimm;
|
reg [15:0] spr_addrimm;
|
reg sig_syscall;
|
reg sig_syscall;
|
reg sig_trap;
|
reg sig_trap;
|
reg except_illegal;
|
reg except_illegal;
|
reg ex_macrc_op;
|
reg ex_macrc_op;
|
wire id_void;
|
wire id_void;
|
|
|
//
|
//
|
// Register file read addresses
|
// Register file read addresses
|
//
|
//
|
assign rf_addra = if_insn[20:16];
|
assign rf_addra = if_insn[20:16];
|
assign rf_addrb = if_insn[15:11];
|
assign rf_addrb = if_insn[15:11];
|
assign rf_rda = if_insn[31];
|
assign rf_rda = if_insn[31];
|
assign rf_rdb = if_insn[30];
|
assign rf_rdb = if_insn[30];
|
|
|
//
|
//
|
// Force fetch of delay slot instruction when jump/branch is preceeded by load/store
|
// Force fetch of delay slot instruction when jump/branch is preceeded by load/store
|
// instructions
|
// instructions
|
//
|
//
|
// SIMON
|
// SIMON
|
// assign force_dslot_fetch = ((|pre_branch_op) & (|lsu_op));
|
// assign force_dslot_fetch = ((|pre_branch_op) & (|lsu_op));
|
assign force_dslot_fetch = 1'b0;
|
assign force_dslot_fetch = 1'b0;
|
assign no_more_dslot = |branch_op & !id_void & branch_taken | (branch_op == `OR1200_BRANCHOP_RFE);
|
assign no_more_dslot = |branch_op & !id_void & branch_taken | (branch_op == `OR1200_BRANCHOP_RFE);
|
assign id_void = (id_insn[31:26] == `OR1200_OR32_NOP) & id_insn[16];
|
assign id_void = (id_insn[31:26] == `OR1200_OR32_NOP) & id_insn[16];
|
assign ex_void = (ex_insn[31:26] == `OR1200_OR32_NOP) & ex_insn[16];
|
assign ex_void = (ex_insn[31:26] == `OR1200_OR32_NOP) & ex_insn[16];
|
|
|
//
|
//
|
// Sign/Zero extension of immediates
|
// Sign/Zero extension of immediates
|
//
|
//
|
assign simm = (imm_signextend == 1'b1) ? {{16{id_insn[15]}}, id_insn[15:0]} : {{16'b0}, id_insn[15:0]};
|
assign simm = (imm_signextend == 1'b1) ? {{16{id_insn[15]}}, id_insn[15:0]} : {{16'b0}, id_insn[15:0]};
|
|
|
//
|
//
|
// Sign extension of branch offset
|
// Sign extension of branch offset
|
//
|
//
|
assign branch_addrofs = {{4{ex_insn[25]}}, ex_insn[25:0]};
|
assign branch_addrofs = {{4{ex_insn[25]}}, ex_insn[25:0]};
|
|
|
//
|
//
|
// l.macrc in ID stage
|
// l.macrc in ID stage
|
//
|
//
|
assign id_macrc_op = (id_insn[31:26] == `OR1200_OR32_MOVHI) & id_insn[16];
|
assign id_macrc_op = (id_insn[31:26] == `OR1200_OR32_MOVHI) & id_insn[16];
|
|
|
//
|
//
|
//
|
//
|
//
|
//
|
assign rfe = (pre_branch_op == `OR1200_BRANCHOP_RFE) | (branch_op == `OR1200_BRANCHOP_RFE);
|
assign rfe = (pre_branch_op == `OR1200_BRANCHOP_RFE) | (branch_op == `OR1200_BRANCHOP_RFE);
|
|
|
//
|
//
|
// Generation of sel_a
|
// Generation of sel_a
|
//
|
//
|
always @(rf_addrw or id_insn or rfwb_op or wbforw_valid or wb_rfaddrw)
|
always @(rf_addrw or id_insn or rfwb_op or wbforw_valid or wb_rfaddrw)
|
if ((id_insn[20:16] == rf_addrw) && rfwb_op[0])
|
if ((id_insn[20:16] == rf_addrw) && rfwb_op[0])
|
sel_a = `OR1200_SEL_EX_FORW;
|
sel_a = `OR1200_SEL_EX_FORW;
|
else if ((id_insn[20:16] == wb_rfaddrw) && wbforw_valid)
|
else if ((id_insn[20:16] == wb_rfaddrw) && wbforw_valid)
|
sel_a = `OR1200_SEL_WB_FORW;
|
sel_a = `OR1200_SEL_WB_FORW;
|
else
|
else
|
sel_a = `OR1200_SEL_RF;
|
sel_a = `OR1200_SEL_RF;
|
|
|
//
|
//
|
// Generation of sel_b
|
// Generation of sel_b
|
//
|
//
|
always @(rf_addrw or sel_imm or id_insn or rfwb_op or wbforw_valid or wb_rfaddrw)
|
always @(rf_addrw or sel_imm or id_insn or rfwb_op or wbforw_valid or wb_rfaddrw)
|
if (sel_imm)
|
if (sel_imm)
|
sel_b = `OR1200_SEL_IMM;
|
sel_b = `OR1200_SEL_IMM;
|
else if ((id_insn[15:11] == rf_addrw) && rfwb_op[0])
|
else if ((id_insn[15:11] == rf_addrw) && rfwb_op[0])
|
sel_b = `OR1200_SEL_EX_FORW;
|
sel_b = `OR1200_SEL_EX_FORW;
|
else if ((id_insn[15:11] == wb_rfaddrw) && wbforw_valid)
|
else if ((id_insn[15:11] == wb_rfaddrw) && wbforw_valid)
|
sel_b = `OR1200_SEL_WB_FORW;
|
sel_b = `OR1200_SEL_WB_FORW;
|
else
|
else
|
sel_b = `OR1200_SEL_RF;
|
sel_b = `OR1200_SEL_RF;
|
|
|
//
|
//
|
// l.macrc in EX stage
|
// l.macrc in EX stage
|
//
|
//
|
always @(posedge clk or posedge rst) begin
|
always @(posedge clk or posedge rst) begin
|
if (rst)
|
if (rst)
|
ex_macrc_op <= #1 1'b0;
|
ex_macrc_op <= #1 1'b0;
|
else if (!ex_freeze & id_freeze | flushpipe)
|
else if (!ex_freeze & id_freeze | flushpipe)
|
ex_macrc_op <= #1 1'b0;
|
ex_macrc_op <= #1 1'b0;
|
else if (!ex_freeze)
|
else if (!ex_freeze)
|
ex_macrc_op <= #1 id_macrc_op;
|
ex_macrc_op <= #1 id_macrc_op;
|
end
|
end
|
|
|
//
|
//
|
// Decode of spr_addrimm
|
// Decode of spr_addrimm
|
//
|
//
|
always @(posedge clk or posedge rst) begin
|
always @(posedge clk or posedge rst) begin
|
if (rst)
|
if (rst)
|
spr_addrimm <= #1 16'h0000;
|
spr_addrimm <= #1 16'h0000;
|
else if (!ex_freeze & id_freeze | flushpipe)
|
else if (!ex_freeze & id_freeze | flushpipe)
|
spr_addrimm <= #1 16'h0000;
|
spr_addrimm <= #1 16'h0000;
|
else if (!ex_freeze) begin
|
else if (!ex_freeze) begin
|
case (id_insn[31:26]) // synopsys parallel_case
|
case (id_insn[31:26]) // synopsys parallel_case
|
// l.mfspr
|
// l.mfspr
|
`OR1200_OR32_MFSPR:
|
`OR1200_OR32_MFSPR:
|
spr_addrimm <= #1 id_insn[15:0];
|
spr_addrimm <= #1 id_insn[15:0];
|
// l.mtspr
|
// l.mtspr
|
default:
|
default:
|
spr_addrimm <= #1 {id_insn[25:21], id_insn[10:0]};
|
spr_addrimm <= #1 {id_insn[25:21], id_insn[10:0]};
|
endcase
|
endcase
|
end
|
end
|
end
|
end
|
|
|
//
|
//
|
// Decode of multicycle
|
// Decode of multicycle
|
//
|
//
|
always @(id_insn) begin
|
always @(id_insn) begin
|
case (id_insn[31:26]) // synopsys parallel_case
|
case (id_insn[31:26]) // synopsys parallel_case
|
`ifdef UNUSED
|
`ifdef UNUSED
|
// l.lwz
|
// l.lwz
|
`OR1200_OR32_LWZ:
|
`OR1200_OR32_LWZ:
|
multicycle = `OR1200_TWO_CYCLES;
|
multicycle = `OR1200_TWO_CYCLES;
|
|
|
// l.lbz
|
// l.lbz
|
`OR1200_OR32_LBZ:
|
`OR1200_OR32_LBZ:
|
multicycle = `OR1200_TWO_CYCLES;
|
multicycle = `OR1200_TWO_CYCLES;
|
|
|
// l.lbs
|
// l.lbs
|
`OR1200_OR32_LBS:
|
`OR1200_OR32_LBS:
|
multicycle = `OR1200_TWO_CYCLES;
|
multicycle = `OR1200_TWO_CYCLES;
|
|
|
// l.lhz
|
// l.lhz
|
`OR1200_OR32_LHZ:
|
`OR1200_OR32_LHZ:
|
multicycle = `OR1200_TWO_CYCLES;
|
multicycle = `OR1200_TWO_CYCLES;
|
|
|
// l.lhs
|
// l.lhs
|
`OR1200_OR32_LHS:
|
`OR1200_OR32_LHS:
|
multicycle = `OR1200_TWO_CYCLES;
|
multicycle = `OR1200_TWO_CYCLES;
|
|
|
// l.sw
|
// l.sw
|
`OR1200_OR32_SW:
|
`OR1200_OR32_SW:
|
multicycle = `OR1200_TWO_CYCLES;
|
multicycle = `OR1200_TWO_CYCLES;
|
|
|
// l.sb
|
// l.sb
|
`OR1200_OR32_SB:
|
`OR1200_OR32_SB:
|
multicycle = `OR1200_TWO_CYCLES;
|
multicycle = `OR1200_TWO_CYCLES;
|
|
|
// l.sh
|
// l.sh
|
`OR1200_OR32_SH:
|
`OR1200_OR32_SH:
|
multicycle = `OR1200_TWO_CYCLES;
|
multicycle = `OR1200_TWO_CYCLES;
|
`endif
|
`endif
|
// ALU instructions except the one with immediate
|
// ALU instructions except the one with immediate
|
`OR1200_OR32_ALU:
|
`OR1200_OR32_ALU:
|
multicycle = id_insn[`OR1200_ALUMCYC_POS];
|
multicycle = id_insn[`OR1200_ALUMCYC_POS];
|
|
|
// Single cycle instructions
|
// Single cycle instructions
|
default: begin
|
default: begin
|
multicycle = `OR1200_ONE_CYCLE;
|
multicycle = `OR1200_ONE_CYCLE;
|
end
|
end
|
|
|
endcase
|
endcase
|
|
|
end
|
end
|
|
|
//
|
//
|
// Decode of imm_signextend
|
// Decode of imm_signextend
|
//
|
//
|
always @(id_insn) begin
|
always @(id_insn) begin
|
case (id_insn[31:26]) // synopsys parallel_case
|
case (id_insn[31:26]) // synopsys parallel_case
|
|
|
// l.addi
|
// l.addi
|
`OR1200_OR32_ADDI:
|
`OR1200_OR32_ADDI:
|
imm_signextend = 1'b1;
|
imm_signextend = 1'b1;
|
|
|
// l.addic
|
// l.addic
|
`OR1200_OR32_ADDIC:
|
`OR1200_OR32_ADDIC:
|
imm_signextend = 1'b1;
|
imm_signextend = 1'b1;
|
|
|
// l.xori
|
// l.xori
|
`OR1200_OR32_XORI:
|
`OR1200_OR32_XORI:
|
imm_signextend = 1'b1;
|
imm_signextend = 1'b1;
|
|
|
// l.muli
|
// l.muli
|
`OR1200_OR32_MULI:
|
`OR1200_OR32_MULI:
|
imm_signextend = 1'b1;
|
imm_signextend = 1'b1;
|
|
|
// l.maci
|
// l.maci
|
`OR1200_OR32_MACI:
|
`OR1200_OR32_MACI:
|
imm_signextend = 1'b1;
|
imm_signextend = 1'b1;
|
|
|
// SFXX insns with immediate
|
// SFXX insns with immediate
|
`OR1200_OR32_SFXXI:
|
`OR1200_OR32_SFXXI:
|
imm_signextend = 1'b1;
|
imm_signextend = 1'b1;
|
|
|
// Instructions with no or zero extended immediate
|
// Instructions with no or zero extended immediate
|
default: begin
|
default: begin
|
imm_signextend = 1'b0;
|
imm_signextend = 1'b0;
|
end
|
end
|
|
|
endcase
|
endcase
|
|
|
end
|
end
|
|
|
//
|
//
|
// LSU addr offset
|
// LSU addr offset
|
//
|
//
|
always @(lsu_op or ex_insn) begin
|
always @(lsu_op or ex_insn) begin
|
lsu_addrofs[10:0] = ex_insn[10:0];
|
lsu_addrofs[10:0] = ex_insn[10:0];
|
case(lsu_op) // synopsys parallel_case
|
case(lsu_op) // synopsys parallel_case
|
`OR1200_LSUOP_SW, `OR1200_LSUOP_SH, `OR1200_LSUOP_SB :
|
`OR1200_LSUOP_SW, `OR1200_LSUOP_SH, `OR1200_LSUOP_SB :
|
lsu_addrofs[31:11] = {{16{ex_insn[25]}}, ex_insn[25:21]};
|
lsu_addrofs[31:11] = {{16{ex_insn[25]}}, ex_insn[25:21]};
|
default :
|
default :
|
lsu_addrofs[31:11] = {{16{ex_insn[15]}}, ex_insn[15:11]};
|
lsu_addrofs[31:11] = {{16{ex_insn[15]}}, ex_insn[15:11]};
|
endcase
|
endcase
|
end
|
end
|
|
|
//
|
//
|
// Register file write address
|
// Register file write address
|
//
|
//
|
always @(posedge clk or posedge rst) begin
|
always @(posedge clk or posedge rst) begin
|
if (rst)
|
if (rst)
|
rf_addrw <= #1 5'd0;
|
rf_addrw <= #1 5'd0;
|
else if (!ex_freeze & id_freeze)
|
else if (!ex_freeze & id_freeze)
|
rf_addrw <= #1 5'd00;
|
rf_addrw <= #1 5'd00;
|
else if (!ex_freeze)
|
else if (!ex_freeze)
|
case (pre_branch_op) // synopsys parallel_case
|
case (pre_branch_op) // synopsys parallel_case
|
`OR1200_BRANCHOP_JR, `OR1200_BRANCHOP_BAL:
|
`OR1200_BRANCHOP_JR, `OR1200_BRANCHOP_BAL:
|
rf_addrw <= #1 5'd09; // link register r9
|
rf_addrw <= #1 5'd09; // link register r9
|
default:
|
default:
|
rf_addrw <= #1 id_insn[25:21];
|
rf_addrw <= #1 id_insn[25:21];
|
endcase
|
endcase
|
end
|
end
|
|
|
//
|
//
|
// rf_addrw in wb stage (used in forwarding logic)
|
// rf_addrw in wb stage (used in forwarding logic)
|
//
|
//
|
always @(posedge clk or posedge rst) begin
|
always @(posedge clk or posedge rst) begin
|
if (rst)
|
if (rst)
|
wb_rfaddrw <= #1 5'd0;
|
wb_rfaddrw <= #1 5'd0;
|
else if (!wb_freeze)
|
else if (!wb_freeze)
|
wb_rfaddrw <= #1 rf_addrw;
|
wb_rfaddrw <= #1 rf_addrw;
|
end
|
end
|
|
|
//
|
//
|
// Instruction latch in id_insn
|
// Instruction latch in id_insn
|
//
|
//
|
always @(posedge clk or posedge rst) begin
|
always @(posedge clk or posedge rst) begin
|
if (rst)
|
if (rst)
|
id_insn <= #1 {`OR1200_OR32_NOP, 26'h041_0000};
|
id_insn <= #1 {`OR1200_OR32_NOP, 26'h041_0000};
|
else if (flushpipe)
|
else if (flushpipe)
|
id_insn <= #1 {`OR1200_OR32_NOP, 26'h041_0000}; // id_insn[16] must be 1
|
id_insn <= #1 {`OR1200_OR32_NOP, 26'h041_0000}; // id_insn[16] must be 1
|
else if (!id_freeze) begin
|
else if (!id_freeze) begin
|
id_insn <= #1 if_insn;
|
id_insn <= #1 if_insn;
|
`ifdef OR1200_VERBOSE
|
`ifdef OR1200_VERBOSE
|
// synopsys translate_off
|
// synopsys translate_off
|
$display("%t: id_insn <= %h", $time, if_insn);
|
$display("%t: id_insn <= %h", $time, if_insn);
|
// synopsys translate_on
|
// synopsys translate_on
|
`endif
|
`endif
|
end
|
end
|
end
|
end
|
|
|
//
|
//
|
// Instruction latch in ex_insn
|
// Instruction latch in ex_insn
|
//
|
//
|
always @(posedge clk or posedge rst) begin
|
always @(posedge clk or posedge rst) begin
|
if (rst)
|
if (rst)
|
ex_insn <= #1 {`OR1200_OR32_NOP, 26'h041_0000};
|
ex_insn <= #1 {`OR1200_OR32_NOP, 26'h041_0000};
|
else if (!ex_freeze & id_freeze | flushpipe)
|
else if (!ex_freeze & id_freeze | flushpipe)
|
ex_insn <= #1 {`OR1200_OR32_NOP, 26'h041_0000}; // ex_insn[16] must be 1
|
ex_insn <= #1 {`OR1200_OR32_NOP, 26'h041_0000}; // ex_insn[16] must be 1
|
else if (!ex_freeze) begin
|
else if (!ex_freeze) begin
|
ex_insn <= #1 id_insn;
|
ex_insn <= #1 id_insn;
|
`ifdef OR1200_VERBOSE
|
`ifdef OR1200_VERBOSE
|
// synopsys translate_off
|
// synopsys translate_off
|
$display("%t: ex_insn <= %h", $time, id_insn);
|
$display("%t: ex_insn <= %h", $time, id_insn);
|
// synopsys translate_on
|
// synopsys translate_on
|
`endif
|
`endif
|
end
|
end
|
end
|
end
|
|
|
//
|
//
|
// Instruction latch in wb_insn
|
// Instruction latch in wb_insn
|
//
|
//
|
always @(posedge clk or posedge rst) begin
|
always @(posedge clk or posedge rst) begin
|
if (rst)
|
if (rst)
|
wb_insn <= #1 {`OR1200_OR32_NOP, 26'h041_0000};
|
wb_insn <= #1 {`OR1200_OR32_NOP, 26'h041_0000};
|
else if (flushpipe)
|
else if (flushpipe)
|
wb_insn <= #1 {`OR1200_OR32_NOP, 26'h041_0000}; // wb_insn[16] must be 1
|
wb_insn <= #1 {`OR1200_OR32_NOP, 26'h041_0000}; // wb_insn[16] must be 1
|
else if (!wb_freeze) begin
|
else if (!wb_freeze) begin
|
wb_insn <= #1 ex_insn;
|
wb_insn <= #1 ex_insn;
|
end
|
end
|
end
|
end
|
|
|
//
|
//
|
// Decode of sel_imm
|
// Decode of sel_imm
|
//
|
//
|
always @(posedge clk or posedge rst) begin
|
always @(posedge clk or posedge rst) begin
|
if (rst)
|
if (rst)
|
sel_imm <= #1 1'b0;
|
sel_imm <= #1 1'b0;
|
else if (!id_freeze) begin
|
else if (!id_freeze) begin
|
case (if_insn[31:26]) // synopsys parallel_case
|
case (if_insn[31:26]) // synopsys parallel_case
|
|
|
// j.jalr
|
// j.jalr
|
`OR1200_OR32_JALR:
|
`OR1200_OR32_JALR:
|
sel_imm <= #1 1'b0;
|
sel_imm <= #1 1'b0;
|
|
|
// l.jr
|
// l.jr
|
`OR1200_OR32_JR:
|
`OR1200_OR32_JR:
|
sel_imm <= #1 1'b0;
|
sel_imm <= #1 1'b0;
|
|
|
// l.rfe
|
// l.rfe
|
`OR1200_OR32_RFE:
|
`OR1200_OR32_RFE:
|
sel_imm <= #1 1'b0;
|
sel_imm <= #1 1'b0;
|
|
|
// l.mfspr
|
// l.mfspr
|
`OR1200_OR32_MFSPR:
|
`OR1200_OR32_MFSPR:
|
sel_imm <= #1 1'b0;
|
sel_imm <= #1 1'b0;
|
|
|
// l.mtspr
|
// l.mtspr
|
`OR1200_OR32_MTSPR:
|
`OR1200_OR32_MTSPR:
|
sel_imm <= #1 1'b0;
|
sel_imm <= #1 1'b0;
|
|
|
// l.sys, l.brk and all three sync insns
|
// l.sys, l.brk and all three sync insns
|
`OR1200_OR32_XSYNC:
|
`OR1200_OR32_XSYNC:
|
sel_imm <= #1 1'b0;
|
sel_imm <= #1 1'b0;
|
|
|
// l.mac/l.msb
|
// l.mac/l.msb
|
`OR1200_OR32_MACMSB:
|
`OR1200_OR32_MACMSB:
|
sel_imm <= #1 1'b0;
|
sel_imm <= #1 1'b0;
|
|
|
// l.sw
|
// l.sw
|
`OR1200_OR32_SW:
|
`OR1200_OR32_SW:
|
sel_imm <= #1 1'b0;
|
sel_imm <= #1 1'b0;
|
|
|
// l.sb
|
// l.sb
|
`OR1200_OR32_SB:
|
`OR1200_OR32_SB:
|
sel_imm <= #1 1'b0;
|
sel_imm <= #1 1'b0;
|
|
|
// l.sh
|
// l.sh
|
`OR1200_OR32_SH:
|
`OR1200_OR32_SH:
|
sel_imm <= #1 1'b0;
|
sel_imm <= #1 1'b0;
|
|
|
// ALU instructions except the one with immediate
|
// ALU instructions except the one with immediate
|
`OR1200_OR32_ALU:
|
`OR1200_OR32_ALU:
|
sel_imm <= #1 1'b0;
|
sel_imm <= #1 1'b0;
|
|
|
// SFXX instructions
|
// SFXX instructions
|
`OR1200_OR32_SFXX:
|
`OR1200_OR32_SFXX:
|
sel_imm <= #1 1'b0;
|
sel_imm <= #1 1'b0;
|
|
|
// l.nop
|
// l.nop
|
`OR1200_OR32_NOP:
|
`OR1200_OR32_NOP:
|
sel_imm <= #1 1'b0;
|
sel_imm <= #1 1'b0;
|
|
|
// All instructions with immediates
|
// All instructions with immediates
|
default: begin
|
default: begin
|
sel_imm <= #1 1'b1;
|
sel_imm <= #1 1'b1;
|
end
|
end
|
|
|
endcase
|
endcase
|
|
|
end
|
end
|
end
|
end
|
|
|
//
|
//
|
// Decode of except_illegal
|
// Decode of except_illegal
|
//
|
//
|
always @(posedge clk or posedge rst) begin
|
always @(posedge clk or posedge rst) begin
|
if (rst)
|
if (rst)
|
except_illegal <= #1 1'b0;
|
except_illegal <= #1 1'b0;
|
else if (!ex_freeze & id_freeze | flushpipe)
|
else if (!ex_freeze & id_freeze | flushpipe)
|
except_illegal <= #1 1'b0;
|
except_illegal <= #1 1'b0;
|
else if (!ex_freeze) begin
|
else if (!ex_freeze) begin
|
case (id_insn[31:26]) // synopsys parallel_case
|
case (id_insn[31:26]) // synopsys parallel_case
|
|
|
`OR1200_OR32_J,
|
`OR1200_OR32_J,
|
`OR1200_OR32_JAL,
|
`OR1200_OR32_JAL,
|
`OR1200_OR32_JALR,
|
`OR1200_OR32_JALR,
|
`OR1200_OR32_JR,
|
`OR1200_OR32_JR,
|
`OR1200_OR32_BNF,
|
`OR1200_OR32_BNF,
|
`OR1200_OR32_BF,
|
`OR1200_OR32_BF,
|
`OR1200_OR32_RFE,
|
`OR1200_OR32_RFE,
|
`OR1200_OR32_MOVHI,
|
`OR1200_OR32_MOVHI,
|
`OR1200_OR32_MFSPR,
|
`OR1200_OR32_MFSPR,
|
`OR1200_OR32_XSYNC,
|
`OR1200_OR32_XSYNC,
|
`OR1200_OR32_MACI,
|
`OR1200_OR32_MACI,
|
`OR1200_OR32_LWZ,
|
`OR1200_OR32_LWZ,
|
`OR1200_OR32_LBZ,
|
`OR1200_OR32_LBZ,
|
`OR1200_OR32_LBS,
|
`OR1200_OR32_LBS,
|
`OR1200_OR32_LHZ,
|
`OR1200_OR32_LHZ,
|
`OR1200_OR32_LHS,
|
`OR1200_OR32_LHS,
|
`OR1200_OR32_ADDI,
|
`OR1200_OR32_ADDI,
|
`OR1200_OR32_ADDIC,
|
`OR1200_OR32_ADDIC,
|
`OR1200_OR32_ANDI,
|
`OR1200_OR32_ANDI,
|
`OR1200_OR32_ORI,
|
`OR1200_OR32_ORI,
|
`OR1200_OR32_XORI,
|
`OR1200_OR32_XORI,
|
`OR1200_OR32_MULI,
|
`OR1200_OR32_MULI,
|
`OR1200_OR32_SH_ROTI,
|
`OR1200_OR32_SH_ROTI,
|
`OR1200_OR32_SFXXI,
|
`OR1200_OR32_SFXXI,
|
`OR1200_OR32_MTSPR,
|
`OR1200_OR32_MTSPR,
|
`OR1200_OR32_MACMSB,
|
`OR1200_OR32_MACMSB,
|
`OR1200_OR32_SW,
|
`OR1200_OR32_SW,
|
`OR1200_OR32_SB,
|
`OR1200_OR32_SB,
|
`OR1200_OR32_SH,
|
`OR1200_OR32_SH,
|
`OR1200_OR32_ALU,
|
`OR1200_OR32_ALU,
|
`OR1200_OR32_SFXX,
|
`OR1200_OR32_SFXX,
|
`OR1200_OR32_NOP:
|
`OR1200_OR32_NOP:
|
except_illegal <= #1 1'b0;
|
except_illegal <= #1 1'b0;
|
|
|
// Illegal and OR1200 unsupported instructions
|
// Illegal and OR1200 unsupported instructions
|
default:
|
default:
|
except_illegal <= #1 1'b1;
|
except_illegal <= #1 1'b1;
|
|
|
endcase
|
endcase
|
|
|
end
|
end
|
end
|
end
|
|
|
//
|
//
|
// Decode of alu_op
|
// Decode of alu_op
|
//
|
//
|
always @(posedge clk or posedge rst) begin
|
always @(posedge clk or posedge rst) begin
|
if (rst)
|
if (rst)
|
alu_op <= #1 `OR1200_ALUOP_NOP;
|
alu_op <= #1 `OR1200_ALUOP_NOP;
|
else if (!ex_freeze & id_freeze | flushpipe)
|
else if (!ex_freeze & id_freeze | flushpipe)
|
alu_op <= #1 `OR1200_ALUOP_NOP;
|
alu_op <= #1 `OR1200_ALUOP_NOP;
|
else if (!ex_freeze) begin
|
else if (!ex_freeze) begin
|
case (id_insn[31:26]) // synopsys parallel_case
|
case (id_insn[31:26]) // synopsys parallel_case
|
|
|
// l.j
|
// l.j
|
`OR1200_OR32_J:
|
`OR1200_OR32_J:
|
alu_op <= #1 `OR1200_ALUOP_IMM;
|
alu_op <= #1 `OR1200_ALUOP_IMM;
|
|
|
// j.jal
|
// j.jal
|
`OR1200_OR32_JAL:
|
`OR1200_OR32_JAL:
|
alu_op <= #1 `OR1200_ALUOP_IMM;
|
alu_op <= #1 `OR1200_ALUOP_IMM;
|
|
|
// l.bnf
|
// l.bnf
|
`OR1200_OR32_BNF:
|
`OR1200_OR32_BNF:
|
alu_op <= #1 `OR1200_ALUOP_NOP;
|
alu_op <= #1 `OR1200_ALUOP_NOP;
|
|
|
// l.bf
|
// l.bf
|
`OR1200_OR32_BF:
|
`OR1200_OR32_BF:
|
alu_op <= #1 `OR1200_ALUOP_NOP;
|
alu_op <= #1 `OR1200_ALUOP_NOP;
|
|
|
// l.movhi
|
// l.movhi
|
`OR1200_OR32_MOVHI:
|
`OR1200_OR32_MOVHI:
|
alu_op <= #1 `OR1200_ALUOP_MOVHI;
|
alu_op <= #1 `OR1200_ALUOP_MOVHI;
|
|
|
// l.mfspr
|
// l.mfspr
|
`OR1200_OR32_MFSPR:
|
`OR1200_OR32_MFSPR:
|
alu_op <= #1 `OR1200_ALUOP_MFSR;
|
alu_op <= #1 `OR1200_ALUOP_MFSR;
|
|
|
// l.mtspr
|
// l.mtspr
|
`OR1200_OR32_MTSPR:
|
`OR1200_OR32_MTSPR:
|
alu_op <= #1 `OR1200_ALUOP_MTSR;
|
alu_op <= #1 `OR1200_ALUOP_MTSR;
|
|
|
// l.addi
|
// l.addi
|
`OR1200_OR32_ADDI:
|
`OR1200_OR32_ADDI:
|
alu_op <= #1 `OR1200_ALUOP_ADD;
|
alu_op <= #1 `OR1200_ALUOP_ADD;
|
|
|
// l.addic
|
// l.addic
|
`OR1200_OR32_ADDIC:
|
`OR1200_OR32_ADDIC:
|
alu_op <= #1 `OR1200_ALUOP_ADD;
|
alu_op <= #1 `OR1200_ALUOP_ADD;
|
|
|
// l.andi
|
// l.andi
|
`OR1200_OR32_ANDI:
|
`OR1200_OR32_ANDI:
|
alu_op <= #1 `OR1200_ALUOP_AND;
|
alu_op <= #1 `OR1200_ALUOP_AND;
|
|
|
// l.ori
|
// l.ori
|
`OR1200_OR32_ORI:
|
`OR1200_OR32_ORI:
|
alu_op <= #1 `OR1200_ALUOP_OR;
|
alu_op <= #1 `OR1200_ALUOP_OR;
|
|
|
// l.xori
|
// l.xori
|
`OR1200_OR32_XORI:
|
`OR1200_OR32_XORI:
|
alu_op <= #1 `OR1200_ALUOP_XOR;
|
alu_op <= #1 `OR1200_ALUOP_XOR;
|
|
|
// l.muli
|
// l.muli
|
`OR1200_OR32_MULI:
|
`OR1200_OR32_MULI:
|
alu_op <= #1 `OR1200_ALUOP_MUL;
|
alu_op <= #1 `OR1200_ALUOP_MUL;
|
|
|
// Shift and rotate insns with immediate
|
// Shift and rotate insns with immediate
|
`OR1200_OR32_SH_ROTI:
|
`OR1200_OR32_SH_ROTI:
|
alu_op <= #1 `OR1200_ALUOP_SHROT;
|
alu_op <= #1 `OR1200_ALUOP_SHROT;
|
|
|
// SFXX insns with immediate
|
// SFXX insns with immediate
|
`OR1200_OR32_SFXXI:
|
`OR1200_OR32_SFXXI:
|
alu_op <= #1 `OR1200_ALUOP_COMP;
|
alu_op <= #1 `OR1200_ALUOP_COMP;
|
|
|
// ALU instructions except the one with immediate
|
// ALU instructions except the one with immediate
|
`OR1200_OR32_ALU:
|
`OR1200_OR32_ALU:
|
alu_op <= #1 id_insn[3:0];
|
alu_op <= #1 id_insn[3:0];
|
|
|
// SFXX instructions
|
// SFXX instructions
|
`OR1200_OR32_SFXX:
|
`OR1200_OR32_SFXX:
|
alu_op <= #1 `OR1200_ALUOP_COMP;
|
alu_op <= #1 `OR1200_ALUOP_COMP;
|
|
|
// Default
|
// Default
|
default: begin
|
default: begin
|
alu_op <= #1 `OR1200_ALUOP_NOP;
|
alu_op <= #1 `OR1200_ALUOP_NOP;
|
end
|
end
|
|
|
endcase
|
endcase
|
|
|
end
|
end
|
end
|
end
|
|
|
//
|
//
|
// Decode of mac_op
|
// Decode of mac_op
|
//
|
//
|
always @(posedge clk or posedge rst) begin
|
always @(posedge clk or posedge rst) begin
|
if (rst)
|
if (rst)
|
mac_op <= #1 `OR1200_MACOP_NOP;
|
mac_op <= #1 `OR1200_MACOP_NOP;
|
else if (!ex_freeze & id_freeze | flushpipe)
|
else if (!ex_freeze & id_freeze | flushpipe)
|
mac_op <= #1 `OR1200_MACOP_NOP;
|
mac_op <= #1 `OR1200_MACOP_NOP;
|
else if (!ex_freeze)
|
else if (!ex_freeze)
|
case (id_insn[31:26]) // synopsys parallel_case
|
case (id_insn[31:26]) // synopsys parallel_case
|
|
|
// l.maci
|
// l.maci
|
`OR1200_OR32_MACI:
|
`OR1200_OR32_MACI:
|
mac_op <= #1 `OR1200_MACOP_MAC;
|
mac_op <= #1 `OR1200_MACOP_MAC;
|
|
|
// l.nop
|
// l.nop
|
`OR1200_OR32_MACMSB:
|
`OR1200_OR32_MACMSB:
|
mac_op <= #1 id_insn[1:0];
|
mac_op <= #1 id_insn[1:0];
|
|
|
// Illegal and OR1200 unsupported instructions
|
// Illegal and OR1200 unsupported instructions
|
default: begin
|
default: begin
|
mac_op <= #1 `OR1200_MACOP_NOP;
|
mac_op <= #1 `OR1200_MACOP_NOP;
|
end
|
end
|
|
|
endcase
|
endcase
|
else
|
else
|
mac_op <= #1 `OR1200_MACOP_NOP;
|
mac_op <= #1 `OR1200_MACOP_NOP;
|
end
|
end
|
|
|
//
|
//
|
// Decode of shrot_op
|
// Decode of shrot_op
|
//
|
//
|
always @(posedge clk or posedge rst) begin
|
always @(posedge clk or posedge rst) begin
|
if (rst)
|
if (rst)
|
shrot_op <= #1 `OR1200_SHROTOP_NOP;
|
shrot_op <= #1 `OR1200_SHROTOP_NOP;
|
else if (!ex_freeze & id_freeze | flushpipe)
|
else if (!ex_freeze & id_freeze | flushpipe)
|
shrot_op <= #1 `OR1200_SHROTOP_NOP;
|
shrot_op <= #1 `OR1200_SHROTOP_NOP;
|
else if (!ex_freeze) begin
|
else if (!ex_freeze) begin
|
shrot_op <= #1 id_insn[`OR1200_SHROTOP_POS];
|
shrot_op <= #1 id_insn[`OR1200_SHROTOP_POS];
|
end
|
end
|
end
|
end
|
|
|
//
|
//
|
// Decode of rfwb_op
|
// Decode of rfwb_op
|
//
|
//
|
always @(posedge clk or posedge rst) begin
|
always @(posedge clk or posedge rst) begin
|
if (rst)
|
if (rst)
|
rfwb_op <= #1 `OR1200_RFWBOP_NOP;
|
rfwb_op <= #1 `OR1200_RFWBOP_NOP;
|
else if (!ex_freeze & id_freeze | flushpipe)
|
else if (!ex_freeze & id_freeze | flushpipe)
|
rfwb_op <= #1 `OR1200_RFWBOP_NOP;
|
rfwb_op <= #1 `OR1200_RFWBOP_NOP;
|
else if (!ex_freeze) begin
|
else if (!ex_freeze) begin
|
case (id_insn[31:26]) // synopsys parallel_case
|
case (id_insn[31:26]) // synopsys parallel_case
|
|
|
// j.jal
|
// j.jal
|
`OR1200_OR32_JAL:
|
`OR1200_OR32_JAL:
|
rfwb_op <= #1 `OR1200_RFWBOP_LR;
|
rfwb_op <= #1 `OR1200_RFWBOP_LR;
|
|
|
// j.jalr
|
// j.jalr
|
`OR1200_OR32_JALR:
|
`OR1200_OR32_JALR:
|
rfwb_op <= #1 `OR1200_RFWBOP_LR;
|
rfwb_op <= #1 `OR1200_RFWBOP_LR;
|
|
|
// l.movhi
|
// l.movhi
|
`OR1200_OR32_MOVHI:
|
`OR1200_OR32_MOVHI:
|
rfwb_op <= #1 `OR1200_RFWBOP_ALU;
|
rfwb_op <= #1 `OR1200_RFWBOP_ALU;
|
|
|
// l.mfspr
|
// l.mfspr
|
`OR1200_OR32_MFSPR:
|
`OR1200_OR32_MFSPR:
|
rfwb_op <= #1 `OR1200_RFWBOP_SPRS;
|
rfwb_op <= #1 `OR1200_RFWBOP_SPRS;
|
|
|
// l.lwz
|
// l.lwz
|
`OR1200_OR32_LWZ:
|
`OR1200_OR32_LWZ:
|
rfwb_op <= #1 `OR1200_RFWBOP_LSU;
|
rfwb_op <= #1 `OR1200_RFWBOP_LSU;
|
|
|
// l.lbz
|
// l.lbz
|
`OR1200_OR32_LBZ:
|
`OR1200_OR32_LBZ:
|
rfwb_op <= #1 `OR1200_RFWBOP_LSU;
|
rfwb_op <= #1 `OR1200_RFWBOP_LSU;
|
|
|
// l.lbs
|
// l.lbs
|
`OR1200_OR32_LBS:
|
`OR1200_OR32_LBS:
|
rfwb_op <= #1 `OR1200_RFWBOP_LSU;
|
rfwb_op <= #1 `OR1200_RFWBOP_LSU;
|
|
|
// l.lhz
|
// l.lhz
|
`OR1200_OR32_LHZ:
|
`OR1200_OR32_LHZ:
|
rfwb_op <= #1 `OR1200_RFWBOP_LSU;
|
rfwb_op <= #1 `OR1200_RFWBOP_LSU;
|
|
|
// l.lhs
|
// l.lhs
|
`OR1200_OR32_LHS:
|
`OR1200_OR32_LHS:
|
rfwb_op <= #1 `OR1200_RFWBOP_LSU;
|
rfwb_op <= #1 `OR1200_RFWBOP_LSU;
|
|
|
// l.addi
|
// l.addi
|
`OR1200_OR32_ADDI:
|
`OR1200_OR32_ADDI:
|
rfwb_op <= #1 `OR1200_RFWBOP_ALU;
|
rfwb_op <= #1 `OR1200_RFWBOP_ALU;
|
|
|
// l.addic
|
// l.addic
|
`OR1200_OR32_ADDIC:
|
`OR1200_OR32_ADDIC:
|
rfwb_op <= #1 `OR1200_RFWBOP_ALU;
|
rfwb_op <= #1 `OR1200_RFWBOP_ALU;
|
|
|
// l.andi
|
// l.andi
|
`OR1200_OR32_ANDI:
|
`OR1200_OR32_ANDI:
|
rfwb_op <= #1 `OR1200_RFWBOP_ALU;
|
rfwb_op <= #1 `OR1200_RFWBOP_ALU;
|
|
|
// l.ori
|
// l.ori
|
`OR1200_OR32_ORI:
|
`OR1200_OR32_ORI:
|
rfwb_op <= #1 `OR1200_RFWBOP_ALU;
|
rfwb_op <= #1 `OR1200_RFWBOP_ALU;
|
|
|
// l.xori
|
// l.xori
|
`OR1200_OR32_XORI:
|
`OR1200_OR32_XORI:
|
rfwb_op <= #1 `OR1200_RFWBOP_ALU;
|
rfwb_op <= #1 `OR1200_RFWBOP_ALU;
|
|
|
// l.muli
|
// l.muli
|
`OR1200_OR32_MULI:
|
`OR1200_OR32_MULI:
|
rfwb_op <= #1 `OR1200_RFWBOP_ALU;
|
rfwb_op <= #1 `OR1200_RFWBOP_ALU;
|
|
|
// Shift and rotate insns with immediate
|
// Shift and rotate insns with immediate
|
`OR1200_OR32_SH_ROTI:
|
`OR1200_OR32_SH_ROTI:
|
rfwb_op <= #1 `OR1200_RFWBOP_ALU;
|
rfwb_op <= #1 `OR1200_RFWBOP_ALU;
|
|
|
// ALU instructions except the one with immediate
|
// ALU instructions except the one with immediate
|
`OR1200_OR32_ALU:
|
`OR1200_OR32_ALU:
|
rfwb_op <= #1 `OR1200_RFWBOP_ALU;
|
rfwb_op <= #1 `OR1200_RFWBOP_ALU;
|
|
|
// Instructions w/o register-file write-back
|
// Instructions w/o register-file write-back
|
default: begin
|
default: begin
|
rfwb_op <= #1 `OR1200_RFWBOP_NOP;
|
rfwb_op <= #1 `OR1200_RFWBOP_NOP;
|
end
|
end
|
|
|
endcase
|
endcase
|
end
|
end
|
end
|
end
|
|
|
//
|
//
|
// Decode of pre_branch_op
|
// Decode of pre_branch_op
|
//
|
//
|
always @(posedge clk or posedge rst) begin
|
always @(posedge clk or posedge rst) begin
|
if (rst)
|
if (rst)
|
pre_branch_op <= #1 `OR1200_BRANCHOP_NOP;
|
pre_branch_op <= #1 `OR1200_BRANCHOP_NOP;
|
else if (flushpipe)
|
else if (flushpipe)
|
pre_branch_op <= #1 `OR1200_BRANCHOP_NOP;
|
pre_branch_op <= #1 `OR1200_BRANCHOP_NOP;
|
else if (!id_freeze) begin
|
else if (!id_freeze) begin
|
case (if_insn[31:26]) // synopsys parallel_case
|
case (if_insn[31:26]) // synopsys parallel_case
|
|
|
// l.j
|
// l.j
|
`OR1200_OR32_J:
|
`OR1200_OR32_J:
|
pre_branch_op <= #1 `OR1200_BRANCHOP_BAL;
|
pre_branch_op <= #1 `OR1200_BRANCHOP_BAL;
|
|
|
// j.jal
|
// j.jal
|
`OR1200_OR32_JAL:
|
`OR1200_OR32_JAL:
|
pre_branch_op <= #1 `OR1200_BRANCHOP_BAL;
|
pre_branch_op <= #1 `OR1200_BRANCHOP_BAL;
|
|
|
// j.jalr
|
// j.jalr
|
`OR1200_OR32_JALR:
|
`OR1200_OR32_JALR:
|
pre_branch_op <= #1 `OR1200_BRANCHOP_JR;
|
pre_branch_op <= #1 `OR1200_BRANCHOP_JR;
|
|
|
// l.jr
|
// l.jr
|
`OR1200_OR32_JR:
|
`OR1200_OR32_JR:
|
pre_branch_op <= #1 `OR1200_BRANCHOP_JR;
|
pre_branch_op <= #1 `OR1200_BRANCHOP_JR;
|
|
|
// l.bnf
|
// l.bnf
|
`OR1200_OR32_BNF:
|
`OR1200_OR32_BNF:
|
pre_branch_op <= #1 `OR1200_BRANCHOP_BNF;
|
pre_branch_op <= #1 `OR1200_BRANCHOP_BNF;
|
|
|
// l.bf
|
// l.bf
|
`OR1200_OR32_BF:
|
`OR1200_OR32_BF:
|
pre_branch_op <= #1 `OR1200_BRANCHOP_BF;
|
pre_branch_op <= #1 `OR1200_BRANCHOP_BF;
|
|
|
// l.rfe
|
// l.rfe
|
`OR1200_OR32_RFE:
|
`OR1200_OR32_RFE:
|
pre_branch_op <= #1 `OR1200_BRANCHOP_RFE;
|
pre_branch_op <= #1 `OR1200_BRANCHOP_RFE;
|
|
|
// Non branch instructions
|
// Non branch instructions
|
default: begin
|
default: begin
|
pre_branch_op <= #1 `OR1200_BRANCHOP_NOP;
|
pre_branch_op <= #1 `OR1200_BRANCHOP_NOP;
|
end
|
end
|
endcase
|
endcase
|
end
|
end
|
end
|
end
|
|
|
//
|
//
|
// Generation of branch_op
|
// Generation of branch_op
|
//
|
//
|
always @(posedge clk or posedge rst)
|
always @(posedge clk or posedge rst)
|
if (rst)
|
if (rst)
|
branch_op <= #1 `OR1200_BRANCHOP_NOP;
|
branch_op <= #1 `OR1200_BRANCHOP_NOP;
|
else if (!ex_freeze & id_freeze | flushpipe)
|
else if (!ex_freeze & id_freeze | flushpipe)
|
branch_op <= #1 `OR1200_BRANCHOP_NOP;
|
branch_op <= #1 `OR1200_BRANCHOP_NOP;
|
else if (!ex_freeze)
|
else if (!ex_freeze)
|
branch_op <= #1 pre_branch_op;
|
branch_op <= #1 pre_branch_op;
|
|
|
//
|
//
|
// Decode of lsu_op
|
// Decode of lsu_op
|
//
|
//
|
always @(posedge clk or posedge rst) begin
|
always @(posedge clk or posedge rst) begin
|
if (rst)
|
if (rst)
|
lsu_op <= #1 `OR1200_LSUOP_NOP;
|
lsu_op <= #1 `OR1200_LSUOP_NOP;
|
else if (!ex_freeze & id_freeze | flushpipe)
|
else if (!ex_freeze & id_freeze | flushpipe)
|
lsu_op <= #1 `OR1200_LSUOP_NOP;
|
lsu_op <= #1 `OR1200_LSUOP_NOP;
|
else if (!ex_freeze) begin
|
else if (!ex_freeze) begin
|
case (id_insn[31:26]) // synopsys parallel_case
|
case (id_insn[31:26]) // synopsys parallel_case
|
|
|
// l.lwz
|
// l.lwz
|
`OR1200_OR32_LWZ:
|
`OR1200_OR32_LWZ:
|
lsu_op <= #1 `OR1200_LSUOP_LWZ;
|
lsu_op <= #1 `OR1200_LSUOP_LWZ;
|
|
|
// l.lbz
|
// l.lbz
|
`OR1200_OR32_LBZ:
|
`OR1200_OR32_LBZ:
|
lsu_op <= #1 `OR1200_LSUOP_LBZ;
|
lsu_op <= #1 `OR1200_LSUOP_LBZ;
|
|
|
// l.lbs
|
// l.lbs
|
`OR1200_OR32_LBS:
|
`OR1200_OR32_LBS:
|
lsu_op <= #1 `OR1200_LSUOP_LBS;
|
lsu_op <= #1 `OR1200_LSUOP_LBS;
|
|
|
// l.lhz
|
// l.lhz
|
`OR1200_OR32_LHZ:
|
`OR1200_OR32_LHZ:
|
lsu_op <= #1 `OR1200_LSUOP_LHZ;
|
lsu_op <= #1 `OR1200_LSUOP_LHZ;
|
|
|
// l.lhs
|
// l.lhs
|
`OR1200_OR32_LHS:
|
`OR1200_OR32_LHS:
|
lsu_op <= #1 `OR1200_LSUOP_LHS;
|
lsu_op <= #1 `OR1200_LSUOP_LHS;
|
|
|
// l.sw
|
// l.sw
|
`OR1200_OR32_SW:
|
`OR1200_OR32_SW:
|
lsu_op <= #1 `OR1200_LSUOP_SW;
|
lsu_op <= #1 `OR1200_LSUOP_SW;
|
|
|
// l.sb
|
// l.sb
|
`OR1200_OR32_SB:
|
`OR1200_OR32_SB:
|
lsu_op <= #1 `OR1200_LSUOP_SB;
|
lsu_op <= #1 `OR1200_LSUOP_SB;
|
|
|
// l.sh
|
// l.sh
|
`OR1200_OR32_SH:
|
`OR1200_OR32_SH:
|
lsu_op <= #1 `OR1200_LSUOP_SH;
|
lsu_op <= #1 `OR1200_LSUOP_SH;
|
|
|
// Non load/store instructions
|
// Non load/store instructions
|
default: begin
|
default: begin
|
lsu_op <= #1 `OR1200_LSUOP_NOP;
|
lsu_op <= #1 `OR1200_LSUOP_NOP;
|
end
|
end
|
endcase
|
endcase
|
end
|
end
|
end
|
end
|
|
|
//
|
//
|
// Decode of comp_op
|
// Decode of comp_op
|
//
|
//
|
always @(posedge clk or posedge rst) begin
|
always @(posedge clk or posedge rst) begin
|
if (rst) begin
|
if (rst) begin
|
comp_op <= #1 4'd0;
|
comp_op <= #1 4'd0;
|
end else if (!ex_freeze & id_freeze | flushpipe)
|
end else if (!ex_freeze & id_freeze | flushpipe)
|
comp_op <= #1 4'd0;
|
comp_op <= #1 4'd0;
|
else if (!ex_freeze)
|
else if (!ex_freeze)
|
comp_op <= #1 id_insn[24:21];
|
comp_op <= #1 id_insn[24:21];
|
end
|
end
|
|
|
//
|
//
|
// Decode of l.sys
|
// Decode of l.sys
|
//
|
//
|
always @(posedge clk or posedge rst) begin
|
always @(posedge clk or posedge rst) begin
|
if (rst)
|
if (rst)
|
sig_syscall <= #1 1'b0;
|
sig_syscall <= #1 1'b0;
|
else if (!ex_freeze & id_freeze | flushpipe)
|
else if (!ex_freeze & id_freeze | flushpipe)
|
sig_syscall <= #1 1'b0;
|
sig_syscall <= #1 1'b0;
|
else if (!ex_freeze) begin
|
else if (!ex_freeze) begin
|
`ifdef OR1200_VERBOSE
|
`ifdef OR1200_VERBOSE
|
// synopsys translate_off
|
// synopsys translate_off
|
if (id_insn[31:23] == {`OR1200_OR32_XSYNC, 3'b000})
|
if (id_insn[31:23] == {`OR1200_OR32_XSYNC, 3'b000})
|
$display("Generating sig_syscall");
|
$display("Generating sig_syscall");
|
// synopsys translate_on
|
// synopsys translate_on
|
`endif
|
`endif
|
sig_syscall <= #1 (id_insn[31:23] == {`OR1200_OR32_XSYNC, 3'b000});
|
sig_syscall <= #1 (id_insn[31:23] == {`OR1200_OR32_XSYNC, 3'b000});
|
end
|
end
|
end
|
end
|
|
|
//
|
//
|
// Decode of l.trap
|
// Decode of l.trap
|
//
|
//
|
always @(posedge clk or posedge rst) begin
|
always @(posedge clk or posedge rst) begin
|
if (rst)
|
if (rst)
|
sig_trap <= #1 1'b0;
|
sig_trap <= #1 1'b0;
|
else if (!ex_freeze & id_freeze | flushpipe)
|
else if (!ex_freeze & id_freeze | flushpipe)
|
sig_trap <= #1 1'b0;
|
sig_trap <= #1 1'b0;
|
else if (!ex_freeze) begin
|
else if (!ex_freeze) begin
|
`ifdef OR1200_VERBOSE
|
`ifdef OR1200_VERBOSE
|
// synopsys translate_off
|
// synopsys translate_off
|
if (id_insn[31:23] == {`OR1200_OR32_XSYNC, 3'b010})
|
if (id_insn[31:23] == {`OR1200_OR32_XSYNC, 3'b010})
|
$display("Generating sig_trap");
|
$display("Generating sig_trap");
|
// synopsys translate_on
|
// synopsys translate_on
|
`endif
|
`endif
|
sig_trap <= #1 (id_insn[31:23] == {`OR1200_OR32_XSYNC, 3'b010});
|
sig_trap <= #1 (id_insn[31:23] == {`OR1200_OR32_XSYNC, 3'b010});
|
end
|
end
|
end
|
end
|
|
|
endmodule
|
endmodule
|
|
|