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

📄 pic.v

📁 verilog实例100多个
💻 V
📖 第 1 页 / 共 5 页
字号:
// 
// SYNTHETIC PIC 2.0                                          4/23/98
//
//    This is a synthesizable Microchip 16C57 compatible
//    microcontroller.  This core is not intended as a high fidelity model of
//    the PIC, but simply a way to offer a simple processor core to people
//    familiar with the PIC who also have PIC tools.  
//
//    pictest.v  -   top-level testbench (NOT SYNTHESIZABLE)
//    piccpu.v   -   top-level synthesizable module
//    picregs.v  -   register file instantiated under piccpu
//    picalu.v   -   ALU instantiated under piccpu
//    picidec.v  -   Instruction Decoder instantiated under piccpu
//    hex2rom.c  -   C program used to translate MPLAB's INTEL HEX output
//                   into the Verilog $readmemh compatible file
//    test*.asm  -   (note the wildcard..) Several test programs used
//                   to help debug the verilog.  I used MPLAB and the simulator
//                   to develop these programs and get the expected results.
//                   Then, I ran them on Verilog-XL where they appeared to
//                   match.
//
//    Copyright, Tom Coonan, '97.
//    Use freely, but not for resale as is.  You may use this in your
//    own projects as desired.  Just don't try to sell it as is!
//
//
module picalu (
   op,
   a,
   b,
   y,
   cin,
   cout,
   zout
);

input  [3:0]	op;	// ALU Operation
input  [7:0]	a;	// 8-bit Input a
input  [7:0]	b;	// 8-bit Input b
output [7:0]	y;	// 8-bit Output
input		cin;
output		cout;
output		zout;

// Reg declarations for outputs
reg		cout;
reg		zout;
reg [7:0]	y;

// Internal declarations
reg		addercout; // Carry out straight from the adder itself.
 
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;


