当前位置:   article > 正文

Xilinx FPGA:vivado关于真双端口的串口传输数据的实验

Xilinx FPGA:vivado关于真双端口的串口传输数据的实验

一、实验内容

      用一个真双端RAM,端口A和端口B同时向RAM里写入数据0-99,A端口读出单数并存入单端口RAM1中,B端口读出双数并存入但端口RAM2中,当检测到按键1到来时将RAM1中的单数读出显示到PC端,当检测到按键2到来时,将RAM2中的双数显示到pc端。

二、信号流向图

TIPS:这里我本来想将single_ram_1和single_ram_2分成两个单独的模块,但是经过实验后发现,如果分成两个单独的模块的话会导致:

       ①两个单端RAM模块的tx_start(0或1)都会有值给uart_tx模块,即使是RAM1给【1】,RAM2中没有值【0】,uart_tx模块是无法判断 tx_start 到底来自于哪个模块,所以此时uart_tx模块只是能接收到一个tx_start的脉冲信号,但是无法判断信号来自哪个RAM模块,无法获取到相应的uart_data ,最终导致tx_flag都无法变成高电平,那就更不会返回给RAM模块tx_done信号了。

       ②如果单独为了正确信号能赋值给tx_start而重新去写一个ctrl模块的话,那么在ctrl模块中将无法使用判断条件,因为我们将状态作为了赋值条件而不仅仅是key_flag信号。

       那么我的解决方法就是把single_ram_2例化到single_ram_1当中,将single_ram_2输出的数据(uart_data_b及tx_start_b)和single_ram_1输出的数据(douta即tx_start_a)全部放在一个模块即single_ram_1中去做判断,但是我们仍然无法将single_ram_2的状态作为赋值的条件,所以只能采用这种比较粗暴的方式,也就是除了( cur_state == REG || cur_state == READ )时候tx_start <= tx_start_a ;那么其他情况就是tx_start <= tx_start_b ; uart_data的处理也是同样。详见后面程序。

       其实最好的方式是将single_ram_2和single_ram_1写在同一个模块中,程序放在文章最后了。

三、程序设计

(1)按键消抖模块:

