RAM + 串口的简单应用

REVIEW

之前已经学习过:

RAM: RAM IP核配置_ip核 ram配置-CSDN博客

串口接收:Vivado 串口接收优化-CSDN博客

串口发送:Vivado 串口通信(UART)------串口发送_vivado串口收发实验-CSDN博客

按键:基于状态机的按键消抖实现-CSDN博客

按键+串口发送实验_串口发按键值-CSDN博客

1.  今日摸鱼任务

小梅哥教材:02_【逻辑教程】基于HDL的FPGA逻辑设计与验证教程V3.4.pdf

                        15 搭建串口收发与存储双口 RAM 简易应用系统
实现:串口写入RAM,按键控制串口发送RAM中的数据

2.  系统框图

系统框图如下图:

(其中baud_set[2:0],摸鱼怪是直接改的波特率)

(俺下载的这版还有小错误嘎嘎嘎~右下角应该是串口发送tx)

分析:

        绿色:已封装好的模块

        黄色:添加RAM IP核

        红色ctrl:编写ctrl模块

        总:写顶层

3.  RAM配置

 RAM: RAM IP核配置_ip核 ram配置-CSDN博客

使用的是无ena 、enb第一版

4.  RX + RAM

uartrx.v

区别于之前的程序,使rx_data提前于rx_done一个clk

module uartrx(
                 input clk ,
                 input reset_n ,
                 input uart_rx ,
                 output reg [7:0]rx_data,
                 output reg rx_done    );
    //默认使用波特率BAUD 115200  时钟频率 CLK_FREQ  50MHz
//    parameter start_bit = 0 ;
//    parameter stop_bit  = 1 ;
    parameter BAUD = 9600;
    parameter CLK_FREQ = 50_000_000;
    parameter bps_c = CLK_FREQ / BAUD ;    
    reg rx_en ;   
    reg[3:0] rx_flag;
        // bps 
        reg [30:0] counter_bps ;        
      always@(posedge clk or negedge reset_n)
        if(! reset_n) 
            counter_bps <= 0 ;
        else if (rx_en)
            if(counter_bps == bps_c - 1)
                counter_bps <= 0 ;
            else
                counter_bps <= counter_bps + 1'b1 ;
        else
            counter_bps <= 0 ;
        reg dff_rx_0 , dff_rx_1 ;
        reg r_uart_rx; 
        wire neg_rx_go ;
        always@(posedge clk )    
            dff_rx_0 <= uart_rx ;
        always@(posedge clk )    
            dff_rx_1 <= dff_rx_0 ;
        always@(posedge clk )    
            r_uart_rx <= dff_rx_1 ;
            
        assign neg_rx_go = (dff_rx_1 == 0)&&(r_uart_rx == 1);
        
      // rx_en 
        always@(posedge clk or negedge reset_n)
        if(! reset_n) 
            rx_en <= 0 ;
        else if(neg_rx_go) 
            rx_en <= 1 ;
        else if((rx_flag==9)&&(counter_bps == bps_c / 2))
            rx_en <= 0 ;
        else if((rx_flag==0)&&(counter_bps == bps_c/2 )&&(dff_rx_1==1)) 
            rx_en <= 0 ;
               
     // rx_flag
        always@(posedge clk or negedge reset_n)
        if(!reset_n) rx_flag <= 4'b0000 ;
        else if((rx_flag == 9)&&(counter_bps == bps_c /2)) rx_flag <= 4'b0000 ;
        else if(counter_bps == bps_c - 1)  rx_flag <= rx_flag + 1'b1 ;
         
     // [7:0]r_rx_data   
     reg [7:0] r_rx_data;
     always@(posedge clk )
       if(!rx_en) r_rx_data <= r_rx_data;
       else if(counter_bps == bps_c / 2)
        begin 
            case(rx_flag)
            1 : r_rx_data[0] <= dff_rx_1;
            2 : r_rx_data[1] <= dff_rx_1;
            3 : r_rx_data[2] <= dff_rx_1;
            4 : r_rx_data[3] <= dff_rx_1;
            5 : r_rx_data[4] <= dff_rx_1;
            6 : r_rx_data[5] <= dff_rx_1;
            7 : r_rx_data[6] <= dff_rx_1;
            8 : r_rx_data[7] <= dff_rx_1;
            default : r_rx_data <= r_rx_data;
            endcase
            
        end      
    // rx_done
     always@(posedge clk)
            rx_done <= (rx_flag==9)&&(counter_bps == bps_c /2);
    // rx_data ;
       always@(posedge clk)
           if((rx_flag==9)&&(counter_bps == bps_c /2
-1))

                 rx_data <= r_rx_data;  
endmodule

rx_ram_00.v

