• FPGA project : uart232_ram_vga


    重点学习:

    本实验重点学习了双口ram解决多bit跨时钟域同步处理的问题。

    其实signal port ram,它的输入口和输出口分别用不同的时钟,也可以解决这个问题。

    让我意识到的比较重要的事情:

    1,代码设计中,一些大于10的数字,尽量用parameter设定一些可以重传的参数来代替。因为这样方便仿真修改。我就是之前写uart_rx模块,数字啥的没用参数替代。这个实验中仿真时需要修改参数,然后重新修改了uart_rx代码。使得仿真时间大大缩短,很方便。

    2,在vga_pic模块中模拟产生的ram,读完数据后,ram里面的数据并没有消失,还在。

    写数据:在时钟上升沿,写使能拉高,与此同时要有对应的地址与数据。然后数据就写进对应的地址里面了。

    读数据:在时钟上升沿,读使能拉高,与此同时给出地址,然后数据就都出来了。值得一提的是,数据会滞后一个时钟周期(相对于读使能与地址),说明ram内部用的时序逻辑嘛。

    3, task input ...如果写在task内部了。那么在task name 后面就不要加括号了。否则modulism会报错。

     

    1. module vga_pic (
    2. input wire clk_25 , // ram 的输出时钟,也是vga图像的时钟。
    3. input wire clk_50 , // ram 的输入时钟
    4. input wire rst_n , // 经过系统复位和pll的locked相与后的复位。
    5. input wire [9:0] pix_x ,
    6. input wire [9:0] pix_y ,
    7. input wire [7:0] po_data , // 写入的数据的数据
    8. input wire po_flag , // 用作ram的读使能。
    9. output wire [7:0] pix_data
    10. );
    11. // parameter
    12. parameter H_VALID = 10'd640 ,
    13. V_VALID = 10'd480 ;
    14. parameter PIC_SIZE= 14'd1_0000 ,
    15. H_PIC = 10'd100 ,
    16. V_PIC = 10'd100 ;
    17. parameter RED = 8'b1110_0000 ,
    18. GREEN = 8'b0001_1100 ,
    19. BLUE = 8'b0000_0011 ,
    20. WHITE = 8'b1111_1111 ,
    21. BLACK = 8'b0000_0000 ;
    22. // reg signal define
    23. reg [13:0] wr_addr ; // ram 的写地址。
    24. reg [ 7:0] data_pix ; // 彩条像素
    25. reg pic_valid; // 图片有效
    26. wire [ 7:0] pic_data ; // 图片像素
    27. reg rd_en ; // ram读使能
    28. reg [13:0] rd_addr ;
    29. /************************************************************************/
    30. // reg [13:0] wr_addr ; // ram 的写地址。
    31. always @(posedge clk_50 or negedge rst_n) begin
    32. if(~rst_n) begin
    33. wr_addr <= 14'd0 ;
    34. end else begin
    35. if(po_flag) begin
    36. if(wr_addr == 9999) begin // 记到最大的地址后归零。
    37. wr_addr <= 14'd0 ;
    38. end else begin
    39. wr_addr <= wr_addr + 1'b1 ;
    40. end
    41. end else begin
    42. wr_addr <= wr_addr ;
    43. end
    44. end
    45. end
    46. // reg [ 7:0] data_pix ; // 彩条像素
    47. always @(posedge clk_25 or negedge rst_n) begin
    48. if(~rst_n) begin
    49. data_pix <= BLACK ;
    50. end else begin
    51. if(pix_y >= 0 && pix_y <= (V_VALID / 5 - 1))
    52. data_pix <= RED ;
    53. else if((pix_y >= V_VALID / 5) && pix_y <= ((V_VALID / 5 ) * 2) - 1)
    54. data_pix <= GREEN ;
    55. else if((pix_y >= (V_VALID / 5) * 2) && pix_y <= ((V_VALID / 5 ) * 3) - 1)
    56. data_pix <= BLUE ;
    57. else if((pix_y >= (V_VALID / 5) * 3) && pix_y <= ((V_VALID / 5 ) * 4) - 1)
    58. data_pix <= WHITE ;
    59. else if((pix_y >= (V_VALID / 5) * 4) && pix_y <= (V_VALID - 1))
    60. data_pix <= BLACK ;
    61. else
    62. data_pix <= BLACK ;
    63. end // 先不写else 一会看编译是否会通过。
    64. end
    65. // reg pic_valid; // 图片有效
    66. always @(posedge clk_25 or negedge rst_n) begin
    67. if(~rst_n) begin
    68. pic_valid <= 1'b0 ;
    69. end else begin
    70. if(pix_x >= 269 && pix_x <= 368 && pix_y >= 190 && pix_y <= 289) begin
    71. pic_valid <= 1'b1 ;
    72. end else begin
    73. pic_valid <= 1'b0 ;
    74. end
    75. end
    76. end
    77. // wire [ 7:0] pic_data ; // 图片像素
    78. // 图片像素存在了ram中,所以只需要取出来就是图片像素了。
    79. // reg rd_en ; // ram读使能
    80. always @(posedge clk_25 or negedge rst_n) begin
    81. if(~rst_n) begin
    82. rd_en <= 1'b0 ;
    83. end else begin
    84. if(pix_x >= 268 && pix_x <= 367 && pix_y >= 190 && pix_y <= 289) begin
    85. rd_en <= 1'b1 ;
    86. end else begin
    87. rd_en <= 1'b0 ;
    88. end
    89. end
    90. end
    91. // reg [13:0] rd_addr ;
    92. always @(posedge clk_25 or negedge rst_n) begin
    93. if(~rst_n) begin
    94. rd_addr <= 14'd0 ;
    95. end else begin
    96. if(rd_en) begin
    97. if(rd_addr == 9999) begin
    98. rd_addr <= 14'd0 ;
    99. end else begin
    100. rd_addr <= rd_addr + 1'b1 ;
    101. end
    102. end else begin
    103. rd_addr <= rd_addr ;
    104. end
    105. end
    106. end
    107. /**********************output signal define**************************************/
    108. // wire [7:0] pix_data ;
    109. assign pix_data = (pic_valid == 1'b1) ? pic_data : data_pix ;
    110. /******************例化双口ram*******************/
    111. ram_10000_double ram_10000_double_insert(
    112. .data ( po_data ) ,
    113. .inclock ( clk_50 ) ,
    114. .outclock ( clk_25 ) ,
    115. .rdaddress ( rd_addr ) ,
    116. .wraddress ( wr_addr ) ,
    117. .wren ( po_flag ) ,
    118. .q ( pic_data)
    119. );
    120. endmodule

     

    1. module top(
    2. input wire sys_clk ,
    3. input wire sys_rst_n ,
    4. input wire rx ,
    5. output wire [7:0] rgb ,
    6. output wire hsync ,
    7. output wire vsync
    8. );
    9. // 例化间连线
    10. wire rst_n ;
    11. wire [7:0] po_data ;
    12. wire po_flag ;
    13. wire [7:0] pix_data ;
    14. wire [9:0] pix_x ;
    15. wire [9:0] pix_y ;
    16. wire clk_25 ;
    17. wire clk_50 ;
    18. pll pll_inst (
    19. .sys_rst_n ( sys_rst_n ) ,
    20. .areset ( ~sys_rst_n ) ,
    21. .inclk0 ( sys_clk ) ,
    22. .c0 ( clk_25 ) ,
    23. .c1 ( clk_50 ) ,
    24. .locked ( rst_n )
    25. );
    26. uart_rx uart_rx_inst(
    27. .sys_clk ( clk_50 ) ,
    28. .sys_rst_n ( rst_n ) ,
    29. .rx ( rx ) ,
    30. .po_data ( po_data ) ,
    31. .po_flag ( po_flag )
    32. );
    33. vga_ctrl vga_ctrl_inst(
    34. .vga_clk ( clk_25 ) ,
    35. .vga_rst_n ( rst_n ) ,
    36. .pix_data ( pix_data ) ,
    37. .hsync ( hsync ) ,
    38. .vsync ( vsync ) ,
    39. .pix_x ( pix_x ) ,
    40. .pix_y ( pix_y ) ,
    41. .rgb ( rgb )
    42. );
    43. vga_pic vga_pic_inst(
    44. .clk_25 ( clk_25 ) ,
    45. .clk_50 ( clk_50 ) ,
    46. .rst_n ( rst_n ) ,
    47. .pix_x ( pix_x ) ,
    48. .pix_y ( pix_y ) ,
    49. .po_data ( po_data ) ,
    50. .po_flag ( po_flag ) ,
    51. .pix_data ( pix_data )
    52. );
    53. endmodule
    1. `timescale 1ns/1ns
    2. module test_top();
    3. reg sys_clk ;
    4. reg sys_rst_n ;
    5. reg rx ;
    6. wire [7:0] rgb ;
    7. wire hsync ;
    8. wire vsync ;
    9. reg [7:0] data_mem [9999:0];
    10. top top_insert(
    11. .sys_clk ( sys_clk ) ,
    12. .sys_rst_n ( sys_rst_n ) ,
    13. .rx ( rx ) ,
    14. .rgb ( rgb ) ,
    15. .hsync ( hsync ) ,
    16. .vsync ( vsync )
    17. );
    18. defparam top_insert.uart_rx_inst.CLK_FREQ = 5 ;
    19. defparam top_insert.uart_rx_inst.UART_BPS = 1 ;
    20. parameter CYCLE = 20 ;
    21. initial begin
    22. sys_clk = 1'b1 ;
    23. sys_rst_n <=1'b0 ;
    24. #(CYCLE) ;
    25. sys_rst_n <=1'b1 ;
    26. end
    27. always #(CYCLE / 2) sys_clk = ~sys_clk ;
    28. initial begin
    29. $readmemh ("D:/intel_FPGA/VScodedocument/EmbedFire/31 rs232_vga/matlab/data_test.txt",data_mem);
    30. end
    31. initial begin
    32. rx <= 1'b1 ;
    33. #(CYCLE * 10) ;
    34. rx_byte ;
    35. end
    36. task rx_byte;
    37. integer j ; // j 是存储器的地址。
    38. for (j = 0;j < 10000 ;j = j + 1 ) begin
    39. rx_bit(data_mem[j]) ; // 没有输入端口,自然不需要输入参数。
    40. end
    41. endtask
    42. task rx_bit;
    43. input [7:0]data ;
    44. integer i ;
    45. for (i = 0;i < 10 ;i = i + 1 ) begin
    46. case (i)
    47. 0:rx <= 1'b0;
    48. 1:rx <= data[0];
    49. 2:rx <= data[1];
    50. 3:rx <= data[2];
    51. 4:rx <= data[3];
    52. 5:rx <= data[4];
    53. 6:rx <= data[5];
    54. 7:rx <= data[6];
    55. 8:rx <= data[7];
    56. 9:rx <= 1'b1;
    57. default: rx <= 1'b1;
    58. endcase
    59. #(5 * CYCLE) ;
    60. end
    61. endtask
    62. endmodule

     

  • 相关阅读:
    移动端项目创建,脚手架,vant3移动开发的UI组件
    JAVA基础学习笔记(4) 程序控制结构
    软件设计师考试错题
    学Python的漫画漫步进阶 -- 第十一步.常用的内置模块
    SpringBoot SSMP项目搭建保姆级教程
    二、Java内存模型与volatile
    SQL 练习
    猿创征文|手把手教你微服务分布式事务与Seata框架源码分析
    错误 0x800700DF 文件大小超出允许的限制,无法保存
    《天天数学》连载65:三月五日
  • 原文地址:https://blog.csdn.net/Meng_long2022/article/details/133319679