bad_fpga 发表于 2009-5-6 15:45:43

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

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

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

bad_fpga 发表于 2009-5-6 23:52:47

继续顶~~

wangli1013 发表于 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 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

wangli1013 发表于 2009-5-15 00:24:59

/********************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

wangli1013 发表于 2009-5-15 00:25:27

/********************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

wangli1013 发表于 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 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

wangli1013 发表于 2009-5-15 00:26:53

找个时间整理下,让大家详细了解ACTEL的FPGA

suiciki 发表于 2010-9-26 10:06:55

楼上贴出来的是双端口(dual port)ram的程序。。。
页: [1]
查看完整版本: 请问谁有"周立功—Two Port Ram实验例程" 的这份资料的程序?