module rx_ram_00(
                input clk ,
                input reset_n ,
                input uart_rx ,
                input clkb ,
                input[7 : 0]addrb ,
                output  [7 : 0] doutb
                );
    
    wire rx_done;
    wire [7:0]rx_data;
    reg [7:0]addra;

    ram ram_ (
                 .clka(clk), // input wire clka
                 .wea(rx_done), // input wire [0 : 0] wea
                 .addra(addra), // input wire [7 : 0] addra
                 .dina(rx_data), // input wire [7 : 0] dina
                 .clkb(clkb), // input wire clkb
                 .addrb(addrb), // input wire [7 : 0] addrb
                 .doutb(doutb) // output wire [7 : 0] doutb
                                    );
    
    uartrx uart_rx_(
                 . clk(clk) ,
                 . reset_n(reset_n) ,
                 . uart_rx(uart_rx) ,
                 . rx_data(rx_data),
                 . rx_done(rx_done)    );
    
    
    always@(posedge clk or negedge reset_n)
    if(!reset_n)
        addra <= 8'B0000_0000;
    else  if(rx_done)
         addra <= addra + 1'b1;


endmodule

rx_tb.v

`timescale 1ns / 1ns
module rx_tb();
    reg clk , reset_n ;
    reg uart_rx;
    reg clkb;
    reg [7:0]addrb;
    wire [7:0]doutb;
      integer i;
    rx_ram_00 rx_ram_00_(
                        . clk(clk) ,
                        . reset_n(reset_n) ,
                        . uart_rx(uart_rx) ,
                        . clkb(clkb) ,
                        . addrb(addrb) ,
                        . doutb(doutb)
                        );
    initial clk = 1 ;
    always #10 clk = ~clk ;
    initial clkb = 1 ;
    always #20 clkb = ~clkb ;
    initial
    begin
        
        reset_n = 0 ;
        uart_rx = 1 ;
        addrb = 255;
        i = 0 ;
        #201;
        reset_n = 1 ;  #2000;     
        //   F0   1111_0000
        uart_rx = 0 ; #(5208*20);        uart_rx = 0 ; #(5208*20);        uart_rx = 0 ; #(5208*20);
        uart_rx = 0 ; #(5208*20);        uart_rx = 0 ; #(5208*20);        uart_rx = 1 ; #(5208*20);
        uart_rx = 1 ; #(5208*20);        uart_rx = 1 ; #(5208*20);        uart_rx = 1 ; #(5208*20);
        uart_rx = 1 ; #(5208*20);        #200000;
     //   55   0101_0101
        uart_rx = 0 ; #(5208*20);        uart_rx = 1 ; #(5208*20);        uart_rx = 0 ; #(5208*20);
        uart_rx = 1 ; #(5208*20);        uart_rx = 0 ; #(5208*20);        uart_rx = 1 ; #(5208*20);
        uart_rx = 0 ; #(5208*20);        uart_rx = 1 ; #(5208*20);        uart_rx = 0 ; #(5208*20);
        uart_rx = 1 ; #(5208*20);        #200000;
       //   55   0101_0101
        uart_rx = 0 ; #(5208*20);        uart_rx = 1 ; #(5208*20);        uart_rx = 0 ; #(5208*20);
        uart_rx = 1 ; #(5208*20);        uart_rx = 0 ; #(5208*20);        uart_rx = 1 ; #(5208*20);
        uart_rx = 0 ; #(5208*20);        uart_rx = 1 ; #(5208*20);        uart_rx = 0 ; #(5208*20);
        uart_rx = 1 ; #(5208*20);        #200000; 
        //   F0   1111_0000
        uart_rx = 0 ; #(5208*20);        uart_rx = 0 ; #(5208*20);        uart_rx = 0 ; #(5208*20);
        uart_rx = 0 ; #(5208*20);        uart_rx = 0 ; #(5208*20);        uart_rx = 1 ; #(5208*20);
        uart_rx = 1 ; #(5208*20);        uart_rx = 1 ; #(5208*20);        uart_rx = 1 ; #(5208*20);
        uart_rx = 1 ; #(5208*20);        #200000;
         //   F0   1111_0000
        uart_rx = 0 ; #(5208*20);        uart_rx = 0 ; #(5208*20);        uart_rx = 0 ; #(5208*20);
        uart_rx = 0 ; #(5208*20);        uart_rx = 0 ; #(5208*20);        uart_rx = 1 ; #(5208*20);
        uart_rx = 1 ; #(5208*20);        uart_rx = 1 ; #(5208*20);        uart_rx = 1 ; #(5208*20);
        uart_rx = 1 ; #(5208*20);        #200000;
     //   55   0101_0101
        uart_rx = 0 ; #(5208*20);        uart_rx = 1 ; #(5208*20);        uart_rx = 0 ; #(5208*20);
        uart_rx = 1 ; #(5208*20);        uart_rx = 0 ; #(5208*20);        uart_rx = 1 ; #(5208*20);
        uart_rx = 0 ; #(5208*20);        uart_rx = 1 ; #(5208*20);        uart_rx = 0 ; #(5208*20);
        uart_rx = 1 ; #(5208*20);        #200000;
       //   55   0101_0101
        uart_rx = 0 ; #(5208*20);        uart_rx = 1 ; #(5208*20);        uart_rx = 0 ; #(5208*20);
        uart_rx = 1 ; #(5208*20);        uart_rx = 0 ; #(5208*20);        uart_rx = 1 ; #(5208*20);
        uart_rx = 0 ; #(5208*20);        uart_rx = 1 ; #(5208*20);        uart_rx = 0 ; #(5208*20);
        uart_rx = 1 ; #(5208*20);        #200000; 
        //   F0   1111_0000
        uart_rx = 0 ; #(5208*20);        uart_rx = 0 ; #(5208*20);        uart_rx = 0 ; #(5208*20);
        uart_rx = 0 ; #(5208*20);        uart_rx = 0 ; #(5208*20);        uart_rx = 1 ; #(5208*20);
        uart_rx = 1 ; #(5208*20);        uart_rx = 1 ; #(5208*20);        uart_rx = 1 ; #(5208*20);
        uart_rx = 1 ; #(5208*20);        #200000; 
        
                    for (i = 0 ; i < 8 ; i = i+1)
                    begin
                        addrb = i;
                        #40;
                    end
                   addrb = 255; 
            #2000;
        $stop;
    end
    
    
endmodule

测试了向RAM中写入8个数据,并读出
由图可以看出串口写入模块正常

摸鱼怪碎碎念:之前

  always@(posedge clk or negedge reset_n)
    if(!reset_n)
        addra <= 8'B0000_0000;
    else  if(rx_done)
         addra <= addra + 1'b1;

 always@(posedge clk)
           if((rx_flag==9)&&(counter_bps == bps_c /2
-1))

                 rx_data <= r_rx_data;  

这两部分调试出来滴,之前没有连续传输过,so没注意到这个问题,嘿嘿嘿~

5.  RX + RAM +Key + TX

key_one.v

module key_one(
                 input clk , 
                 input reset_n,
                 input key,
                 output reg key_flag,
                 output reg key_state);
                 
        // nedge_key pedge_key
        reg dff_k_0 , dff_k_1 ;
        reg r_key; 
        wire  nedge_key, pedge_key;
        always@(posedge clk )    
            dff_k_0 <= key ;
        always@(posedge clk )    
            dff_k_1 <= dff_k_0 ;
        always@(posedge clk )    
            r_key <= dff_k_1 ;
            
        assign nedge_key = (r_key == 1)&&(dff_k_1 == 0);
        assign pedge_key = (r_key == 0)&&(dff_k_1 == 1);
   
        // key_now   0:IDLE   1:FILTER0   2:DOWN   3:FILTER1
        // cnt 20ms/20ns = 1000000 ;
        reg [1:0]key_now;
        reg [19:0] cnt;
        parameter cnt_N = 1000;   

        //测试的时候为了速度快一点调成这个,当然之前参数化有学习过应该咋做

        //摸鱼怪是这样的(确信

        //上板记得改回6个0
        always@(posedge clk or negedge reset_n ) 
            if(!reset_n) 
                begin
                    key_now <= 0 ;
                    cnt <= 0;
                    key_flag <= 0;
                    key_state <= 1;
                end
            else 
                begin
                    key_flag <= 0;
                    case(key_now)
                        0:
                           if(!nedge_key) key_now <= 0;
                           else 
                               begin 
                                 cnt <= 0 ;
                                 key_now <= 1; 
                               end
                               
                        1:
                            if(pedge_key) key_now <= 0;
                            else if(cnt >= cnt_N - 1) 
                                begin
                                    cnt <= 0 ;
                                    key_now <= 2;
                                    key_flag <= 1;
                                    key_state <= 0;
                                end
                            else cnt <= cnt + 1'b1;
                            
                        2:
                            if(!pedge_key) key_now <= 2;
                            else
                                begin
                                    cnt <= 0 ;
                                    key_now <= 3;
                                end
                        
                        3:
                            if(nedge_key) key_now <= 2;
                            else if(cnt >= cnt_N - 1)
                                 begin
                                    cnt <= 0 ;
                                    key_now <= 0;
                                    key_flag <= 1;
                                    key_state <= 1;
                                end
                            else cnt <= cnt + 1'b1;    
                        
                    endcase
                end

endmodule

uarttx.v

module uarttx(input clk , 
                input reset_n , 
                input [7:0]data , 
                input Send_Go ,
                output reg uart_tx , 
                output reg tx_done  );
        //默认使用波特率BAUD 9600  时钟频率 CLK_FREQ  50MHz
    parameter start_bit = 0 ;
    parameter stop_bit  = 1 ;
    parameter BAUD = 9600;
    parameter CLK_FREQ = 50_000_000;
    parameter bps_c = CLK_FREQ / BAUD ;    
    
        reg Send_en ; 
        always@(posedge clk or negedge reset_n )
        if(! reset_n) 
            Send_en <= 0 ;
        else if(Send_Go)
            Send_en <= 1 ; 
        else if((tx_flag==9)&&(counter_bps == bps_c - 1)) 
            Send_en <= 0 ;
        
      // bps
      reg [30:0] counter_bps ;        
      always@(posedge clk or negedge reset_n)
        if(! reset_n) 
            counter_bps <= 0 ;
        else if (Send_en)
            if(counter_bps == bps_c - 1)
                counter_bps <= 0 ;
            else
                counter_bps <= counter_bps + 1'b1 ;
        else
            counter_bps <= 0 ;
            
      // 发送状态
      reg [3:0] tx_flag;
      always@(posedge clk or negedge reset_n)
        if(! reset_n) 
            tx_flag <= 0 ;
        else if (!Send_en) tx_flag <= 0 ;
        else if ((tx_flag==9)&&(counter_bps == bps_c - 1))
             tx_flag <= 0 ;
        else
             if(counter_bps == bps_c - 1)
                tx_flag <= tx_flag + 1'b1 ;
                
//       Send_Go改变发送信号         
        reg [7:0]r_data;
        always@(posedge clk)
        if(Send_Go)
         r_data <= data;
        else
         r_data <= r_data;                    
         
    //  tx_flag          
       always@(*)
       if(!Send_en) uart_tx <= 1'b1;
       else
        begin 
            case(tx_flag)
            4'b0000 : uart_tx <= start_bit;
            4'b0001 : uart_tx <= r_data[0];
            4'b0010 : uart_tx <= r_data[1];
            4'b0011 : uart_tx <= r_data[2];
            4'b0100 : uart_tx <= r_data[3];
            4'b0101 : uart_tx <= r_data[4];
            4'b0110 : uart_tx <= r_data[5];
            4'b0111 : uart_tx <= r_data[6];
            4'b1000 : uart_tx <= r_data[7];
            4'b1001 : uart_tx <= stop_bit;
            default : uart_tx <= uart_tx;
            endcase
            
        end      
        
        
        always@(posedge clk )        
        tx_done <= (tx_flag==9)&&(counter_bps == bps_c - 1);
     
endmodule

rx_ram_tx.v(第一版)

module rx_ram_tx(
                     input clk ,
                     input reset_n ,
                     input uart_rx ,
                     input key ,
                     output uart_tx
                    );
        
    wire rx_done;
    wire [7:0]rx_data;
    reg [7:0]addra;
    reg [7:0]addrb;
    wire [7:0]doutb;
    wire key_flag;
    wire key_state;
    
    wire tx_done;
    ram ram_ (
                 .clka(clk), // input wire clka
                 .wea(rx_done), // input wire [0 : 0] wea
                 .addra(addra), // input wire [7 : 0] addra
                 .dina(rx_data), // input wire [7 : 0] dina
                 .clkb(clk), // input wire clkb
                 .addrb(addrb), // input wire [7 : 0] addrb
                 .doutb(doutb) // output wire [7 : 0] doutb
                                    );
    
    uartrx uart_rx_(
                 . clk(clk) ,
                 . reset_n(reset_n) ,
                 . uart_rx(uart_rx) ,
                 . rx_data(rx_data),
                 . rx_done(rx_done)    );
    
    
    always@(posedge clk or negedge reset_n)
    if(!reset_n)
        addra <= 8'b0000_0000;
    else  if(rx_done)
         addra <= addra + 1'b1;
        
    key_one key_(
                 . clk(clk) , 
                 . reset_n(reset_n),
                 . key(key),
                 . key_flag(key_flag),
                 . key_state(key_state)
                 );   
                 
    always@(posedge clk or negedge reset_n)
    if(!reset_n)
        addrb <= 8'b0000_0000;
    else  if(tx_done)
         addrb <= addrb + 1'b1;
 
         //这其实是是有问题滴!!!
     reg tx_en ;  
     always@(posedge clk or negedge reset_n)
     if(!reset_n)    
         tx_en <= 1'b0 ;
     else  if((key_flag)&&(key_state==0))
         tx_en <= 1'b1;   
     else  if(addrb == 11//这里也是因为测试才这样写滴
         tx_en <= 1'b0 ;
         
     reg Send_Go ;
     always@(posedge clk or negedge reset_n)
     if(!reset_n)    
         Send_Go <= 1'b0 ;
     else  if((key_flag)&&(key_state==0))
         Send_Go <= 1'b1;   
     else  if(tx_en && tx_done)
         Send_Go <= 1'b1 ;   
     else      
         Send_Go <= 1'b0 ;

            //为什么跟addrb 同样的颜色捏~
    uarttx uart_tx_(
                . clk(clk) , 
                . reset_n(reset_n) , 
                . data(doutb) , 
                . Send_Go(Send_Go) ,
                . uart_tx(uart_tx) , 
                . tx_done(tx_done)  
                );    
endmodule

rx_ram_key_tx_tb.v

`timescale 1ns / 1ns

