verilog 实现乒乓操作(附代码)

这篇具有很好参考价值的文章主要介绍了verilog 实现乒乓操作(附代码)。希望对大家有所帮助。如果存在错误或未考虑完全的地方,请大家不吝赐教,您也可以点击"举报违法"按钮提交疑问。

乒乓操作原理

乒乓操作整体流程图如下图所示:
verilog 实现乒乓操作(附代码)
乒乓操作的原理简单点说就是:
控制两个存储RAM1和RAM2,当数据开始存储进入RAM1时,将RAM2的数据输出进行处理;当数据开始存储进入RAM2时,将RAM1的数据输出进行处理。
何时存储数据由输入数据流选择模块控制,何时输出,由输出数据流选择模块进行控制。

RTL 图

verilog 实现乒乓操作(附代码)
整体RTL图如图所示:
其中 :
controller为控制模块,主要生成控制两个选择模块的使能信号。
mux21为输入数据流选择模块,控制两个RAM数据流何时输入。
RAM1和RAM2为两个存储模块,用于存储输入的数据流。
mux22为输出数据流控制模块,用于选择两个RAM的数据流,进行输出。

代码编写

下面对各个模块代码进行具体介绍:
顶层模块:

module dpram_pingpang_top(
input clk,
input rst_n,
input [15:0] i_data,

output [15:0] o_data,
//test
output [7:0] o_addr,
output [7:0] o_addw
    );
    
    wire mux1_en;
    wire mux2_en;
    
     controller controller_m1(
   .clk(clk),
   .rst_n(rst_n),
    .mux1_en(mux1_en),
    .mux2_en(mux2_en)
       );
    wire wr_en1;
    wire wr_en2;
    
    mux21 mux21_m1(
       .clk(clk),
       .rst_n(rst_n),
       .en1(mux1_en),
        .wr_en1(wr_en1),
        .wr_en2(wr_en2)
       );
       wire [15:0] o_data1;
      DRAM DRAM_m1(
       .clk(clk),
       .rst_n(rst_n),
       .data(i_data),
       .wr_en(wr_en1),
       .o_data(o_data1),
       .o_addr(o_addr),
       .o_addw(o_addw)
           );
     wire [15:0] o_data2;
     DRAM DRAM_m2(
        .clk(clk),
        .rst_n(rst_n),
        .data(i_data),
        .wr_en(wr_en2),
        .o_data(o_data2)
        //.o_addr(o_addr),
        //.o_addw(o_addw)
                      ); 
        
        mux22 mux22_m1(
         .clk(clk),
         .rst_n(rst_n),
         .wr_en(mux1_en),
         .o_data1(o_data1),
         .o_data2(o_data2),
         .o_data(o_data)
            );
endmodule

顶层模块主要包含控制模块controller,两个RAM模块,两个mux二选一模块。

控制模块 controller

module controller(
input clk,
input rst_n,

output reg mux1_en,
output reg mux2_en
    );

