本练习的目的是实现算术运算电路。每种电路用2种方法实现:Verilog语言描述和LPM。并比较其不同。
要求:
代码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
图1 part1编译结果
这部分要注意的就是2的补码的表示,和溢出信号的推导。可参阅Reference【1】。
要求:
在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
图2 Part II编译结果
这部分,很简单,由2的补码表示可知,减法运算变为加法,只需要在part I加一个控制信号add_sub,并将其作为cin,当其为1时,即为减法。
代码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
代码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
图3 Part IV时序分析
代码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
图4 part V仿真
代码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
图5 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
图6 part VII使用的LEs
图7 part Vii时序分析
要求:
用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
图8 partViii时序分析
图9 指定fmax后的时序分析
代码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
图10 part IX仿真
这个练习时到目前为止最繁琐的,有的题海的意思,没办法,熟能生巧。断断续续,花了一周才完成。很多细节确实做了才知道,很多文章用的时候再翻阅,会有新的理解。
【1】《数字逻辑基础与Verilog HDL设计》--chapter 5 夏宇闻,译
夏译版的很不错了,yy一下,如果笔法有侯捷先生的风格,。。。
【2】《Using Library Modules in Verilog Designs》
【3】《Timing Considerations with Verilog-Based Designs》