module rx_ram_key_tx_tb(  );
   
   reg clk ;
   reg reset_n ;
   reg uart_rx ;
   reg key ;
   wire uart_tx ;
  
        
   rx_ram_tx rx_ram_tx_(
                         . clk(clk) ,
                         . reset_n(reset_n) ,
                         . uart_rx(uart_rx) ,
                         . key(key) ,
                         . uart_tx(uart_tx)
                        );
        
       initial clk = 1 ;
       always#10 clk = ~clk ;     
        
       initial 
        begin
            reset_n = 0 ;
            uart_rx = 1 ;
            key = 1'b1 ;
            #201;
            reset_n = 1 ;  #2000;     
        //   0F   0000_1111
        uart_rx = 0 ; #(5208*20);
        uart_rx = 0 ; #(5208*20);
        uart_rx = 0 ; #(5208*20);
        uart_rx = 0 ; #(5208*20);
        uart_rx = 0 ; #(5208*20);
        uart_rx = 1 ; #(5208*20);
        uart_rx = 1 ; #(5208*20);
        uart_rx = 1 ; #(5208*20);
        uart_rx = 1 ; #(5208*20);
        uart_rx = 1 ; #(5208*20);
        #200000;
     //   55   0101_0101
        uart_rx = 0 ; #(5208*20);
        uart_rx = 1 ; #(5208*20);
        uart_rx = 0 ; #(5208*20);
        uart_rx = 1 ; #(5208*20);
        uart_rx = 0 ; #(5208*20);
        uart_rx = 1 ; #(5208*20);
        uart_rx = 0 ; #(5208*20);
        uart_rx = 1 ; #(5208*20);
        uart_rx = 0 ; #(5208*20);
        uart_rx = 1 ; #(5208*20);
        #200000;
       //   55   0101_0101
        uart_rx = 0 ; #(5208*20);
        uart_rx = 1 ; #(5208*20);
        uart_rx = 0 ; #(5208*20);
        uart_rx = 1 ; #(5208*20);
        uart_rx = 0 ; #(5208*20);
        uart_rx = 1 ; #(5208*20);
        uart_rx = 0 ; #(5208*20);
        uart_rx = 1 ; #(5208*20);
        uart_rx = 0 ; #(5208*20);
        uart_rx = 1 ; #(5208*20);
        #200000; 
        //   0F   0000_1111
        uart_rx = 0 ; #(5208*20);
        uart_rx = 0 ; #(5208*20);
        uart_rx = 0 ; #(5208*20);
        uart_rx = 0 ; #(5208*20);
        uart_rx = 0 ; #(5208*20);
        uart_rx = 1 ; #(5208*20);
        uart_rx = 1 ; #(5208*20);
        uart_rx = 1 ; #(5208*20);
        uart_rx = 1 ; #(5208*20);
        uart_rx = 1 ; #(5208*20);
        #200000;
         //   0F   0000_1111
        uart_rx = 0 ; #(5208*20);
        uart_rx = 0 ; #(5208*20);
        uart_rx = 0 ; #(5208*20);
        uart_rx = 0 ; #(5208*20);
        uart_rx = 0 ; #(5208*20);
        uart_rx = 1 ; #(5208*20);
        uart_rx = 1 ; #(5208*20);
        uart_rx = 1 ; #(5208*20);
        uart_rx = 1 ; #(5208*20);
        uart_rx = 1 ; #(5208*20);
        #200000;
     //   55   0101_0101
        uart_rx = 0 ; #(5208*20);
        uart_rx = 1 ; #(5208*20);
        uart_rx = 0 ; #(5208*20);
        uart_rx = 1 ; #(5208*20);
        uart_rx = 0 ; #(5208*20);
        uart_rx = 1 ; #(5208*20);
        uart_rx = 0 ; #(5208*20);
        uart_rx = 1 ; #(5208*20);
        uart_rx = 0 ; #(5208*20);
        uart_rx = 1 ; #(5208*20);
        #200000;
       //   55   0101_0101
        uart_rx = 0 ; #(5208*20);
        uart_rx = 1 ; #(5208*20);
        uart_rx = 0 ; #(5208*20);
        uart_rx = 1 ; #(5208*20);
        uart_rx = 0 ; #(5208*20);
        uart_rx = 1 ; #(5208*20);
        uart_rx = 0 ; #(5208*20);
        uart_rx = 1 ; #(5208*20);
        uart_rx = 0 ; #(5208*20);
        uart_rx = 1 ; #(5208*20);
        #200000; 
        //   0F   0000_1111
        uart_rx = 0 ; #(5208*20);
        uart_rx = 0 ; #(5208*20);
        uart_rx = 0 ; #(5208*20);
        uart_rx = 0 ; #(5208*20);
        uart_rx = 0 ; #(5208*20);
        uart_rx = 1 ; #(5208*20);
        uart_rx = 1 ; #(5208*20);
        uart_rx = 1 ; #(5208*20);
        uart_rx = 1 ; #(5208*20);
        uart_rx = 1 ; #(5208*20);
        #200000; 
        
        key_press(2);
        #(5208*20*8*20); 
        
        
        
        
        $stop;
        end
       
 reg [13:0] rand;
 task key_press;
    input[3:0]seed;
    begin
        key =  1'b1 ;
        #1000;
        repeat(10)
            begin
                rand = {$random(seed)} % 10000;
                #rand;
                key=~key;
            end
        key = 1'b0 ;
        #100000; 
        key =  1'b1 ;   
   end
