📄 dspuva16.v
字号:
//
// 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 + -