简单卷积器的设计代码Word格式文档下载.docx
《简单卷积器的设计代码Word格式文档下载.docx》由会员分享,可在线阅读,更多相关《简单卷积器的设计代码Word格式文档下载.docx(33页珍藏版)》请在冰点文库上搜索。
![简单卷积器的设计代码Word格式文档下载.docx](https://file1.bingdoc.com/fileroot1/2023-5/4/a23cf1f2-77b0-4131-9992-8d860f767fb0/a23cf1f2-77b0-4131-9992-8d860f767fb01.gif)
0]line;
reg[11:
0]counter;
reghigh;
reg[4:
0]j;
regEOC;
parameterh1=1,h2=2,h3=3;
//假设的系统系数
parameterIDLE=9'
b000000001,START=9'
b000000010,NCONVST=9'
b000000100,
READ=9'
b000001000,CALCU=9'
b000010000,WRREADY=9'
b000100000,
WR=9'
b001000000,WREND=9'
b010000000,WAITFOR=9'
b100000000;
parameterFMAX=20;
//因为A/D转换的时间是随机的,为保证按一定的频率采样,A/D
//转换控制信号应以一定频率给出。
这里采样频率通过FMAX控制
//为500KHZ。
always@(posedgeCLK)
if(!
reset)
begin
state<
=IDLE;
nconvst<
=1'
b1;
enout1<
=1;
enout2<
counter<
=12'
b0;
high<
=0;
wr<
line<
=24'
address<
=11'
end
else
case(state)
IDLE:
if(start==1)
//counter是一个计数器,记录已
//用的RAM空间
=START;
else
//START状态控制A/D开始转换
START:
if(EOC)
=NCONVST;
//NCONVST状态是A/D转换保持阶段
NCONVST:
=READ;
end
//READ状态读取A/D转换结果,计算卷积结果
READ:
={line[15:
0],indata};
=CALCU;
CALCU:
result<
=line[7:
0]*h1+line[15:
8]*h2+line[23:
16]*h3;
=WRREADY;
//将卷积结果写入RAM时,先写入低字节,再写入高字节
//WRREADY状态是写RAM准备状态,建立地址和数据信号
WRREADY:
begin
=counter;
high)outdata<
=result[7:
0];
elseoutdata<
=result[15:
8];
=WR;
//WR状态产生片选和写脉冲
WR:
high)enout1<
elseenout2<
=WREND;
//WREND状态结束一次写操作,若还未写入高字节则转到WRREADY状
//态开始高字节写入
WREND:
high)
elsestate<
=WAITFOR;
//WAITFOR状态控制采样频率并判断RAM是否已被写满
WAITFOR:
if(j==FMAX-1)
=counter+1;
counter[11])state<
$display($time,"
Theramisused
up."
);
$stop;
default:
state<
endcase
//assignrd=1;
//RAM的读信号始终保持为高
//j记录时钟,与FMAX共同控制采样频率
//由于直接用CLK的上升沿对nbusy判断以
//决定某些操作是否运行时,会因为两个信号
//的跳变沿相隔太近而令状态机不能正常工作。
因此
//利用CLK的下降沿建立EOC信号与nbusy同步,相位
//相差180度,然后用CLK的上升沿判断操作是否进行。
always@(negedgeCLK)
EOC<
=nbusy;
reset||state==START)
j<
=j+1;
endmodule
//---------------------------testcon1.v-------------------
moduletestcon1;
wirewr,
enin,
wire[10:
regrd,
CLK,
reset,
start;
wirenconvst;
wire[7:
integeri;
parameterHALF_PERIOD=1000;
//产生10KHZ的时钟
initial
rd=1;
i=0;
CLK=1;
forever#HALF_PERIODCLK=~CLK;
//产生置位信号
reset=1;
#(HALF_PERIOD*2+50)reset=0;
#(HALF_PERIOD*3)reset=1;
//产生开始卷积控制信号
start=0;
#(HALF_PERIOD*7+20)start=1;
#(HALF_PERIOD*2)start=0;
#(HALF_PERIOD*1000)start=1;
assignenin=1;
con1con(.address(address),.indata(indata),.outdata(outdata),.wr(wr),
.nconvst(nconvst),.nbusy(nbusy),.enout1(enout1),
.enout2(enout2),.CLK(CLK),.reset(reset),.start(start));
sramramlow(.Address(address),.Data(outdata),.SRW(wr),.SRG(rd),.SRE(enout1));
adcadc(.nconvst(nconvst),.nbusy(nbusy),.data(indata));
//卷积器的改进
//----------------------con3ad.v----------------------------------------
`timescale1ns/100ps
modulecon3ad(indata,outdata,address,CLK,reset,start,nconvst1,nconvst2,nconvst3,
nbusy1,nbusy2,nbusy3,wr,enout1,enout2);
inputindata,
start,
nbusy1,
nbusy2,
nbusy3;
outputoutdata,
address,
nconvst1,//采用三根控制线控制三片A/D转换器
nconvst2,
nconvst3,
wr,
wireCLK,
regnconvst1,
reg[6:
reg[5:
0]i;
reg[1:
regk;
regEOC1,EOC2,EOC3;
parameterIDLE=7'
b0000001,READ_PRE=7'
b0000010,
READ=7'
b0000100,CALCU=7'
b0001000,
WRREADY=7'
b0010000,WR=7'
b0100000,
WREND=7'
b1000000;
outdata<
=8'
bz;
=16'
end//endof"
if"
if(start)
begin
=READ_PRE;
READ_PRE:
if(EOC1||EOC2||EOC3)//由于频率相对改进前的卷积
//器大大提高,所以加入
//READ_PRE状态对取数操作
//予以缓冲。
if(j==1)
if(EOC1)
elseif(j==2&
&
counter!
=0)
if(EOC2)
elseif(j==3&
if(EOC3)
16]*h;
if(k==1)state<
if(k==1)state<
if(k==1)
if(counter[11]&
counter[0])
endcase//endofthecase
else"
always"
//计数器i用来记录时间
reset)i<
if(i==44)i<
elsei<
=i+1;
//j是控制信号,协调卷积器轮流从三片A/D上读取数据。
if(i==4)j<
=2;
elseif(i==10)j<
elseif(i==19)j<
=3;
elseif(i==25)j<
elseif(i==34)j<
elseif(i==40)j<
//k是计数器,用以控制写操作信号
if(state==WRREADY||state==WR||state==WREND)
if(k==1)k<
elsek<
//根据计数器i控制三片A/D转换信号NCONVST1,NCONVST2,NCONVST3
reset)nconvst1<
elseif(i==0)nconvst1<
elseif(i==3)nconvst1<
reset)nconvst2<
elseif(i==15)nconvst2<
elseif(i==18)nconvst2<
reset)nconvst3<
elseif(i==30)nconvst3<
elseif(i==33)nconvst3<
always@(negedgeCLK)
EOC1<
=nbusy1;
EOC2<
=nbusy2;
EOC3<
=nbusy3;
//----------------测试程序如下:
moduletestcon3ad;
regclk,
rd;
wirenbusy1,
wirenconvst1,
nconvst3;
parameterHALF_PERIOD=15;
//时钟周期为30ns
clk=1;
forever#HALF_PERIODclk=~clk;
#110reset=0;
#140reset=1;
#420start=1;
#120start=0;
#107600start=1;
#150start=0;
assignenin=1;
con3adcon3ad(.indata(indata),.outdata(outdata),.address(address),
.CLK(clk),.reset(reset),.start(start),
.nconvst1(nconvst1),.nconvst2(nconvst2),.nconvst3(nconvst3),
.nbusy1(nbusy1),.nbusy2(nbusy2),.nbusy3(nbusy3),
.wr(wr),.enout1(enout1),.enout2(enout2));
adcad_1(.nconvst(nconvst1),.nbusy(nbusy1),.data(indata));
adcad_2(.nconvst(nconvst2),.nbusy(nbusy2),.data(indata));
adcad_3(.nconvst(nconvst3),.nbusy(nbusy3),.data(indata));
//---------A/D转换器的VerilogHDL行为模型如下:
//--------------------adc.v------------------------
moduleadc(nconvst,nbusy,data);
inputnconvst;
//A/D启动脉冲ST,即上图中
outputnbusy;
//A/D工作标志,即上图中
outputdata;
//数据总线,从AD.DATA文件中读取数据后经端口输出
reg[7:
0]databuf,i;
//内部寄存器
regnbusy;
wire[7:
0]data;
0]data_mem[0:
255];
reglink_bus;
integertconv,
t5,
t8,
t9,
t12;
integerwideth1,
wideth2,
wideth;
//时间参数定义(依据AD7886手册):
always@(negedgenconvst)
tconv=9500+{$random}%500;
//(type950ns,max1000ns)ConversionTime
t5={$random}%1000;
//(max100ns)CONVSTtoBUSYPropagationDlay
//CL=10pf
t8=200;
//(min20ns)CL=20pfDataSetupTimePriortoBUSY
//(min10ns)CL=100pf
t9=100+{$random}%900;
//(min10ns,max100ns)BusRelinquishTimeAfterCONVST
t12=2500;
//(type)BUSYHightoCONVSTLow,SHAAcquisitionTime
initial
$readmemh("
adc.data"
data_mem);
//从数据文件adc.data中读取数据
i=0;
nbusy=1;
link_bus=0;
assigndata=link_bus?
databuf:
8'
bzz;
//三态总线
/*----------------------------------------