endtask 
        
        
endmodule

嘎嘎嘎~是不是觉得貌似没有问题~

那为什么要说存在问题捏!

自行调试一下:

always@(posedge clk or negedge reset_n)
    if(!reset_n)
        addrb <= 8'b1111_1111;
    else  if((key_flag)&&(key_state==0))
         addrb <= 8'b0000_0000;     
    else  if(tx_done)
         addrb <= addrb + 1'b1;  

(俺这里没有保存,就是之前学习RAM读取,配置中存在一个Latentcy

rx_ram_tx.v(修改后)

module rx_ram_tx(
                     input clk ,
                     input reset_n ,
                     input uart_rx ,
                     input key ,
                     output uart_tx
                    );
        
    wire rx_done;
    wire [7:0]rx_data;
    reg [7:0]addra;
    reg [7:0]addrb;
    wire [7:0]doutb;
    wire key_flag;
    wire key_state;
    
    wire tx_done;
    ram ram_ (
                 .clka(clk), // input wire clka
                 .wea(rx_done), // input wire [0 : 0] wea
                 .addra(addra), // input wire [7 : 0] addra
                 .dina(rx_data), // input wire [7 : 0] dina
                 .clkb(clk), // input wire clkb
                 .addrb(addrb), // input wire [7 : 0] addrb
                 .doutb(doutb) // output wire [7 : 0] doutb
                                    );
    
    uartrx uart_rx_(
                 . clk(clk) ,
                 . reset_n(reset_n) ,
                 . uart_rx(uart_rx) ,
                 . rx_data(rx_data),
                 . rx_done(rx_done)    );
    
    
    always@(posedge clk or negedge reset_n)
    if(!reset_n)
        addra <= 8'b0000_0000;
    else  if(rx_done)
         addra <= addra + 1'b1;
        
    key_one key_(
                 . clk(clk) , 
                 . reset_n(reset_n),
                 . key(key),
                 . key_flag(key_flag),
                 . key_state(key_state)
                 );   
                 
    always@(posedge clk or negedge reset_n)
    if(!reset_n)
        addrb <= 8'b1111_1111;
   
else  if((key_flag)&&(key_state==0))   //发送从首地址开始
         addrb <= 8'b0000_0000;  
  
    else  if(tx_done)
         addrb <= addrb + 1'b1;  

         
     reg tx_en ; 
     always@(posedge clk or negedge reset_n)
     if(!reset_n)    
         tx_en <= 1'b0 ;
     else  if((key_flag)&&(key_state==0))
         tx_en <= 1'b1;   
     else  if(addrb == 11)
         tx_en <= 1'b0 ;
         
     reg Send_Go_0 , Send_Go_1 ,Send_Go_2 ,Send_Go ;

       //这部分是之前的Send_Go
     always@(posedge clk or negedge reset_n)
     if(!reset_n)    
         Send_Go_0 <= 1'b0 ;
   
 else  if((key_flag)&&(key_state==0))    
         Send_Go_0 <= 1'b1;   
     else  if(tx_en && tx_done)
         Send_Go_0 <= 1'b1 ;   
     else      
         Send_Go_0 <= 1'b0 ;

         //这部分是Latentcy
    always@(posedge clk or negedge reset_n)
     if(!reset_n)  
        begin  
         Send_Go_1 <= 1'b0 ;
         Send_Go_2 <= 1'b0 ;
         Send_Go <= 1'b0 ;
       end 
     else
        begin  
         Send_Go_1 <= Send_Go_0 ;
         Send_Go_2 <= Send_Go_1 ;
         Send_Go <= Send_Go_2 ;
       end   

       
    uarttx uart_tx_(
                . clk(clk) , 
                . reset_n(reset_n) , 
                . data(doutb) , 
                . Send_Go(Send_Go) ,
                . uart_tx(uart_tx) , 
                . tx_done(tx_done)  
                );    
endmodule

6.  板级验证

.xdc

set_property IOSTANDARD LVCMOS33 [get_ports clk]
set_property IOSTANDARD LVCMOS33 [get_ports key]
set_property IOSTANDARD LVCMOS33 [get_ports reset_n]
set_property IOSTANDARD LVCMOS33 [get_ports uart_rx]
set_property IOSTANDARD LVCMOS33 [get_ports uart_tx]
set_property PACKAGE_PIN U18 [get_ports clk]
set_property PACKAGE_PIN H18 [get_ports key]
set_property PACKAGE_PIN H20 [get_ports reset_n]
set_property PACKAGE_PIN K16 [get_ports uart_rx]
set_property PACKAGE_PIN J16 [get_ports uart_tx]

依次向RAM中写入:0x10~0x1F(一开始把0忘记哩~)读取到的数值是正确的

但是写入:0x01~0xF1 可以看出,最高两位的数据一直为0

存在的小错误下次继续调试叭~

摸鱼怪跑路~

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.mzph.cn/bicheng/30574.shtml

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈email:809451989@qq.com,一经查实,立即删除!

相关文章

ADOP带你了解:数据中心的高速互联解决方案

随着大语言模型和AIGC的飞速发展&#xff0c;数据中心对于高速、高可靠性的网络连接需求日益增长。ADOP系列产品正是在这样的背景下应运而生&#xff0c;为现代数据中心提供了全面的连接解决方案。 ADOP系列产品概览 ADOP系列产品旨在为云、高性能计算、Web 2.0、企业、电信、…

SparkSQL的分布式执行引擎-Thrift服务:学习总结(第七天)

系列文章目录 SparkSQL的分布式执行引擎 1、启动Thrift服务 2、beeline连接Thrift服务 3、开发工具连接Thrift服务 4、控制台编写SQL代码 文章目录 系列文章目录前言一、SparkSQL的分布式执行引擎(了解)1、启动Thrift服务2、beeline连接Thrift服务3、开发工具连接Thrift服务4、…

(7)摄像机和云台

文章目录 前言 1 云台 2 带有MAVLink接口的摄像机 3 相机控制和地理标签 4 视频质量差的常见修复方法 5 详细主题 前言 Copter、Plane 和 Rover 最多支持 3 轴云台&#xff0c;包括自动瞄准感兴趣区域&#xff08;ROI&#xff09;的相机和自动触发相机快门等先进功能。按…

好书推荐:AI教母李飞飞自传《我看见的世界》,豆瓣9.1分!

大家好&#xff0c;我是木易&#xff0c;一个持续关注AI领域的互联网技术产品经理&#xff0c;国内Top2本科&#xff0c;美国Top10 CS研究生&#xff0c;MBA。我坚信AI是普通人变强的“外挂”&#xff0c;所以创建了“AI信息Gap”这个公众号&#xff0c;专注于分享AI全维度知识…

子组件和父组件之间传值#Vue3#defineProps

子组件和父组件之间传值#Vue3#defineProps 效果&#xff1a; 子组件&#xff1a; <!-- 6s执行项详情图片的子组件 --> <template><div><imgv-if"itemsLocal.url":src"itemsLocal.url"style"width: 50px; height: 50px; marg…

【Ardiuno】实验ESP32单片机搭建简易Web服务器功能(图文)

今天&#xff0c;小飞鱼继续来测试使用ESP32来实现简易的wifi无线web服务器功能。使用Ardiuno平台编辑器输入以下示例代码&#xff1a; #include <WiFi.h> #include <WiFiClient.h> #include <WebServer.h> #include <ESPmDNS.h>const char* ssid &q…

java 不可变集合的创建和Stream流的使用

文章目录 一、创建不可变的集合1.1为什么创建不可变的集合1.2 创建List、Set和Map的不可变集合1.2.1 创建List的不可变集合1.2.2 创建Set 的不可变集合1.2.3 创建Map的不可变集合 二、使用集合 的Stream 流2.1 Stream的使用步骤2.2 Stream的方法 三、如何获取Stream 流对象四、…

深度学习增强的非线性光纤单像素成像系统

1、光子器件的逆向设计&#xff1a;通过机器学习&#xff0c;特别是深度学习&#xff0c;可以高效地进行光子器件的逆向设计&#xff0c;这在传统的多参数优化问题中尤为重要。 2、超构表面和超材料设计&#xff1a;机器学习被用于设计具有特定光学特性的超构表面和超材料&…

初阶 《数组》 1. 一维数组的创建和初始化

1. 一维数组的创建和初始化 1.1 数组的创建 数组是一组相同类型元素的集合 数组的创建方式&#xff1a; type_t arr_name [const_n]; //type_t 是指数组的元素类型 //const_n 是一个常量表达式&#xff0c;用来指定数组的大小数组创建的实例&#xff1a; //代码1 int ar…

Wills Room Environment Dormitory Room Environment

有126个独特的网格。包括所有展示的资产和优质资产。具有良好的细节水平,并针对Gameready项目进行了优化。 艺术家Jonjo Hemmens创造的环境 如果想填充你的游戏环境或任何类型的虚拟制作级别,这里有一个包,你可以获得并使用它来得到高质量的视觉效果和优化的资产。 下载:​…

【病毒分析】Steloj勒索病毒分析

1.背景 1.1 来源 近期&#xff0c;Solar团队收到某汽车制造公司的援助请求&#xff0c;该公司的计算机服务器受到了Steloj勒索家族的侵害&#xff0c;所有的文件被加密并且添加了.steloj后缀&#xff0c;该勒索软件的初始入侵方式是MSSQL数据库弱口令进行入侵&#xff0c;后续…

Ubuntu22.04 下安装Curl库

1. apt 安装&#xff1a; sudo apt-get install curl 2. 官网压缩包&#xff1a; 下载地址&#xff1a;curl downloads wget https://curl.haxx.se/download/curl-7.78.0.tar.gz tar -xzvf curl-7.78.0.tar.gz cd curl-7.78.0 ./configure --with-openssl make sudo make i…

前端技术栈二(promise模块化编程)

一、promise 1 Promise 基本介绍 传统的 Ajax 异步调用在需要多个操作的时候&#xff0c;会导致多个回调函数嵌套&#xff0c;导致代码不够直观&#xff0c;就是常说的 Callback Hell 为了解决上述的问题&#xff0c;Promise 对象应运而生&#xff0c;在 EMCAScript 2015 当中…

M1失效后,哪个是观察A股的关键新指标?

M1失效后&#xff0c;哪个是观察A股的关键新指标&#xff1f; 央地支出增速差&#xff08;地方-中央支出增速的差值&#xff09;或许是解释沪深300定价更有效的前瞻指标。该数值扩张&#xff0c;则有利于大盘指数&#xff0c;反之亦然&#xff0c;该指标从2017年至今对大盘指数…

Hedra:让您的照片说话

在数字内容创作的世界里&#xff0c;我们总是在寻找那些能够让我们的作品更加生动和吸引人的工具。Hedra软件就是这样一款工具&#xff0c;它能够让您的照片动起来&#xff0c;甚至说话。想象一下&#xff0c;您的家庭相册中的照片突然变得栩栩如生&#xff0c;或者您的产品图片…

Python微磁学磁倾斜和西塔规则算法

&#x1f4dc;有限差分-用例 &#x1f4dc;离散化偏微分方程求解器和模型定型 | &#x1f4dc;三维热传递偏微分方程解 | &#x1f4dc;特定资产期权价值偏微分方程计算 | &#x1f4dc;三维波偏微分方程空间导数计算 | &#x1f4dc;应力-速度公式一阶声波方程模拟二维地震波…

磁链观测器设计与Simulink建模

1. 磁链观测器设计 如下方程描述了模块输入计算永磁同步电机得电角度&#xff0c;磁通量和电扭矩。 假设 那么&#xff0c;以下拉普拉斯变换表示 Ψα 和 Ψβ 中的积分项&#xff1a; 为了滤除噪声信号&#xff0c;这里使用带低通滤波器得积分器。注意&#xff0c;低通滤波器得…

[笔记] CCD相机测距相关的一些基础知识

1.35mm胶片相机等效焦距 https://zhuanlan.zhihu.com/p/419616729 拿到摄像头拍摄的数码照片后&#xff0c;我们会看到这样的信息&#xff1a; 这里显示出了两个焦距&#xff1a;一个是实际焦距&#xff1a;5mm&#xff0c;一个是等效焦距&#xff1a;25mm。 实际焦距很容易…

OpenGL3.3_C++_Windows(14)

demo演示 demo演示 天空盒 作用&#xff1a;我们想要一个立方体每个面都有不同的纹理&#xff0c;可以在while使用&#xff1a;glActiveTexture&#xff08;&#xff09;&#xff0c;激活绑定相应纹理&#xff0c;glVertexAttribPointer设置布局&#xff0c;glDrawArrays&…

21.0docker企业级镜像仓库harbor(vmware 中国团队)

docker企业级镜像仓库harbor(vmware 中国团队) 网站下载harbor软件包 https://github.com/goharbor/harbor 查看软件安装harbor版本需求限制 本地环境需求已满足 点击下载harbor安装包 点击releases根据版本信息下载 下面的在线安装就是docker pull。离线就是下载之后…