FPGA-DDR-SDRAM/example-selftest/axi_self_test_master.v

135 lines
4.0 KiB
Coq
Raw Normal View History

2022-03-30 02:03:32 +08:00
//--------------------------------------------------------------------------------------------------------
// Module : axi_self_test_master
// Type : synthesizable
2023-06-06 19:52:19 +08:00
// Standard: Verilog 2001 (IEEE1364-2001)
2022-03-30 02:03:32 +08:00
// Function: write increase data to AXI4 slave,
// then read data and check whether they are increasing
//--------------------------------------------------------------------------------------------------------
2021-01-27 18:06:35 +08:00
module axi_self_test_master #(
parameter A_WIDTH_TEST = 26,
parameter A_WIDTH = 26,
parameter D_WIDTH = 16,
parameter D_LEVEL = 1,
parameter [7:0] WBURST_LEN = 8'd7,
parameter [7:0] RBURST_LEN = 8'd7
)(
2022-04-01 21:15:25 +08:00
input wire rstn,
input wire clk,
2021-01-27 18:06:35 +08:00
output wire awvalid,
input wire awready,
output reg [A_WIDTH-1:0] awaddr,
output wire [ 7:0] awlen,
output wire wvalid,
input wire wready,
output wire wlast,
output wire [D_WIDTH-1:0] wdata,
input wire bvalid,
output wire bready,
output wire arvalid,
input wire arready,
output reg [A_WIDTH-1:0] araddr,
output wire [ 7:0] arlen,
input wire rvalid,
output wire rready,
input wire rlast,
input wire [D_WIDTH-1:0] rdata,
output reg error,
output reg [ 15:0] error_cnt
);
2023-06-06 19:52:19 +08:00
initial {awaddr, araddr} = 0;
initial {error, error_cnt} = 0;
2022-03-30 02:03:32 +08:00
2021-01-27 18:06:35 +08:00
wire aw_end;
2023-06-06 19:52:19 +08:00
reg awaddr_carry = 1'b0;
reg [7:0] w_cnt = 8'd0;
localparam [2:0] INIT = 3'd0,
AW = 3'd1,
W = 3'd2,
B = 3'd3,
AR = 3'd4,
R = 3'd5;
reg [2:0] stat = INIT;
2021-01-27 18:06:35 +08:00
generate if(A_WIDTH_TEST<A_WIDTH)
assign aw_end = awaddr[A_WIDTH_TEST];
else
assign aw_end = awaddr_carry;
endgenerate
assign awvalid = stat==AW;
assign awlen = WBURST_LEN;
assign wvalid = stat==W;
assign wlast = w_cnt==WBURST_LEN;
2023-06-06 19:52:19 +08:00
assign wdata = awaddr;
2021-01-27 18:06:35 +08:00
assign bready = 1'b1;
assign arvalid = stat==AR;
assign arlen = RBURST_LEN;
assign rready = 1'b1;
2023-06-06 19:52:19 +08:00
localparam [A_WIDTH:0] ADDR_INC = (1<<D_LEVEL);
wire [A_WIDTH:0] araddr_next = {1'b0,araddr} + ADDR_INC;
2022-03-30 02:03:32 +08:00
2022-04-01 21:15:25 +08:00
always @ (posedge clk or negedge rstn)
if(~rstn) begin
2023-06-06 19:52:19 +08:00
{awaddr_carry, awaddr} <= 0;
2021-01-27 18:06:35 +08:00
w_cnt <= 8'd0;
2023-06-06 19:52:19 +08:00
araddr <= 0;
2021-01-27 18:06:35 +08:00
stat <= INIT;
end else begin
case(stat)
INIT: begin
2023-06-06 19:52:19 +08:00
{awaddr_carry, awaddr} <= 0;
2021-01-27 18:06:35 +08:00
w_cnt <= 8'd0;
2023-06-06 19:52:19 +08:00
araddr <= 0;
2021-01-27 18:06:35 +08:00
stat <= AW;
end
AW: if(awready) begin
w_cnt <= 8'd0;
stat <= W;
end
W: if(wready) begin
2023-06-06 19:52:19 +08:00
{awaddr_carry, awaddr} <= {awaddr_carry, awaddr} + ADDR_INC;
2021-01-27 18:06:35 +08:00
w_cnt <= w_cnt + 8'd1;
if(wlast)
stat <= B;
end
B: if(bvalid) begin
stat <= aw_end ? AR : AW;
end
AR: if(arready) begin
stat <= R;
end
R: if(rvalid) begin
araddr <= araddr_next[A_WIDTH-1:0];
if(rlast) begin
stat <= AR;
if(araddr_next[A_WIDTH_TEST])
2023-06-06 19:52:19 +08:00
araddr <= 0;
2021-01-27 18:06:35 +08:00
end
end
endcase
end
// ------------------------------------------------------------
// read and write mismatch detect
// ------------------------------------------------------------
2023-06-06 19:52:19 +08:00
wire [D_WIDTH-1:0] rdata_idle = araddr;
2022-04-01 21:15:25 +08:00
always @ (posedge clk or negedge rstn)
if(~rstn) begin
2021-01-27 18:06:35 +08:00
error <= 1'b0;
error_cnt <= 16'd0;
end else begin
error <= rvalid && rready && rdata!=rdata_idle;
if(error)
error_cnt <= error_cnt + 16'd1;
end
2022-03-30 02:03:32 +08:00
endmodule