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

📄 dspuva16.v

📁 * DESCRIPTION: DDS design BY PLD DEVICES. * * AUTHOR: Sun Yu * * HISTORY: 12/06/2002 *
💻 V
📖 第 1 页 / 共 2 页
字号:
//
// PROJECT:	OpenDSP - The 'DSPuva16' 16-bit fixed-point DSP for FPGA
//		http://www.DTE.eis.uva.es/OpenProjects/OpenDSP/index.htm
//
// RIGHTS:	Santiago de Pablo
//		Copyright (c) 2001. All Rights Reserved.
//
// GPL:		You may freely copy, change, and distribute it,
//		but you may not impose restrictions on further distribution,
//		and you must make the source code available.
//
//		This code is supplied "as is", without any warranty.
//		Please, tell us how many devices have you implemented.
//
// AUTHOR:	Santiago de Pablo (sanpab@eis.uva.es)
//		Department of Electronics Technology (DTE)
//		University of Valladolid (Spain)
//
// MODULE:	DSPuva16.v
//
// DESCRIPTION:	The 'DSPuva16' is a 16-bit fixed-point DSP processor for FPGA.
//		It has 16 internal 24-bit registers, r0 to r15, but it has no more memory.
//		All registers, except r0, can be used in all operations.
//		It can operate with up to three registers (rD = rS op rT) with "uva" architecture.
//		It can execute 16x16 MAC operations (rD = rD +/- rS * rT) in one instruction cycle.
//		The ALU has eight 24-bit operations: logic, arithmetic, conditional assignment.
//		Precission is extended up to 24 bits (from <1,15> to <1,23>) in all operations.
//		The executable code is from 256 words (version 'A') up to 4K words (version 'E').
//		External accesses are made through 128 I/O ports (P0 to P127).
//
//		The "uva" architecture means that 'r0' is replaced depending on where it's used:
//		  - rD = rS op rT  Uses three registers, anyone from 'r1' to r15'.
//		  - rD = rS op K   Uses an immediate constant because 'r0' is used as rT.
//		  - rD =  0 op rT  A zero is included if the operand rS is 'r0'.
//		  - rD =  0 op K   Both, a zero and a constant, can be used simultaneously.
//		  -      rS op rT  A compare operation is done because 'r0' is used as rD.
//
//		The size of the processor core is about 250 slices in Virtex/Spartan2 FPGAs.
//		Up to eight 16-words memory blocks can be added, with only 9 CLB for each one.
//		All components can be integrated in the same FPGA: core, code memory, ports and added memory.
//
// VERSIONS:	'A' has 256x16 code; 'B' has 512x16; 'C' has 1Kx16; 'D' has 2Kx16; 'E' has 4Kx16.
//
// REVISION:	1.02	20010421	Introducing ACC (same behaviour)
//		1.00	20010416	First stable version (HDL simulation only)
//		0.25	20010411	Adding MODELs for 256-4K code.
//		0.23	20010409	Cheching for '<='
//		0.21	20010326	First public version (not simulated yet)
//		0.19	20010318	More code
//		0.17	20010209	More code
//		0.15	20001221	Successful compilation in Verilog
//		0.13	20001219	Initial version in Verilog
//		0.11	20001209	Initial version in VHDL
//
// TO DO LIST:	Beta tests.
//		Better Test Bench.
//		Test with Program Memory.
//		Generate V flag with MAC?
//		16-bit ports or 24-bit ports?
//
// OPCODES:	NOP            rD =      rS x rT   IF flag, R = T    rD = rS and rT   rD = 0
//		BREAK/MODEL    rD =      rS x K    IF flag, R = K    rD = rS and K    rD = K
//		RET (rS)       rD =      rS * rT   IF flag, R = -T   rD = rS or  rT   rD = -K
//		IN  rD,pN      rD =      rS * K    IF flag, R = -K   rD = rS or  K    rD = rT
//		OUT pN,rD      rD = rD + rS * rT   rD = rS + rT      rD = rS nor rT   rD = -rT
//		JP flag,nn     rD = rD + rS * K    rD = rS + K       rD = rS nor K    rD = not rT
//		GOTO nn        rD = rD - rS * rT   rD = rS - rT      rD = rS xor rT   rD = not K
//		CALL (rD) nn   rD = rD - rS * K    rD = rS - K       rD = rS xor K    -
//
// FLAGS:	(eq), (ne), (ov), (nv), (ge), (gt), (le), (lt) and 8 more for interfacing/control.
//
// BUGS:	Please, report bugs to "dteopenp@eis.uva.es" with reference "OpenDSP v1.02".
//


