第一届全国研究生EDA大赛笔试(1996)第九题题解
九、电气装置的遥控器发射频率为38KHz的间歇红外波,需要一个脉冲调制信号,对于待发射的码序列中的“1”信号,脉冲调制信号的脉宽为4个时钟周期,占空比为1/8;对于“0”信号,脉冲调制信号的脉宽为2个时钟周期,占空比为1/4。如图6所示(所看到题目没图)。待发射的固定码序列存于移位寄存器中,以Reset信号启动一个电路模块,当Reset=1时,脉宽调制信号输出保持高电平;当Reset变为低电平时,电路模块按照移位寄存器最后一位的数码产生相应的脉宽调制信号,并发给移位寄存器一个时钟脉冲使之移位,继而产生脉宽调制信号序列。如图7所示。用硬件描述语言描述电路。
按题意可以分为移位寄存器描述模块和电路模块,其中电路模块包含两个分频模块,分别为4倍分频占空比为1/8,2倍分频占空比为1/4模块。下面分别是各个模块的描述。
![](https://images.cnblogs.com/OutliningIndicators/ContractedBlock.gif)
1 //移位寄存描述,这里在复位时寄存器有固定值
2 module shift_reg (clk_in,data_out,rst);
3 input clk_in,rst;
4 output data_out;
5
6 reg m1,m2,m3,m4,m5,data_out;
7
8 always @(posedge rst or posedge clk_in)
9 if(rst)
10 begin
11 m1<=1;
12 m2<=0;
13 m3<=0;
14 m4<=1;
15 m5<=0;
16 data_out<=0;
17 end
18 else
19 begin
20 m2<=m1;
21 m3<=m2;
22 m4<=m3;
23 m5<=m4;
24 data_out<=m5;
25 end
26 endmodule
27
28
![](https://images.cnblogs.com/OutliningIndicators/ContractedBlock.gif)
1 //这里用时钟的上下跳变来产生1/4占空比
2 //很多书都讲不要同时用上下跳变,但那是指不要在同一个
3 //always模块,这里是在不同always模块不同计数器中
4 module div_2(clk_in,rst,out2);
5 input clk_in,rst;
6 output out2;
7
8 reg [1:0] counter1,counter2;
9
10
11 always @(posedge rst or posedge clk_in)
12 begin
13 if(rst==1)
14 begin
15 counter1<=0;
16 counter2<=0;
17 end
18 else begin
19 if(counter1==1)
20 begin
21 counter1<=0;
22 end
23 else begin
24 counter1<=counter1+1;
25 end
26 end
27 end
28
29 always @(negedge clk_in)
30 if(counter2==1)
31 counter2<=0;
32 else counter2<=counter2+1;
33
34 assign out2=counter1[0]&counter2[0];
35 endmodule
36
37
38
![](https://images.cnblogs.com/OutliningIndicators/ContractedBlock.gif)
1 module test_div_2;
2 reg clk_in,rst;
3 wire out2;
4
5 initial begin clk_in<=0;
6 rst<=0;
7 #10 rst<=1;
8 #10 rst<=0;
9 end
10 always #30 clk_in<=~clk_in;
11
12 div_2 U (.clk_in(clk_in),.rst(rst),.out2(out2));
13 endmodule
14
测试结果图形:
![](https://images.cnblogs.com/OutliningIndicators/ContractedBlock.gif)
module div_4(clk_in,rst,out1);
input clk_in,rst;
output out1;
reg [1:0] counter1,counter2;
always @(posedge rst or posedge clk_in)
begin
if(rst==1)
begin
counter1<=0;
counter2<=0;
end
else begin
if(counter1==3)
begin
counter1<=0;
end
else begin
counter1<=counter1+1;
end
end
end
always @(negedge clk_in)
if(counter2==3)
counter2<=0;
else counter2<=counter2+1;
assign out1=counter1[0]&counter1[1]&counter2[0]&counter2[1];
endmodule
module test_div_4;
reg clk_in,rst;
wire out1;
initial begin clk_in<=0;
rst<=0;
#10 rst<=1;
#10 rst<=0;
end
always #30 clk_in<=~clk_in;
div_4 U (.clk_in(clk_in),.rst(rst),.out1(out1));
endmodule
测试结果:
![](https://images.cnblogs.com/OutliningIndicators/ContractedBlock.gif)
1 //data是移位寄存的输出数据,clk_out是输入移位寄存器的时钟
2 //out是电路模块的输出
3 module transmit(data,clk_in,rst,out,clk_out);
4 input data,clk_in,rst;
5 output out,clk_out;
6
7 reg [1:0] counter1;
8 reg [1:0] counter2;
9 wire out1,out2;
10 reg clk_out;
11
12 div_4 U1(.clk_in(clk_in),.rst(rst),.out1(out1));
13 div_2 U2(.clk_in(clk_in),.rst(rst),.out2(out2));
14
15 always @(posedge rst or posedge clk_in)
16 if(rst==1)
17 begin
18 counter1<=0;
19 counter2<=0;
20 clk_out<=0;
21 end
22 else begin
23 if(data)
24 begin
25 if(counter1==3)
26 begin
27 clk_out<=1;
28 counter1<=0;
29 end
30 else begin
31 counter1<=counter1+1;
32 clk_out<=0;
33 end
34 end
35 else
36 begin
37 if(counter2==1)
38 begin
39 clk_out<=1;
40 counter2<=0;
41 end
42 else begin
43 counter2<=counter2+1;
44 clk_out<=0;
45 end
46 end
47 end
48
49 assign out=data?out1:out2;
50 endmodule
![](https://images.cnblogs.com/OutliningIndicators/ContractedBlock.gif)
1 //其中data_out及clk_out是为了观测相应的数据方便才写在输出端口
2 module transmit_shift(rst,clk_in,out,data_out,clk_out);
3 input rst,clk_in;
4 output out,data_out,clk_out;
5
6 wire clk_out,data_out;
7
8 transmit U1 (.rst(rst),.clk_in(clk_in),.out(out),.clk_out(clk_out),
9 .data(data_out));
10 shift_reg U2 (.rst(rst),.clk_in(clk_out),.data_out(data_out));
11
12 endmodule
13
14
15 module test_transmit_shift;
16 reg clk_in,rst;
17 wire out,data_out,clk_out;
18
19 initial begin clk_in<=0;
20 rst<=0;
21 #10 rst<=1;
22 #10 rst<=0;
23 end
24
25 always #30 clk_in<=~clk_in;
26
27 transmit_shift C (.rst(rst),.clk_in(clk_in),.out(out),
28 .data_out(data_out),.clk_out(clk_out));
29 endmodule
30
测试结果:
这道题总体难度不大,但要在很短时间内完成还是有点难度,难点在于两个分频模块的编写。这里都是用时钟的上下跳变来计数,然后通过与来得到占空比不为50%的分频电路。