📄 leg_mult.v
字号:
/////////////////////////////////////////////////////////////////////
//// ////
//// LEG cpu core ////
//// ////
//// This file is part of the LEG FPGA SOC project ////
//// ////
//// ////
//// To Do: ////
//// - make it smaller and faster ////
//// - rewrite the register file and data path ////
//// Author(s): ////
//// - Alex Li, Alexli8055@hotmail.com ////
//// ////
/////////////////////////////////////////////////////////////////////
//// ////
//// Copyright (C) 2006-2007 Li datou ////
//// Alexli8055@hotmail.com ////
//// ////
//// ////
//// This source file may be used and distributed freely without ////
//// restriction provided that this copyright statement is not ////
//// removed from the file and any derivative work contains the ////
//// original copyright notice and the associated disclaimer. ////
//// ////
//// ARM, the ARM Powered logo, Thumb, and StrongARM are ////
//// registerd trademarks of ARM Limited, this core is simply ////
//// build for fun, please do not use for commerical propose ////
//// ////
//// 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. ////
//// ////
/////////////////////////////////////////////////////////////////////
//// ////
//// Date of Creation: 2006.11.28 ////
//// ////
//// Version: 0.0.1 ////
//// ////
//// Description ////
//// leg core multiplier module. ////
//// ////
//// ////
/////////////////////////////////////////////////////////////////////
//// ////
//// Change log: ////
//// ////
/////////////////////////////////////////////////////////////////////
`include "leg_define.v"
module leg_mult(
clk,
dataa,
datab,
rst,
r_en,
a_en,
result_low, //first cycle
result_high //next cycle
);
input clk;
input rst;
input [31:0] dataa;
input [31:0] datab;
input r_en;
input a_en;
output [31:0] result_low;
output [31:0] result_high;
`ifdef ALTERA_CYCLONE
`else
reg [32:0] result_low_r;
reg [31:0] result_high_r;
wire [31:0] low_16_result;
wire [31:0] middle_resulta;
wire [31:0] middle_resultb;
wire [16:0] long_selection_result;
wire [31:0] high_16_result;
wire [32:0] low_temp_result;
wire [31:0] high_temp_result;
wire [15:0] da;
wire [15:0] db;
wire [15:0] dc;
wire [15:0] dd;
reg [15:0] da_r;
reg [15:0] dc_r;
reg [15:0] middle_resulta_r;
reg [15:0] middle_resultb_r;
assign da = dataa[31:16];
assign db = dataa[15:00];
assign dc = datab[31:16];
assign dd = datab[15:00];
//mult result
//(2^16*A + B) * (2^16*C + D) = 2^32*A*C + 2^16*(AD+CB) + BD
// =
assign low_16_result = db * dd ;
assign middle_resulta = da * dd;
assign middle_resultb = db * dc;
assign long_selection_result = middle_resulta[15:0] + middle_resultb[15:0];
assign high_16_result = da_r * dc_r;
assign low_temp_result = {{1'b0,low_16_result[31:16]} + long_selection_result, low_16_result[15:0]};
assign high_temp_result = high_16_result + middle_resulta_r + middle_resultb_r + result_low_r[32]; //long delay path
assign result_low = result_low_r[31:0];
assign result_high = result_high_r[31:0];
always@(posedge clk or posedge rst)
begin
if (rst) begin
da_r <= 16'h0;
end
else begin
if (r_en)
da_r <= da;
end
end
always@(posedge clk or posedge rst)
begin
if (rst) begin
dc_r <= 16'h0;
end
else begin
if (r_en)
dc_r <= dc;
end
end
always@(posedge clk or posedge rst)
begin
if (rst) begin
result_low_r <= 33'h0;
end
else begin
if (a_en)
result_low_r <= low_temp_result;
end
end
//high result has no dependence on d stall
always@(posedge clk or posedge rst)
begin
if (rst) begin
result_high_r <= 32'h0;
end
else begin
result_high_r <= high_temp_result;
end
end
always@(posedge clk or posedge rst)
begin
if (rst) begin
middle_resulta_r <= 16'h0;
end
else begin
if (a_en)
middle_resulta_r <= middle_resulta[31:16];
end
end
always@(posedge clk or posedge rst)
begin
if (rst) begin
middle_resultb_r <= 16'h0;
end
else begin
if (a_en)
middle_resultb_r <= middle_resultb[31:16];
end
end
`endif
endmodule
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -