搜索
bottom↓
回复: 7

请问谁有"周立功—Two Port Ram实验例程" 的这份资料的程序?

[复制链接]

出0入0汤圆

发表于 2009-5-6 15:45:43 | 显示全部楼层 |阅读模式
请问谁有"周立功—Two Port Ram实验例程" 的这份资料的程序?

点击此处下载 ourdev_442552.pdf(文件大小:623K) (原文件名:Two Port RAM实验例程.pdf)

阿莫论坛20周年了!感谢大家的支持与爱护!!

知道什么是神吗?其实神本来也是人,只不过神做了人做不到的事情 所以才成了神。 (头文字D, 杜汶泽)

出0入0汤圆

 楼主| 发表于 2009-5-6 23:52:47 | 显示全部楼层
继续顶~~

出0入0汤圆

发表于 2009-5-15 00:24:25 | 显示全部楼层
// top.v
module top(clk_48m,RXD,key,rst,TXD);
input       clk_48m;   //系统时钟
input       RXD;       //串口接收端
input       key;       //读写切换按键

output      rst;       //读写指示信号
output      TXD;       //串口发送端

wire [10:0] Waddress_temp,Raddress_temp;
wire [7:0]  datawr,datard;
wire        RI_temp,TI_temp;
wire        sendwr_temp;
wire        rst_temp;
wire [10:0] 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

出0入0汤圆

发表于 2009-5-15 00:24:59 | 显示全部楼层
/********************send*************************
**模块名称:send
**功能描述:UART的发送程序
**************************************************/
module send(
                        clk,                                                                        //时钟
                        clkout,                                                                        //输出
                        Datain,                                                                        //需要发送的一个字节数据
                        TXD,                                                                        //uart发送引脚       
                        TI,                                                                                //发送中断
                        WR                                                                                //写控制信号
                        );
input                        clk;                                                                //输入时钟
input                        WR;                                                                        //写信号
input        [7:0]        Datain;                                                                //发送的一字节数据
output                        clkout;                                                                //输出时钟
output                        TXD,TI;                                                                //串行数据,发送中断

reg                [9:0]        Datainbuf,Datainbuf2;                                //发送数据缓存
reg                         WR_ctr,TI,txd_reg;                                        //写标志、中断标志、一位发送寄存器
reg                [3:0]        bincnt;                                                                //发送数据计数器
reg                [15:0]        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[7:0],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[0];                                //从最低位开始发送
                                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

出0入0汤圆

发表于 2009-5-15 00:25:27 | 显示全部楼层
/********************rec*************************
**模块名称:rec
**功能描述:uart的接收模块,接收采样率为波特率的16倍
************************************************/
module rec(clk,clkout,Dataout,RXD,RI);
input                         clk,RXD;                                                                        //时钟与数据输入
output                         clkout,RI;                                                                        //时钟输入、接收中断输出
output        [7:0]        Dataout;                                                                         //并行数据输出

reg                         StartF,RI;                                                                        //开始与接收中断标志
reg                [9:0]         UartBuff;                                                                          //接收缓存区
reg                [3:0]        count,count_bit;                                                        //位接收计数器
reg                [15:0]         cnt;                                                                                //时钟节拍计数器
reg                [2:0]        bit_collect;                                                                //采集数据缓存区
reg     [7:0]  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[0]&bit_collect[1];                                //对采样数据进行判断
assign   bit2 = bit_collect[1]&bit_collect[2];                                //对采样数据进行判断
assign   bit3 = bit_collect[0]&bit_collect[2];                                //对采样数据进行判断
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
                        else  RI = 1'b1;
                end
                else
                begin
                        count = count+1'b1;                                                                //位接收状态加1
                        if(count==4'd6)
                                bit_collect[0] = RXD;                                                //数据采集
                        if(count==4'd7)
                                bit_collect[1] = RXD;                                                //数据采集
                        if(count==4'd8)
                        begin
                                bit_collect[2] = RXD;                                                //数据采集
                                UartBuff[count_bit] = bit4;
                                count_bit = count_bit+1'b1;                                        //位计数器加1
                                if((count_bit==4'd1)&&(UartBuff[0]==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[7:0] <= UartBuff[8:1];

end

endmodule

出0入0汤圆

发表于 2009-5-15 00:25:40 | 显示全部楼层
// 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 [10:0] Waddress;        //写数据地址
output [10:0] Raddress;        //读数据地址

parameter   wrcntbit=11;
parameter   rdcntbit=11;

reg [10:0]  Waddress;          //写地址
reg [10:0]  Raddress;          //读地址

reg         rst_reg;
reg [15:0]  count;

reg [wrcntbit-1:0] wrcnt;
reg [rdcntbit-1:0] 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 [15:0]  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[15])
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

出0入0汤圆

发表于 2009-5-15 00:26:53 | 显示全部楼层
找个时间整理下,让大家详细了解ACTEL的FPGA

出0入0汤圆

发表于 2010-9-26 10:06:55 | 显示全部楼层
楼上贴出来的是双端口(dual port)ram的程序。。。
回帖提示: 反政府言论将被立即封锁ID 在按“提交”前,请自问一下:我这样表达会给举报吗,会给自己惹麻烦吗? 另外:尽量不要使用Mark、顶等没有意义的回复。不得大量使用大字体和彩色字。【本论坛不允许直接上传手机拍摄图片,浪费大家下载带宽和论坛服务器空间,请压缩后(图片小于1兆)才上传。压缩方法可以在微信里面发给自己(不要勾选“原图),然后下载,就能得到压缩后的图片。注意:要连续压缩2次才能满足要求!!】。另外,手机版只能上传图片,要上传附件需要切换到电脑版(不需要使用电脑,手机上切换到电脑版就行,页面底部)。
您需要登录后才可以回帖 登录 | 注册

本版积分规则

手机版|Archiver|amobbs.com 阿莫电子技术论坛 ( 粤ICP备2022115958号, 版权所有:东莞阿莫电子贸易商行 创办于2004年 (公安交互式论坛备案:44190002001997 ) )

GMT+8, 2024-7-24 17:27

© Since 2004 www.amobbs.com, 原www.ourdev.cn, 原www.ouravr.com

快速回复 返回顶部 返回列表