?? oc54_alu.v
字號:
///////////////////////////////////////////////////////////////////////// //////// OpenCores54 DSP, ALU //////// //////// Author: Richard Herveille //////// richard@asics.ws //////// www.asics.ws //////// ///////////////////////////////////////////////////////////////////////////// //////// Copyright (C) 2002 Richard Herveille //////// richard@asics.ws //////// //////// This source file may be used and distributed without //////// restriction provided that this copyright statement is not //////// removed from the file and that any derivative work contains //////// the original copyright notice and the associated disclaimer.//////// //////// THIS SOFTWARE IS PROVIDED ``AS IS'' AND WITHOUT ANY //////// EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED //////// TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS //////// FOR A PARTICULAR PURPOSE. IN NO EVENT SHALL THE AUTHOR //////// OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, //////// INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES //////// (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE //////// GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR //////// BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF //////// LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT //////// (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT //////// OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE //////// POSSIBILITY OF SUCH DAMAGE. //////// ///////////////////////////////////////////////////////////////////////// //// Xilinx Virtex-E WC: 617 CLB slices @ 58MHz// // CVS Log // // $Id: oc54_alu.v,v 1.1.1.1 2002/04/10 09:34:40 rherveille Exp $ // // $Date: 2002/04/10 09:34:40 $ // $Revision: 1.1.1.1 $ // $Author: rherveille $ // $Locker: $ // $State: Exp $ // // Change History: // $Log: oc54_alu.v,v $// Revision 1.1.1.1 2002/04/10 09:34:40 rherveille// Initial relase OpenCores54x DSP (CPU)// `include "timescale.v"`include "oc54_alu_defines.v"module oc54_alu ( clk, ena, inst, seli, doublet, a, b, s, t, cb, bp_a, bp_b, bp_ar, bp_br, c16, sxm, ci, tci, co, tco, result );//// parameters////// inputs & outputs//input clk;input ena;input [ 6:0] inst; // instructioninput [ 1:0] seli; // input selectioninput doublet; // {T, T}input [39:0] a, b, s; // accumulators + shifter inputsinput [15:0] t, cb; // TREG + c-bus inputinput [39:0] bp_ar, bp_br; // bypass a register, bypass b registerinput bp_a, bp_b; // bypass selectinput c16, sxm; // dual-mode, sign-extend-mode, input ci, tci; // carry in, tc-inoutput co, tco; // carry out, overflow, zero, tc-outoutput [39:0] result;reg co, tco;reg [39:0] result;//// variables//reg [39:0] iresult;reg itco, ico;reg [39:0] x;wire [39:0] y;reg dc16, dci, dtci;reg [6:0] dinst;//// module body////// generate input selection, barrel-shifter has 1cycle delay//always@(posedge clk) if (ena) case(seli) // synopsis full_case parallel_case 2'b00 : if (doublet) x <= #1 { {39-31{1'b0}}, t, t}; // is this correct ?? else x <= #1 { {39-15{sxm ? t[15] : 1'b0}}, t}; 2'b01 : x <= #1 bp_a ? bp_ar : a; 2'b10 : x <= #1 bp_b ? bp_br : b; 2'b11 : x <= #1 { {39-15{sxm ? cb[15] : 1'b0}}, cb}; endcaseassign y = s; // second input from barrel-shifter//// delay control signals//always@(posedge clk) if (ena) begin dc16 <= #1 c16; dci <= #1 ci; dtci <= #1 tci; dinst <= #1 inst; end//// generate ALU//always@(dinst or x or y or dc16 or dtci or dci)begin ico = dci; itco = dtci; iresult = x; case(dinst) // synopsis full_case parallel_case // // Arithmetic instructions // `ABS : // absolute value begin if (x[39]) iresult = (~x) + 1'b1; else iresult = x; ico = ~|(iresult); end `ADD : // ALSO ADDC, ADDS. For ADD, ADDS ci = 1'b0; begin iresult = x + y + dci; ico = iresult[32]; end `MAX : // ALSO MIN. MAX: x==accA, y==accB, MIN: x==accB, y ==accA begin ico = (x > y); iresult = (x > y) ? x : y; end `NEG : begin iresult = (~x) + 1'b1; ico = ~|(iresult); end `SUB : // ALSO SUBB, SUBS. For SUB, SUBS ci = 1'b1; begin iresult = x - y - ~dci; ico = iresult[32]; end `SUBC : // subtract conditional (for division) begin // FIXME: Is this correct ?? How does SUBC affect the carry bit ? iresult = x - y; ico = iresult[32]; if ( iresult > 0 )// iresult = (iresult << 1) + 1'b1; iresult = ({x[38:0], 1'b0}) + 1'b1; else// iresult = x << 1; iresult = {x[38:0], 1'b0}; end // // Dual Precision Arithmetic instructions // `DADD : if (dc16) // dual add result_hi/lo = x_hi/lo + y_hi/lo begin iresult[39:16] = x[31:16] + y[31:16]; iresult[15: 0] = x[15: 0] + y[15: 0]; end else // 32bit add result = x + y {ico, iresult} = x + y; `DSUB : if (dc16) // dual subtract result_hi/lo = x_hi/lo - y_hi/lo begin iresult[39:16] = x[31:16] - y[31:16]; iresult[15: 0] = x[15: 0] - y[15: 0]; end else // 32bit subtract result = x - y begin iresult = x - y; ico = iresult[32]; end `DRSUB : // ALSO DSUBT: make sure x = {T, T} if (dc16) // dual reverse sub. result_hi/lo = y_hi/lo - x_hi/lo begin iresult[39:16] = y[31:16] - x[31:16]; iresult[15: 0] = y[15: 0] - x[15: 0]; end else // 32bit reverse sub.result = y - x begin iresult = y - x; ico = iresult[32]; end `DSUBADD : // DSADT: make sure x = {T, T} if (dc16) begin iresult[39:16] = y[31:16] - x[31:16]; iresult[15: 0] = y[15: 0] + x[15: 0]; end else begin iresult = y - x; ico = iresult[32]; end `DADDSUB : // DADST: make sure x = {T, T} if (dc16) begin iresult[39:16] = y[31:16] + x[31:16]; iresult[15: 0] = y[15: 0] - x[15: 0]; end else begin iresult = x + y; ico = iresult[32]; end // // logical instructions // `NOT : // CMPL iresult = ~x; `AND : iresult = x & y; `OR : iresult = x | y; `XOR : iresult = x ^ y; // // shift instructions // `ROL : begin iresult[39:32] = 8'h0; iresult[31: 0] = {x[30:0], dci}; ico = x[31]; end `ROLTC : begin iresult[39:32] = 8'h0; iresult[31: 0] = {x[30:0], dtci}; ico = x[31]; end `ROR : begin iresult[39:32] = 8'h0; iresult[31: 0] = {dci, x[31:1]}; ico = x[0]; end `SHFT_CMP : if (x[31] & x[30]) begin// iresult = x << 1; iresult = {x[38:0], 1'b0}; itco = 1'b0; end else begin iresult = x; itco = 1'b1; end // // bit test and compare instructions // `BITF : itco = ~|( x[15:0] & y[15:0] ); `BTST : // BIT, BITT y=Smem, x=imm or T itco = y[ ~x[3:0] ]; // maybe do ~x at a higher level ?? `CMP_EQ : // ALSO CMPM. for CMPM [39:16]==0 itco = ~|(x ^ y); `CMP_LT : itco = x < y; `CMP_GT : itco = x > y; `CMP_NEQ : itco = |(x ^ y); // // NOP // default : begin ico = dci; itco = dtci; iresult = x; end endcase end//// generate registers//// resultalways@(posedge clk) if (ena) result <= #1 iresult;// tco, coalways@(posedge clk) if (ena) begin tco <= #1 itco; co <= #1 ico; endendmodule
?? 快捷鍵說明
復制代碼
Ctrl + C
搜索代碼
Ctrl + F
全屏模式
F11
切換主題
Ctrl + Shift + D
顯示快捷鍵
?
增大字號
Ctrl + =
減小字號
Ctrl + -