赞
踩
一、项目要求
1、用两个伪双端口的RAM实现缓存
2、先写buffer1,再写buffer2 ,在读buffer1的同时写buffer2,在读buffer2的同时写buffer1。
3、写端口50M时钟,写入16个8bit 的数据,读出时钟25M,读出8个16bit 的数据。
二、信号转换图:
三、状态转换图:
四、程序设计:
先配置IP:
- `timescale 1ns / 1ps
- module ping_pang_1(
- input sys_clk ,
- input rst_n ,
- output wire [15 : 0] doutb1 ,
- output wire [15 : 0] doutb2
- );
- wire clk_50M ;
- wire clk_25M ;
- wire locked ;
- wire en ;
- assign en = locked & rst_n;
- clk_wiz_0 instance_name
- (
- // Clock out ports
- .clk_50M(clk_50M), // output clk_out1
- .clk_25M(clk_25M), // output clk_out2
- // Status and control signals
- .resetn(rst_n), // input resetn
- .locked(locked), // output locked
- // Clock in ports
- .sys_clk(sys_clk)); // input clk_in1
- ram1
- reg wea1 ;
- reg [3 : 0] addra1 ;
- reg [7 : 0] dina1 ;
- reg enb1 ;
- reg [2 : 0] addrb1 ;
-
-
- ping_pang ram1 (
- .clka(clk_50M), // input wire clka
- .ena(1), // input wire ena
- .wea(wea1), // input wire [0 : 0] wea
- .addra(addra1), // input wire [3 : 0] addra
- .dina(dina1), // input wire [7 : 0] dina
- .clkb(clk_25M), // input wire clkb
- .enb(enb1), // input wire enb
- .addrb(addrb1), // input wire [2 : 0] addrb
- .doutb(doutb1) // output wire [15 : 0] doutb
- );
- ram2
- reg wea2 ;
- reg [3 : 0] addra2 ;
- reg [7 : 0] dina2 ;
- reg enb2 ;
- reg [2 : 0] addrb2 ;
-
- ping_pang ram2 (
- .clka(clk_50M), // input wire clka
- .ena(1), // input wire ena
- .wea(wea2), // input wire [0 : 0] wea
- .addra(addra2), // input wire [3 : 0] addra
- .dina(dina2), // input wire [7 : 0] dina
- .clkb(clk_25M), // input wire clkb
- .enb(enb2), // input wire enb
- .addrb(addrb2), // input wire [2 : 0] addrb
- .doutb(doutb2) // output wire [15 : 0] doutb
- );
- /状态机
- localparam IDLE = 3'd0;
- localparam W1 = 3'd1;
- localparam W2_R1 = 3'd2;
- localparam W1_R2 = 3'd3;
- reg [2:0] cur_state,next_state;
- always@(posedge clk_50M)
- if(!rst_n)
- cur_state <= IDLE;
- else if(en)
- cur_state <= next_state;
- else
- cur_state <= IDLE;
- always@(*)
- case(cur_state)
- IDLE :begin
- next_state = W1;
- end
- W1 :begin
- if(addra1 == 14 && wea1)
- next_state = W2_R1;
- else
- next_state = cur_state;
- end
- W2_R1 :begin
- if(addra2 == 14 && wea2)
- next_state = W1_R2;
- else
- next_state = cur_state;
- end
- W1_R2 :begin
- if(addra1 == 14 && wea1)
- next_state = W2_R1;
- else
- next_state = cur_state;
- end
- default:;
- endcase
- /写状态机
- always@(posedge clk_50M)
- if(!rst_n)begin
- wea1 <= 0;
- addra1 <= 0;
- dina1 <= 0;
- wea2 <= 0;
- addra2 <= 0;
- dina2 <= 0;
- end
- else
- case(cur_state)
- IDLE :begin
-
- end
- W1 :begin
- if(addra1 == 15)
- wea1 <= 0;
- else
- wea1 <= 1;
- if(wea1 == 1)
- dina1 <= dina1 + 8'h27 ;
- else
- dina1 <= 0;
- if(wea1 == 1 && addra1 == 15)
- addra1 <= 0;
- else if(wea1 == 1)
- addra1 <= addra1 + 1;
- else
- addra1 <= addra1;
- end
- W2_R1:begin
- addra1 <= 0;
- wea1 <= 0; /ram1的写使能关闭
- if(addra2 == 15)
- wea2 <= 0;
- else
- wea2 <= 1;
- if(wea2 == 1)
- dina2 <= dina2 + 8'h19 ;
- else
- dina2 <= 0;
- if(wea2 == 1 && addra2 == 15)
- addra2 <= 0;
- else if(wea2 == 1)
- addra2 <= addra2 + 1;
- else
- addra2 <= 0;
- end
- W1_R2:begin
- wea2 <= 0;
- addra2 <= 0;
- if(addra1 == 15)
- wea1 <= 0;
- else
- wea1 <= 1;
- if(wea1 == 1)
- dina1 <= dina1 + 8'h27 ;
- else
- dina1 <= 0;
- if(wea1 == 1 && addra1 == 15)
- addra1 <= 0;
- else if(wea1 == 1)
- addra1 <= addra1 + 1;
- else
- addra1 <= 0;
- end
- default:;
- endcase
- 读状态机
- always@(negedge clk_25M)
- if(!rst_n)begin
- enb1 <= 0;
- addrb1 <= 0;
- enb2 <= 0;
- addrb2 <= 0;
- end
- else
- case(cur_state)
- IDLE :begin
-
- end
- W1 :begin
-
- end
- W2_R1 :begin
- enb2 <= 0;
- addrb2 <= 0;
- if(addrb1 == 7 && enb1)
- enb1 <= 0;
- else
- enb1 <= 1;
- if(enb1 == 1 && addrb1 == 7)
- addrb1 <= 0;
- else if(enb1)
- addrb1 <= addrb1 + 1;
- else
- addrb1 <= 0;
- end
- W1_R2 :begin
- addrb1 <= 0;
- enb1 <= 0;
- if(addrb2 == 7)
- enb2 <= 0;
- else
- enb2 <= 1;
- if(enb2 == 1 && addrb2 == 7)
- addrb2 <= 0;
- else if(enb2)
- addrb2 <= addrb2 + 1;
- else
- addrb2 <= 0;
- end
- default:;
- endcase
-
- endmodule
-
![](https://csdnimg.cn/release/blogv2/dist/pc/img/newCodeMoreWhite.png)
五、仿真设计
- `timescale 1ns / 1ps
- module test_ping_pang( );
-
- reg sys_clk ;
- reg rst_n ;
- wire[15:0] doutb1 ;
- wire[15:0] doutb2 ;
-
- initial
- begin
- sys_clk = 0 ;
- rst_n = 0 ;
- #10
- rst_n = 1 ;
- end
-
- always #1 sys_clk = ~sys_clk ;
-
-
- ping_pang_1 ping_pang_1_1(
- . sys_clk ( sys_clk ) ,
- . rst_n ( rst_n ) ,
- . doutb1 (doutb1 ) ,
- . doutb2 (doutb2 )
- );
-
- endmodule
![](https://csdnimg.cn/release/blogv2/dist/pc/img/newCodeMoreWhite.png)
五、仿真结果
六、记录一些小问题:
(2)
(3)
所以修改思路就是尽量让enb1和enb2之间没有空隙,在时序上是衔接着的
Copyright © 2003-2013 www.wpsshop.cn 版权所有,并保留所有权利。