Line 1... |
Line 1... |
// +++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
|
// ++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
|
//
|
//
|
// This file is part of the M32632 project
|
// This file is part of the M32632 project
|
// http://opencores.org/project,m32632
|
// http://opencores.org/project,m32632
|
//
|
//
|
// Filename: I_PFAD.v
|
// Filename: I_PFAD.v
|
// Version: 2.0
|
// Version: 3.0
|
// History: 1.1 bug fix of 7 November 2015
|
// History: 1.1 bug fix of 7 November 2015
|
// 1.0 first release of 30 Mai 2015
|
// 1.0 first release of 30 Mai 2015
|
// Date: 14 August 2016
|
// Date: 2 December 2018
|
//
|
//
|
// Copyright (C) 2016 Udo Moeller
|
// Copyright (C) 2018 Udo Moeller
|
//
|
//
|
// This source file may be used and distributed without
|
// This source file may be used and distributed without
|
// restriction provided that this copyright statement is not
|
// restriction provided that this copyright statement is not
|
// removed from the file and that any derivative work contains
|
// removed from the file and that any derivative work contains
|
// the original copyright notice and the associated disclaimer.
|
// the original copyright notice and the associated disclaimer.
|
Line 30... |
Line 30... |
//
|
//
|
// You should have received a copy of the GNU Lesser General
|
// You should have received a copy of the GNU Lesser General
|
// Public License along with this source; if not, download it
|
// Public License along with this source; if not, download it
|
// from http://www.opencores.org/lgpl.shtml
|
// from http://www.opencores.org/lgpl.shtml
|
//
|
//
|
// +++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
|
// ++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
|
//
|
//
|
// Modules contained in this file:
|
// Modules contained in this file:
|
// 1. BITMASK Mask Generator , was a ROM on falling edge in early days
|
// 1. BITMASK Mask Generator , was a ROM on falling edge in early days
|
// 2. MULFILTER Filter for Multiplier Input Data
|
// 2. MULFILTER Filter for Multiplier Input Data
|
// 3. SIGNMUL Signed Multiplier for Integer Multiplication
|
// 3. SHIFTER Barrel Shifter for all Shift Opcodes
|
// 4. SHIFTER Barrel Shifter for all Shift Opcodes
|
// 4. FFS_LOGIK Logic for FFS opcode
|
// 5. FFS_LOGIK Logic for FFS opcode
|
// 5. SCHALE Enclosure for Adder/Subtractor
|
// 6. SCHALE Enclosure for Adder/Subtractor
|
// 6. I_PFAD The Integer Datapath
|
// 7. I_PFAD The Integer Datapath
|
|
//
|
//
|
// ++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
|
// ++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
|
|
|
// ++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
|
// ++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
|
//
|
//
|
Line 113... |
Line 112... |
// ++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
|
// ++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
|
//
|
//
|
// 2. MULFILTER Filter for Multiplier Input Data
|
// 2. MULFILTER Filter for Multiplier Input Data
|
//
|
//
|
// ++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
|
// ++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
|
module MULFILTER (BWD, FLOAT, SRC1, SRC2, DEST1, DEST2);
|
module MULFILTER (BWD, SRC1, SRC2, MRESULT);
|
|
|
input [1:0] BWD;
|
input [1:0] BWD;
|
input FLOAT;
|
input signed [31:0] SRC1,SRC2;
|
input [31:0] SRC1,SRC2;
|
output [32:0] MRESULT;
|
output [31:0] DEST1,DEST2;
|
|
|
|
reg [31:0] DEST1,DEST2;
|
wire signed [63:0] muld;
|
|
wire signed [31:0] mulw;
|
|
|
always @(FLOAT or BWD or SRC1)
|
wire no_ovf;
|
casex ({FLOAT,BWD})
|
|
3'b0_00 : DEST1 = {{24{SRC1[7]}}, SRC1[7:0]};
|
|
3'b0_01 : DEST1 = {{16{SRC1[15]}},SRC1[15:0]};
|
|
3'b1_xx : DEST1 = { 9'h001,SRC1[22:0]};
|
|
default : DEST1 = SRC1;
|
|
endcase
|
|
|
|
always @(FLOAT or BWD or SRC2)
|
|
casex ({FLOAT,BWD})
|
|
3'b0_00 : DEST2 = {{24{SRC2[7]}}, SRC2[7:0]};
|
|
3'b0_01 : DEST2 = {{16{SRC2[15]}},SRC2[15:0]};
|
|
3'b1_xx : DEST2 = { 9'h001,SRC2[22:0]};
|
|
default : DEST2 = SRC2;
|
|
endcase
|
|
|
|
endmodule
|
assign muld = SRC1 * SRC2;
|
|
assign mulw = {(BWD[0] ? SRC1[15:8] : {8{SRC1[7]}}),SRC1[7:0]} * {(BWD[0] ? SRC2[15:8] : {8{SRC2[7]}}),SRC2[7:0]};
|
|
|
// ++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
|
assign no_ovf = BWD[1] ? (muld[63:32] == {32{muld[31]}})
|
//
|
: ( BWD[0] ? (mulw[31:16] == {16{mulw[15]}})
|
// 3. SIGNMUL Signed Multiplier for Integer Multiplication
|
: (mulw[15:8] == {8{mulw[7]}}) );
|
//
|
|
// ++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
|
|
module SIGNMUL (dataa, datab, result);
|
|
|
|
input signed [31:0] dataa,datab;
|
|
output signed [63:0] result;
|
|
|
|
assign result = dataa * datab;
|
assign MRESULT = {~no_ovf,muld[31:16],(BWD[1] ? muld[15:0] : mulw[15:0])};
|
|
|
endmodule
|
endmodule
|
|
|
// ++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
|
// ++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
|
//
|
//
|
// 4. SHIFTER Barrel Shifter for all Shift Opcodes
|
// 3. SHIFTER Barrel Shifter for all Shift Opcodes
|
//
|
//
|
// ++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
|
// ++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
|
module SHIFTER ( MASKE,ROT,LSH,ASH,SIZE,SH_VAL,SH_DAT,SH_OUT,MASK_SEL);
|
module SHIFTER ( MASKE,ROT,LSH,ASH,SIZE,SH_VAL,SH_DAT,SH_OUT,MASK_SEL);
|
|
|
input [31:0] MASKE;
|
input [31:0] MASKE;
|
Line 231... |
Line 211... |
|
|
endmodule
|
endmodule
|
|
|
// ++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
|
// ++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
|
//
|
//
|
// 5. FFS_LOGIK Logic for FFS opcode
|
// 4. FFS_LOGIK Logic for FFS opcode
|
//
|
//
|
// ++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
|
// ++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
|
module FFS_LOGIK (SRC1, SRC2, BWD, FLAG, DOUT);
|
module FFS_LOGIK (SRC1, SRC2, BWD, FLAG, DOUT);
|
|
|
input [31:0] SRC1;
|
input [31:0] SRC1;
|
Line 307... |
Line 287... |
|
|
endmodule
|
endmodule
|
|
|
// ++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
|
// ++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
|
//
|
//
|
// 6. SCHALE Enclosure for Adder/Subtractor
|
// 5. SCHALE Enclosure for Adder/Subtractor
|
//
|
//
|
// ++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
|
// ++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
|
module SCHALE (dataa, datab, cin, add_sub, bwd, result, cout, overflow);
|
module SCHALE (dataa, datab, cin, add_sub, bwd, result, cout, overflow);
|
|
|
input [31:0] dataa,datab;
|
input [31:0] dataa,datab;
|
Line 349... |
Line 329... |
|
|
endmodule
|
endmodule
|
|
|
// ++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
|
// ++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
|
//
|
//
|
// 7. I_PFAD The Integer Datapath
|
// 6. I_PFAD The Integer Datapath
|
//
|
//
|
// ++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
|
// ++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
|
module I_PFAD ( BCLK, BRESET, SFP_DAT, FSR, DP_OUT, SRC1, SRC2, BMASKE, ADDR, MRESULT, OPCODE, BWD, FL, SP_CMP, DP_CMP, LD_OUT,
|
module I_PFAD ( BCLK, BRESET, SFP_DAT, FSR, DP_OUT, SRC1, SRC2, BMASKE, ADDR, MRESULT, OPCODE, BWD, FL, SP_CMP, DP_CMP, LD_OUT,
|
WREN, WRADR, RDAA, DETOIP, BITSEL, OVF_BCD, DISP, RWVFLAG, DSR, I_OUT, PSR, BMCODE, OV_FLAG, ACB_ZERO, STRING);
|
WREN, WRADR, RDAA, DETOIP, BITSEL, OVF_BCD, DISP, RWVFLAG, DSR, I_OUT, PSR, BMCODE, OV_FLAG, ACB_ZERO, STRING);
|
|
|
input BCLK,BRESET;
|
input BCLK,BRESET;
|
input [31:0] SFP_DAT,FSR,DP_OUT;
|
input [31:0] SFP_DAT,FSR,DP_OUT;
|
input [31:0] SRC1,SRC2;
|
input [31:0] SRC1,SRC2;
|
input [31:0] BMASKE;
|
input [31:0] BMASKE;
|
input [31:0] ADDR;
|
input [31:0] ADDR;
|
input [63:0] MRESULT;
|
input [32:0] MRESULT;
|
input [7:0] OPCODE;
|
input [7:0] OPCODE;
|
input [1:0] BWD;
|
input [1:0] BWD;
|
input FL;
|
input FL;
|
input [2:0] SP_CMP;
|
input [2:0] SP_CMP;
|
input [2:0] DP_CMP;
|
input [2:0] DP_CMP;
|
Line 528... |
Line 508... |
|
|
assign PSR = {psr_high,psr_low};
|
assign PSR = {psr_high,psr_low};
|
|
|
// ++++++++++++++ Overflow Detection ++++++++++++++++++++++++++++++++++++++
|
// ++++++++++++++ Overflow Detection ++++++++++++++++++++++++++++++++++++++
|
|
|
reg ovf_mul,ovf_ash;
|
reg ovf_ash;
|
wire [31:0] shdat;
|
wire [31:0] shdat;
|
|
|
always @(posedge BCLK or negedge BRESET)
|
always @(posedge BCLK or negedge BRESET)
|
if (!BRESET) OV_FLAG <= 1'b0;
|
if (!BRESET) OV_FLAG <= 1'b0;
|
else
|
else
|
if (OVF_BCD[3]) OV_FLAG <= OVF_BCD[2]; // DEI,QUO,DIV
|
if (OVF_BCD[3]) OV_FLAG <= OVF_BCD[2]; // DEI,QUO,DIV
|
else
|
else
|
if (LD_OUT)
|
if (LD_OUT)
|
case (OPCODE)
|
case (OPCODE)
|
8'h78 : OV_FLAG <= ovf_mul;
|
8'h78 : OV_FLAG <= MRESULT[32];
|
8'h61 : OV_FLAG <= ovf_ash;
|
8'h61 : OV_FLAG <= ovf_ash;
|
8'h40 : OV_FLAG <= over_flow & acb_reg; // ADD Opcode at ACB
|
8'h40 : OV_FLAG <= over_flow & acb_reg; // ADD Opcode at ACB
|
default : OV_FLAG <= 1'b0;
|
default : OV_FLAG <= 1'b0;
|
endcase
|
endcase
|
|
|
always @(BWD or MRESULT)
|
|
casex (BWD)
|
|
2'b00 : ovf_mul = ~((MRESULT[15:7] == 9'd0) | (MRESULT[15:7] == 9'h1FF));
|
|
2'b01 : ovf_mul = ~((MRESULT[31:15] == 17'd0) | (MRESULT[31:15] == 17'h1FFFF));
|
|
default : ovf_mul = ~((MRESULT[63:31] == 33'd0) | (MRESULT[63:31] == 33'h1FFFFFFFF));
|
|
endcase
|
|
|
|
always @(BWD or SRC2 or shdat)
|
always @(BWD or SRC2 or shdat)
|
casex (BWD)
|
casex (BWD)
|
2'b00 : ovf_ash = (SRC2[7] != shdat[7]);
|
2'b00 : ovf_ash = (SRC2[7] != shdat[7]);
|
2'b01 : ovf_ash = (SRC2[15] != shdat[15]);
|
2'b01 : ovf_ash = (SRC2[15] != shdat[15]);
|
default : ovf_ash = (SRC2[31] != shdat[31]);
|
default : ovf_ash = (SRC2[31] != shdat[31]);
|