******学院
**级***系
姓名:***
学号:********
指导老师:****
目录
一、除法器的基本原理与改进 第1页
二,程序源代码及QuartusII仿真 第4页
三,测试代码及Modelsim仿真 第8页
四,DC综合部分 第11页
五.Astro版图及解释 第14页
一,除法器的基本原理与改进
本设计是基于传统的除法器的基础上改进而来的。
传统除法器的设计:
一、先取除数和被除数的正负关系,然后正值化被除数。传统除法器因为需要递减的关系,所以除数就取负值的补码,方便操作。
二、被除数递减除数,每一次的递减,商数递增。
三、直到被除数小于除数,递减过程剩下的是余数。
四、输出的结果根据除数和被除数的正负关系。
例如:10除以3
其操作流程就是:
1,10-3 余7>3;
2,7-3 余4>3;
3,4-3 余1<3。
即经过三次的运算比较,得出10÷3=3并且余1。此次运算需要三个时钟周期来进行比较运算,显然,随着被除数的增大,其所需的时钟周期会呈递增趋势,加入,被除数过大的话,其过多的时钟消耗将会减慢运算速度。
改进的循环型除法器
循环型的除法器,就是位操作的除法器。循环型的除法器是典型的除法器,假设除数和被除数的位宽为N位,那么除法器就会循环N次的除法操作。
这样时钟消耗就不会随着被除数的增加而增加了,提高了计算的速度。
假设被除数A = 7(0111),除数B = 2 ( 0010 ),它们均为4位位宽。那么操作空间就是 temp 就是 2 * Width。temp[ Width - 1 : 0 ]是用来填充被除数,temp[ Width * 2 - 1:Width -1 ] 是用与除数递减操作。为了方便操作,我们建立 5位位宽的s空间用来寄存除数B的负值补码形式。此外还要考虑同步操作,temp[ Width * 2 - 1:Width -1 ] 和 除数B的递减操作应该发生别的空间,亦即diff空间。diff空间和temp操作空间拥有同样的位宽。
reg [7:0]temp;
reg [7:0]diff;
reg [4:0]s;
首先初始化 temp空间和s空间。temp空间的[ Width - 1 : 0 ] 填入 被除数A,然而s空间用于寄存 除数B负值的补码形式。最后顺便清理diff空间。
temp <= { 4'd0 , A };
s <= B[3] ? { B[3] , B } ? { ~B[3] , ~B + 1'b }; //如果除数B为负值,就直接填入,
//否则转换为负值后填入。
diff <= 8'd0;
s空间寄存B的负值的动作,其实是“小空间向大空间转换 + B绝对负值化”。
接下来的动作,是核心的部分。每一次的操作:
一、在diff空间先取 temp[ Width * 2 - 1 : Width - 1 ] - B 或者 temp[ 7:3] + s
二、然后判断diff空间的“最高位”, 亦即符号位,是逻辑1还是逻辑0。
三、如果是逻辑1表示temp[7:3] 的值小于除数B,temp空间左移一位补0。
反之如果是逻辑0,表示 temp[7:3] 的值大于除数B,temp空间被赋予diff
空间的值,并且左移一位补1。
case( i )
......
1,2,3,4: // 因为除数B和被除数A的位宽均为4位,所以循环4次。
begin
diff = temp + { s , 3'b0 } ; // “=”表示当前步骤取得结果
if( diff[7] ) temp <= { temp [6:0], 1'b0};
else temp <= { diff[6:0] , 1'b1 };
i <= i + 1'b1;
end
当经过 4 次的循环操作后。temp空间的 [ Width - 1 : 0 ] 是商数,[ Width * 2 -1: Width ] 是余数。在这里,重点是“=”这一段代码,diff取得的即时结果是在当前步骤,而不是在该步骤的未来。
assign Quotient = temp[3:0];
assign Reminder = temp[7:4];
如下表所示:
即得:7÷2=3余1。
二,程序源代码QuartusII仿真
module luckyguy_divider
(input clk,
input rst,
input start,
input [7:0] dividend,
input [7:0] divisor,
output done,
output [7:0] quotient,
output [7:0] reminder,
output [15:0] sq_diff,
output [15:0] sq_temp
);
reg [3:0] i;
reg [8:0] s;
reg [15:0] temp;
reg [15:0] diff;
reg isneg;
reg isdone;
always @ (posedge clk or negedge rst)
if (!rst)
begin
i <= 4'd0;
s <= 9'd0;
temp <= 16'd0;
diff <= 16'd0;
isneg <= 1'b0;
isdone <= 1'b0;
end
else if(start)
case(i)
0:
begin
isneg <= dividend[7]^divisor[7];
s <= divisor[7] ? {1'b1, divisor}:{1'b1,~divisor +1'b1};
temp <= dividend[7] ? {8'd0, ~dividend+1'b1}:{8'd0,dividend};
diff <= 16'd0;
i <= i + 1'b1;
end
1,2,3,4,5,6,7,8:
begin
diff = temp + {s,7'd0};
if(diff[15])
temp <= {temp[14:0],1'b0};
else
temp <={diff[14:0],1'b1};
i <= i +1'b1;
end
9:
begin
isdone <= 1'b1;
i <= i +1'b1;
end
10:
begin
isdone <=1'b0;
i <= 2'd0;
end
endcase
assign done = isdone;
assign quotient = isneg ? (~temp[7:0]+1'b1):temp[7:0];
assign reminder = temp[15:8];
assign sq_diff = diff;
assign sq_temp = temp;
endmodule
例化模块:
仿真波形:
输入被除数和除数分别是25和4,得到的结果是商为6,余数为1,符合正确运算。
其RTL电路:
三,测试代码及Modelsim仿真
`timescale 1ps/1ps
module test_luckyguy_divider();
reg clk;
reg rst;
reg start;
reg [7:0]dividend;
reg [7:0]divisor;
wire done;
wire [7:0]quotient;
wire [7:0]reminder;
wire [15:0]sq_diff;
wire [15:0]sq_temp;
initial
begin
rst=0;#0;rst=1;
clk=0;
forever
#10 clk=~clk;
end
reg [1:0]i;
always @ (posedge clk or negedge rst)
if(!rst)
begin
i<=2'b00;
dividend<=8'd0;
divisor<=8'd0;
start<=1'b0;
end
else
case (i)
2'b00:
if(done)
begin
start<=1'b0;
i<=i+1'b1;
end
else
begin
dividend<=8'd8; //被除数为8
divisor<=8'b11111101;//除数为-3
start<=1'b1;
end
2'b01:
if(done)
begin
start<=1'b0;
i<=i+1'b1;
end
else
begin
dividend<=8'b10000010; //被除数为-126
divisor<=8'b11111100;//除数为-4
start<=1'b1;
end
2'b10:
if(done)
begin
start<=1'b0;
i<=i+1'b1;
end
else
begin
dividend<=8'd100;//被除数为100
divisor<=8'd25;//除数为4
start<=1'b1;
end
2'b11:
i<=4'd3;
endcase
luckyguy_divider m(.clk(clk),.rst(rst),.start(start),.dividend(dividend),.divisor(divisor),.done(done),.quotient(quotient),.reminder(reminder),.sq_diff(sq_diff),.sq_temp(sq_temp));
endmodule
该测试代码一共有三组测试数据分别是:8 -3、-126 -4 、100 25。
其结果分别是:商-2余2、商31余2、商4余0.
四,DC综合部分
Table I. DC synthesis results
target_library | list cb13fs120_tsmc_max.db cb13io320_tsmc_max.db |
link_library | cb13_tsmc_memory_max.db cb13io320_tsmc_max.db cb13special.db cb13fs120_tsmc_max.db cb13fs120_tsmc_min.db cb13fs120_tsmc_typ.db |
symbol_library | generic.sdb |
search_path | /home/sevidchang/softwares/synopsys /libraries/syn/home/sevidchang/softwares/synopsys/ dw/sim_ver ./scripts ./libraries ./sources |
area or gate account | Number of ports: 68 Number of nets: 330 Number of cells: 275 Number of references: 25 Combinational area: 233434.187500 Noncombinational area: 392.750000 Net Interconnect area: 279.845215 Total cell area: 233826.812500 Total area: 234106.781250 |
power | Cell Internal Power = 51.0636 mW (60%) Net Switching Power = 33.5905 mW (40%) --------- Total Dynamic Power = 84.6541 mW (100%) Cell Leakage Power = 8.6295 uW |
number and types of constraint violations | 0 |
max delay (met/violated/slack) | data required time 9.81 data arrival time -6.87 ------------------------------------------------------ slack (MET) 2.94 |
min delay (met/violated/slack) | data required time -0.06 data arrival time -0.58 ------------------------------------------------------- slack (MET) 0. |
脚本文件:luckyguy.tcl
################################################################################
# IMPORTANT:WHEN YOU INSERT IO PADS AUTOMATICALLY,YOU SHOULD ADD
IO LIBRARY #
# (E.G.,"cb13io320_tsmc_max.db") TO YOUR "target_library" OF YOUR ".synopsys_dc.setup". #
# BUT WHEN YOU INSERT YOUR IO PADS MANUALLY IN A TOP MODULE,YOU #
# SHOULD NOT ADD IO LIBRARY TO YOUR "target_library". #
################################################################################
# variables declaration
set TOP luckyguy_divider
set MAPPED mapped
set REPORTS_DIR reports
# setup max/min library
set_min_library cb13fs120_tsmc_max.db -min_version cb13fs120_tsmc_min.db
# read in design
read_verilog sources/luckyguy_divider.v
current_design luckyguy_divider
# insert pads
set_port_is_pad [all_inputs]
set_port_is_pad [all_outputs]
set_pad_type -exact pc3c01 [get_ports clk]
set_pad_type -exact pc3d01 [remove_from_collection [all_inputs] [get_ports clk]]
set_pad_type -exact pc3o01 [all_outputs]
# uniquify (MYNOTE:SHOULD BE A "uniquify" HERE IF THERE ARE MULTI-REFERENCES.)
insert_pads
# set constraint on design
set_max_area 0
create_clock -p 10 -n my_clock [get_ports clk]
set_dont_touch_network [get_clocks my_clock]
set_input_delay 0.6 -max -clock my_clock [remove_from_collection [all_inputs] [get_ports clk]]
set_input_delay 0.0 -min -clock my_clock [remove_from_collection [all_inputs] [get_ports clk]]
# NOTE:"-max/min" specifies that delay_value refers to the longest/shortest path
set_output_delay 0.6 -max -clock my_clock [all_outputs]
set_output_delay -0.1 -min -clock my_clock [all_outputs]
set_drive 0 [all_inputs]
set_load [load_of cb13fs120_tsmc_max/bufbd1/I] [all_outputs]
set_operating_conditions -max cb13fs120_tsmc_max
set_max_transition 0.5 [remove_from_collection [all_inputs] [get_ports clk]]
set_max_transition 0.5 [all_outputs]
# compile design
current_design luckyguy_divider
compile
# write the result
current_design luckyguy_divider
write -f db -hierarchy -output $MAPPED/$TOP.db
write -f verilog -hierarchy -output $MAPPED/$TOP.v
write_sdf $MAPPED/$TOP.sdf
write_script -output $MAPPED/$TOP.tcl
report_timing -delay max -max_paths 1 -path full -nworst 1 > $REPORTS_DIR/timing_$TOP.rpt
report_timing -delay min -max_paths 1 -path full -nworst 1 >> $REPORTS_DIR/timing_$TOP.rpt
report_area > $REPORTS_DIR/area_$TOP.rpt |
版图管脚分配:
一共有84个管脚,每面21个管脚,其中程序的输入输出共68个管脚,每面还有VDD与VSS各两个。
1、DC综合出的文件:
luckyguy_divider.v:
module luckyguy_divider_DW01_inc_8_0 ( A, SUM );
input [7:0] A;
output [7:0] SUM;
wire \\carry[7] , \\carry[6] , \\carry[5] , \\carry[4] , \\carry[3] ,
\\carry[2] , n1;
ah01d0 U1_1_3 ( .A(A[3]), .B(\\carry[3] ), .S(SUM[3]), .CO(\\carry[4] ) );
ah01d0 U1_1_5 ( .A(A[5]), .B(\\carry[5] ), .S(SUM[5]), .CO(\\carry[6] ) );
ah01d0 U1_1_2 ( .A(A[2]), .B(\\carry[2] ), .S(SUM[2]), .CO(\\carry[3] ) );
ah01d0 U1_1_6 ( .A(A[6]), .B(\\carry[6] ), .S(SUM[6]), .CO(\\carry[7] ) );
ah01d0 U1_1_1 ( .A(A[1]), .B(A[0]), .S(SUM[1]), .CO(\\carry[2] ) );
ah01d0 U1_1_4 ( .A(A[4]), .B(\\carry[4] ), .S(SUM[4]), .CO(\\carry[5] ) );
xn02d1 U5 ( .A1(n1), .A2(\\carry[7] ), .ZN(SUM[7]) );
inv0d1 U6 ( .I(A[7]), .ZN(n1) );
inv0d1 U7 ( .I(A[0]), .ZN(SUM[0]) );
endmodule
module luckyguy_divider_DW01_addsub_8_0 ( A, B, CI, ADD_SUB, SUM, CO );
input [7:0] A;
input [7:0] B;
output [7:0] SUM;
input CI, ADD_SUB;
output CO;
wire \\carry[6] , \\carry[5] , \\carry[4] , \\carry[3] , \\carry[2] ,
\\carry[1] , \\carry[0] , \\B_AS[6] , \\B_AS[5] , \\B_AS[4] , \\B_AS[3] ,
\\B_AS[2] , \\B_AS[1] , \\B_AS[0] , n1, n2, n3, n4, n5, n6, n7;
。。
。。
。。
。。
。。
assign \\carry[0] = B[7];
inv0d1 U229 ( .I(i[3]), .ZN(n208) );
pc3d01 U230 ( .PAD(rst), .CIN(n70) );
pc3d01 U231 ( .PAD(start), .CIN(n71) );
pc3d01 U232 ( .PAD(dividend[7]), .CIN(n72) );
pc3d01 U233 ( .PAD(dividend[6]), .CIN(n73) );
pc3d01 U234 ( .PAD(dividend[5]), .CIN(n74) );
pc3d01 U235 ( .PAD(dividend[4]), .CIN(n75) );
pc3d01 U236 ( .PAD(dividend[3]), .CIN(n76) );
pc3d01 U237 ( .PAD(dividend[2]), .CIN(n77) );
pc3d01 U238 ( .PAD(dividend[1]), .CIN(n78) );
pc3d01 U239 ( .PAD(dividend[0]), .CIN(n79) );
pc3d01 U240 ( .PAD(divisor[7]), .CIN(n80) );
pc3d01 U241 ( .PAD(divisor[6]), .CIN(n81) );
pc3d01 U242 ( .PAD(divisor[5]), .CIN(n82) );
pc3d01 U243 ( .PAD(divisor[4]), .CIN(n83) );
pc3d01 U244 ( .PAD(divisor[3]), .CIN(n84) );
pc3d01 U245 ( .PAD(divisor[2]), .CIN(n85) );
pc3d01 U246 ( .PAD(divisor[1]), .CIN(n86) );
pc3d01 U247 ( .PAD(divisor[0]), .CIN(n87) );
pc3o01 U248 ( .I(n259), .PAD(done) );
pc3o01 U249 ( .I(n260), .PAD(quotient[7]) );
pc3o01 U250 ( .I(n261), .PAD(quotient[6]) );
pc3o01 U251 ( .I(n262), .PAD(quotient[5]) );
pc3o01 U252 ( .I(n263), .PAD(quotient[4]) );
pc3o01 U253 ( .I(n2), .PAD(quotient[3]) );
pc3o01 U254 ( .I(n265), .PAD(quotient[2]) );
pc3o01 U255 ( .I(n266), .PAD(quotient[1]) );
pc3o01 U256 ( .I(n267), .PAD(quotient[0]) );
pc3o01 U257 ( .I(n268), .PAD(reminder[7]) );
pc3o01 U258 ( .I(n269), .PAD(reminder[6]) );
pc3o01 U259 ( .I(n270), .PAD(reminder[5]) );
pc3o01 U260 ( .I(n271), .PAD(reminder[4]) );
pc3o01 U261 ( .I(n272), .PAD(reminder[3]) );
pc3o01 U262 ( .I(n273), .PAD(reminder[2]) );
pc3o01 U263 ( .I(n274), .PAD(reminder[1]) );
pc3o01 U2 ( .I(n275), .PAD(reminder[0]) );
pc3o01 U265 ( .I(n276), .PAD(sq_diff[15]) );
pc3o01 U266 ( .I(n277), .PAD(sq_diff[14]) );
pc3o01 U267 ( .I(n278), .PAD(sq_diff[13]) );
pc3o01 U268 ( .I(n279), .PAD(sq_diff[12]) );
pc3o01 U269 ( .I(n280), .PAD(sq_diff[11]) );
pc3o01 U270 ( .I(n281), .PAD(sq_diff[10]) );
pc3o01 U271 ( .I(n282), .PAD(sq_diff[9]) );
pc3o01 U272 ( .I(n283), .PAD(sq_diff[8]) );
pc3o01 U273 ( .I(n284), .PAD(sq_diff[7]) );
pc3o01 U274 ( .I(n285), .PAD(sq_diff[6]) );
pc3o01 U275 ( .I(n286), .PAD(sq_diff[5]) );
pc3o01 U276 ( .I(n287), .PAD(sq_diff[4]) );
pc3o01 U277 ( .I(n288), .PAD(sq_diff[3]) );
pc3o01 U278 ( .I(n2), .PAD(sq_diff[2]) );
pc3o01 U279 ( .I(n290), .PAD(sq_diff[1]) );
pc3o01 U280 ( .I(n291), .PAD(sq_diff[0]) );
pc3o01 U281 ( .I(n268), .PAD(sq_temp[15]) );
pc3o01 U282 ( .I(n269), .PAD(sq_temp[14]) );
pc3o01 U283 ( .I(n270), .PAD(sq_temp[13]) );
pc3o01 U284 ( .I(n271), .PAD(sq_temp[12]) );
pc3o01 U285 ( .I(n272), .PAD(sq_temp[11]) );
pc3o01 U286 ( .I(n273), .PAD(sq_temp[10]) );
pc3o01 U287 ( .I(n274), .PAD(sq_temp[9]) );
pc3o01 U288 ( .I(n275), .PAD(sq_temp[8]) );
pc3o01 U2 ( .I(n292), .PAD(sq_temp[7]) );
pc3o01 U290 ( .I(n293), .PAD(sq_temp[6]) );
pc3o01 U291 ( .I(n294), .PAD(sq_temp[5]) );
pc3o01 U292 ( .I(n295), .PAD(sq_temp[4]) );
pc3o01 U293 ( .I(n296), .PAD(sq_temp[3]) );
pc3o01 U294 ( .I(n297), .PAD(sq_temp[2]) );
pc3o01 U295 ( .I(n298), .PAD(sq_temp[1]) );
pc3o01 U296 ( .I(n299), .PAD(sq_temp[0]) );
luckyguy_divider_DW01_inc_8_0 add_66 ( .A({N151, N152, N153, N154, N155,
N156, N157, N158}), .SUM({N166, N165, N1, N163, N162, N161, N160,
N159}) );
luckyguy_divider_DW01_addsub_8_0 r154 ( .A({1'b0, 1'b0, 1'b0, 1'b0, 1'b0,
1'b0, 1'b0, n131}), .B({\\U71/U7/Z_0 , \\U71/U6/Z_6 , \\U71/U6/Z_5 ,
\\U71/U6/Z_4 , \\U71/U6/Z_3 , \\U71/U6/Z_2 , \\U71/U6/Z_1 , \\U71/U6/Z_0 }),
.CI(1'b0), .ADD_SUB(\\U71/U7/Z_0 ), .SUM({N210, N209, N208, N207, N206,
N205, N204, N203}) );
luckyguy_divider_DW01_addsub_16_0 r153 ( .A({\\U71/U2/Z_15 , \\U71/U2/Z_14 ,
\\U71/U2/Z_13 , \\U71/U2/Z_12 , \\U71/U2/Z_11 , \\U71/U2/Z_10 ,
\\U71/U2/Z_9 , \\U71/U2/Z_8 , \\U71/U2/Z_7 , 1'b0, 1'b0, 1'b0, 1'b0, 1'b0,
1'b0, 1'b0}), .B({\\U71/U3/Z_15 , \\U71/U3/Z_14 , \\U71/U3/Z_13 ,
\\U71/U3/Z_12 , \\U71/U3/Z_11 , \\U71/U3/Z_10 , \\U71/U3/Z_9 ,
\\U71/U3/Z_8 , \\U71/U3/Z_7 , \\U71/U3/Z_6 , \\U71/U3/Z_5 , \\U71/U3/Z_4 ,
\\U71/U3/Z_3 , \\U71/U3/Z_2 , \\U71/U3/Z_1 , \\U71/U3/Z_0 }), .CI(1'b0),
.ADD_SUB(\\U71/U4/Z_0 ), .SUM({N190, N1, N188, N187, N186, N185, N184,
N183, N182, N181, N180, N179, N178, N177, N176, N175}) );
endmodule
2、Asrto管脚分配:
luckyguy_divider.tdf
define _cell (geGetEditCell)
; create power pads
; Core power supply
。。
。。
。。
。。
。。
;;;;;;;;;;;;;;;;;;;;;;;;;;
;; dbCreateCellInst : Creates a cell instance in a cell.
;; SYNTAX:
;; dbCreateCellInst cellId "childLibName" "childCellName" "ce;; llInstName" "rotationStr" "mirrorStr" Points "topCellName"
;;
;; tdfPurgePadConstr: instructs the Synopsys tool to delete all pin or pad
;; location constraints created previously by pin or pad
;; functions.
;;
;; pad : Creates a TDF pad constraint with the specified values.
;; SYNTAX:
;; pad ;;;;;;;;;;;;;;;;;;;;;;;;;; ; place the corner cells pad "cornerll" "bottom" pad "cornerur" "top" pad "cornerlr" "right" pad "cornerul" "left" ; place io and power pads pad "U70" "left" 1 pad "U230" "left" 2 pad "U231" "left" 3 pad "U232" "left" 4 pad "U233" "left" 5 pad "U234" "left" 6 pad "U235" "left" 7 pad "U236" "left" 8 pad "vdd1left" "left" 9 pad "vdd2left" "left" 10 pad "vss1left" "left" 11 pad "vss2left" "left" 12 pad "U237" "left" 13 pad "U238" "left" 14 pad "U239" "left" 15 pad "U240" "left" 16 pad "U241" "left" 17 pad "U242" "left" 18 pad "U243" "left" 19 pad "U244" "left" 20 pad "U245" "left" 21 pad "U246" "top" 1 pad "U247" "top" 2 pad "U248" "top" 3 pad "U249" "top" 4 pad "U250" "top" 5 pad "U251" "top" 6 pad "U252" "top" 7 pad "U253" "top" 8 pad "vdd1top" "top" 9 pad "vdd2top" "top" 10 pad "vss1top" "top" 11 pad "vss2top" "top" 12 pad "U254" "top" 13 pad "U255" "top" 14 pad "U256" "top" 15 pad "U257" "top" 16 pad "U258" "top" 17 pad "U259" "top" 18 pad "U260" "top" 19 pad "U261" "top" 20 pad "U262" "top" 21 pad "U263" "right" 1 pad "U2" "right" 2 pad "U265" "right" 3 pad "U266" "right" 4 pad "U267" "right" 5 pad "U268" "right" 6 pad "U269" "right" 7 pad "U270" "right" 8 pad "vdd1right" "right" 9 pad "vdd2right" "right" 10 pad "vss1right" "right" 11 pad "vss2right" "right" 12 pad "U271" "right" 13 pad "U272" "right" 14 pad "U273" "right" 15 pad "U274" "right" 16 pad "U275" "right" 17 pad "U276" "right" 18 pad "U277" "right" 19 pad "U278" "right" 20 pad "U279" "right" 21 pad "U280" "bottom" 1 pad "U281" "bottom" 2 pad "U282" "bottom" 3 pad "U283" "bottom" 4 pad "U284" "bottom" 5 pad "U285" "bottom" 6 pad "U286" "bottom" 7 pad "U287" "bottom" 8 pad "vdd1bottom" "bottom" 9 pad "vdd2bottom" "bottom" 10 pad "vss1bottom" "bottom" 11 pad "vss2bottom" "bottom" 12 pad "U288" "bottom" 13 pad "U2" "bottom" 14 pad "U290" "bottom" 15 pad "U291" "bottom" 16 pad "U292" "bottom" 17 pad "U293" "bottom" 18 pad "U294" "bottom" 19 pad "U295" "bottom" 20 pad "U296" "bottom" 21