安路EF2系列芯片单口ram ip核使用方法
测试平台:EF2L45LG144B
IP配置:
测试代码:
module Top(input wire I_clk, // 系统时钟output reg O_led2 = 1'b0
);// ------------------------------------------------------------------// RAM 接口信号(根据BRAM配置调整)// ------------------------------------------------------------------wire [7:0] ram_dout; reg [7:0] ram_din;reg [7:0] ram_addr; // 地址位宽扩展到8位wire ram_oe = 1'b1; // 输出使能始终有效wire ram_clk = I_clk; wire ram_rst = 1'b0;reg ram_we;// ------------------------------------------------------------------// 实例化单口 RAM(写优先模式,带输出寄存器)// ------------------------------------------------------------------SinglePortRam single_port_ram (.doa (ram_dout), // 数据输出.dia (ram_din), // 数据输入.addra (ram_addr), // 地址.ocea (ram_oe), // 输出使能,控制输出寄存器.clka (ram_clk), // 时钟.wea (ram_we), // 写使能.rsta (ram_rst) // 复位);// ------------------------------------------------------------------// 状态机定义// ------------------------------------------------------------------localparam S_IDLE = 3'd0;localparam S_WRITE = 3'd1; // 写操作localparam S_READ_SETUP = 3'd2; // 准备读地址localparam S_READ_WAIT = 3'd3; // 等待输出寄存器localparam S_CHECK = 3'd4; // 比较结果localparam S_WRITE_HOLD = 3'd5; // 保持写使能多一个周期reg [2:0] state = S_IDLE;reg [3:0] cnt = 4'd0; // 测试地址 0~7// 数据与期望值的管线,适应输出寄存器延迟reg [7:0] exp_data; // 期望数据reg [7:0] dout_reg; // 寄存后的读出数据// 统计/调试reg [3:0] error_count;reg [7:0] last_error_addr;reg [7:0] last_error_data;reg [7:0] last_expected;// ------------------------------------------------------------------// 主状态机:写 -> 读 -> 等待输出 -> 比较// 针对写优先模式优化:写操作时输出会立即更新// ------------------------------------------------------------------always @(posedge I_clk) begincase (state)S_IDLE: beginram_we <= 1'b0;ram_addr <= 8'd0;ram_din <= 8'd0;cnt <= 4'd0;error_count <= 4'd0;state <= S_WRITE;end// 先给地址/数据S_WRITE: beginram_addr <= {4'd0, cnt};ram_din <= {4'd0, cnt};exp_data <= {4'd0, cnt};state <= S_WRITE_HOLD;end// 再拉高写使能并保持一个周期S_WRITE_HOLD: beginram_we <= 1'b1;state <= S_READ_SETUP;endS_READ_SETUP: beginram_we <= 1'b0;ram_addr <= {4'd0, cnt}; // 保持同一地址state <= S_READ_WAIT;endS_READ_WAIT: begindout_reg <= ram_dout;state <= S_CHECK;endS_CHECK: beginif (dout_reg != exp_data) beginerror_count <= error_count + 1'b1;last_error_addr <= {4'd0, cnt};last_error_data <= dout_reg;last_expected <= exp_data;endif (cnt == 4'd7) begincnt <= 4'd0;state <= S_IDLE;end else begincnt <= cnt + 1'b1;state <= S_WRITE;endenddefault: state <= S_IDLE;endcaseend// ------------------------------------------------------------------// LED 指示:无错误常亮,有错误慢闪// ------------------------------------------------------------------reg [24:0] led_counter = 25'd0;reg slow_toggle = 1'b0;always @(posedge I_clk) beginif (error_count == 4'd0) beginO_led2 <= 1'b0; // 无错误:常亮end else beginif (led_counter >= 25'd10_000_000 - 1) beginled_counter <= 25'd0;slow_toggle <= ~slow_toggle;O_led2 <= slow_toggle; // 有错误:慢速闪烁end else beginled_counter <= led_counter + 1'b1;endendend// ------------------------------------------------------------------// 调试信号(便于 ILA/在线抓取)// ------------------------------------------------------------------wire [7:0] error_count_out = {4'b0, error_count};wire [7:0] current_addr = {4'd0, cnt};wire [7:0] current_data = dout_reg;wire [7:0] expected_out = exp_data;endmodule