请问谁有"周立功—Two Port Ram实验例程" 的这份资料的程序?
请问谁有"周立功—Two Port Ram实验例程" 的这份资料的程序?点击此处下载 ourdev_442552.pdf(文件大小:623K) (原文件名:Two Port RAM实验例程.pdf) 继续顶~~ // top.v
module top(clk_48m,RXD,key,rst,TXD);
input clk_48m; //系统时钟
input RXD; //串口接收端
input key; //读写切换按键
output rst; //读写指示信号
output TXD; //串口发送端
wire Waddress_temp,Raddress_temp;
wire datawr,datard;
wire RI_temp,TI_temp;
wire sendwr_temp;
wire rst_temp;
wire RWaddress;
assign rst = rst_temp;
assign RWaddress = rst_temp? Raddress_temp:Waddress_temp; //读写地址选择
rec rec( //接收模块
.clk(clk_48m),
.RXD(RXD),
.Dataout(datawr),
.RI(RI_temp)
);
send send( //发送模块
.clk(clk_48m),
.TXD(TXD),
.TI(TI_temp),
.WR(sendwr_temp),
.Datain(datard)
);
writeram u1( //读写RAM控制模块
.key(key),
.RI(RI_temp),
.clk(clk_48m),
.rst(rst_temp),
.Waddress(Waddress_temp),
.Raddress(Raddress_temp),
.TI(TI_temp),
.sendwr(sendwr_temp)
);
RAM2k8 u3( //2048*8 RAM
.DINA(datawr),
.DOUTA(datard),
.ADDRA(RWaddress),
.CLKA(clk_48m),
.BLKA(1'b0),
.RWA(rst_temp)
);
endmodule /********************send*************************
**模块名称:send
**功能描述:UART的发送程序
**************************************************/
module send(
clk, //时钟
clkout, //输出
Datain, //需要发送的一个字节数据
TXD, //uart发送引脚
TI, //发送中断
WR //写控制信号
);
input clk; //输入时钟
input WR; //写信号
input Datain; //发送的一字节数据
output clkout; //输出时钟
output TXD,TI; //串行数据,发送中断
reg Datainbuf,Datainbuf2; //发送数据缓存
reg WR_ctr,TI,txd_reg; //写标志、中断标志、一位发送寄存器
reg bincnt; //发送数据计数器
reg cnt; //计数器
wire clk_equ; //分频时钟
parameter cout = 5000; //根据具体的时钟来设定分频系数
//这里是48M时钟,波特率选择是9600,所以分频系数为48000000/9600= 5000;
/*************波特率发生进程****************************/
always@(posedge clk)
begin
if(clk_equ)
cnt = 16'd0;
else
cnt=cnt+1'b1;
end
assign clk_equ = (cnt == cout);
assign clkout = clk_equ;
/*************读数据到缓存进程****************************/
always@(posedge clk)
begin
if(WR)
begin
Datainbuf = {1'b1,Datain,1'b0}; //读入数据,并把缓存组成一帧数据,10位
WR_ctr = 1'b1; //置开始标志位
end
else if(TI==0)
WR_ctr = 1'b0;
end
/*************主程序进程****************************/
always@(posedge clk)
begin
if(clk_equ)
begin
if(WR_ctr==1||bincnt<4'd10) //发送条件判断,保证发送数据的完整性
begin
if(bincnt<4'd10)
begin
txd_reg =Datainbuf2; //从最低位开始发送
Datainbuf2 = Datainbuf>>bincnt; //移位输出
bincnt = bincnt+4'd1; //发送数据位计数
TI = 1'b0;
end
else
bincnt = 4'd0;
end
else
begin //发送完毕或者处于等待状态时TXD和TI为高
txd_reg = 1'b1;
TI = 1'b1;
end
end
end
assign TXD = txd_reg; //TXD连续输出
endmodule /********************rec*************************
**模块名称:rec
**功能描述:uart的接收模块,接收采样率为波特率的16倍
************************************************/
module rec(clk,clkout,Dataout,RXD,RI);
input clk,RXD; //时钟与数据输入
output clkout,RI; //时钟输入、接收中断输出
output Dataout; //并行数据输出
reg StartF,RI; //开始与接收中断标志
reg UartBuff; //接收缓存区
reg count,count_bit; //位接收计数器
reg cnt; //时钟节拍计数器
reg bit_collect; //采集数据缓存区
reg Dataout;
wire clk_equ,bit1,bit2,bit3,bit4; //连线
parameter cout = 312; //时钟是48M所以16*9600的分频数为312.5,这里取整数
/*************波特率发生进程****************************/
always@(posedge clk) //时钟节拍计数器
begin
if(clk_equ)
cnt = 16'd0;
else
cnt=cnt+1'b1;
end
assign clk_equ = (cnt == cout); //采样时钟
assign clkout = clk_equ;
assign bit1 = bit_collect&bit_collect; //对采样数据进行判断
assign bit2 = bit_collect&bit_collect; //对采样数据进行判断
assign bit3 = bit_collect&bit_collect; //对采样数据进行判断
assign bit4 = bit1|bit2|bit3; //对采样数据进行判断,只要有两次相同就可以
always@(posedge clk)
begin
if(clk_equ)
begin
if(!StartF) //是否处于接收状态
begin
if(!RXD)
begin
count = 4'b0; //复位计数器
count_bit = 4'b0;
RI = 1'b1;
StartF = 1'b1;
end
elseRI = 1'b1;
end
else
begin
count = count+1'b1; //位接收状态加1
if(count==4'd6)
bit_collect = RXD; //数据采集
if(count==4'd7)
bit_collect = RXD; //数据采集
if(count==4'd8)
begin
bit_collect = RXD; //数据采集
UartBuff = bit4;
count_bit = count_bit+1'b1; //位计数器加1
if((count_bit==4'd1)&&(UartBuff==1'b1)) //判断开始位是否为0
begin
StartF = 1'b0; //标志开始接收
end
RI = 1'b0; //中断标志位低
end
if(count_bit>4'd9) //检测是否接收结束
begin
RI = 1'b1; //中断标志为高标志转换结束
StartF = 1'b0;
end
end
end
end
always@(posedge RI)
begin
Dataout <= UartBuff;
end
endmodule // writeram.v
module writeram(key,RI,clk,rst,Waddress,TI,Raddress,sendwr);
input key; //按键
input clk; //时钟
input RI; //接收中断
input TI; //发送中断
output sendwr; //发送模块写信号
output rst;
output Waddress; //写数据地址
output Raddress; //读数据地址
parameter wrcntbit=11;
parameter rdcntbit=11;
reg Waddress; //写地址
reg Raddress; //读地址
reg rst_reg;
reg count;
reg wrcnt;
reg rdcnt;
wire key_buff;
reg bit0,bit1,bit2;
wire rst_posedge,rst_negedge;
reg rst_buff;
wire RI_negedge;
reg RI_buff;
wire sendclk;
reg sendclkdiv;
wire TI_posedge;
reg TI_buff;
reg rst1,rst2,rst3,rst4,rst5;
//下面产生写地址复位信号rst,同时该信号也是单片机复位信号,存储器的读写周期指示信号
assign rst = rst_reg;
always @(posedge clk)
begin
count <= count + 1'b1;
end
assign key_buff = bit0 & bit1 & bit2;
always@( posedge count)
begin
bit0 <= key;
bit1 <= bit0;
bit2 <= bit1;
end
//assign key_negedge = key_buff & (~key);
always@(posedge key_buff)
begin
rst_reg <= ~rst_reg;
end
//写地址处理进程
always@(posedge clk)
begin
rst_buff<=rst_reg;
end
always@(posedge clk)
begin
RI_buff <= RI;
end
assign rst_negedge = (~rst_reg) & rst_buff;
assign RI_negedge = (~RI) & RI_buff;
always@(posedge clk)
begin
if(rst_negedge)
begin
Waddress <= 11'b11111111111;
wrcnt <= 0;
end
else if(RI_negedge)//else if(RI_negedge&&(rst_reg==0))
begin
Waddress <= Waddress+11'd1;
wrcnt <= wrcnt+1'b1;
end
end
//下读地址发生进程
always@(posedge clk)
begin
TI_buff<=TI;
end
assign rst_posedge = rst_reg&(~rst_buff);
assign TI_posedge = (TI)&(~TI_buff);
always@(posedge clk)
begin
if(rst_posedge)
begin
Raddress <= 0;
rdcnt <= 0;
end
else if(TI_posedge)
begin
Raddress <= Raddress+1;
rdcnt <= rdcnt+1'b1;
end
end
//sendclk产生进程
assign sendclk =(sendclkdiv == 16'd65535);
always@(posedge clk)
begin
if(sendclk)
sendclkdiv = 0;
else
sendclkdiv = sendclkdiv + 16'd1;
end
//产生sendwr信号
assign sendwr = rst5 & sendclk & ((rdcnt!= wrcnt));
//产生rst延迟5个时钟rst5信号
always@(posedge clk)
begin
rst1 <= rst;
rst2 <= rst1;
rst3 <= rst2;
rst4 <= rst3;
rst5 <= rst4;
end
//
endmodule 找个时间整理下,让大家详细了解ACTEL的FPGA 楼上贴出来的是双端口(dual port)ram的程序。。。
页:
[1]