reg [7:0] cnt; //0-255
always@(posedge clk or negedge rst_n)
begin
    if(rst_n ==1'b0)
        cnt <= 'd0;
    else if(cnt =='d255)
        cnt <='d0;
    else
        cnt <= cnt +'d1;
end

always@(posedge clk or negedge rst_n)
begin
    if(rst_n ==1'b0)
    begin
        mux1_en <='d0;
        mux2_en <='d0;
    end
    else if(cnt <'d128)
    begin
        mux1_en <= 'd1;
        mux2_en <= 'd0;
    end
    else if(cnt >'d127&&cnt <'d256)
    begin
        mux1_en <='d0;
        mux2_en <='d1;
    end
end

endmodule

控制模块主要控制两个mux选择器的使能信号。

输入数据二选一选择器mux21:

module mux21(
input clk,
input rst_n,
input en1,

output wr_en1,
output wr_en2
    );
    
assign wr_en1 = en1;
assign wr_en2 =~en1;
endmodule

由controller模块可知:计数0-255,在0-127时往RAM1中写入数据,读取RAM2中的数据;128-255时,往RAM2中写入数据,读取RAM1中的数据。

RAM存储模块:

module DRAM(
input clk,
input rst_n,
input [15:0] data,
input wr_en,

output reg [15:0] o_data,
output reg [7:0] o_addr,
output reg [7:0] o_addw
    );
    
always@(posedge clk or negedge rst_n)
begin
    if(rst_n ==1'b0)
    begin
        o_addr <='d0;
        o_addw <='d0;
    end
    else if(wr_en)
    begin
        o_addw <=o_addw+'d1;
        o_addr <='d0;
    end
    else if(!wr_en)
    begin
        o_addr <= o_addr +'d1;
        o_addw <='d0;
    end
end

reg [15:0] aRAM[127:0];
integer i;

always@(posedge clk or negedge rst_n)
begin
    if(rst_n ==1'b0)
    begin
        o_data <='d0;
        for(i=0;i<=127;i=i+1)
        aRAM[i] <='d0;
    end
    else if(wr_en)
    begin
    aRAM[o_addw]<=data;
    o_data <='d0;
    end
    else if(!wr_en)
    begin
    o_data<=aRAM[o_addr];
    end
end
endmodule

加入o_addr和o_addw两个信号用来观察RAM读和RAM写的地址,当RAM进行读操作时,o_addr地址每个时钟+1;当RAM进行写操作时,o_addw地址每个时钟+1.

输出数据二选一模块mux22:

module mux22(
input clk,
input rst_n,
input wr_en,
input [15:0] o_data1,
input [15:0] o_data2,

output [15:0] o_data
    );
reg flag1;
reg flag2; //打两拍

always@(posedge clk or negedge rst_n)
begin
    if(rst_n ==1'b0)
    begin
        flag1 <='d0;
        flag2 <='d0;
    end
    else
    begin
        flag1 <= wr_en;
        flag2 <= flag1;
    end
end

reg [15:0] din1;
reg [15:0] din2;
always@(posedge clk or negedge rst_n)
begin
    if(rst_n ==1'b0)
    begin
        din1 <='d0;
        din2 <='d0;
    end
    else
    begin
        din1 <=o_data1;
        din2 <=o_data2;
    end
end

assign o_data =(flag2=='d1)?din2:din1;
endmodule

对输出的数据进行选择,这里直接用controller模块输出的使能信号来控制即可。

进行仿真testbench测试后,其仿真如图所示:
verilog 实现乒乓操作(附代码)
RAM1和RAM2的使能信号en1和en2交替为高,这里拉出来RAM1模块的o_addr和o_addw信号,o_addr为0时表示RAM1此时为读操作,o_addw为高表示此时RAM1为写操作。

附工程代码(vivado版本2017.4)
https://download.csdn.net/download/weixin_44413306/87234366文章来源地址https://www.toymoban.com/news/detail-425199.html

到了这里,关于verilog 实现乒乓操作(附代码)的文章就介绍完了。如果您还想了解更多内容,请在右上角搜索TOY模板网以前的文章或继续浏览下面的相关文章,希望大家以后多多支持TOY模板网!

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处: 如若内容造成侵权/违法违规/事实不符,请点击违法举报进行投诉反馈,一经查实,立即删除!

领支付宝红包 赞助服务器费用

相关文章

  • FPGA实现Verilog 2分频:从原理到代码实现

    FPGA实现Verilog 2分频:从原理到代码实现 在数字电路设计中,2分频是一种常见的电路实现方式,可以将输入信号的频率减半。在FPGA设计中,我们可以利用Verilog语言快速实现2分频电路。本文将从原理出发,结合代码介绍FPGA实现2分频电路的方法。 原理及实现 2分频电路通常采

    2024年02月02日
    浏览(35)
  • 【Verilog编程】线性反馈移位寄存器(LFSR)原理及Verilog代码实现

    移位寄存器 :指若干个寄存器排成一列,每个寄存器中存放1bit二进制数据(0或1),每个时钟周期向左或向右移动一个bit。下图所示为一个向右移动的移位寄存器。 反馈移位寄存器(Feedback Shift Register,FSR) :每个时钟脉冲,移位寄存器向右移动一位,则移位寄存器的左左侧就

    2024年02月15日
    浏览(40)
  • CRC校验码生成逻辑的实现原理详解——结合C语言和Verilog语言代码分析

    因为前段时间用到CRC校验码,所以在网上找到了很多有关CRC校验码计算原理以及生成CRC校验码的代码实现(包括C语言和Verilog语言的实现)的文章,但关于CRC校验码代码实现的原理未能找到相关文章,于是自己结合C语言和Veirlog语言的实现代码以及CRC校验码的计算原理,对CR

    2023年04月22日
    浏览(88)
  • FPGA纯verilog代码实现8位精简指令集CPU,一学期的微机原理不如看懂这套代码,提供工程源码和技术支持

    本文章主要针对大学本科阶段学生; 读文章之前先来几个灵魂拷问: 1、你是否学过《微机原理》、《单片机》、《汇编语言》之类有关微型计算机的课程? 2、上这些课时你的老师是否只是机械的讲着PPT,你听着无聊,听不懂,逐渐对计算机专业产生了畏惧? 3、这些计算机

    2024年02月11日
    浏览(41)
  • 【Verilog实现FPGA上的信号延迟】—— 用Verilog代码实现将信号延迟N拍,这是FPGA中非常重要的一个操作,可以使数据在不同模块之间精确同步。

    【Verilog实现FPGA上的信号延迟】—— 用Verilog代码实现将信号延迟N拍,这是FPGA中非常重要的一个操作,可以使数据在不同模块之间精确同步。 模块是FPGA中最基本的构建模块。通常一个模块代表一个电路,包括输入、输出和处理逻辑。模块中包含的处理逻辑被称为时序逻辑。

    2024年02月04日
    浏览(62)
  • 流水线乘法器的原理及verilog代码

    二进制数乘法的显著特点就是可以将乘法转换为移位,乘2就是左移一位,乘2^n就是左移n位。而一个二进制数又可以看成是由若干个2的i次方的和。 设被乘数和乘数分别为M、N,且都是32位的二进制数,乘积结果为64位 的向量CO则 。 所以乘法可以由移位电路和加法器完成。计算

    2024年02月10日
    浏览(32)
  • 基2-booth乘法器原理及verilog代码

    对于一个n位的有符号二进制数B,首位是0则B可以表示为: 首位是1,B[n-2:0]是实际数字的补码,所以可以得到 。 可以得到合并的公式如下所示: 将公式展开: 除了n-1项外的每一项乘2之后再减去本身: 根据2^i重构公式: 为了统一形式,添加一项B[-1],初始值为0.注意这里的B

    2024年02月03日
    浏览(30)
  • 等精度频率计verilog,quartus仿真视频,原理图,代码

    名称:等精度频率计设计verilog quartus仿真 软件:Quartus 语言:Verilog 要求: A:测量范围信号:方波     频率:100Hz~1MHz; B:测试误差:0.1%(全量程) C:时钟频率:50kHz D:预闸门时间:01s E:系统时钟频率:50MHz F:频率计算:保留1位小数 本代码下载:等精度频率计设计verilog,quartus仿真

    2024年02月07日
    浏览(56)
  • 【数字IC手撕代码】Verilog无毛刺时钟切换电路|题目|原理|设计|仿真

    芯片设计验证社区·芯片爱好者聚集地·硬件相关讨论社区·数字verifier星球 四社区 联合力荐 !近500篇 数字IC精品文章收录 ! 【数字IC精品文章收录】学习路线·基础知识·总线·脚本语言·芯片求职·EDA工具·低功耗设计Verilog·STA·设计·验证·FPGA·架构·AMBA·书籍 本系列旨在提

    2023年04月08日
    浏览(27)
  • 【Verilog】同步FIFO原理及verilog实现(参数化)

            旨在学习理解,项目中还是用成熟IP靠谱~ 目录 一、FIFO原理 二、同步FIFO设计 2.1 位宽和深度 2.2 空、满标志 2.3 FIFO计数 2.4 ram模型 2.5 读/写操作 三、​​​​​​​verilog代码 四、仿真验证 后记 FIFO( First Input First Output)是指先进先出。模型如下:           F

    2024年02月05日
    浏览(27)

觉得文章有用就打赏一下文章作者

支付宝扫一扫打赏

博客赞助

微信扫一扫打赏

请作者喝杯咖啡吧~博客赞助

支付宝扫一扫领取红包,优惠每天领

二维码1

领取红包

二维码2

领红包