这里注意key1和key2不能使用同一个计数器,不然在同一个模块中也会判断出问题。

  1. `timescale 1ns / 1ps
  2. module key_debounce(
  3. input sys_clk ,
  4. input rst_n ,
  5. input key1 ,
  6. input key2 ,
  7. output key_flag_1 ,
  8. output key_flag_2
  9. );
  10. // parameter delay = 100_000_0 ; //20ms
  11. parameter delay = 100;// 测试用
  12. reg[19:0] cnt1 ;
  13. reg[19:0] cnt2 ;
  14. key_flag_1
  15. always@(posedge sys_clk )
  16. if(!rst_n)
  17. cnt1 <= 0 ;
  18. else if ( key1 == 0 )begin
  19. if ( cnt1 == delay -1 )
  20. cnt1 <= cnt1 ;
  21. else
  22. cnt1 <= cnt1 +1 ;
  23. end
  24. else
  25. cnt1 <= 0 ;
  26. assign key_flag_1 = ( cnt1 == delay -2 )?1:0 ;
  27. ///key_flag_2
  28. always@(posedge sys_clk )
  29. if(!rst_n)
  30. cnt2 <= 0 ;
  31. else if ( key2 == 0 )begin
  32. if ( cnt2 == delay -1 )
  33. cnt2 <= cnt2 ;
  34. else
  35. cnt2 <= cnt2 +1 ;
  36. end
  37. else
  38. cnt2 <= 0 ;
  39. assign key_flag_2 = ( cnt2 == delay -2 )?1:0 ;
  40. endmodule

(2)真双端模块:

IP参数:

  1. `timescale 1ns / 1ps
  2. module the_true_ram(
  3. input sys_clk ,
  4. input rst_n ,
  5. output [7:0] ram_odd_data ,
  6. output [7:0] ram_even_data
  7. );
  8. A端口
  9. reg wea ;
  10. reg [6 : 0] addra ;
  11. reg [7 : 0] dina ;
  12. wire [7 : 0] douta ;
  13. always@(posedge sys_clk )
  14. if(!rst_n)
  15. wea <= 0 ;
  16. else if ( addra >= 99 )
  17. wea <= 0 ;
  18. else
  19. wea <= 1 ;
  20. always@(posedge sys_clk )
  21. if(!rst_n)
  22. addra <= 0 ;
  23. else if ( addra >= 99 )
  24. addra <= 99 ;
  25. else
  26. addra <= addra +1 ;
  27. always@(posedge sys_clk )
  28. if(!rst_n)
  29. dina <= 0 ;
  30. else if (dina >= 99)
  31. dina <= 99 ;
  32. else
  33. dina <= dina +1 ;
  34. wire [7:0] data_a ;
  35. assign data_a = douta ;
  36. assign ram_odd_data = (data_a%2 == 1)?data_a : ram_odd_data ;
  37. ///b端口
  38. reg web ;
  39. reg [6 : 0] addrb ;
  40. reg [7 : 0] dinb ;
  41. wire [7 : 0] doutb ;
  42. always@(posedge sys_clk )
  43. if(!rst_n)
  44. web <= 0 ;
  45. else if ( addrb >= 99 )
  46. web <= 0 ;
  47. else
  48. web <= 1 ;
  49. always@(posedge sys_clk )
  50. if(!rst_n)
  51. addrb <= 0 ;
  52. else if ( addrb >= 99 )
  53. addrb <= 99 ;
  54. else
  55. addrb <= addrb +1 ;
  56. always@(posedge sys_clk )
  57. if(!rst_n)
  58. dinb <= 0 ;
  59. else if ( dinb >= 99 )
  60. dinb <= 99 ;
  61. else
  62. dinb <= dinb +1 ;
  63. wire[7:0] data_b ;
  64. assign data_b = doutb ;
  65. assign ram_even_data = (data_b %2 == 0 )? data_b : ram_even_data ;
  66. //----------- Begin Cut here for INSTANTIATION Template ---// INST_TAG
  67. true_ram your_instance_name (
  68. .clka(sys_clk ), // input wire clka
  69. .ena(1), // input wire ena
  70. .wea(wea), // input wire [0 : 0] wea
  71. .addra(addra), // input wire [6 : 0] addra
  72. .dina(dina), // input wire [7 : 0] dina
  73. .douta(douta), // output wire [7 : 0] douta
  74. .clkb(sys_clk ), // input wire clkb
  75. .enb(1), // input wire enb
  76. .web(web), // input wire [0 : 0] web
  77. .addrb(addrb), // input wire [6 : 0] addrb
  78. .dinb(dinb), // input wire [7 : 0] dinb
  79. .doutb(doutb) // output wire [7 : 0] doutb
  80. );
  81. // INST_TAG_END ------ End INSTANTIATION Template ---------
  82. endmodule

(3)单端RAM2模块:

