2000年全国研究生EDA竞赛上机试题
设计一加法器阵列,完成下列复数运算功能,其中R为数据的实部,1为数据的虚部。
Ra’=(Ra+Rc)+(Rb+Rd)
Ia’=(Ia+Ic)+(Ib+Id)
Rc’=(Ra+Rc)-(Rb+Rd)
Ic’=(Ia+Ic)-(Ib+Id)
Rb’=(Ra-Rc)+(Ib-Id)
Ib’=(Ia-Ic)-(Rb-Rd)
Rd’=(Ra-Rc)-(Ib-Id)
Id’=(Ia-Ic)+(Rb-Rd)
功能框图如下:
输入信号:
1.输入数实部Ra,Rb,Rc,Rd,虚部Ia,Ib,Ic,Id的数据宽度均为19位;每次向加法器阵列只能送一个操作数,包括实数R(19bit)、虚部I(19bit);操作数据a、c、b、d的顺序连续送入,在加法器列中要进行串并变换。
2.CP脉冲。
输出信号:
输出数实部Ra’,Rb’,Rc’,Rd’,虚部Ia’,Ib’,Ic’,Id’的数据宽度均为21位。
设计要求:
1.加法器要求采用快速进位链(Look Ahead)。
2.在加法器阵列中加入流水线结构(Pipelinc),每一拍完成一个加法,输入连续送数,输出连续出结果。
3.逻辑要求最简化。
4.要求写出完整的实验报告。
由运算式知,加法要并行执行的,而输入输出是串行的,所以要在输入端和输出端分别进行串转并、并转串,由设计要求可划分为19位相加、20位相加模块,19相减、20位相减模块(由这些模块组成加法器阵列,由于快速进位链比较简单,可以参考相关书籍,这里为了方便直接用描述语句描述加法和减法),输入端口的串转并模块,输出端口的并转串模块。
按题意,插入流水线,可以画出电路图如下。由图可以看出从输入到输出要经过六级流水线,所以正确输出在第六个时钟。
可以按上图画出时序图
下面为各个模块的Verilog语句描述
![](https://images.cnblogs.com/OutliningIndicators/ContractedBlock.gif)
1 module Ahead_add(in1,in2,out); //19位加法器
2 input [18:0] in1,in2;
3 output [19:0] out;
4
5 assign out=in1+in2;
6 endmodule
7
8 module Ahead_add1(in1,in2,out); //20位加法器
9 input [19:0] in1,in2;
10 output [20:0] out;
11
12 assign out=in1+in2;
13 endmodule
14
15 module Ahead_sub(in1,in2,out); //19位减法器
16
17 input [18:0] in1,in2;
18 output [19:0] out;
19
20 assign out=in1-in2;
21 endmodule
22
23 module Ahead_sub(in1,in2,out); //20位减法器
24
25 input [19:0] in1,in2;
26 output [20:0] out;
27
28 assign out=in1-in2;
29 endmodule
30
31
输入端口的串转并(这里的串转并结合整体的时序要求用同步复位,每4个周期才并行输出数据,其实结合上面整体电路图可知不要其中的计数器也是可以的,但电路开始工作的前5个时钟周期输出的数据应该舍去,从第六个周期开始才输出正确的输出数据)
![](https://images.cnblogs.com/OutliningIndicators/ContractedBlock.gif)
1 module s2p(s_in,p_out1,p_out2,p_out3,p_out4,clk,rst_n);
2 input [18:0] s_in;
3 input rst_n,clk;
4 output [18:0] p_out1,p_out2,p_out3,p_out4;
5
6 reg [18:0] pp_out1,pp_out2,pp_out3,pp_out4;
7 reg [2:0] counter;
8
9 always @( posedge clk)
10 if(!rst_n)
11 begin
12 pp_out1<=0;
13 pp_out2<=0;
14 pp_out3<=0;
15 pp_out4<=0;
16 counter<=0;
17 end
18 else
19 begin
20 if(counter==4)
21 counter=1; //第5个周期才把counter置为1,所以这里要置为1
22 else counter=counter+1;
23 pp_out1<=s_in;
24 pp_out2<=pp_out1;
25 pp_out3<=pp_out2;
26 pp_out4<=pp_out3;
27 end
28
29 assign p_out1=(counter==4)?pp_out1:19'd0;
30 assign p_out2=(counter==4)?pp_out2:19'd0;
31 assign p_out3=(counter==4)?pp_out3:19'd0;
32 assign p_out4=(counter==4)?pp_out4:19'd0;
33 endmodule
34
35
36 module test_s2p;
37 reg clk,rst_n;
38 reg [18:0] s_in;
39 wire [18:0] p_out1,p_out2,p_out3,p_out4;
40
41 initial begin
42 rst_n<=1;
43 clk<=0;
44 #10 rst_n<=0;
45 #30 rst_n<=1;
46 end
47
48 always #30 clk<=~clk;
49
50 initial begin
51 s_in=19'd0;
52 #60 s_in=19'd1;
53 #60 s_in=19'd2;
54 #60 s_in=19'd3;
55 #60 s_in=19'd4;
56 #60 s_in=19'd5;
57 #60 s_in=19'd6;
58 #60 s_in=19'd7;
59 #60 s_in=19'd8;
60 #60 s_in=19'd9;
61 #60 s_in=19'd10;
62 #60 s_in=19'd11;
63 #60 s_in=19'd12;
64 end
65
66 s2p c (.clk(clk),.rst_n(rst_n),.s_in(s_in),.p_out1(p_out1)
67 ,.p_out2(p_out2),.p_out3(p_out3),.p_out4(p_out4));
68 endmodule
69
输出并转串模块,同样结合整体电路图和时序图可知在第六个时钟周期才正确输出数据,所以在这个模块有一个5计数器,第一次计到5后,在第6个时钟把counter置为2,同时把并行输出loading,然后输出。此后,每隔4个周期loading一次,从第6个时钟周期起输出都是连续而且正确的。
![](https://images.cnblogs.com/OutliningIndicators/ContractedBlock.gif)
1 module p2s(clk,rst_n,p_in1,p_in2,p_in3,p_in4,s_out);
2 input clk,rst_n;
3 input [20:0] p_in1,p_in2,p_in3,p_in4;
4 output [20:0] s_out;
5
6 reg [2:0] counter;
7 reg [20:0] pp_in1,pp_in2,pp_in3,pp_in4;
8
9 always @( posedge clk)
10 if(!rst_n)
11 begin
12 pp_in1<=0;
13 pp_in2<=0;
14 pp_in3<=0;
15 pp_in4<=0;
16 counter<=0;
17 end
18 else
19 begin
20 if(counter==5)
21 begin
22 counter<=2;
23 pp_in1<=p_in1;
24 pp_in2<=p_in2;
25 pp_in3<=p_in3;
26 pp_in4<=p_in4;
27 end
28 else
29 begin
30 counter=counter+1;
31 pp_in1<=pp_in2;
32 pp_in2<=pp_in3;
33 pp_in3<=pp_in4;
34 end
35 end
36
37 assign s_out=pp_in1;
38 endmodule
39
40 module test_p2s;
41 reg [20:0] p_in1,p_in2,p_in3,p_in4;
42 reg clk,rst_n;
43 wire [20:0] s_out;
44
45 initial begin
46 rst_n=1;
47 clk=0;
48 #10 rst_n=0;
49 #30 rst_n=1;
50 end
51
52 always #30 clk=~clk;
53
54 initial begin
55 p_in1=0;
56 p_in2=0;
57 p_in3=0;
58 p_in4=0;
59 #60
60 #60
61 #60
62 #60
63 #60 p_in1=1;
64 p_in2=2;
65 p_in3=3;
66 p_in4=4;
67 #60
68 #60
69 #60
70 #60
71 #60 p_in1=5;
72 p_in2=6;
73 p_in3=7;
74 p_in4=8;
75
76 #60 p_in1=0;
77 p_in2=0;
78 p_in3=0;
79 p_in4=0;
80 end
81 p2s c (.clk(clk),.rst_n(rst_n),.p_in1(p_in1),.p_in2(p_in2),
82 .p_in3(p_in3),.p_in4(p_in4),.s_out(s_out));
83 endmodule
加法器阵列模块,按照上面的电路图把各个模块组合起来即可。
![](https://images.cnblogs.com/OutliningIndicators/ContractedBlock.gif)
1 module Adder_array(clk,rst_n,R_in,I_in,R_out,I_out);
2 input clk,rst_n;
3 input [18:0] R_in,I_in;
4 output [20:0] R_out,I_out;
5
6 wire [18:0] Ra,Rb,Rc,Rd,Ia,Ib,Ic,Id;
7 wire [19:0] R5,R6,R7,R8,I9,I10,I11,I12;
8 wire [20:0] Raa,Rbb,Rcc,Rdd,Iaa,Ibb,Icc,Idd;
9 reg [19:0] reg5,reg6,reg7,reg8,reg9,reg10,reg11,reg12;
10
11 s2p U0 (.clk(clk),.rst_n(rst_n),.s_in(R_in),
12 .p_out1(Rd),.p_out2(Rc),.p_out3(Rb),.p_out4(Ra));
13 s2p U1 (.clk(clk),.rst_n(rst_n),.s_in(I_in),
14 .p_out1(Id),.p_out2(Ic),.p_out3(Ib),.p_out4(Ia));
15
16 Ahead_add U2 (.out(R5),.in1(Rb),.in2(Rd));
17 Ahead_sub U3 (.out(R6),.in1(Ra),.in2(Rc));
18 Ahead_sub U4 (.out(R7),.in1(Rb),.in2(Rd));
19 Ahead_add U5 (.out(R8),.in1(Ra),.in2(Rc));
20
21 Ahead_add U6 (.out(I9),.in1(Ib),.in2(Id));
22 Ahead_sub U7 (.out(I10),.in1(Ia),.in2(Ic));
23 Ahead_sub U8 (.out(I11),.in1(Ib),.in2(Id));
24 Ahead_add U9 (.out(I12),.in1(Ia),.in2(Ic));
25
26 always @(posedge clk)
27 if(!rst_n)
28 begin
29 reg5<=0;reg6<=0;reg7<=0;reg8<=0;
30 reg9<=0;reg10<=0;reg11<=0;reg12<=0;
31 end
32 else
33 begin
34 reg5<=R5;reg6<=R6;reg7<=R7;reg8<=R8;
35 reg9<=I9;reg10<=I10; reg11<=I11;reg12<=I12;
36 end
37
38 Ahead_add1 U10 (.out(Raa),.in1(reg5),.in2(reg8));
39 Ahead_add1 U11 (.out(Rbb),.in1(reg6),.in2(reg11));
40 Ahead_add1 U12 (.out(Idd),.in1(reg10),.in2(reg7));
41 Ahead_sub1 U13 (.out(Rcc),.in1(reg8),.in2(reg5));
42
43 Ahead_sub1 U14 (.out(Icc),.in1(reg12),.in2(reg9));
44 Ahead_sub1 U15 (.out(Ibb),.in1(reg10),.in2(reg7));
45 Ahead_sub1 U16 (.out(Rdd),.in1(reg6),.in2(reg11));
46 Ahead_add1 U17 (.out(Iaa),.in1(reg9),.in2(reg12));
47
48 p2s U18 (.clk(clk),.rst_n(rst_n),.s_out(R_out),
49 .p_in1(Raa),.p_in2(Rbb),.p_in3(Rcc),.p_in4(Rdd));
50 p2s U19 (.clk(clk),.rst_n(rst_n),.s_out(I_out),
51 .p_in1(Iaa),.p_in2(Ibb),.p_in3(Icc),.p_in4(Idd));
52 endmodule
53
54 module test_Adder_array;
55 reg [18:0] R_in,I_in;
56 reg clk,rst_n;
57 wire [20:0] R_out,I_out;
58
59 initial begin
60 rst_n=1;
61 clk=0;
62 #10 rst_n=0;
63 #30 rst_n=1;
64 end
65
66 always #30 clk=~clk;
67
68 initial begin
69 R_in=0;
70 I_in=0;
71
72 #60
73 R_in=1;
74 I_in=1;
75 #60
76 R_in=2;
77 I_in=2;
78 #60
79 R_in=3;
80 I_in=3;
81 #60
82 R_in=4;
83 I_in=4;
84 #60
85 R_in=1;
86 I_in=1;
87 #60
88 R_in=1;
89 I_in=1;
90 #60
91 R_in=1;
92 I_in=1;
93 #60
94 R_in=1;
95 I_in=1;
96 #60
97 R_in=0;
98 I_in=0;
99 end
100 Adder_array cc (.clk(clk),.rst_n(rst_n),.R_in(R_in),.I_in(I_in),
101 .R_out(R_out),.I_out(I_out));
102 endmodule
仿真波形