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

📄 cpu.v

📁 8位RISC CPU的VERILOG编程 SOURCECODE
💻 V
📖 第 1 页 / 共 2 页
字号:
/* ***********************************************************************  The Free IP Project  Free-RISC8 -- Verilog 8-bit Microcontroller  (c) 1999, The Free IP Project and Thomas Coonan  FREE IP GENERAL PUBLIC LICENSE  TERMS AND CONDITIONS FOR USE, COPYING, DISTRIBUTION, AND MODIFICATION  1.  You may copy and distribute verbatim copies of this core, as long      as this file, and the other associated files, remain intact and      unmodified.  Modifications are outlined below.    2.  You may use this core in any way, be it academic, commercial, or      military.  Modified or not.    3.  Distribution of this core must be free of charge.  Charging is      allowed only for value added services.  Value added services      would include copying fees, modifications, customizations, and      inclusion in other products.  4.  If a modified source code is distributed, the original unmodified      source code must also be included (or a link to the Free IP web      site).  In the modified source code there must be clear      identification of the modified version.  5.  Visit the Free IP web site for additional information.      http://www.free-ip.com*********************************************************************** */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;// 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;

⌨️ 快捷键说明

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