ASIC设计.docx
《ASIC设计.docx》由会员分享,可在线阅读,更多相关《ASIC设计.docx(27页珍藏版)》请在冰豆网上搜索。
ASIC设计
《ASIC设计》课程实验报告
学院:
电子工程学院
班级:
姓名:
学号:
序号:
实验一多路选择器的设计
实验目的:
1.掌握门级电路与行为级电路设计的区别;
2.掌握逻辑电路设计方法;
3.熟悉测试程序的编写;
4.注意代码规范性的要求;
实验内容:
1.设计一个有两位选择信号的四位一多路选择器,可以根据控制信号从两个或多个输入源中选择一个予以输出。
2.用基本逻辑门来实现多路选择器,即门级语言进行描述。
参考门级电路
3.用行为级语言进行描述,通过case语句重新设计仿真。
4.编写多路选择器的测试激励模块,并通过Synopsys工具进行仿真。
问题回答:
1.门级电路与行为级电路设计的主要区别是什么?
门级电路需要引入每个门的输出信号(y0,y1,y2,y3),并且列出每个门的输出信号与输入信号之间的关系,最后再由门输出信号与out信号之间的关系确定最终的输出信号。
行为级电路引入了always块,在always块中只需要定义相应的输入信号对应的输出信号即可。
2.将门级电路与行为级电路的仿真波形进行对比。
两种方式的仿真波形是相同的,门电路中引入的门输出信号并不会显示在仿真波形中。
3.如果设计中改用开关级建模,你的思路是什么?
用四个CMOS开关并联起来,i0-i3作为CMOS开关的data输入,连个控制信号s0,s1接到control端口作为控制信号,最后将每一个CMOS的输出信号并联起来作为输出。
实验总结:
这次实验的内容是四选一选择器,总体来说并不困难,程序的编写也比较简单,但是因为是第一次接触verilog语言,刚开始的时候还是遇到了一些困难,而且对于编写测试程序不太了解,一开始遇到很多地方语法都不是很明确,在和同伴讨论并修改之后程序终于正式通过,通过这次实验对于门级描述和行为级描述有了具体的了解,虽然在本次实验不是很明显但是对于比较大型的实验行为级描述应该会比门级描述简单许多。
实验三交通信号灯控制器设计
实验目的:
1.掌握时序逻辑电路设计,注意阻塞赋值与非阻塞赋值;
2.熟练运用状态机设计;
3.熟悉测试程序的编写;
4.注意代码规范性要求;
实验内容:
1.根据以下功能描述设计一个交通信号灯控制器:
该交通信号灯控制器用于控制一条主干道与一条乡村公路的交叉口的交通,它必须具有下面的功能:
1)由于主干道上来往的车辆很多,因此控制主干道的交通信号具有最高优先级,在默认情况下主干道的绿灯点亮;
2)乡村公路间断性地有车经过,有车来时乡村公路的交通灯必须变为绿灯,只需维持一段足够长的时间,以便让车通过;
3)只要乡村公路上不再有车辆,那么乡村公路上的绿灯马上变为黄灯,然后变为红灯;同时,主干道上的绿灯重新点亮;
4)一个传感器用于监视乡村公路上是否有车等待,它向控制器输入信号x;如果x=1,则表示有车等待,否则x=0;
5)各个状态装换时,具有一定的延迟,这些延迟必须能够控制。
2.
有限状态机设计图
S0:
city绿灯,country红灯s1:
city黄灯,country红灯s2:
city红灯,country绿灯s3:
city红灯,country绿灯s4:
city绿灯,country黄灯
3.编写相应的验证程序,对编写的行为级模型进行验证,要求涵盖到状态机所有可能的装换。
实验结果:
City为城市交通灯,0表示绿灯,1表示黄灯,3表示红灯
Country为乡村交通灯,0表示绿灯,1表示黄灯,3表示红灯
实验代码:
问题回答:
1:
非阻塞赋值方式:
赋值方式为b<=a,块结束后才完成赋值操作,b的值并不是在赋值语句执行完之后立刻就改变的,常用语编写可综合模块
阻塞赋值方式:
赋值方式为b=a,赋值语句执行完后块才结束,b的值在赋值语句执行完后立刻就改变的,执行结果可能与预计的不同
2:
city绿country红,city黄country红,city红country绿,city红country黄,city绿country红,其中在city红country绿的状态中加入了三个周期的延时以保障乡村道路的同行。
实验总结:
本次实验中,考虑到状态的装换之间需要一定的延时,所以采用了非阻塞赋值的方式对程序进行编写,但是刚开始的时候country绿灯的延时不够,只能有一个时钟周期,所以加入个一个count的判断语句将延时改为了三个时钟周期,实验的重点在于弄清楚各种状态之间是如何装换的,其次就是采用了边沿触发的方式对状态进行控制以实现延时的控制和状态的转换,通过这次实验,对于非阻塞赋值方式形成了具体的了解。
实验五NRZ/HDB3码制变换的功能与时序验证
实验目的:
1、掌握复杂时序逻辑电路设计;
2、掌握RTL级设计的基本要求;
3、掌握验证程序的设计方法与技巧;
设计思路:
编码部分:
在实际电路设计时,先在纯粹的数字电路下完成插“V”的操作,再完成插“B”的操作;然后再将单极性变成双极性。
这样可以在数字电路中实现,且降低寄存器需求。
因为“V”、“B”是认为标识的符号,所以在具体电路中,需做以下替换:
0-00,1-01,V-11,B-10。
译码部分:
根据编码规则,破坏点V脉冲与前一个脉冲同极性。
因此可从所接受的信码中找到V码,然后根据加取代节的原则,V码与前面的三位码必然是取代码,需要全部复原为四连0。
只要找到V码,不管V码前是两个“0”码,一律把取代节清零,完成了去除V和去除B功能,进而得到原二元信码序列。
可实现HDB3译码,HDB3译码器包括双/单极性变换、V码检测、去除V去除B四部分组成。
实验代码:
译码部分:
Trans.v(BP,BN转换模块)
moduletrans(clk,rst,BP,BN,P,N);
inputclk,BP,BN;
inputrst;
output[1:
0]P,N;
reg[1:
0]P;
reg[1:
0]N;
initialbegin
P=0;
N=0;
end
always@(rst)
beginP<=2'b00;
N<=2'b00;
end
always@(posedgeclk)
begin
if(BP==0)P<=2'b00;
elseP<=2'b01;
if(BN==0)N<=2'b00;
elseN<=2'b01;
end
endmodule
findv.v
modulefindv(clk,P,N,out1,out2);
inputclk;
input[1:
0]P,N;
output[1:
0]out1,out2;
reg[1:
0]counter1;
reg[1:
0]counter2;
reg[1:
0]out1;
reg[1:
0]out2;
initial
begin
counter1=2'b00;
out1=2'b00;
out2=2'b00;
end
always@(posedgeclk)
begin
if(P==2'b01)
begin
counter1=counter1+1;
if(counter1==2'b10)
beginout1=2'b11;counter1=2'b00;end
elsebeginout1=2'b01;end
end
elsebeginout1=2'b00;
if(N==2'b01)counter1=2'b00;end
end
always@(posedgeclk)
begin
if(N==2'b01)
begin
counter2=counter2+1;
if(counter2==2'b10)
beginout2=2'b11;counter2=2'b00;end
elsebeginout2=2'b01;end
end
elsebeginout2=2'b00;
if(P==2'b01)counter2=2'b00;end
end
endmodule
Jia.v(信号叠加模块)
modulejia(in1,in2,clk,out0);
input[1:
0]in1;
input[1:
0]in2;
inputclk;
outputout0;
reg[1:
0]a;
reg[1:
0]b;
initialbegin
a=2'b00;
b=2'b00;
end
always@(posedgeclk)
begin
a<=in1;
b<=in2;
end
assignout0=a+b;
endmodule
chvb.v
modulechvb(in,clk,out);
inputclk;
//inputrst;
input[1:
0]in;
output[1:
0]out;
reg[1:
0]d[3:
0];
//always@(rst)
//beginout<=2'b00;
//end
initialbegin
d[3]=2'b00;
d[2]=2'b00;
d[1]=2'b00;
d[0]=2'b00;
end
always@(posedgeclk)
begin
d[3]=d[2];
d[2]=d[1];
d[1]=d[0];
d[0]=in;
if(d[0]==2'b11)
begin
d[0]<=2'b00;
d[1]<=2'b00;
d[2]<=2'b00;
d[3]<=2'b00;
end
end
assign
out=d[3];
endmodule
Yima.v(顶层模块)
moduleyima(clk,BP,BN,out3,rst);
inputclk,rst,BP,BN;
outputout3;
wire[1:
0]P,N;
wire[1:
0]a,b;
wire[1:
0]out1,out2;
wireout3;
transu1(.clk(clk),.BP(BP),.BN(BN),.P(P),.N(N),.rst(rst));
findvu2(.clk(clk),.P(P),.N(N),.out1(out1),.out2(out2));
chvbu3(.clk(clk),.in(out1),.out(a));
chvbu4(.clk(clk),.in(out2),.out(b));
jiau5(.clk(clk),.in1(a),.in2(b),.out0(out3));
endmodule
test1.v
`timescale1ns/1ps
moduletest1();
regclk,BN,BP,rst;
wireout3;
initial
begin
$dumpvars(2,test1);
clk=0;
BN=0;
BP=0;
rst=1;
#20rst=0;
#20BN=1;
#20BP=1;BN=0;
#20BN=1;BP=0;
#20BP=0;BN=0;
#20BP=1;
#20BP=0;BN=1;
#20BP=0;BN=0;
#40BN=1;
#20BN=0;BP=1;
#20BP=0;
#20BN=1;
#20BP=1;BN=0;
#20BP=0;
#60BP=1;
#20BN=1;BP=0;
#20BP=1;BN=0;
//#140BP=1;
//#20BP=0;
//#60BP=1;
//#20BN=1;BP=0;
//#20BN=0;
//#40BN=1;
//#20BN=0;BP=1;
//#20BP=0;
//#20BN=1;
//#20BN=0;BP=1;
//#20BP=0;
//#40BP=1;
//#20BP=0;BN=1;
//#20BN=0;
//#20BP=1;
//#20BP=0;
#500$finish;
end
yimadut(.clk(clk),.BP(BP),.BN(BN),.out3(out3));
always
#10clk=~clk;
Endmodule
Findv.v模块是用于+V/-V检测:
(1)+V检测模块
为了方便起见,设从正整流电路输出的信号为+B,从负整流电路输出的信号为-B。
+V码检测模块-B的控制下,对输入的+B进行检测。
其原理是:
当+B的上升沿到来时,对输入的+B脉冲进行计数,当计数值等于2时,输出一个脉冲作为+V脉冲,同时计数器清零,而且计数期间,一旦有-B信号为“1”电平时,立即对计数器清零,计数器重新从零开始计数。
这是因为在两个+B脉冲之间,存在-B脉冲,说明第二个+B脉冲不是+V码,而只有在连续两个+B脉冲之间无-B脉冲,才能说明这两个+B脉冲在HDB3码中,是真正同极性的于是就可以判定第二个+B脉冲实际上是+V码,达到检测+V码的目的。
(2)-V检测模块
V码检测原理与+V码检测的类似。
所不同的是,-V码检测电路在+B控制下,对来自-B信号进行计数和检测、判定,若检测到-V码,则输出到-V码信号
Chvb.v模块用于去除V和B:
去除V去除B模块有三个输入信号,即时钟信号、V码信号和来自正、负整流输出的和路信号。
由于该和路信号可能包含有B脉冲和V脉冲,因此需要在chvb.v模块中,去除V和B脉冲。
用V码检测模块所检测出的V码信号,去控制一个移位寄存器,若未碰到V脉冲,则整流输出合成信号在时钟的节拍下,顺利通过移位寄存器,当碰到有V脉冲时,该V脉冲将使移位寄存器清零。
考虑到四连0,即V脉冲及其前面的三个码元应为0码,所以,可设置四位的移位寄存器,当V码清零时,同时将移存器中的四位码全变为0。
不管是否有B脉冲,在此模块中,一并清零,因而无需另设去除B电路。
另外移位四位寄存器起到延时四位时钟周期的作用,以使所检测出的V脉冲与信号流中的V脉冲位置对齐,保证清零的准确性
程序运行流程图:
编码部分:
Code_b;
modulecode_b(add_in,addb_out,clk);
inputclk;
input[1:
0]add_in;
output[1:
0]addb_out;
regfirstv;
regcounter;
reg[1:
0]d[3:
0];
always@(posedgeclk)
begin
d[3]<=d[2];
d[2]<=d[1];
d[1]<=d[0];
d[0]<=add_in;
end
always@(posedgeclk)
begin
if(d[0]==2'b11)begincounter=0;firstv=0;end
elseif(d[0]==2'b01)begincounter=counter+1;firstv=1;end
elsebeginfirstv=1;end
end
assign
addb_out=(counter==0)&&(firstv==1)&&(d[0]==2'b11)?
2'b10:
d[3];
endmodule
code_v.v
modulecode_v(data_in,clk,data_out,rst);
inputdata_in;
inputclk;
inputrst;
output[1:
0]data_out;
reg[1:
0]data_out;
integercounter;
always@(rst)
begindata_out<=2'b00;
end
always@(posedgeclk)
if(data_in==1'b1)begincounter<=0;data_out<=2'b01;end
else
begin
if(counter==3)begindata_out<=2'b11;counter<=0;end
elsebegindata_out<=2'b00;counter<=counter+1;end
end
endmodule
polar.v
modulepolar(addb_out,clk,BP,BN,rst);
input[1:
0]addb_out;
inputclk,rst;
outputBP,BN;
reg[1:
0]polar_out;
regBP,BN;
regeven;
always@(rst)
begin
BP=0;
BN=0;
end
always@(posedgeclk)
if(addb_out==2'b11)
begin
if(even==1)beginpolar_out<=2'b11;end
elsebeginpolar_out<=2'b01;end
end
elseif(addb_out==2'b01||addb_out==2'b10)
if(even==1)begineven<=0;polar_out<=2'b01;end
elsebegineven<=1;polar_out<=2'b11;end
elsebeginpolar_out<=2'b00;end
always@(polar_out)
begin
if(polar_out==2'b01)beginBP=0;BN=1;end
elseif(polar_out==2'b11)beginBP=1;BN=0;end
elsebeginBP=0;BN=0;end
end
endmodule
HDB.v(顶层模块)
moduleHDB(clk,data,BP,BN,rst);
inputclk,data,rst;
outputBP,BN;
wire[1:
0]a,b;
code_vu1(.clk(clk),.data_in(data),.data_out(a),.rst(rst));
code_bu2(.clk(clk),.add_in(a),.addb_out(b));
polaru3(.clk(clk),.addb_out(b),.BP(BP),.BN(BN),.rst(rst));
endmodule
test.v
`timescale1ns/1ps
moduletest();
regclk,data,rst;
wireBP,BN;
initial
begin
$dumpvars(2,test);
clk=0;
data=0;
rst=1;
#20rst=0;
//#200data=0;
#20data=1;
#20data=1;
#20data=1;
#20data=0;
#20data=1;
#20data=0;
#20data=0;
#20data=0;
#20data=0;
#20data=1;
#20data=0;
#20data=1;
#20data=1;
#20data=0;
#20data=0;
#20data=0;
#20data=0;
#20data=1;
#20data=1;
#20data=1;
#20data=1;
#20data=1;
#20data=0;
#20data=1;
#20data=0;
#20data=0;
#20data=0;
#20data=0;
#20data=1;
#20data=0;
#20data=1;
#20data=1;
#20data=0;
#20data=0;
#20data=0;
#20data=0;
#20data=1;
#20data=1;
#10$finish;
end
HDBdut(.clk(clk),.data(data),.BP(BP),.BN(BN),.rst(rst));
always
#10clk=~clk;
endmodule
Code_v.v模块:
实现V码的插入1、设置连“0”计数器,复位为0;
2、对输入信号进行判断,如果为1则计数器复位,且输出“01”;
3、如果为“0”,则对“0”进行计数,如果计数值不为4,则输出“00”;
4、如果计数值为“4”,则计数器复位,同时输出为“11”。
Code_b.v模块:
实现B码的插入1、设置对“01”的计数器counter为0,设置对“11”的计数器firstV为0;
2、对输入进行判断,如果为“01”,则counter加1,仍然输出“01”;
3、如果输入为“00”,输出为“00”,计数器不变;
4、如果输入为“11”,firstV加1,此时如果counter为奇数,则输出仍为“11”;
5、如果counter为偶数,则将counter复位,且将此处前第4个数变成“10”。
注:
关键要设置四位的移位寄存器
Polar.v模块:
实现单双极性的变换由HDB3编码规则,“V”的极性是正负交替,而“1”和“B”的极性看成一体,为正负交替的,同时“V”的极性与前面的非“0”码一致。
1、设置一个极性标志even=0;
2、如果输入信号为“00”,输出仍为“00”;
3、输入为“01”,或“10”,如果even=1,输出“01”;如果even=0,输出为“10”,然后将even翻转;
4、如果输入为“11”,判断even,如果为1,则输出“10”,如果位0,输出“01”。
注意:
输出后的“10”和“01”表示的不再是“1”、“V”、和“B”了,而是标识符号的正负极性。
再将输出控制4选1的开关,就可以将“00”、“01”、“10”转化为0、+1和-1了。
程序运行流程:
NRZ
HDB3
实验结果:
译码:
编码:
全1输入:
问题回答:
1、验证程序的三要素是电路、激励和显示。
test.v
`timescale1ns/1ps
moduletest();
HDBdut(.clk(clk),.data(data),.BP(BP),.BN(BN),.rst(rst));//电路
regclk,data,rst;
wireBP,BN;
Initial//激励
begin
$dumpvars(2,test);
clk=0;
data=0;
rst=1;
#20rst=0;
//#200data=0;
#20data=1;
#20data=1;
#20data=1;
#20data=0;
#20data=1;
#20data=0;
#20data=0;
#20data=0;
#20data=0;
#20data=1;
#20data=0;
#20dat