但其实深度在50就够用了。(100里面的奇数和偶数50)

  1. `timescale 1ns / 1ps
  2. module single_ram_2_FMS(
  3. input sys_clk ,
  4. input rst_n ,
  5. input key_flag_2 ,
  6. input tx_done ,
  7. input [7:0] ram_even_data ,
  8. output reg tx_start_b ,
  9. output reg[7:0] uart_data_b
  10. );
  11. 存双数的RAM
  12. reg ena ;
  13. reg [0 : 0] wea ;
  14. reg [6 : 0] addra ;
  15. reg [7 : 0] dina ;
  16. wire [7 : 0] douta ;
  17. //先写再读出
  18. localparam IDLE = 3'd0 ;
  19. localparam WRITE = 3'd1 ;
  20. localparam REG = 3'd2 ;
  21. localparam READ = 3'd3 ;
  22. reg[2:0] cur_state ;
  23. reg[2:0] next_state ;
  24. //state1
  25. always@(posedge sys_clk )
  26. if(!rst_n)
  27. cur_state <= IDLE ;
  28. else
  29. cur_state <= next_state ;
  30. //state2
  31. always@(*)
  32. case(cur_state)
  33. IDLE :
  34. begin
  35. next_state = WRITE ;
  36. end
  37. WRITE :
  38. begin
  39. if ( key_flag_2 )
  40. next_state = REG ;
  41. else
  42. next_state = cur_state ;
  43. end
  44. REG :
  45. begin
  46. next_state = READ ;
  47. end
  48. READ :
  49. begin
  50. if(addra == 49)
  51. next_state = IDLE ;
  52. else
  53. next_state <= cur_state ;
  54. end
  55. default:;
  56. endcase
  57. //state3
  58. always@(posedge sys_clk )
  59. if(!rst_n)begin
  60. ena <= 0 ;
  61. wea <= 0 ;
  62. addra <= 0 ;
  63. dina <= 0 ;
  64. tx_start_b <= 0 ;
  65. end
  66. else
  67. case(cur_state)
  68. IDLE :
  69. begin
  70. ena <= 0 ;
  71. wea <= 0 ;
  72. addra <= 0 ;
  73. dina <= ram_even_data ;
  74. end
  75. WRITE :
  76. begin
  77. ena <= 1 ;
  78. wea <= 1 ;
  79. if(addra == 49)
  80. addra <= 49 ;
  81. else
  82. addra <= addra +1 ;
  83. dina <= ram_even_data ;
  84. end
  85. REG :
  86. begin
  87. addra <= 0 ;
  88. ena <= 0 ;
  89. wea <= 0 ;
  90. dina <= 0 ;
  91. tx_start_b <= 1 ;
  92. end
  93. READ :
  94. begin
  95. ena <= 1 ;
  96. wea <= 0 ;
  97. dina<= 0 ;
  98. if(tx_done)begin
  99. tx_start_b <= 1 ;
  100. addra <= addra +1 ;
  101. end
  102. else begin
  103. tx_start_b <= 0 ;
  104. addra <= addra ;
  105. end
  106. end
  107. default:;
  108. endcase
  109. //----------- Begin Cut here for INSTANTIATION Template ---// INST_TAG
  110. single_ram ram2 (
  111. .clka(sys_clk ), // input wire clka
  112. .ena(ena), // input wire ena
  113. .wea(wea), // input wire [0 : 0] wea
  114. .addra(addra), // input wire [6 : 0] addra
  115. .dina(dina), // input wire [7 : 0] dina
  116. .douta(douta) // output wire [7 : 0] douta
  117. );
  118. // INST_TAG_END ------ End INSTANTIATION Template ---------
  119. always@(posedge sys_clk )
  120. if(!rst_n)
  121. uart_data_b <= 0 ;
  122. else if ( cur_state == READ )
  123. uart_data_b <= douta ;
  124. else
  125. uart_data_b <= uart_data_b ;
  126. always@(posedge sys_clk )
  127. if(!rst_n)
  128. tx_start_b <= 0 ;
  129. else if ( cur_state == REG || cur_state == READ )
  130. tx_start_b <= 1 ;
  131. else
  132. tx_start_b <= tx_start_b ;
  133. endmodule

(4)单端RAM1模块

配置和前面一样

  1. `timescale 1ns / 1ps
  2. module single_ram_1_FMS(
  3. input sys_clk ,
  4. input rst_n ,
  5. input key_flag_1 ,
  6. input key_flag_2 ,
  7. input tx_done ,
  8. input[7:0] ram_odd_data ,
  9. input[7:0] ram_even_data,
  10. output reg tx_start ,
  11. output reg[7:0] uart_data
  12. );
  13. /读单数的RAM
  14. reg ena ;
  15. reg wea ;
  16. reg [6 : 0] addra ;
  17. reg [7 : 0] dina ;
  18. wire [7 : 0] douta ;
  19. reg tx_start_a ;
  20. wire tx_start_b ;
  21. wire[7:0] uart_data_b ;
  22. 先写再读出
  23. localparam IDLE = 3'd0 ;
  24. localparam ERITE = 3'd1 ;
  25. localparam REG = 3'd2 ;
  26. localparam READ = 3'd3 ;
  27. reg[2:0] cur_state ;
  28. reg[2:0] next_state ;
  29. //state1
  30. always@(posedge sys_clk )
  31. if(!rst_n)
  32. cur_state <= IDLE ;
  33. else
  34. cur_state <= next_state ;
  35. //state2
  36. always@(*)
  37. case(cur_state)
  38. IDLE :
  39. begin
  40. next_state = ERITE ;
  41. end
  42. ERITE :
  43. begin
  44. if(key_flag_1)
  45. next_state = REG ;
  46. else
  47. next_state <= cur_state ;
  48. end
  49. REG :
  50. begin
  51. next_state = READ ;//用来发送tx_start
  52. end
  53. READ :
  54. begin
  55. if(addra == 49)//100内的单数是50
  56. next_state = IDLE ;
  57. else
  58. next_state = cur_state ;
  59. end
  60. default:;
  61. endcase
  62. //state3
  63. always@(posedge sys_clk )
  64. if(!rst_n)begin
  65. ena <= 0 ;
  66. wea <= 0 ;
  67. addra<= 127 ;
  68. dina <= 0 ;
  69. tx_start_a <= 0 ;
  70. end
  71. else
  72. case(cur_state)
  73. IDLE :
  74. begin
  75. ena <= 0 ;
  76. wea <= 0 ;
  77. addra<= 7'd127 ;
  78. dina <= ram_odd_data ;
  79. end
  80. ERITE :
  81. begin
  82. ena <= ~ena ;
  83. wea <= ~wea ;
  84. if( addra == 49 && wea)
  85. addra <= 49 ;
  86. else if(wea)
  87. addra <= addra +1 ;
  88. dina <= ram_odd_data ;
  89. end
  90. REG :
  91. begin
  92. ena <= 0 ;
  93. wea <= 0 ;
  94. addra<= 0 ;
  95. dina <= 0 ;
  96. tx_start_a <= 1 ;
  97. end
  98. READ :
  99. begin
  100. ena <= 1 ;
  101. wea <= 0 ;
  102. dina<= 0 ;
  103. if(tx_done)begin
  104. tx_start_a <= 1 ;
  105. addra <= addra +1 ;
  106. end
  107. else begin
  108. tx_start_a <= 0 ;
  109. addra <= addra ;
  110. end
  111. end
  112. default:;
  113. endcase
  114. //----------- Begin Cut here for INSTANTIATION Template ---// INST_TAG
  115. single_ram ram1 (
  116. .clka(sys_clk ), // input wire clka
  117. .ena(ena), // input wire ena
  118. .wea(wea), // input wire [0 : 0] wea
  119. .addra(addra), // input wire [6 : 0] addra
  120. .dina(dina), // input wire [7 : 0] dina
  121. .douta(douta) // output wire [7 : 0] douta
  122. );
  123. // INST_TAG_END ------ End INSTANTIATION Template ---------
  124. always@(posedge sys_clk )
  125. if(!rst_n)
  126. uart_data <= 0;
  127. else if ( cur_state == READ )
  128. uart_data <= douta ;
  129. else
  130. uart_data <= uart_data_b ;
  131. always@(posedge sys_clk )
  132. if(!rst_n)
  133. tx_start <= 0 ;
  134. else if ( cur_state == REG || cur_state == READ )
  135. tx_start <= tx_start_a ;
  136. else
  137. tx_start <= tx_start_b ;
  138. 例化ram2
  139. single_ram_2_FMS single_ram_2_FMS_u(
  140. . sys_clk (sys_clk ) ,
  141. . rst_n (rst_n ) ,
  142. . key_flag_2 (key_flag_2 ) ,
  143. . tx_done (tx_done ) ,
  144. . ram_even_data (ram_even_data) ,
  145. . tx_start_b (tx_start_b ) ,
  146. . uart_data_b (uart_data_b )
  147. );
  148. endmodule

