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

📄 cpu.v

📁 简单的一个8位RISC
💻 V
📖 第 1 页 / 共 2 页
字号:
module cpu (   clk,   reset,      paddr,   pdata,   portain,   portbout,   portcout,      expdin,   expdout,   expaddr,   expread,   expwrite,      debugw,   debugpc,   debuginst,   debugstatus);// Basic Core I/O.input		clk;input		reset;// Program memory interfaceoutput [10:0]	paddr;input  [11:0]	pdata;// Basic I/O Portsinput  [7:0]	portain;output [7:0]	portbout;output [7:0]	portcout;// Expansion Interfaceinput [7:0]	expdin;		// Data from expansion circuits TO the PIC Coreoutput [7:0]	expdout;	// Data to the expansion circuits FROM the PIC Coreoutput [6:0]	expaddr;	// File addressoutput		expread;	// Active high read signal (read FROM expansion circuit)output		expwrite;	// Active high write signal (write TO expansion circuit)// Debuggingoutput [7:0]	debugw;output [10:0]	debugpc;output [11:0]	debuginst;output [7:0]	debugstatus;// Register declarations for outputsreg [10:0]	paddr;reg [7:0]	portbout;reg [7:0]	portcout;reg [7:0]	expdout;reg [6:0]	expaddr;reg		expread;reg		expwrite;//// Copyright (c) 1999 Thomas Coonan (tcoonan@mindspring.com)////    This source code is free software; you can redistribute it//    and/or modify it in source code form under the terms of the GNU//    General Public License as published by the Free Software//    Foundation; either version 2 of the License, or (at your option)//    any later version.////    This program 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 General Public License for more details.////    You should have received a copy of the GNU General Public License//    along with this program; if not, write to the Free Software//    Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA//// This should be set to the ROM location where our restart vector is.// As set here, we have 512 words of program space.//parameter RESET_VECTOR = 11'h7FF;parameter	INDF_ADDRESS	= 3'h0,		TMR0_ADDRESS	= 3'h1,		PCL_ADDRESS	= 3'h2,		STATUS_ADDRESS	= 3'h3,		FSR_ADDRESS	= 3'h4,		PORTA_ADDRESS	= 3'h5,		PORTB_ADDRESS	= 3'h6,		PORTC_ADDRESS	= 3'h7;// *********  Special internal registers// Instruction Registerreg  [11:0]	inst;// Program Counterreg  [10:0]	pc, pc_in;// Stack Registers and Stack "levels" register.reg [ 1:0]	stacklevel;reg [10:0]	stack1;reg [10:0]	stack2;// W Registerreg [ 7:0]	w;// The STATUS register (#3) is 8 bits wide, however, we only currently use 2 bits// of it; the C and Z bit.//// bit 0  -  C// bit 2  -  Z//reg [ 7:0]	status;// The FSR register is the pointer register used for Indirect addressing (e.g. using INDF).reg  [ 7:0]	fsr;// Timer 0reg  [ 7:0]	tmr0;reg  [ 7:0]	prescaler;// Option Registerreg [7:0]	option;// Tristate Control registers. We do not neccessarily support bidirectional ports, but//    will save a place for these registers and the TRIS instruction.  Use for debug.reg [7:0]	trisa;reg [7:0]	trisb;reg [7:0]	trisc;// I/O Port registers//reg [7:0]	porta;	// Input PORTreg [7:0]	portb;	// Output PORTreg [7:0]	portc;	// Output PORT// ********** Instruction Related signals ******reg 		skip;  // When HI force a NOP (all zeros) into inst// Derive special sub signals from inst registerwire [ 7:0]	k;wire [ 4:0]	fsel;wire		d;wire [ 2:0]	b;// ********** File Address ************//// This is the 7-bit Data Address that includes the lower 5-bit fsel, the// FSR bits and any indirect addressing.// Use this bus to address the Register File as well as all special registers, etc.//reg [6:0]	fileaddr;// Address Selectsreg		specialsel;reg		regfilesel;reg		expsel;// ******  Instruction Decoder Outputs **************// Write enable for the actual ZERO and CARRY bits within the status register.// Generated by the Instruction Decoder.//wire [1:0]	aluasel;wire [1:0]	alubsel;wire [3:0]	aluop;wire		zwe;wire		cwe;wire		isoption;wire		istris;wire		fwe;	// High if any "register" is being written to at all.wire		wwe;	// Write Enable for the W register.  Produced by Instruction Decoder.// *************  Internal Busses, mux connections, etc.  ********************// Bit decoder bits.  reg [7:0]	bd;	// Final decoder value after any polarity inversion.reg [7:0]	bdec;	// e.g. "Bit Decoded"wire		bdpol;	// Polarity bit for the bit test operations.// Data in and out of the and out of the register file//reg [7:0]	regfilein;	// Input into Register File, is connected to the dbus.wire [7:0]	regfileout;	// Path leaving the register file, goes to SBUS Muxreg		regfilewe;	// Write Enablereg		regfilere;	// Read Enable//// The dbus (Destination Bus) comes out of the ALU.  It is available to all// writable registers.//// The sbus (Source Bus) comes from all readable registers as well as the output// of the Register File.  It is one of the primary inputs into the ALU muxes.//// The (Expansion Bus) is another potential source.  See the 'exp' signals.//reg  [7:0]	dbus;reg  [7:0]	sbus;// ALU Signals//reg  [7:0]	alua;reg  [7:0]	alub;wire [7:0]	aluout;wire		alucout;wire       	aluz;// ALU A and B mux selects.//parameter [1:0]	ALUASEL_W	= 2'b00,		ALUASEL_SBUS	= 2'b01,		ALUASEL_K	= 2'b10,		ALUASEL_BD	= 2'b11;		parameter [1:0]	ALUBSEL_W	= 2'b00,		ALUBSEL_SBUS	= 2'b01,		ALUBSEL_K	= 2'b10,		ALUBSEL_1	= 2'b11;// ALU Operation codes.//		parameter  [3:0] ALUOP_ADD  = 4'b0000;parameter  [3:0] ALUOP_SUB  = 4'b1000;parameter  [3:0] ALUOP_AND  = 4'b0001;parameter  [3:0] ALUOP_OR   = 4'b0010;parameter  [3:0] ALUOP_XOR  = 4'b0011;parameter  [3:0] ALUOP_COM  = 4'b0100;parameter  [3:0] ALUOP_ROR  = 4'b0101;parameter  [3:0] ALUOP_ROL  = 4'b0110;parameter  [3:0] ALUOP_SWAP = 4'b0111;// Instantiate each of our subcomponents//regs  regs (   .clk		(clk),    .reset	(reset),   .we  	(regfilewe),   .re		(regfilere),   .bank	(fileaddr[6:5]),    .location	(fileaddr[4:0]),   .din		(regfilein),    .dout	(regfileout));// Instatiate the ALU.//alu alu  (   .op         (aluop),    .a          (alua),    .b          (alub),   .y          (aluout),   .cin        (status[0]),    .cout       (alucout),    .zout       (aluz));// Instantiate the Instruction Decoder.  This is really just a lookup table.// Given the instruction, generate all the signals we need.  //// For example, each instruction implies a specific ALU operation.  Some of// these are obvious such as the ADDW uses an ADD alu op.  Less obvious is// that a mov instruction uses an OR op which lets us do a simple copy.// // Data has to funnel through the ALU, which sometimes makes for contrived// ALU ops.//wire		idecwwe;wire		idecfwe;wire		ideczwe;wire		ideccwe;idec idec (   .inst     (inst),   .aluasel  (aluasel),   .alubsel  (alubsel),   .aluop    (aluop),   .wwe      (idecwwe),   .fwe      (idecfwe),   .zwe      (ideczwe),   .cwe      (ideccwe),   .bdpol    (bdpol),   .option   (isoption),   .tris     (istris));// Wire decoder enables to enables in at this module.  I did this because at// one time I had another global 'enable' that was ANDed in, but I removed that.//assign wwe = idecwwe;assign fwe = idecfwe;assign zwe = ideczwe;assign cwe = ideccwe;// *********** Debug ****************assign	debugw = w;assign	debugpc = pc;assign	debuginst = inst;assign	debugstatus = status;// *********** REGISTER FILE Addressing ****************//// We implement the following://    - The 5-bit fsel address is within a "BANK" which is 32 bytes.//    - The FSR bits 6:5 are the BANK select, so there are 4 BANKS, a //      total of 128 bytes.  Minus the 8 special registers, that's //      really 120 bytes.//    - The INDF register is for indirect addressing.  Referencing INDF//      uses FSR as the pointer.  Therefore, using INDF/FSR you address//      7-bits of memory.// We DO NOT currently implement the PAGE for program (e.g. STATUS register// bits 6:5)//// The fsel address *may* be zero in which case, we are to do indirect// addressing, using FSR register as the 8-bit pointer.//// Otherwise, use the 5-bits of FSEL (from the Instruction itself) and // 2 bank bits from the FSR register (bits 6:5).//always @(fsel or fsr or status) begin   if (fsel == INDF_ADDRESS) begin      // The INDEX register is addressed.  There really is no INDEX register.      // Use the FSR as an index, e.g. the FSR contents are the fsel.      //      fileaddr = fsr[6:0];   end   else begin      // Use FSEL field and status bank select bits      //      fileaddr = {status[6:5], fsel};   endend// Write Enable to Register File.  // Assert this when the general fwe (write enable to *any* register) is true AND Register File//    address range is specified.//  always @(regfilesel or fwe)   regfilewe = regfilesel & fwe;// Read Enable (this if nothing else, helps in debug.)// Assert if Register File address range is specified AND the ALU is actually using some//    data off the SBUS.//   always @(regfilesel or aluasel or alubsel)   regfilere = regfilesel & ((aluasel == ALUASEL_SBUS) | (alubsel == ALUBSEL_SBUS));// *********** Address Decodes **************//// Generate 3 selects: specialsel, regfilesel and expsel//// ** NOTE:	Must change this whenever more or few expansion addresses are//		added or removed from the memory map.  Otherwise, the dbus mux// 		won't be controlled properly!//always @(fileaddr) begin   casex (fileaddr) // synopsys full_case parallel_case      // This shouldn't really change.      //      7'bXX00XXX: // The SPECIAL Registers are lower 8 addresses, in ALL BANKS         begin            specialsel	= 1'b1;            regfilesel	= 1'b0;            expsel	= 1'b0;         end               // Adjust this case as EXPANSION locations change!      //      7'b11111XX: // EXPANSION Registers are the top (4) addresses         begin            specialsel	= 1'b0;            regfilesel	= 1'b0;            expsel	= 1'b1;         end               // Assume everything else must be the Register File..      //      default:         begin            specialsel	= 1'b0;            regfilesel	= 1'b1;            expsel	= 1'b0;         end   endcaseend  // *********** Expansion Interface **************always @(dbus)   expdout = dbus;   always @(fileaddr)   expaddr = fileaddr;always @(expsel or aluasel or alubsel)   expread = expsel & ((aluasel == ALUASEL_SBUS) | (alubsel == ALUBSEL_SBUS));always @(expsel or fwe)   expwrite = expsel & fwe;//// *********** SBUS **************// The sbus (Source Bus) is the output of a multiplexor that takes// inputs from the Register File, and all other special registers// and input ports.  The Source Bus then, one of the inputs to the ALU// First MUX selects from all the special regsiters//always @(fsel or fsr or tmr0 or pc or status         or porta or portb or portc or regfileout or expdin         or specialsel or regfilesel or expsel) begin            // For our current mix of registers and peripherals, only the first 8 addresses   // are "special" registers (e.g. not in the Register File).  As more peripheral   // registers are added, they must be muxed into this MUX as well.   //   // We currently prohibit tristates.   //   //   if (specialsel) begin      // Special register      case (fsel[2:0]) // synopsys parallel_case full_case         3'h0:	sbus = fsr;         3'h1:	sbus = tmr0;         3'h2:	sbus = pc[7:0];         3'h3:	sbus = status;         3'h4:	sbus = fsr;         3'h5:	sbus = porta; // PORTA is an input-only port         3'h6:	sbus = portb; // PORTB is an output-only port         3'h7:	sbus = portc; // PORTC is an output-only port      endcase   end   else begin      //      // Put whatever address equation is neccessary here.  Remember to remove unnecessary      // memory elements from Register File (regs.v).  It'll still work, but they'd be      // wasted flip-flops.      //      if (expsel) begin         sbus = expdin;      end      else begin         if (regfilesel) begin            // Final Priority is Choose the register file            sbus = regfileout;         end         else begin            sbus = 8'h00;         end      end   endend// ************** DBUS ******//  The Destination bus is just the output of the ALU.//always @(aluout)   dbus = aluout;always @(dbus)   regfilein = dbus;   // Drive the ROM address bus straight from the PC_IN bus//always @(pc_in)   paddr = pc_in;// Define sub-signals out of inst//

⌨️ 快捷键说明

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