always @(a or b or cin or op) begin
   case (op) // synopsys full_case parallel_case
      ALUOP_ADD:  {addercout,  y}  <= a + b;
      ALUOP_SUB:  {addercout,  y}  <= a - b; // Carry out is really "borrow"
      ALUOP_AND:  {addercout,  y}  <= {1'b0, a & b};
      ALUOP_OR:   {addercout,  y}  <= {1'b0, a | b};
      ALUOP_XOR:  {addercout,  y}  <= {1'b0, a ^ b};
      ALUOP_COM:  {addercout,  y}  <= {1'b0, ~a};
      ALUOP_ROR:  {addercout,  y}  <= {a[0], cin, a[7:1]};
      ALUOP_ROL:  {addercout,  y}  <= {a[7], a[6:0], cin};
      ALUOP_SWAP: {addercout,  y}  <= {1'b0, a[3:0], a[7:4]};
      default:    {addercout,  y}  <= {1'b0, 8'h00};
   endcase
end

always @(y)
   zout <= (y == 8'h00);

always @(addercout or op)
   if (op == ALUOP_SUB) cout <= ~addercout; // Invert adder's carry to get borrow
   else                 cout <=  addercout;
      
endmodule
// 
// SYNTHETIC PIC 2.0                                          4/23/98
//
//    This is a synthesizable Microchip 16C57 compatible
//    microcontroller.  This core is not intended as a high fidelity model of
//    the PIC, but simply a way to offer a simple processor core to people
//    familiar with the PIC who also have PIC tools.  
//
//    pictest.v  -   top-level testbench (NOT SYNTHESIZABLE)
//    piccpu.v   -   top-level synthesizable module
//    picregs.v  -   register file instantiated under piccpu
//    picalu.v   -   ALU instantiated under piccpu
//    picidec.v  -   Instruction Decoder instantiated under piccpu
//    hex2rom.c  -   C program used to translate MPLAB's INTEL HEX output
//                   into the Verilog $readmemh compatible file
//    test*.asm  -   (note the wildcard..) Several test programs used
//                   to help debug the verilog.  I used MPLAB and the simulator
//                   to develop these programs and get the expected results.
//                   Then, I ran them on Verilog-XL where they appeared to
//                   match.
//
//    Copyright, Tom Coonan, '97.
//    Use freely, but not for resale as is.  You may use this in your
//    own projects as desired.  Just don't try to sell it as is!
//
//
module piccpu (
   clk,
   reset,
   paddr,
   pdata,
   portain,
   portbout,
   portcout,
   
   debugw,
   debugpc,
   debuginst,
   debugstatus
);

input		clk;
input		reset;
output [8:0]	paddr;
input  [11:0]	pdata;
input  [7:0]	portain;
output [7:0]	portbout;
output [7:0]	portcout;

output [7:0]	debugw;
output [8:0]	debugpc;
output [11:0]	debuginst;
output [7:0]	debugstatus;

// Register declarations for outputs
reg [8:0]	paddr;
reg [7:0]	portbout;
reg [7:0]	portcout;

// 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 = 9'h1FF;

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;

// Experimental custom peripheral, "Lil Adder (a 4-bit adder)" is at this address.
//
parameter	EXPADDRESS_LILADDER = 7'h7F;

// *********  Special internal registers

// Instruction Register
reg  [11:0]	inst;

// Program Counter
reg  [8:0]	pc;
reg  [8:0]	pcplus1; // Output of the pc incrementer.

// Stack Registers and Stack "levels" register.
reg [ 1:0]	stacklevel;
reg [ 8:0]	stack1;
reg [ 8:0]	stack2;

// W Register
reg [ 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 0
reg  [ 7:0]	tmr0;
reg  [ 7:0]	prescaler;

// Option Register
reg [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 PORT
reg [7:0]	portb;	// Output PORT
reg [7:0]	portc;	// Output PORT

// ********** Instruction Related signals ******

reg 		skip;  // When HI force a NOP (all zeros) into inst

reg  [2:0]	pcinsel;

// Derive special sub signals from inst register
wire [ 7:0]	k;
wire [ 4:0]	fsel;
wire [ 8:0]	longk;
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 Selects
reg		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"

// 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 Mux
reg		regfilewe;	// Write Enable
reg		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 ebus (Expansion Bus) comes from any of our custom modules.  They must
// all coordinate to place whoever's data onto ebus.
//
reg  [7:0]	dbus;
reg  [7:0]	sbus;
reg  [7:0]	ebus;


// ALU Signals
//
reg  [7:0]	alua;
reg  [7:0]	alub;
wire [7:0]	aluout;
wire 		alucin;
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
//
picregs  regs (
   .clk		(clk), 
   .reset	(reset),
   .we  	(regfilewe),
   .re		(regfilere),
   .bank	(fileaddr[6:5]), 
   .location	(fileaddr[4:0]),
   .din		(regfilein), 
   .dout	(regfileout)
);

// Instatiate the ALU.
//
picalu   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.
//
picidec  idec (
   .inst     (inst),
   .aluasel  (aluasel),
   .alubsel  (alubsel),
   .aluop    (aluop),
   .wwe      (wwe),
   .fwe      (fwe),
   .zwe      (zwe),
   .cwe      (cwe),
   .bdpol    (bdpol),
   .option   (isoption),
   .tris     (istris)
);

// *********** 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) 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 <= {fsr[6:5], fsel};
   end
end

// 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
always @(fileaddr) begin
   casex (fileaddr)
      7'bXX00XXX: // The SPECIAL Registers are lower 8 addresses, in ALL BANKS
         begin
            specialsel	<= 1'b1;
            regfilesel	<= 1'b0;
            expsel	<= 1'b0;
         end
      7'b1111111: // EXPANSION Registers are the top (1) addresses
         begin
            specialsel	<= 1'b0;
            regfilesel	<= 1'b0;
            expsel	<= 1'b1;

⌨️ 快捷键说明

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