(5)uart_tx模块:

  1. `timescale 1ns / 1ps
  2. module uart_tx(
  3. input sys_clk ,
  4. input rst_n ,
  5. input wire[7:0] uart_data ,
  6. input rx_done ,
  7. output reg tx_data ,
  8. output reg tx_done
  9. );
  10. parameter SYSCLK = 50_000_000 ;
  11. parameter Baud = 115200 ;
  12. parameter COUNT = SYSCLK/Baud ;//434 传输1比特所需要的时钟周期
  13. parameter MID = COUNT/2 ;
  14. wire start_flag ;
  15. reg tx_flag ;
  16. reg tx_reg1 ;
  17. reg tx_reg2 ;
  18. reg[4:0] cnt_bit ;
  19. reg[10:0] cnt ;
  20. //tx_start
  21. always@(posedge sys_clk)
  22. if(!rst_n)begin
  23. tx_reg1 <= 0 ;
  24. tx_reg2 <= 0 ;
  25. end
  26. else begin
  27. tx_reg1 <= rx_done ;
  28. tx_reg2 <= tx_reg1 ;
  29. end
  30. assign start_flag = tx_reg1 & ~tx_reg2 ;
  31. ///tx_flag
  32. always@(posedge sys_clk)
  33. if(!rst_n)
  34. tx_flag <= 0 ;
  35. else if ( start_flag == 1 )
  36. tx_flag <= 1 ;
  37. else if ( cnt == COUNT -1 && cnt_bit == 10)
  38. // else if ( cnt == MID -1 && cnt_bit == 10)
  39. tx_flag <= 0 ;
  40. else
  41. tx_flag <= tx_flag ;
  42. ///计时器
  43. // cnt 434
  44. always@(posedge sys_clk )
  45. if(!rst_n)
  46. cnt <= 0;
  47. else if ( tx_flag == 1 )begin
  48. if ( cnt == COUNT -1) ///一定要减一,如果不减一,实际会计到435次,反算回去波特率就不是115200
  49. cnt <= 0;
  50. else
  51. cnt <= cnt +1 ;
  52. end
  53. else
  54. cnt <= 0 ;
  55. // /计数器
  56. always@(posedge sys_clk )
  57. if(!rst_n)
  58. cnt_bit <= 0 ;
  59. else if ( tx_flag )begin
  60. if ( cnt == COUNT -1)begin
  61. if(cnt_bit == 10)///0123456789 10
  62. cnt_bit <= 0 ;
  63. else
  64. cnt_bit <= cnt_bit +1 ;
  65. end
  66. else
  67. cnt_bit <= cnt_bit ;
  68. end
  69. else
  70. cnt_bit <= 0 ;
  71. parameter MODE_CHECK = 0 ;
  72. always@(posedge sys_clk )
  73. if(!rst_n)
  74. tx_data <= 1 ; //表示没有数据
  75. else if ( tx_flag )begin
  76. if ( cnt_bit > 0 && cnt_bit < 9 )
  77. ///cnt_bit 0 12345678 9
  78. ///tx_data 0123456789
  79. ///uart_data 01234567
  80. tx_data <= uart_data [cnt_bit-1]; //这里uart_data是不断随着cnt_bit变化的,只有在第九位的时候才有正确的最终值
  81. else if(cnt_bit == 0)
  82. tx_data <= 0 ;
  83. else if(cnt_bit == 9)
  84. tx_data <= (MODE_CHECK == 0)? ^uart_data: ~^uart_data;
  85. /*
  86. MODE_CHECK == 0是偶校验,假如uart_data是1110_0000,其异或的结果
  87. 1,将异或的结果作为校验位,让数据位和校验位异或的结果为0,满足偶校验。
  88. 假如uart_data是1110_1000,其异或的结果是0,将异或的结果作为校验位,
  89. 让数据位和校验位异或的结果为0,满足偶校验。奇校验则相反。
  90. */
  91. else if (cnt_bit == 10)///停止位
  92. tx_data <= 1 ;
  93. else
  94. tx_data <= tx_data ;
  95. end
  96. else
  97. tx_data <= 1 ;
  98. always@(posedge sys_clk )
  99. if(!rst_n)
  100. tx_done <= 0 ;
  101. else if (tx_flag)begin
  102. if ( cnt_bit == 10 && cnt == COUNT -1)
  103. // if ( cnt_bit == 10 && cnt == MID/2 -1)
  104. tx_done <= 1 ;
  105. else
  106. tx_done <= 0 ;
  107. end
  108. else
  109. tx_done <= 0 ;
  110. endmodule

四、仿真模块

(1)仿真true_ram模块

代码:

  1. `timescale 1ns / 1ps
  2. module test_the_true_ram( );
  3. reg sys_clk ;
  4. reg rst_n ;
  5. wire [7:0] ram_odd_data ;
  6. wire [7:0] ram_even_data ;
  7. initial
  8. begin
  9. sys_clk = 0 ;
  10. rst_n = 0 ;
  11. #10
  12. rst_n = 1 ;
  13. end
  14. always #1 sys_clk = ~sys_clk ;
  15. the_true_ram the_true_ram_1(
  16. . sys_clk (sys_clk ) ,
  17. . rst_n (rst_n ) ,
  18. . ram_odd_data (ram_odd_data ) ,
  19. . ram_even_data (ram_even_data)
  20. );
  21. endmodule

