• 【原创】DE2实验练习解答—lab6 Adders,Subtractors,and Multipliers [Veriglog] [Digital logic]


    本练习的目的是实现算术运算电路。每种电路用2种方法实现:Verilog语言描述和LPM。并比较其不同。

    Part I 8-bit的加法器

    要求:

    1. 支持有符号的数的2的补码的形式;
    2. 带溢出信号,当结果不对时,溢出为1;

    代码part1.v

     

    1 /*
    2 *(C) yf.x 2010 http://halflife.cnblogs.com
    3 *
    4 *Complier :Quartus II 9.1
    5 *Filename :adder_8b_reg.v
    6 *Description:A 8-bit adder,top-level file.which support signed number in 2's complement.
    7 *Release :06/30/2010 1.0
    8  */
    9
    10  module adder_8b_reg(SW, //加数A和B
    11   KEY, //脉冲和复位
    12   LEDR, //
    13   LEDG, //溢出
    14   HEX7, //16进制显示加数A
    15   HEX6,
    16 HEX5, //16进制显示加数B
    17   HEX4,
    18 HEX1, //16进制显示和
    19   HEX0
    20 );
    21
    22 input [15:0]SW;
    23 input [1:0]KEY;
    24 output [7:0]LEDR;
    25 output [8:8]LEDG;
    26 output [6:0]HEX7,HEX6,HEX5,HEX4,HEX1,HEX0;
    27
    28 adder u0(.A(SW[15:8]),
    29 .B(SW[7:0]),
    30 .clk(KEY[1]),
    31 .rst_n(KEY[0]),
    32 .sum(LEDR),
    33 .overflow(LEDG)
    34 );
    35
    36 seg7_lut u1(.oseg(HEX7),
    37 .idig(SW[15:12])
    38 );
    39 seg7_lut u2(.oseg(HEX6),
    40 .idig(SW[11:8])
    41 );
    42 seg7_lut u3(.oseg(HEX5),
    43 .idig(SW[7:4])
    44 );
    45 seg7_lut u4(.oseg(HEX4),
    46 .idig(SW[3:0])
    47 );
    48 seg7_lut u5(.oseg(HEX1),
    49 .idig(LEDR[7:4])
    50 );
    51 seg7_lut u6(.oseg(HEX0),
    52 .idig(LEDR[3:0])
    53 );
    54
    55 endmodule
    56
    57 /*
    58 *(C) yf.x 2010 http://halflife.cnblogs.com
    59 *
    60 *Complier :Quartus II 9.1
    61 *Filename :adder.v
    62 *Description:A 8-bit adder,which support signed number in 2's complement.
    63 *Release :06/30/2010 1.0
    64 */
    65
    66
    67 //=================pins instruction============//
    68 // A | SW[15:8] | HEX[7:6]
    69 // B | SW[7:0] | HEX[5:4]
    70 // clk | KEY[1]
    71 // rst_n | KEY[0]
    72 // sum | LEDR[7:0] | HEX[1:0]
    73 // overflow | LEDG[8]
    74 //=============================================//
    75 module adder (A,
    76 B,
    77 clk,
    78 rst_n,
    79 sum,
    80 overflow
    81 );
    82
    83 parameter n=8;
    84 input [n-1:0]A,B;
    85 input clk,rst_n;
    86 output [n-1:0]sum;
    87 output overflow;
    88 reg overflow;
    89 reg [n-1:0]Areg,Breg,Sreg;
    90 wire [n-1:0]Sw;
    91 wire cout,over_flow;
    92
    93
    94 addern n_bit_adder(0,Areg,Breg,Sw,cout);
    95 defparam n_bit_adder.n=8;
    96 assign over_flow=cout^Areg[n-1]^Breg[n-1]^Sw[n-1];
    97 assign sum=Sreg;
    98
    99 always @(posedge clk or negedge rst_n)
    100 if(!rst_n)
    101 begin
    102 Areg<=0;
    103 Breg<=0;
    104 Sreg<=0;
    105 overflow<=0;
    106 end
    107 else
    108 begin
    109 Areg<=A;
    110 Breg<=B;
    111 Sreg<=Sw;
    112 overflow<=over_flow;
    113 end
    114 endmodule
    115
    116 /*
    117 *(C) yf.x 2010 http://halflife.cnblogs.com
    118 *
    119 *Complier :Quartus II 9.1
    120 *Filename :addern.v
    121 *Description:8-bit 行波进位加法器
    122 *Release :06/30/2010 1.0
    123 */
    124
    125 module addern(carryin,X,Y,S,carryout);
    126 parameter n=8;
    127 input carryin;
    128 input [n-1:0]X,Y;
    129 output reg [n-1:0]S;
    130 output reg carryout;
    131 reg [n:0]C;
    132 integer k;
    133
    134 always @(X,Y,carryin)
    135 begin
    136 C[0]=carryin;
    137 for(k=0;k<n;k=k+1)
    138 begin
    139 S[k]=X[k]^Y[k]^C[k];
    140 C[k+1]=(X[k]&Y[k])|(X[k]&C[k])|(Y[k]&C[k]);
    141 end
    142 carryout=C[n];
    143 end
    144
    145
    146 endmodule
    147
    148
    149

    001

    图1 part1编译结果

    这部分要注意的就是2的补码的表示,和溢出信号的推导。可参阅Reference【1】。

    Part II 加、减电路

    要求:

    在part I的基础上修改,使其可做加、减运算。

    代码part2.v

     

    1 /*
    2 *(C) yf.x 2010 http://halflife.cnblogs.com
    3 *
    4 *Complier :Quartus II 9.1
    5 *Filename :part2.v
    6 *Description:Top-level file of addersubtractor circuit.
    7 *Release :06/30/2010 1.0
    8 */
    9
    10 module part2 (SW, //加数A和B
    11 KEY, //脉冲和复位
    12 LEDR, //
    13 LEDG, //溢出
    14 HEX7, //16进制显示加数A
    15 HEX6,
    16 HEX5, //16进制显示加数B
    17 HEX4,
    18 HEX1, //16进制显示和
    19 HEX0
    20 );
    21
    22 input [16:0]SW;
    23 input [1:0]KEY;
    24 output [7:0]LEDR;
    25 output [8:8]LEDG;
    26 output [6:0]HEX7,HEX6,HEX5,HEX4,HEX1,HEX0;
    27 wire [7:0]sum;
    28
    29 addersubtractor u0(.A(SW[15:8]),
    30 .B(SW[7:0]),
    31 .clk(KEY[1]),
    32 .rst_n(KEY[0]),
    33 .S(sum),
    34 .overflow(LEDG),
    35 .addsub(SW[16])
    36 );
    37
    38 assign LEDR=sum;
    39
    40 seg7_lut u1(.oseg(HEX7),
    41 .idig(SW[15:12])
    42 );
    43 seg7_lut u2(.oseg(HEX6),
    44 .idig(SW[11:8])
    45 );
    46 seg7_lut u3(.oseg(HEX5),
    47 .idig(SW[7:4])
    48 );
    49 seg7_lut u4(.oseg(HEX4),
    50 .idig(SW[3:0])
    51 );
    52 seg7_lut u5(.oseg(HEX1),
    53 .idig(sum[7:4])
    54 );
    55 seg7_lut u6(.oseg(HEX0),
    56 .idig(sum[3:0])
    57 );
    58
    59 endmodule
    60
    61 /*
    62 *(C) yf.x 2010 http://halflife.cnblogs.com
    63 *
    64 *Complier :Quartus II 9.1
    65 *Filename :addersubtractor.v
    66 *Description:addersubtractor ciucuit.
    67 *Release :06/30/2010 1.0
    68 */
    69
    70 //Top-level module
    71 module addersubtractor(A,
    72 B,
    73 clk,
    74 rst_n,
    75 addsub, //0=+,1=-;
    76 S,
    77 overflow
    78 );
    79 parameter n=8;
    80 input [n-1:0]A,B;
    81 input clk,rst_n,addsub;
    82 output [n-1:0]S;
    83 output overflow;
    84
    85 reg addsub_r,overflow;
    86 reg [n-1:0]Areg,Breg,Sreg;
    87 wire [n-1:0]G, H,M;
    88 wire cout,over_flow;
    89
    90 //Define combinational logic circuit
    91 assign H=Breg^{n{addsub_r}},G=Areg;
    92 addern u0(addsub_r,G,H,M,cout);
    93 defparam u0.n=n;
    94 assign over_flow=cout^G[n-1]^H[n-1]^M[n-1];
    95 assign S=Sreg;
    96
    97 //Define flip-flops and registers
    98 always @(posedge clk or negedge rst_n)
    99 if(!rst_n)
    100 begin
    101 Areg<=0;
    102 Breg<=0;
    103 Sreg<=0;
    104 overflow<=0;
    105 addsub_r<=0;
    106 end
    107 else
    108 begin
    109 Areg<=A;
    110 Breg<=B;
    111 Sreg<=M;
    112 overflow<=over_flow;
    113 addsub_r<=addsub;
    114 end
    115 endmodule
     

    001

    图2 Part II编译结果

    这部分,很简单,由2的补码表示可知,减法运算变为加法,只需要在part I加一个控制信号add_sub,并将其作为cin,当其为1时,即为减法。

    Part III 使用lpm_add_sub实现Part I

    代码part3.v

     

    1 //Top-level file
    2 module part3 (SW, //加数A和B
    3 KEY, //脉冲和复位
    4 LEDR, //
    5 LEDG, //溢出
    6 HEX7, //16进制显示加数A
    7 HEX6,
    8 HEX5, //16进制显示加数B
    9 HEX4,
    10 HEX1, //16进制显示和
    11 HEX0
    12 );
    13
    14 input [15:0]SW;
    15 input [1:0]KEY;
    16 output [7:0]LEDR;
    17 output [8:8]LEDG;
    18 output [6:0]HEX7,HEX6,HEX5,HEX4,HEX1,HEX0;
    19
    20 reg [7:0]Areg,Breg,Sreg;
    21 wire over_flow;
    22 wire [7:0]S,H,M;
    23
    24 assign LEDR=S;
    25 assign LEDG=over_flow;
    26 assign H=Areg,M=Breg;
    27
    28 lpa_add8 nbit_adder(.cin(0),
    29 .dataa(H[7:0]),
    30 .datab(M[7:0]),
    31 .overflow(over_flow),
    32 .result(S)
    33 );
    34
    35 always @(posedge KEY[1] or negedge KEY[0])
    36 if(!KEY[0])
    37 begin
    38 Areg<=0;
    39 Breg<=0;
    40 Sreg<=0;
    41
    42 end
    43 else
    44 begin
    45 Areg<=SW[15:8];
    46 Breg<=SW[7:0];
    47 Sreg<=S;
    48
    49 end
    50
    51 seg7_lut u1(.oseg(HEX7),
    52 .idig(H[7:4])
    53 );
    54 seg7_lut u2(.oseg(HEX6),
    55 .idig(H[3:0])
    56 );
    57 seg7_lut u3(.oseg(HEX5),
    58 .idig(M[7:4])
    59 );
    60 seg7_lut u4(.oseg(HEX4),
    61 .idig(M[3:0])
    62 );
    63 seg7_lut u5(.oseg(HEX1),
    64 .idig(S[7:4])
    65 );
    66 seg7_lut u6(.oseg(HEX0),
    67 .idig(S[3:0])
    68 );
    69
    70 endmodule
    71
    72 // synopsys translate_off
    73 `timescale 1 ps / 1 ps
    74 // synopsys translate_on
    75 module lpa_add8 (
    76 cin,
    77 dataa,
    78 datab,
    79 overflow,
    80 result);
    81
    82 input cin;
    83 input [7:0] dataa;
    84 input [7:0] datab;
    85 output overflow;
    86 output [7:0] result;
    87
    88 wire sub_wire0;
    89 wire [7:0] sub_wire1;
    90 wire overflow = sub_wire0;
    91 wire [7:0] result = sub_wire1[7:0];
    92
    93 lpm_add_sub lpm_add_sub_component (
    94 .dataa (dataa),
    95 .datab (datab),
    96 .cin (cin),
    97 .overflow (sub_wire0),
    98 .result (sub_wire1)
    99 // synopsys translate_off
    100 ,
    101 .aclr (),
    102 .add_sub (),
    103 .clken (),
    104 .clock (),
    105 .cout ()
    106 // synopsys translate_on
    107 );
    108 defparam
    109 lpm_add_sub_component.lpm_direction = "ADD",
    110 lpm_add_sub_component.lpm_hint = "ONE_INPUT_IS_CONSTANT=NO,CIN_USED=YES",
    111 lpm_add_sub_component.lpm_representation = "SIGNED",
    112 lpm_add_sub_component.lpm_type = "LPM_ADD_SUB",
    113 lpm_add_sub_component.lpm_width = 8;
    114
    115
    116 endmodule

    Part IV 用lpm_add_sub实现Part II

    代码part4.v

    1 module part4 (SW, //加数A和B
    2 KEY, //脉冲和复位
    3 LEDR, //
    4 LEDG, //溢出
    5 HEX7, //16进制显示加数A
    6 HEX6,
    7 HEX5, //16进制显示加数B
    8 HEX4,
    9 HEX1, //16进制显示和
    10 HEX0
    11 );
    12
    13 input [16:0]SW;
    14 input [1:0]KEY;
    15 output [7:0]LEDR;
    16 output [8:8]LEDG;
    17 output [6:0]HEX7,HEX6,HEX5,HEX4,HEX1,HEX0;
    18 wire [7:0]sum;
    19 reg [7:0]Areg,Breg,Sreg;
    20 wire over_flow,cout;
    21 wire [7:0]Aw,Bw;
    22
    23
    24 assign Aw=Areg,Bw=Breg;
    25
    26
    27 always @(posedge KEY[1] or negedge KEY[0])
    28 begin
    29 if(!KEY[0])
    30 begin
    31 Areg<=0;
    32 Breg<=0;
    33 Sreg<=0;
    34 end
    35 else
    36 begin
    37 Areg<=SW[15:8];
    38 Breg<=SW[7:0];
    39 Sreg<=sum;
    40 end
    41 end
    42
    43
    44 lpm_addsub u0(.dataa(Aw),
    45 .datab(Bw),
    46 .cin(~SW[16]),
    47 .cout(cout),
    48 .result(sum),
    49 .overflow(over_flow),
    50 .add_sub(SW[16])
    51 );
    52
    53 assign LEDR=sum,LEDG=over_flow;
    54
    55 seg7_lut u1(.oseg(HEX7),
    56 .idig(SW[15:12])
    57 );
    58 seg7_lut u2(.oseg(HEX6),
    59 .idig(SW[11:8])
    60 );
    61 seg7_lut u3(.oseg(HEX5),
    62 .idig(SW[7:4])
    63 );
    64 seg7_lut u4(.oseg(HEX4),
    65 .idig(SW[3:0])
    66 );
    67 seg7_lut u5(.oseg(HEX1),
    68 .idig(sum[7:4])
    69 );
    70 seg7_lut u6(.oseg(HEX0),
    71 .idig(sum[3:0])
    72 );
    73
    74 endmodule
    75
    76 // synopsys translate_off
    77 `timescale 1 ps / 1 ps
    78 // synopsys translate_on
    79 module lpm_addsub (
    80 add_sub,
    81 cin,
    82 dataa,
    83 datab,
    84 cout,
    85 overflow,
    86 result);
    87
    88 input add_sub;
    89 input cin;
    90 input [7:0] dataa;
    91 input [7:0] datab;
    92 output cout;
    93 output overflow;
    94 output [7:0] result;
    95
    96 wire sub_wire0;
    97 wire sub_wire1;
    98 wire [7:0] sub_wire2;
    99 wire overflow = sub_wire0;
    100 wire cout = sub_wire1;
    101 wire [7:0] result = sub_wire2[7:0];
    102
    103 lpm_add_sub lpm_add_sub_component (
    104 .dataa (dataa),
    105 .add_sub (add_sub),
    106 .datab (datab),
    107 .cin (cin),
    108 .overflow (sub_wire0),
    109 .cout (sub_wire1),
    110 .result (sub_wire2)
    111 // synopsys translate_off
    112 ,
    113 .aclr (),
    114 .clken (),
    115 .clock ()
    116 // synopsys translate_on
    117 );
    118 defparam
    119 lpm_add_sub_component.lpm_direction = "UNUSED",
    120 lpm_add_sub_component.lpm_hint = "ONE_INPUT_IS_CONSTANT=NO,CIN_USED=YES",
    121 lpm_add_sub_component.lpm_representation = "SIGNED",
    122 lpm_add_sub_component.lpm_type = "LPM_ADD_SUB",
    123 lpm_add_sub_component.lpm_width = 8;
    124
    125
    126 endmodule
    127
    128 // ============================================================
    129 // CNX file r

    001

    图3 Part IV时序分析

    Part V 4X4乘法器

    代码part5.v

     

    1 //Top-level file
    2 module part5(SW, //SW[11:8]=A,SW[3:0]=B
    3 HEX6, //A
    4 HEX4, //B
    5 HEX1, //P
    6 HEX0
    7 );
    8
    9 input [11:0]SW;
    10 output [6:0]HEX6,HEX4,HEX1,HEX0;
    11 wire [7:0]P;
    12
    13 multiplier u0(SW[11:8],SW[3:0],P);
    14 seg7_lut A(.oseg(HEX6),
    15 .idig(SW[11:8])
    16 );
    17 seg7_lut B(.oseg(HEX4),
    18 .idig(SW[3:0])
    19 );
    20 seg7_lut p1(.oseg(HEX1),
    21 .idig(P[7:4])
    22 );
    23 seg7_lut p0(.oseg(HEX0),
    24 .idig(P[3:0])
    25 );
    26 endmodule
    27
    28 //multiplier
    29 module multiplier(A,B,P);
    30 input [3:0]A,B;
    31 output [7:0]P;
    32
    33 wire [3:1]ctop,csecond,cbottom;
    34 wire [5:2]pp1;
    35 wire [6:3]pp2;
    36
    37 assign P[0]=A[0]&B[0];
    38
    39 u0 toprow_stage0(A[1],A[0],B[1],B[0],0,ctop[1],P[1]);
    40 u0 toprow_stage1(A[2],A[1],B[1],B[0],ctop[1],ctop[2],pp1[2]);
    41 u0 toprow_stage2(A[3],A[2],B[1],B[0],ctop[2],ctop[3],pp1[3]);
    42 u0 toprow_stage3(0,A[3],B[1],B[0],ctop[3],pp1[5],pp1[4]);
    43 u1 secondrow_stage0(pp1[2],A[0],B[2],0,csecond[1],P[2]);
    44 u1 secondrow_stage1(pp1[3],A[1],B[2],csecond[1],csecond[2],pp2[3]);
    45 u1 secondrow_stage2(pp1[4],A[2],B[2],csecond[2],csecond[3],pp2[4]);
    46 u1 secondrow_stage3(pp1[5],A[3],B[2],csecond[3],pp2[6],pp2[5]);
    47 u1 bottomrow_stage0(pp2[3],A[0],B[3],0,cbottom[1],P[3]);
    48 u1 bottomrow_stage1(pp2[4],A[1],B[3],cbottom[1],cbottom[2],P[4]);
    49 u1 bottomrow_stage2(pp2[5],A[2],B[3],cbottom[2],cbottom[3],P[5]);
    50 u1 bottomrow_stage3(pp2[6],A[3],B[3],cbottom[3],P[7],P[6]);
    51
    52 endmodule
    53
    54 module u0(a_k1,a_k,b1,b0,cin,cout,s);
    55 input a_k1,a_k,b1,b0,cin;
    56 output cout,s;
    57 wire x,y;
    58
    59 assign x=a_k1&b0;
    60 assign y=a_k&b1;
    61
    62 fulladd FA(cin,x,y,cout,s);
    63
    64 endmodule
    65
    66 module u1(ppi_k1,a_k,bj,cin,cout,s);
    67 input ppi_k1,a_k,bj,cin;
    68 output cout,s;
    69
    70 wire y;
    71
    72 assign y=bj&a_k;
    73
    74 fulladd FA(cin,ppi_k1,y,cout,s);
    75
    76 endmodule
    77
    78 module fulladd(cin,a,b,cout,s);
    79 input cin,a,b;
    80 output reg cout,s;
    81
    82 always @(cin,a,b)
    83 {cout,s}=a+b+cin;
    84
    85 endmodule

    001

    图4 part V仿真

    Part VI 8X8乘法器

    代码part6.v

     

    1 //Top-level file
    2 module part6(SW,
    3 KEY,
    4 HEX7,
    5 HEX6,
    6 HEX5,
    7 HEX4,
    8 HEX3,
    9 HEX2,
    10 HEX1,
    11 HEX0
    12 );
    13
    14 input [15:0]SW; //A,B
    15 input [1:0]KEY; //clk & rst_n
    16 output [6:0]HEX7,HEX6, //A
    17 HEX5,HEX4, //B
    18 HEX3,HEX2,HEX1,HEX0; //P
    19
    20 reg [7:0]Areg,Breg;
    21 reg [15:0]Preg;
    22 wire [7:0]Aw,Bw;
    23 wire [15:0]Pw,P;
    24
    25 always @(posedge KEY[1] or negedge KEY[0])
    26 if(!KEY[0])
    27 begin
    28 Areg<=0;
    29 Breg<=0;
    30 Preg<=0;
    31 end
    32 else
    33 begin
    34 Areg<=SW[15:8];
    35 Breg<=SW[7:0];
    36 Preg<=Pw;
    37 end
    38
    39 assign Aw=Areg,Bw=Breg,P=Preg;
    40
    41 multiplier_8X8 mt(.A(Aw),
    42 .B(Bw),
    43 .P(Pw)
    44 );
    45
    46 seg7_lut h7(.oseg(HEX7),
    47 .idig(Aw[7:4])
    48 );
    49 seg7_lut h6(.oseg(HEX6),
    50 .idig(Aw[3:0])
    51 );
    52 seg7_lut h5(.oseg(HEX5),
    53 .idig(Bw[7:4])
    54 );
    55 seg7_lut h4(.oseg(HEX4),
    56 .idig(Bw[3:0])
    57 );
    58 seg7_lut h3(.oseg(HEX3),
    59 .idig(P[15:12])
    60 );
    61 seg7_lut h2(.oseg(HEX2),
    62 .idig(P[11:8])
    63 );
    64 seg7_lut h1(.oseg(HEX1),
    65 .idig(P[7:4])
    66 );
    67 seg7_lut h0(.oseg(HEX0),
    68 .idig(P[3:0])
    69 );
    70
    71 endmodule
    72
    73 //multiplier_8X8.v
    74 module multiplier_8X8(A,
    75 B,
    76 P,
    77 );
    78
    79 input [7:0]A,B;
    80 output [15:0]P;
    81
    82 wire [7:1]c1,c2,c3,c4,c5,c6,c7;
    83 wire [9:2]pp1;
    84 wire [10:3]pp2;
    85 wire [11:4]pp3;
    86 wire [12:5]pp4;
    87 wire [13:6]pp5;
    88 wire [14:7]pp6;
    89
    90 assign P[0]=A[0]&B[0];
    91
    92 u0 row1_stage0(A[1],A[0],B[1],B[0],0,c1[1],P[1]);
    93 u0 row1_stage1(A[2],A[1],B[1],B[0],c1[1],c1[2],pp1[2]);
    94 u0 row1_stage2(A[3],A[2],B[1],B[0],c1[2],c1[3],pp1[3]);
    95 u0 row1_stage3(A[4],A[3],B[1],B[0],c1[3],c1[4],pp1[4]);
    96 u0 row1_stage4(A[5],A[4],B[1],B[0],c1[4],c1[5],pp1[5]);
    97 u0 row1_stage5(A[6],A[5],B[1],B[0],c1[5],c1[6],pp1[6]);
    98 u0 row1_stage6(A[7],A[6],B[1],B[0],c1[6],c1[7],pp1[7]);
    99 u0 row1_stage7(0,A[7],B[1],B[0],c1[7],pp1[9],pp1[8]);
    100
    101 u1 row2_stage0(pp1[2],A[0],B[2],0,c2[1],P[2]);
    102 u1 row2_stage1(pp1[3],A[1],B[2],c2[1],c2[2],pp2[3]);
    103 u1 row2_stage2(pp1[4],A[2],B[2],c2[2],c2[3],pp2[4]);
    104 u1 row2_stage3(pp1[5],A[3],B[2],c2[3],c2[4],pp2[5]);
    105 u1 row2_stage4(pp1[6],A[4],B[2],c2[4],c2[5],pp2[6]);
    106 u1 row2_stage5(pp1[7],A[5],B[2],c2[5],c2[6],pp2[7]);
    107 u1 row2_stage6(pp1[8],A[6],B[2],c2[6],c2[7],pp2[8]);
    108 u1 row2_stage7(pp1[9],A[7],B[2],c2[7],pp2[10],pp2[9]);
    109
    110 u1 row3_stage0(pp2[3],A[0],B[3],0,c3[1],P[3]);
    111 u1 row3_stage1(pp2[4],A[1],B[3],c3[1],c3[2],pp3[4]);
    112 u1 row3_stage2(pp2[5],A[2],B[3],c3[2],c3[3],pp3[5]);
    113 u1 row3_stage3(pp2[6],A[3],B[3],c3[3],c3[4],pp3[6]);
    114 u1 row3_stage4(pp2[7],A[4],B[3],c3[4],c3[5],pp3[7]);
    115 u1 row3_stage5(pp2[8],A[5],B[3],c3[5],c3[6],pp3[8]);
    116 u1 row3_stage6(pp2[9],A[6],B[3],c3[6],c3[7],pp3[9]);
    117 u1 row3_stage7(pp2[10],A[7],B[3],c3[7],pp3[11],pp3[10]);
    118
    119 u1 row4_stage0(pp3[4],A[0],B[4],0,c4[1],P[4]);
    120 u1 row4_stage1(pp3[5],A[1],B[4],c4[1],c4[2],pp4[5]);
    121 u1 row4_stage2(pp3[6],A[2],B[4],c4[2],c4[3],pp4[6]);
    122 u1 row4_stage3(pp3[7],A[3],B[4],c4[3],c4[4],pp4[7]);
    123 u1 row4_stage4(pp3[8],A[4],B[4],c4[4],c4[5],pp4[8]);
    124 u1 row4_stage5(pp3[9],A[5],B[4],c4[5],c4[6],pp4[9]);
    125 u1 row4_stage6(pp3[10],A[6],B[4],c4[6],c4[7],pp4[10]);
    126 u1 row4_stage7(pp3[11],A[7],B[4],c4[7],pp4[12],pp4[11]);
    127
    128 u1 row5_stage0(pp4[5],A[0],B[5],0,c5[1],P[5]);
    129 u1 row5_stage1(pp4[6],A[1],B[5],c5[1],c5[2],pp5[6]);
    130 u1 row5_stage2(pp4[7],A[2],B[5],c5[2],c5[3],pp5[7]);
    131 u1 row5_stage3(pp4[8],A[3],B[5],c5[3],c5[4],pp5[8]);
    132 u1 row5_stage4(pp4[9],A[4],B[5],c5[4],c5[5],pp5[9]);
    133 u1 row5_stage5(pp4[10],A[5],B[5],c5[5],c5[6],pp5[10]);
    134 u1 row5_stage6(pp4[11],A[6],B[5],c5[6],c5[7],pp5[11]);
    135 u1 row5_stage7(pp4[12],A[7],B[5],c5[7],pp5[13],pp5[12]);
    136
    137 u1 row6_stage0(pp5[6],A[0],B[6],0,c6[1],P[6]);
    138 u1 row6_stage1(pp5[7],A[1],B[6],c6[1],c6[2],pp6[7]);
    139 u1 row6_stage2(pp5[8],A[2],B[6],c6[2],c6[3],pp6[8]);
    140 u1 row6_stage3(pp5[9],A[3],B[6],c6[3],c6[4],pp6[9]);
    141 u1 row6_stage4(pp5[10],A[4],B[6],c6[4],c6[5],pp6[10]);
    142 u1 row6_stage5(pp5[11],A[5],B[6],c6[5],c6[6],pp6[11]);
    143 u1 row6_stage6(pp5[12],A[6],B[6],c6[6],c6[7],pp6[12]);
    144 u1 row6_stage7(pp5[13],A[7],B[6],c6[7],pp6[14],pp6[13]);
    145
    146 u1 row7_stage0(pp6[7],A[0],B[7],0,c7[1],P[7]);
    147 u1 row7_stage1(pp6[8],A[1],B[7],c7[1],c7[2],P[8]);
    148 u1 row7_stage2(pp6[9],A[2],B[7],c7[2],c7[3],P[9]);
    149 u1 row7_stage3(pp6[10],A[3],B[7],c7[3],c7[4],P[10]);
    150 u1 row7_stage4(pp6[11],A[4],B[7],c7[4],c7[5],P[11]);
    151 u1 row7_stage5(pp6[12],A[5],B[7],c7[5],c7[6],P[12]);
    152 u1 row7_stage6(pp6[13],A[6],B[7],c7[6],c7[7],P[13]);
    153 u1 row7_stage7(pp6[14],A[7],B[7],c7[7],P[15],P[14]);
    154
    155
    156 endmodule
    157
    158 module u0(a_k1,a_k,b1,b0,cin,cout,s);
    159 input a_k1,a_k,b1,b0,cin;
    160 output cout,s;
    161 wire x,y;
    162
    163 assign x=a_k1&b0;
    164 assign y=a_k&b1;
    165
    166 fulladd FA(cin,x,y,cout,s);
    167
    168 endmodule
    169
    170 module u1(ppi_k1,a_k,bj,cin,cout,s);
    171 input ppi_k1,a_k,bj,cin;
    172 output cout,s;
    173
    174 wire y;
    175
    176 assign y=bj&a_k;
    177
    178 fulladd FA(cin,ppi_k1,y,cout,s);
    179
    180 endmodule
    181
    182 module fulladd(cin,a,b,cout,s);
    183 input cin,a,b;
    184 output reg cout,s;
    185
    186 always @(cin,a,b)
    187 {cout,s}=a+b+cin;
    188
    189 endmodule

    001

    图5 part VI时序分析

    Part VII 用lpm_mult实现Part VI

    代码part7.v

     

    1 //Top-level file
    2 module part7(SW,
    3 KEY,
    4 HEX7,
    5 HEX6,
    6 HEX5,
    7 HEX4,
    8 HEX3,
    9 HEX2,
    10 HEX1,
    11 HEX0
    12 );
    13
    14 input [15:0]SW; //A,B
    15 input [1:0]KEY; //clk & rst_n
    16 output [6:0]HEX7,HEX6, //A
    17 HEX5,HEX4, //B
    18 HEX3,HEX2,HEX1,HEX0; //P
    19
    20 reg [7:0]Areg,Breg;
    21 reg [15:0]Preg;
    22 wire [7:0]Aw,Bw;
    23 wire [15:0]Pw,P;
    24
    25 always @(posedge KEY[1] or negedge KEY[0])
    26 if(!KEY[0])
    27 begin
    28 Areg<=0;
    29 Breg<=0;
    30 Preg<=0;
    31 end
    32 else
    33 begin
    34 Areg<=SW[15:8];
    35 Breg<=SW[7:0];
    36 Preg<=Pw;
    37 end
    38
    39 assign Aw=Areg,Bw=Breg,P=Preg;
    40
    41 mult mt(.dataa(Aw),
    42 .datab(Bw),
    43 .result(Pw)
    44 );
    45
    46 seg7_lut h7(.oseg(HEX7),
    47 .idig(Aw[7:4])
    48 );
    49 seg7_lut h6(.oseg(HEX6),
    50 .idig(Aw[3:0])
    51 );
    52 seg7_lut h5(.oseg(HEX5),
    53 .idig(Bw[7:4])
    54 );
    55 seg7_lut h4(.oseg(HEX4),
    56 .idig(Bw[3:0])
    57 );
    58 seg7_lut h3(.oseg(HEX3),
    59 .idig(P[15:12])
    60 );
    61 seg7_lut h2(.oseg(HEX2),
    62 .idig(P[11:8])
    63 );
    64 seg7_lut h1(.oseg(HEX1),
    65 .idig(P[7:4])
    66 );
    67 seg7_lut h0(.oseg(HEX0),
    68 .idig(P[3:0])
    69 );
    70
    71 endmodule
    72
    73 `timescale 1 ps / 1 ps
    74 // synopsys translate_on
    75 module mult (
    76 dataa,
    77 datab,
    78 result);
    79
    80 input [7:0] dataa;
    81 input [7:0] datab;
    82 output [15:0] result;
    83
    84 wire [15:0] sub_wire0;
    85 wire [15:0] result = sub_wire0[15:0];
    86
    87 lpm_mult lpm_mult_component (
    88 .dataa (dataa),
    89 .datab (datab),
    90 .result (sub_wire0),
    91 .aclr (1'b0),
    92 .clken (1'b1),
    93 .clock (1'b0),
    94 .sum (1'b0));
    95 defparam
    96 lpm_mult_component.lpm_hint = "MAXIMIZE_SPEED=5",
    97 lpm_mult_component.lpm_representation = "UNSIGNED",
    98 lpm_mult_component.lpm_type = "LPM_MULT",
    99 lpm_mult_component.lpm_widtha = 8,
    100 lpm_mult_component.lpm_widthb = 8,
    101 lpm_mult_component.lpm_widthp = 16;
    102
    103
    104 endmodule

    001

    图6 part VII使用的LEs

    002

    图7 part Vii时序分析

    Part VIII 四则运算

    要求:

    用lpm_add_sub和lpm_mult实现S=(AXB)+(CXD)

    代码part8.v

     

    1 //top-level file
    2 //yes-done
    3 module part8(SW,
    4 HEX7,
    5 HEX6,
    6 HEX5,
    7 HEX4,
    8 HEX3,
    9 HEX2,
    10 HEX1,
    11 HEX0,
    12 KEY,
    13 LEDG
    14 );
    15
    16 input [17:0]SW;
    17 input [1:0]KEY;
    18 output [8:8]LEDG;
    19 output [6:0]HEX7,HEX6,HEX5,HEX4,HEX3,HEX2,HEX1,HEX0;
    20
    21 reg [7:0]Areg,Breg,Creg,Dreg;
    22 reg [15:0]S;
    23 reg cout;
    24 wire [15:0]p1,p2;
    25 wire [15:0]sum;
    26 wire c;
    27
    28 mult u0(Areg,Breg,p1);
    29 mult u1(Creg,Dreg,p2);
    30 add u3(p1,p2,c,sum);
    31
    32 assign LEDG=cout;
    33
    34 always @(posedge KEY[1] or negedge KEY[0])
    35 begin
    36 if(!KEY[0])
    37 begin
    38 Areg<=0;
    39 Breg<=0;
    40 Creg<=0;
    41 Dreg<=0;
    42 cout<=0;
    43 S<=0;
    44 end
    45 else
    46
    47 if(SW[17])
    48 begin
    49 if(SW[16])
    50 begin
    51 Areg<=SW[15:8];
    52 Breg<=SW[7:0];
    53 Creg<=Creg;
    54 Dreg<=Dreg;
    55 cout<=c;
    56 S<=sum;
    57 end
    58 else
    59 begin
    60 Areg<=Areg;
    61 Breg<=Breg;
    62 Creg<=SW[15:8];
    63 Dreg<=SW[7:0];
    64 cout<=c;
    65 S<=sum;
    66 end
    67 end
    68 else
    69 begin
    70 Areg<=Areg;
    71 Breg<=Breg;
    72 Creg<=Creg;
    73 Dreg<=Dreg;
    74 cout<=c;
    75 S<=sum;
    76 end
    77 end
    78
    79 seg7_lut H7(.idig(SW[16]?Areg[7:4]:Creg[7:4]),
    80 .oseg(HEX7)
    81 );
    82 seg7_lut H6(.idig(SW[16]?Areg[3:0]:Creg[3:0]),
    83 .oseg(HEX6)
    84 );
    85 seg7_lut H5(.idig(SW[16]?Breg[7:4]:Dreg[7:4]),
    86 .oseg(HEX5)
    87 );
    88 seg7_lut H4(.idig(SW[16]?Breg[3:0]:Dreg[3:0]),
    89 .oseg(HEX4)
    90 );
    91 seg7_lut H3(.idig(S[15:12]),
    92 .oseg(HEX3)
    93 );
    94 seg7_lut H2(.idig(S[11:8]),
    95 .oseg(HEX2)
    96 );
    97 seg7_lut H1(.idig(S[7:4]),
    98 .oseg(HEX1)
    99 );
    100 seg7_lut H0(.idig(S[3:0]),
    101 .oseg(HEX0)
    102 );
    103
    104 endmodule

    001

    图8 partViii时序分析

    002

    图9 指定fmax后的时序分析

    Part IX 用lpm_mult_add实现Part VIII

    代码part9.v

     

    1 //Top-level file
    2
    3 module part9(SW,
    4 HEX7,
    5 HEX6,
    6 HEX5,
    7 HEX4,
    8 HEX3,
    9 HEX2,
    10 HEX1,
    11 HEX0,
    12 KEY,
    13 LEDG
    14 );
    15
    16 input [17:0]SW;
    17 input [1:0]KEY;
    18 output [8:8]LEDG;
    19 output [6:0]HEX7,HEX6,HEX5,HEX4,HEX3,HEX2,HEX1,HEX0;
    20
    21
    22
    23 reg [7:0]A,B,C,D;
    24
    25 wire [15:0]sum;
    26
    27 always @(posedge KEY[1] or negedge KEY[0])
    28 if(!KEY[0])
    29 begin
    30 A<=0;
    31 B<=0;
    32 C<=0;
    33 D<=0;
    34 end
    35 else
    36 begin
    37 if(SW[17])
    38 begin
    39 if(SW[16])
    40 begin
    41 A<=SW[15:8];
    42 B<=SW[7:0];
    43 C<=C;
    44 D<=D;
    45 end
    46 else
    47 begin
    48 A<=A;
    49 B<=B;
    50 C<=SW[15:8];
    51 D<=SW[7:0];
    52 end
    53 end
    54 else
    55 begin
    56 A<=A;
    57 B<=B;
    58 C<=C;
    59 D<=D;
    60 end
    61 end
    62
    63
    64 m_a u0(
    65 .aclr0(~KEY[0]),
    66 .clock0(KEY[1]),
    67 .dataa_0(C),
    68 .dataa_1(A),
    69 .datab_0(D),
    70 .datab_1(B),
    71 .result({LEDG,sum})
    72 );
    73
    74
    75
    76 seg7_lut H7(.idig(SW[16]?A[7:4]:C[7:4]),
    77 .oseg(HEX7)
    78 );
    79 seg7_lut H6(.idig(SW[16]?A[3:0]:C[3:0]),
    80 .oseg(HEX6)
    81 );
    82 seg7_lut H5(.idig(SW[16]?B[7:4]:D[7:4]),
    83 .oseg(HEX5)
    84 );
    85 seg7_lut H4(.idig(SW[16]?B[3:0]:D[3:0]),
    86 .oseg(HEX4)
    87 );
    88 seg7_lut H3(.idig(sum[15:12]),
    89 .oseg(HEX3)
    90 );
    91 seg7_lut H2(.idig(sum[11:8]),
    92 .oseg(HEX2)
    93 );
    94 seg7_lut H1(.idig(sum[7:4]),
    95 .oseg(HEX1)
    96 );
    97 seg7_lut H0(.idig(sum[3:0]),
    98 .oseg(HEX0)
    99 );
    100
    101 endmodule

    001

    图10 part IX仿真

    Conclusion

    这个练习时到目前为止最繁琐的,有的题海的意思,没办法,熟能生巧。断断续续,花了一周才完成。很多细节确实做了才知道,很多文章用的时候再翻阅,会有新的理解。

    Reference

    【1】《数字逻辑基础与Verilog HDL设计》--chapter 5 夏宇闻,译

              夏译版的很不错了,yy一下,如果笔法有侯捷先生的风格,。。。

    【2】《Using Library Modules in Verilog Designs》

    【3】《Timing Considerations with Verilog-Based Designs》

  • 相关阅读:
    Elasticsearch学习,请先看这一篇!
    加解密/数字签名/证书 原理
    C# 给对象赋null值会释放内存吗?
    打包常见问题
    友盟推送
    谈一谈可能用到数据持久化的地方
    浅谈设置字体大小
    AFN和SDWebImage请求网络图片的一点问题
    linux学习(1)——这是一个新的开始,加油吧少年
    C指针——简单总结
  • 原文地址:https://www.cnblogs.com/halflife/p/1771746.html
Copyright © 2020-2023  润新知