📄 aluuva16.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: ALUuva16.v
//
// DESCRIPTION: Computation Core for the DSPuva16.
// The 24-bit ALU has eight operations (+, -, AND, OR, ...).
// The multiplier-acumulator operates in one cycle (four subcycles).
//
// REVISION: 1.00 20010416a First stable version
// 0.06 20010319a Ok
//
// TO DO LIST: Full Test Bench
//
// BUGS: Please, report bugs to "dteopenp@eis.uva.es"
// with reference "OpenDSP ALUuva16 v1.00".
//
module ALUuva16 (Clk, Phase, InA, InB, InC, OpCode, FlagIn, Vflag, OutMAC, OutLogic, OutArith);
parameter ph0 = 2'b00, ph1 = 2'b01, ph2 = 2'b11, ph3 = 2'b10;
input Clk; // DSP Clock (40 MHz)
input [1:0] Phase; // Subcycle Identification
input [23:0] InA; // First operand (RegS or 0)
input [23:0] InB; // Second operand (RegT or K)
input [23:0] InC; // Third operand (RegD for MAC)
input [3:0] OpCode; // Instruction Operation Code (2:0?)
input FlagIn; // Input of the active flag
output Vflag; // Output for the Overflow flag
output [23:0] OutMAC; // Output from the Multiplier-Accumulator
output [23:0] OutLogic; // Logic ALU output
output [23:0] OutArith; // Arithmetic ALU output
//------------------------------------------------------//
// Input registers: receive two 24-bit operands S and T //
//------------------------------------------------------//
reg [23:0] OpA, OpB;
always @(posedge Clk)
begin
OpA <= (Phase == ph3) ? InA : {OpA[3:0],OpA[23:4]}; // Loads S and shifts it
OpB <= (Phase == ph3) ? InB : OpB; // Loads T and keeps it
end
//----------------------------------------------------------------------//
// Multiplier and Accumulator (16-bit fixed point, extended to 24 bits) //
//----------------------------------------------------------------------//
reg [1:0] OldCode;
wire [31:0] OutMULT;
wire x;
always @(posedge Clk)
begin
OldCode <= (Phase == ph1) ? OpCode[1:0] : OldCode; // Keeps old OpCode
end
MULuva16 Multiplier16x16
(
.Clk (Clk),
.InA (OpA[11:8]),
.InB (OpB[23:8]),
.Phase (Phase),
.AxB (OutMULT)
);
wire [23:0] AccA = (OldCode[1]) ? InC : 24'h000000; // Acumulates for 011x, but not for 010x
wire [23:0] AccB = (OldCode[1:0] == 2'b01) ? OutMULT[23:0] // Multiply in 8,8 format for 0101
: (~OldCode[0]) ? OutMULT[30:7] // or in 1,15 format with addition for 01x0
: ~OutMULT[30:7]; // or in 1,15 formtat with substraction for 0111
assign {OutMAC,x} = {AccA, 1'b1} + {AccB, OldCode[0]}; // The MAC does not modify any flag
//-----------//
// Logic ALU //
//-----------//
`define OP_AND 2'b00
`define OP_OR 2'b01
`define OP_NOR 2'b10
`define OP_XOR 2'b11
reg [23:0] OutLogic;
always @(OpA or OpB or OpCode)
begin
case (OpCode[1:0]) // synopsys parallel_case full_case
`OP_AND: OutLogic = OpA & OpB;
`OP_OR: OutLogic = OpA | OpB;
`OP_NOR: OutLogic = ~(OpA | OpB);
`OP_XOR: OutLogic = OpA ^ OpB;
endcase
end
//----------------//
// Arithmetic ALU //
//----------------//
wire [23:0] AddA, AddB;
wire Carry;
assign AddA = ((OpCode[1] | ~FlagIn) ? OpA : 24'h000000);
assign AddB = ((OpCode[1] | FlagIn) ? OpB : 24'h000000);
assign {Carry, OutArith} = (OpCode[0]) ? (AddA - AddB) : (AddA + AddB);
assign Vflag = (Carry ^ OutArith[23] ^ AddA[23] ^ AddB[23]); // Overflow Flag
// Thanks Jan Gray
endmodule // ALUuva16
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -