⭐ 欢迎来到虫虫下载站! | 📦 资源下载 📁 资源专辑 ℹ️ 关于我们
⭐ 虫虫下载站

📄 or1200_ctrl.v

📁 一个开放的risc
💻 V
📖 第 1 页 / 共 2 页
字号:
//////////////////////////////////////////////////////////////////////////                                                              ////////  OR1200's Instruction decode                                 ////////                                                              ////////  This file is part of the OpenRISC 1200 project              ////////  http://www.opencores.org/cores/or1k/                        ////////                                                              ////////  Description                                                 ////////  Majority of instruction decoding is performed here.         ////////                                                              ////////  To Do:                                                      ////////   - make it smaller and faster                               ////////                                                              ////////  Author(s):                                                  ////////      - Damjan Lampret, lampret@opencores.org                 ////////                                                              //////////////////////////////////////////////////////////////////////////////                                                              //////// Copyright (C) 2000 Authors and OPENCORES.ORG                 ////////                                                              //////// This source file may be used and distributed without         //////// restriction provided that this copyright statement is not    //////// removed from the file and that any derivative work contains  //////// the original copyright notice and the associated disclaimer. ////////                                                              //////// This source file is free software; you can redistribute it   //////// and/or modify it under the terms of the GNU Lesser General   //////// Public License as published by the Free Software Foundation; //////// either version 2.1 of the License, or (at your option) any   //////// later version.                                               ////////                                                              //////// This source is distributed in the hope that it will be       //////// useful, but WITHOUT ANY WARRANTY; without even the implied   //////// warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR      //////// PURPOSE.  See the GNU Lesser General Public License for more //////// details.                                                     ////////                                                              //////// You should have received a copy of the GNU Lesser General    //////// Public License along with this source; if not, download it   //////// from http://www.opencores.org/lgpl.shtml                     ////////                                                              ////////////////////////////////////////////////////////////////////////////// CVS Revision History//// $Log: or1200_ctrl.v,v $// Revision 1.8  2003/04/24 00:16:07  lampret// No functional changes. Added defines to disable implementation of multiplier/MAC//// Revision 1.7  2002/09/07 05:42:02  lampret// Added optional SR[CY]. Added define to enable additional (compare) flag modifiers. Defines are OR1200_IMPL_ADDC and OR1200_ADDITIONAL_FLAG_MODIFIERS.//// Revision 1.6  2002/03/29 15:16:54  lampret// Some of the warnings fixed.//// Revision 1.5  2002/02/01 19:56:54  lampret// Fixed combinational loops.//// 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.//// Revision 1.3  2002/01/18 14:21:43  lampret// Fixed 'the NPC single-step fix'.//// 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.14  2001/11/30 18:59:17  simons// force_dslot_fetch does not work -  allways zero.//// Revision 1.13  2001/11/20 18:46:15  simons// Break point bug fixed//// Revision 1.12  2001/11/18 08:36:28  lampret// For GDB changed single stepping and disabled trap exception.//// Revision 1.11  2001/11/13 10:02:21  lampret// Added 'setpc'. Renamed some signals (except_flushpipe into flushpipe etc)//// 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.//// 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:09  lampret// MP3 version.//// Revision 1.1.1.1  2001/10/06 10:18:36  igorm// no message//// Revision 1.2  2001/08/13 03:36:20  lampret// Added cfg regs. Moved all defines into one defines.v file. More cleanup.//// Revision 1.1  2001/08/09 13:39:33  lampret// Major clean-up.////// synopsys translate_off`include "timescale.v"// synopsys translate_on`include "or1200_defines.v"module or1200_ctrl(	// Clock and reset	clk, rst,	// Internal i/f	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,	wb_insn, simm, branch_addrofs, lsu_addrofs, sel_a, sel_b, lsu_op,	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);//// I/O//input					clk;input					rst;input					id_freeze;input					ex_freeze;input					wb_freeze;input					flushpipe;input	[31:0]				if_insn;output	[31:0]				ex_insn;output	[`OR1200_BRANCHOP_WIDTH-1:0]		branch_op;input						branch_taken;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_addrb;output					rf_rda;output					rf_rdb;output	[`OR1200_ALUOP_WIDTH-1:0]		alu_op;output	[`OR1200_MACOP_WIDTH-1:0]		mac_op;output	[`OR1200_SHROTOP_WIDTH-1:0]		shrot_op;output	[`OR1200_RFWBOP_WIDTH-1:0]		rfwb_op;output	[31:0]				wb_insn;output	[31:0]				simm;output	[31:2]				branch_addrofs;output	[31:0]				lsu_addrofs;output	[`OR1200_SEL_WIDTH-1:0]		sel_a;output	[`OR1200_SEL_WIDTH-1:0]		sel_b;output	[`OR1200_LSUOP_WIDTH-1:0]		lsu_op;output	[`OR1200_COMPOP_WIDTH-1:0]		comp_op;output	[`OR1200_MULTICYCLE_WIDTH-1:0]		multicycle;output	[15:0]				spr_addrimm;input					wbforw_valid;output					sig_syscall;output					sig_trap;output					force_dslot_fetch;output					no_more_dslot;output					ex_void;output					id_macrc_op;output					ex_macrc_op;output					rfe;output					except_illegal;//// Internal wires and regs//reg	[`OR1200_BRANCHOP_WIDTH-1:0]		pre_branch_op;reg	[`OR1200_BRANCHOP_WIDTH-1:0]		branch_op;reg	[`OR1200_ALUOP_WIDTH-1:0]		alu_op;`ifdef OR1200_MAC_IMPLEMENTEDreg	[`OR1200_MACOP_WIDTH-1:0]		mac_op;reg					ex_macrc_op;`elsewire	[`OR1200_MACOP_WIDTH-1:0]		mac_op;wire					ex_macrc_op;`endifreg	[`OR1200_SHROTOP_WIDTH-1:0]		shrot_op;reg	[31:0]				id_insn;reg	[31:0]				ex_insn;reg	[31:0]				wb_insn;reg	[`OR1200_REGFILE_ADDR_WIDTH-1:0]	rf_addrw;reg	[`OR1200_REGFILE_ADDR_WIDTH-1:0]	wb_rfaddrw;reg	[`OR1200_RFWBOP_WIDTH-1:0]		rfwb_op;reg	[31:0]				lsu_addrofs;reg	[`OR1200_SEL_WIDTH-1:0]		sel_a;reg	[`OR1200_SEL_WIDTH-1:0]		sel_b;reg					sel_imm;reg	[`OR1200_LSUOP_WIDTH-1:0]		lsu_op;reg	[`OR1200_COMPOP_WIDTH-1:0]		comp_op;reg	[`OR1200_MULTICYCLE_WIDTH-1:0]		multicycle;reg					imm_signextend;reg	[15:0]				spr_addrimm;reg					sig_syscall;reg					sig_trap;reg					except_illegal;wire					id_void;//// Register file read addresses//assign rf_addra = if_insn[20:16];assign rf_addrb = if_insn[15:11];assign rf_rda = if_insn[31];assign rf_rdb = if_insn[30];//// Force fetch of delay slot instruction when jump/branch is preceeded by load/store// instructions//// SIMON// assign force_dslot_fetch = ((|pre_branch_op) & (|lsu_op));assign force_dslot_fetch = 1'b0;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 ex_void = (ex_insn[31:26] == `OR1200_OR32_NOP) & ex_insn[16];//// 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]};//// Sign extension of branch offset//assign branch_addrofs = {{4{ex_insn[25]}}, ex_insn[25:0]};//// l.macrc in ID stage//`ifdef OR1200_MAC_IMPLEMENTEDassign id_macrc_op = (id_insn[31:26] == `OR1200_OR32_MOVHI) & id_insn[16];`elseassign id_macrc_op = 1'b0;`endif//////assign rfe = (pre_branch_op == `OR1200_BRANCHOP_RFE) | (branch_op == `OR1200_BRANCHOP_RFE);//// Generation of sel_a//always @(rf_addrw or id_insn or rfwb_op or wbforw_valid or wb_rfaddrw)	if ((id_insn[20:16] == rf_addrw) && rfwb_op[0])		sel_a = `OR1200_SEL_EX_FORW;	else if ((id_insn[20:16] == wb_rfaddrw) && wbforw_valid)		sel_a = `OR1200_SEL_WB_FORW;	else		sel_a = `OR1200_SEL_RF;//// Generation of sel_b//always @(rf_addrw or sel_imm or id_insn or rfwb_op or wbforw_valid or wb_rfaddrw)	if (sel_imm)		sel_b = `OR1200_SEL_IMM;	else if ((id_insn[15:11] == rf_addrw) && rfwb_op[0])		sel_b = `OR1200_SEL_EX_FORW;	else if ((id_insn[15:11] == wb_rfaddrw) && wbforw_valid)		sel_b = `OR1200_SEL_WB_FORW;	else		sel_b = `OR1200_SEL_RF;//// l.macrc in EX stage//`ifdef OR1200_MAC_IMPLEMENTEDalways @(posedge clk or posedge rst) begin	if (rst)		ex_macrc_op <= #1 1'b0;	else if (!ex_freeze & id_freeze | flushpipe)		ex_macrc_op <= #1 1'b0;	else if (!ex_freeze)		ex_macrc_op <= #1 id_macrc_op;end`elseassign ex_macrc_op = 1'b0;`endif//// Decode of spr_addrimm//always @(posedge clk or posedge rst) begin	if (rst)		spr_addrimm <= #1 16'h0000;	else if (!ex_freeze & id_freeze | flushpipe)		spr_addrimm <= #1 16'h0000;	else if (!ex_freeze) begin		case (id_insn[31:26])	// synopsys parallel_case			// l.mfspr			`OR1200_OR32_MFSPR: 				spr_addrimm <= #1 id_insn[15:0];			// l.mtspr			default:				spr_addrimm <= #1 {id_insn[25:21], id_insn[10:0]};		endcase	endend//// Decode of multicycle//always @(id_insn) begin  case (id_insn[31:26])		// synopsys parallel_case`ifdef UNUSED    // l.lwz    `OR1200_OR32_LWZ:      multicycle = `OR1200_TWO_CYCLES;        // l.lbz    `OR1200_OR32_LBZ:      multicycle = `OR1200_TWO_CYCLES;        // l.lbs    `OR1200_OR32_LBS:      multicycle = `OR1200_TWO_CYCLES;        // l.lhz    `OR1200_OR32_LHZ:      multicycle = `OR1200_TWO_CYCLES;        // l.lhs    `OR1200_OR32_LHS:      multicycle = `OR1200_TWO_CYCLES;        // l.sw    `OR1200_OR32_SW:      multicycle = `OR1200_TWO_CYCLES;        // l.sb    `OR1200_OR32_SB:      multicycle = `OR1200_TWO_CYCLES;        // l.sh    `OR1200_OR32_SH:      multicycle = `OR1200_TWO_CYCLES;`endif        // ALU instructions except the one with immediate    `OR1200_OR32_ALU:      multicycle = id_insn[`OR1200_ALUMCYC_POS];        // Single cycle instructions    default: begin      multicycle = `OR1200_ONE_CYCLE;    end      endcase  end//// Decode of imm_signextend//always @(id_insn) begin  case (id_insn[31:26])		// synopsys parallel_case	// l.addi	`OR1200_OR32_ADDI:		imm_signextend = 1'b1;	// l.addic	`OR1200_OR32_ADDIC:		imm_signextend = 1'b1;	// l.xori	`OR1200_OR32_XORI:		imm_signextend = 1'b1;	// l.muli`ifdef OR1200_MULT_IMPLEMENTED	`OR1200_OR32_MULI:		imm_signextend = 1'b1;`endif	// l.maci`ifdef OR1200_MAC_IMPLEMENTED	`OR1200_OR32_MACI:		imm_signextend = 1'b1;`endif	// SFXX insns with immediate	`OR1200_OR32_SFXXI:		imm_signextend = 1'b1;	// Instructions with no or zero extended immediate	default: begin		imm_signextend = 1'b0;	endendcaseend//// LSU addr offset//always @(lsu_op or ex_insn) begin	lsu_addrofs[10:0] = ex_insn[10:0];	case(lsu_op)	// synopsys parallel_case		`OR1200_LSUOP_SW, `OR1200_LSUOP_SH, `OR1200_LSUOP_SB : 			lsu_addrofs[31:11] = {{16{ex_insn[25]}}, ex_insn[25:21]};		default : 			lsu_addrofs[31:11] = {{16{ex_insn[15]}}, ex_insn[15:11]};	endcaseend//// Register file write address//always @(posedge clk or posedge rst) begin	if (rst)		rf_addrw <= #1 5'd0;	else if (!ex_freeze & id_freeze)		rf_addrw <= #1 5'd00;	else if (!ex_freeze)		case (pre_branch_op)	// synopsys parallel_case			`OR1200_BRANCHOP_JR, `OR1200_BRANCHOP_BAL:				rf_addrw <= #1 5'd09;	// link register r9			default:				rf_addrw <= #1 id_insn[25:21];		endcaseend//// rf_addrw in wb stage (used in forwarding logic)//always @(posedge clk or posedge rst) begin	if (rst)		wb_rfaddrw <= #1 5'd0;	else if (!wb_freeze)		wb_rfaddrw <= #1 rf_addrw;end//// Instruction latch in id_insn//always @(posedge clk or posedge rst) begin	if (rst)		id_insn <= #1 {`OR1200_OR32_NOP, 26'h041_0000};        else if (flushpipe)                id_insn <= #1 {`OR1200_OR32_NOP, 26'h041_0000};        // id_insn[16] must be 1	else if (!id_freeze) begin		id_insn <= #1 if_insn;`ifdef OR1200_VERBOSE// synopsys translate_off		$display("%t: id_insn <= %h", $time, if_insn);// synopsys translate_on`endif	endend//// Instruction latch in ex_insn//always @(posedge clk or posedge rst) begin	if (rst)		ex_insn <= #1 {`OR1200_OR32_NOP, 26'h041_0000};	else if (!ex_freeze & id_freeze | flushpipe)		ex_insn <= #1 {`OR1200_OR32_NOP, 26'h041_0000};	// ex_insn[16] must be 1	else if (!ex_freeze) begin		ex_insn <= #1 id_insn;`ifdef OR1200_VERBOSE// synopsys translate_off		$display("%t: ex_insn <= %h", $time, id_insn);// synopsys translate_on`endif	endend//// Instruction latch in wb_insn//always @(posedge clk or posedge rst) begin	if (rst)		wb_insn <= #1 {`OR1200_OR32_NOP, 26'h041_0000};	else if (flushpipe)		wb_insn <= #1 {`OR1200_OR32_NOP, 26'h041_0000};	// wb_insn[16] must be 1	else if (!wb_freeze) begin		wb_insn <= #1 ex_insn;	endend//// Decode of sel_imm//always @(posedge clk or posedge rst) begin	if (rst)		sel_imm <= #1 1'b0;	else if (!id_freeze) begin	  case (if_insn[31:26])		// synopsys parallel_case	    // j.jalr	    `OR1200_OR32_JALR:	      sel_imm <= #1 1'b0;	    	    // l.jr	    `OR1200_OR32_JR:	      sel_imm <= #1 1'b0;	    	    // l.rfe

⌨️ 快捷键说明

复制代码 Ctrl + C
搜索代码 Ctrl + F
全屏模式 F11
切换主题 Ctrl + Shift + D
显示快捷键 ?
增大字号 Ctrl + =
减小字号 Ctrl + -