仿真结果:

(2)仿真TOP:

代码:

  1. `timescale 1ns / 1ps
  2. module test_TOP( );
  3. reg sys_clk ;
  4. reg rst_n ;
  5. reg key_1 ;
  6. reg key_2 ;
  7. wire tx_data ;
  8. initial
  9. begin
  10. sys_clk = 0 ;
  11. rst_n = 0 ;
  12. key_1 = 1 ;
  13. key_2 = 1 ;
  14. #10
  15. rst_n = 1 ;
  16. #10000
  17. key_1 = 0 ;
  18. end
  19. always #1 sys_clk = ~sys_clk ;
  20. TOP TOP_1(
  21. . sys_clk (sys_clk) ,
  22. . rst_n (rst_n ) ,
  23. . key_1 (key_1 ) ,
  24. . key_2 (key_2 ) ,
  25. . tx_data (tx_data)
  26. );
  27. endmodule

 仿真结果:

TOP:

single_ram_1 :

五、需要注意的一些问题

(1)

(2)

(3)控制模块最好这么写

  1. `timescale 1ns / 1ps
  2. module single_ram_2(
  3. input sysclk ,
  4. input rst_n ,
  5. input key_flag1 ,
  6. input key_flag2 ,
  7. input tx_done ,
  8. input [7:0] ram_odd_data , //单数
  9. input [7:0] ram_even_data , //双数
  10. output reg tx_start ,
  11. output reg [7:0] uart_data
  12. );
  13. //存单数的RAM
  14. reg wea ;
  15. reg ena ;
  16. reg [6:0] addra ;
  17. reg [7:0] dina ;
  18. wire [7:0] douta ;
  19. ///先写再读出
  20. localparam IDLE = 3'd0;
  21. localparam WRITE = 3'd1; 地址加1
  22. localparam REG = 3'd2; ///缓冲状态 地址清零
  23. localparam READ = 3'd3;
  24. reg [2:0] cur_state,next_state;
  25. reg tx_start_a ;
  26. always@(posedge sysclk)
  27. if(!rst_n)
  28. cur_state <= IDLE;
  29. else
  30. cur_state <= next_state;
  31. always@(*)
  32. case(cur_state)
  33. IDLE : begin
  34. if(key_flag1)
  35. next_state = WRITE;
  36. else
  37. next_state = cur_state;
  38. end
  39. WRITE :begin
  40. if(addra >= 49)
  41. next_state = REG;
  42. else
  43. next_state = cur_state;
  44. end
  45. REG :begin
  46. next_state = READ;
  47. end
  48. READ :begin
  49. if(addra >= 49)
  50. next_state = IDLE;
  51. else
  52. next_state = cur_state;
  53. end
  54. default:;
  55. endcase
  56. always@(posedge sysclk)
  57. if(!rst_n)begin
  58. addra <= 0;
  59. wea <= 0;
  60. ena <= 0;
  61. dina <= 0;
  62. tx_start_a <= 0;
  63. end
  64. else
  65. case(cur_state)
  66. IDLE :begin
  67. addra <= 0;
  68. wea <= 0;
  69. ena <= 0;
  70. dina <= ram_odd_data; 维持2
  71. end
  72. WRITE :begin ///99/48
  73. ena <= ~ena; ///
  74. wea <= ~wea; ///
  75. if(addra >= 49)
  76. addra <= 49;
  77. else if(wea)
  78. addra <= addra + 1;
  79. dina <= ram_odd_data;
  80. end
  81. REG :begin
  82. addra <= 0;
  83. ena <= 0;
  84. wea <= 0;
  85. dina <= 0;
  86. tx_start_a <= 1; ///发送第一个数据
  87. end
  88. READ :begin
  89. ena <= 1;
  90. wea <= 0;
  91. dina <= 0;
  92. if(tx_done)begin
  93. tx_start_a <= 1;
  94. addra <= addra + 1;
  95. end
  96. else begin
  97. tx_start_a <= 0;
  98. addra <= addra;
  99. end
  100. end
  101. default:;
  102. endcase
  103. blk_mem_gen_2 ram_a (
  104. .clka(sysclk), // input wire clka
  105. .ena(ena), // input wire ena
  106. .wea(wea), // input wire [0 : 0] wea
  107. .addra(addra), // input wire [6 : 0] addra
  108. .dina(dina), // input wire [7 : 0] dina
  109. .douta(douta) // output wire [7 : 0] douta
  110. );
  111. /b端口 存双数
  112. reg web ;
  113. reg enb ;
  114. reg [6:0] addrb ;
  115. reg [7:0] dinb ;
  116. wire [7:0] doutb;
  117. //状态机
  118. ///先写再读出
  119. localparam RD_IDLE = 3'd4;
  120. localparam RD_WRITE = 3'd5;
  121. localparam RD_REG = 3'd6; ///缓冲状态
  122. localparam RD_READ = 3'd7;
  123. reg [2:0] rd_cur_state,rd_next_state;
  124. reg tx_start_b ;
  125. always@(posedge sysclk)
  126. if(!rst_n)
  127. rd_cur_state <= RD_IDLE;
  128. else
  129. rd_cur_state <= rd_next_state;
  130. always@(*)
  131. case(rd_cur_state)
  132. RD_IDLE : begin
  133. if(key_flag2)
  134. rd_next_state = RD_WRITE;
  135. else
  136. rd_next_state = rd_cur_state;
  137. end
  138. RD_WRITE :begin
  139. if(addrb >= 49)
  140. rd_next_state = RD_REG;
  141. else
  142. rd_next_state = rd_cur_state;
  143. end
  144. RD_REG :begin
  145. rd_next_state = RD_READ;
  146. end
  147. RD_READ :begin
  148. if(addrb >= 49)
  149. rd_next_state = RD_IDLE;
  150. else
  151. rd_next_state = rd_cur_state;
  152. end
  153. default:;
  154. endcase
  155. always@(posedge sysclk)
  156. if(!rst_n)begin
  157. addrb <= 0;
  158. web <= 0;
  159. enb <= 0;
  160. dinb <= 0;
  161. tx_start_b <= 0;
  162. end
  163. else
  164. case(rd_cur_state)
  165. RD_IDLE :begin
  166. addrb <= 0;
  167. web <= 0;
  168. enb <= 0;
  169. dinb <= ram_even_data; ///020406
  170. end
  171. RD_WRITE :begin
  172. enb <= ~enb;
  173. web <= ~web;
  174. if(addrb >= 49)
  175. addrb <= 49;
  176. else if(web)
  177. addrb <= addrb + 1;
  178. dinb <= ram_even_data;
  179. end
  180. RD_REG :begin
  181. addrb <= 0;
  182. enb <= 0;
  183. web <= 0;
  184. dinb <= 0;
  185. tx_start_b <= 1;
  186. end
  187. RD_READ :begin
  188. enb <= 1;
  189. web <= 0;
  190. dinb <= 0;
  191. if(tx_done)begin
  192. tx_start_b <= 1;
  193. addrb <= addrb + 1;
  194. end
  195. else begin
  196. tx_start_b <= 0;
  197. addrb <= addrb;
  198. end
  199. end
  200. default:;
  201. endcase
  202. blk_mem_gen_2 ram_b (
  203. .clka(sysclk), // input wire clka
  204. .ena(enb), // input wire ena
  205. .wea(web), // input wire [0 : 0] wea
  206. .addra(addrb), // input wire [6 : 0] addra
  207. .dina(dinb), // input wire [7 : 0] dina
  208. .douta(doutb) // output wire [7 : 0] douta
  209. );
  210. always@(posedge sysclk)
  211. if(!rst_n)
  212. uart_data <= 0;
  213. else if(cur_state == READ )
  214. uart_data <= douta ;
  215. else if(rd_cur_state == RD_READ )
  216. uart_data <= doutb ;
  217. else
  218. uart_data <= uart_data;
  219. always@(posedge sysclk)
  220. if(!rst_n)
  221. tx_start <= 0;
  222. else if(cur_state == REG || cur_state == READ)
  223. tx_start <= tx_start_a;
  224. else if(rd_cur_state == RD_REG || rd_cur_state == RD_READ)
  225. tx_start <= tx_start_b;
  226. else
  227. tx_start <= tx_start;
  228. endmodule

声明:本文内容由网友自发贡献,不代表【wpsshop博客】立场,版权归原作者所有,本站不承担相应法律责任。如您发现有侵权的内容,请联系我们。转载请注明出处:https://www.wpsshop.cn/w/你好赵伟/article/detail/808397
推荐阅读
相关标签
  

闽ICP备14008679号