`define	LOW_POWER		// Valid LOW_POWER or LOW_LOGIC


//---------------//
// DSPuva16 Core //
//---------------//

module DSPuva16 (CLK, nRESET, PORTin, PORTout, PORTaddr, IOread, IOwrite, CODEaddr, CODEdata);

	parameter MODEL = 4;	// Model 'A' uses 0, 'B' uses 1, ..., 'E' uses 4.

	input  			CLK;		// 40 MHz Clock (=> 100ns/instruction)
	input  			nRESET;		// Active-low external Reset

	input       [15:0]	PORTin;		// Input Data Port
	output      [15:0]	PORTout;	// Output Data Port
	output       [6:0]	PORTaddr;	// Port Address
	output			IOread;		// Port Read Signal, active high
	output			IOwrite;	// Port Write Signal, active high

	output [MODEL+7:0]	CODEaddr;	// Code Memory Address
	input       [15:0]	CODEdata;	// Code Memory Data (always read)


	// Internal Registers and Buses:

	reg         [11:0]	PC;		// Program Counter (up to 4K code)
	reg         [15:0]	IR;		// Instruction Register
	reg         [23:0]	ACC;		// Accumulator for 'rT'
	wire        [23:0]	DataBus;	// Internal Data Bus
	wire        [23:0]	RegOut;		// Output from Register Bank
	reg	       		Flag;		// Selected Flag


//----------------------------------------------------------------------------------------------------------------------//
//   State =>	Operations			Program Counter								\\
//----------------------------------------------------------------------------------------------------------------------//
//	00   =>	Read Instruction		PC = PC									\\
//	01   =>	Load IR				PC = PC + 1								//
//	11   =>	ACC = rT			PC = PC									\\
//	10   =>	Read rS - Load RegS and RegT	PC = PC/PC+1/PC+nn/nnn							//
//	00   =>	MAC1 - Writes on rD if ALU	PC = PC									\\
//	01   =>	MAC2 				PC = PC + 1								//
//	11   =>	MAC3				PC = PC									\\
//	10   =>	MAC4				...									//
//	00   =>	Last MAC cycle (for segmentation)									\\
//	01   =>	Reads, accumulates and Writes on rD if MAC								//
//----------------------------------------------------------------------------------------------------------------------\\
//															//
//	 |       Instruction 0 (MAC)      |       Instruction 1 (ALU)      |       Instruction 2 (GOTO)     |		\\
//	 | ___     ___     ___     ___    | ___     ___     ___     ___    | ___     ___     ___     ___    | ___     __//
//  CLK	_|/   \___/   \___/   \___/   \___|/   \___/   \___/   \___/   \___|/   \___/   \___/   \___/   \___|/   \___/	\\
//	 | _______ _______ _______ _______| _______ _______ _______ _______| _______ _______ _______ _______| _______ __//
//State	_|/__st0__/__st1__/__st2__/__st3__|/__st0__/__st1__/__st2__/__st3__|/__st0__/__st1__/__st2__/__st3__|/__st0__/__\\
//	_| _______________ _______________|________________ _______________|________________ _______________| __________//
//   PC	_|/_______n_______\______n+1______|_______n+1______\______n+2______|_______n+2______\______n+3______|/__(new)___\\
//	_| _______________ _______________|________________ _______________|________________ _______________|___________//
//   IR	_|/_______x_______\_______I0______|________I0______\_______I1______|________I1______\_______I2______|___________\\
//	_| _______________________________| _______________________________| _______________________________|___________//
//  S,T	_|/_______________x_______________|\_____________S0,T0_____________|\_____________S1,T1_____________|\__________\\
//	 | _______ _______ _______ _______| _______ _______ _______ _______| _______ _______ _______ _______| _______ __//
//  MAC	_|/___x___/___x___/___x___/___x___|/__m0a__/__m0b__/__m0c__/__m0d__|/__m1a__/__m1b__/__m1c__/__m1d__|/__m2a__/__\\
//	 |________________________________| _______ _______________________| _______ _______________________| _______ __//
//  ALU	_|____x___/___x___/___x___/___x___|/_(OP0)_/___x___/___x___/___x___|/__OP1__/___x___/___x___/___x___|/_(OP2)_/__\\
//	 | _______ _______ _______ _______| _______ _______ _______ _______| _______ _______ _______ _______| _______ __//
// Rdir	_|/___x___/___x___/___T0__/___S0__|/___R0__/___x___/___T1__/___S1__|/___R1__/___R0__/___T2__/___S2__|/___R2__/__\\
//	 |                                |                                | _______ _______                |		//
//  rWE	_|________________________________|________________________________|/  ALU1 \  MAC0 \_______________|___________\\
//	 |                                |                                | _______                        |		//
//  IOr	_|________________________________|________________________________|/ (IN1) \_______________________|___________\\
//	 |                                |                         _______|                                |		//
//  IOw	_|________________________________|________________________/ (OUT1)|\_______________________________|___________\\
//	_|________________________ _______|________________________ _______|________________________ _______|___________//
//Paddr	_|________________________\_______|_______AD0______________\_______|_______AD1______________\_______|_______AD2_\\
//															//
//----------------------------------------------------------------------------------------------------------------------\\


	//----------------//
	// DFF for nRESET //
	//----------------//

	reg ResetFF;	// DFF for nRESET

	always @(posedge CLK or negedge nRESET)		// External nRESET is active 'low'
	begin
		if (nRESET == 1'b0)	ResetFF <= 1'b1;	// Resets all operations
		else			ResetFF <= 1'b0;	// Release the DSP
	end


	//--------------------------------------------//
	// Processor Control Unit: State and Decoding //
	//--------------------------------------------//

	reg [1:0] State;						// Sequencer
	parameter st0 = 2'b00, st1 = 2'b01, st2 = 2'b11, st3 = 2'b10;	// States

	always @(posedge CLK or posedge ResetFF)
	begin
		if (ResetFF)	State	<= st0;
		else case (State)		// synopsys parallel_case full_case
			st0:	State	<= st1;
			st1:	State	<= st2;
			st2:	State	<= st3;
			st3:	State	<= st0;
		endcase
	end

	`define	PHASE0		(State == st0)
	`define	PHASE1		(State == st1)
	`define	PHASE2		(State == st2)
	`define	PHASE3		(State == st3)

	wire [3:0]		OpCode	= IR[15:12];		// Bits used for OpCode
	wire [3:0]		rD	= IR[11: 8];		// Bits used for the destination reg. (rD)
	wire [3:0]		rS	= IR[ 7: 4];		// Bits used for the first operand (rS)
	wire [3:0]		rT	= IR[ 3: 0];		// Bits used for the second operand (rT)
	wire [7:0]		RelAddr	= IR[ 7: 0];		// Bits used for relative addressing
	wire [7:0]		AbsAddr	= {IR[11:8],IR[3:0]};	// Bits used for absolute addressing
	parameter		r0	= 4'b0000;		// The special register 'r0' is being used

	`define	OP_NOP		(OpCode == 4'b0000)	// A NOP/BREAK/RET operation is executed
	`define	OP_IO		(OpCode == 4'b0001)	// An I/O operation is executed
	`define OP_JP		(OpCode == 4'b0010)	// A conditional jump is executed
	`define OP_GOTO		(OpCode == 4'b0011)	// An absolute jump is executed
	`define OP_CALL		(OpCode == 4'b0011)	// CALL and GOTO are identical

	`define	OP_CTRL		(OpCode[3:2] == 2'b00)	// Program Control operations
	`define	OP_MAC		(OpCode[3:2] == 2'b01)	// MAC operations
	`define	OP_ARITH	(OpCode[3:2] == 2'b10)	// Arithmetic operations
	`define	OP_LOGIC	(OpCode[3:2] == 2'b11)	// Logic operations
	`define OP_ALUMAC	(OpCode[3:2] != 2'b00)	// ALU or MAC operations
	`define	OP_ALU		(OpCode[3])		// Arithmetic or Logic operations

	`define	OUT_IN		(IR[7])				// '1' if OUT, '0' if IN
	`define	OP_IN		(`OP_IO & ~`OUT_IN)		// IN  rD,port
	`define	OP_OUT		(`OP_IO &  `OUT_IN)		// OUT port,rS

⌨️ 快捷键说明

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