Last active
February 19, 2019 13:36
-
-
Save ytbilly3636/4ef3a5aea93eb72b55e053466c85e648 to your computer and use it in GitHub Desktop.
axi_read_write.vよりも簡単な実装法があったンゴ
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
`timescale 1ns / 1ps | |
// 1:IP catalogからFirst Word Fall Through FIFO(データ幅32bit,長さは256以上)を生成する(名前はfifo_32bitにする) | |
// 2:これをTOPモジュールにしてIPを作る | |
module axi_read_write # | |
( parameter integer C_M_AXI_ADDR_WIDTH = 32 | |
, parameter integer C_M_AXI_DATA_WIDTH = 32 | |
, parameter integer C_M_AXI_DATA_LENGTH = 256 | |
, parameter integer C_M_AXI_THREAD_ID_WIDTH = 1 | |
) | |
( input ACLK | |
, input ARESETN | |
// GPIO | |
, input GPI_STT | |
, input [C_M_AXI_ADDR_WIDTH-1:0] GPI_ADDR | |
, output GPO_ENA | |
// AR | |
, output M_AXI_ARVALID | |
, input M_AXI_ARREADY | |
, output [C_M_AXI_ADDR_WIDTH-1:0] M_AXI_ARADDR | |
, output [8-1:0] M_AXI_ARLEN | |
, output [3-1:0] M_AXI_ARSIZE | |
, output [2-1:0] M_AXI_ARBURST | |
, output [2-1:0] M_AXI_ARLOCK | |
, output [4-1:0] M_AXI_ARCACHE | |
, output [3-1:0] M_AXI_ARPROT | |
, output [C_M_AXI_THREAD_ID_WIDTH-1:0] M_AXI_ARID | |
, output [4-1:0] M_AXI_ARQOS | |
, output [4-1:0] M_AXI_ARREGION | |
, output M_AXI_ARUSER | |
// R | |
, input M_AXI_RVALID | |
, output M_AXI_RREADY | |
, input M_AXI_RLAST | |
, input [C_M_AXI_DATA_WIDTH-1:0] M_AXI_RDATA | |
, input [2-1:0] M_AXI_RRESP | |
, input [C_M_AXI_THREAD_ID_WIDTH-1:0] M_AXI_RID | |
, input M_AXI_RUSER | |
// AW | |
, output M_AXI_AWVALID | |
, input M_AXI_AWREADY | |
, output [C_M_AXI_ADDR_WIDTH-1:0] M_AXI_AWADDR | |
, output [8-1:0] M_AXI_AWLEN | |
, output [3-1:0] M_AXI_AWSIZE | |
, output [2-1:0] M_AXI_AWBURST | |
, output [2-1:0] M_AXI_AWLOCK | |
, output [4-1:0] M_AXI_AWCACHE | |
, output [3-1:0] M_AXI_AWPROT | |
, output [C_M_AXI_THREAD_ID_WIDTH-1:0] M_AXI_AWID | |
, output [4-1:0] M_AXI_AWQOS | |
, output [4-1:0] M_AXI_AWREGION | |
, output M_AXI_AWUSER | |
// W | |
, output M_AXI_WVALID | |
, input M_AXI_WREADY | |
, output M_AXI_WLAST | |
, output [C_M_AXI_DATA_WIDTH-1:0] M_AXI_WDATA | |
, output [4-1:0] M_AXI_WSTRB | |
, output M_AXI_WUSER | |
// B | |
, input M_AXI_BVALID | |
, output M_AXI_BREADY | |
, input [2-1:0] M_AXI_BRESP | |
, input M_AXI_BID | |
, input M_AXI_BUSER | |
); | |
// fixed ports | |
localparam LENGTH = C_M_AXI_DATA_LENGTH - 1; | |
assign M_AXI_ARSIZE = 3'b010; | |
assign M_AXI_ARBURST = 2'b01; | |
assign M_AXI_ARLEN = LENGTH[7:0]; | |
assign M_AXI_AWSIZE = 3'b010; | |
assign M_AXI_AWBURST = 2'b01; | |
assign M_AXI_AWLEN = LENGTH[7:0]; | |
assign M_AXI_ARLOCK = 2'b00; | |
assign M_AXI_ARCACHE = 4'b0011; | |
assign M_AXI_ARPROT = 3'b000; | |
assign M_AXI_ARID = 1'b0; | |
assign M_AXI_ARQOS = 4'b0000; | |
assign M_AXI_ARREGION = 4'b0000; | |
assign M_AXI_ARUSER = 1'b0; | |
assign M_AXI_AWLOCK = 2'b00; | |
assign M_AXI_AWCACHE = 4'b0011; | |
assign M_AXI_AWPROT = 3'b000; | |
assign M_AXI_AWID = 1'b0; | |
assign M_AXI_AWQOS = 4'b0000; | |
assign M_AXI_AWREGION = 4'b0000; | |
assign M_AXI_AWUSER = 1'b0; | |
assign M_AXI_WSTRB = 4'b1111; | |
assign M_AXI_WUSER = 1'b0; | |
// registers for AXI | |
reg r_arvalid; | |
reg r_awvalid; | |
reg [C_M_AXI_ADDR_WIDTH-1:0] r_addr; | |
// fifo | |
reg r_srst_fifo; | |
wire [C_M_AXI_DATA_WIDTH-1:0] w_din_fifo; | |
wire w_wr_en_fifo; | |
wire w_rd_en_fifo; | |
wire [C_M_AXI_DATA_WIDTH-1:0] w_dout_fifo; | |
wire w_full_fifo; | |
wire w_empty_fifo; | |
/* | |
// marseeさんが公開している同期FIFO | |
// XilinxのIPはシミュレーションのとき重いので | |
sync_fifo # | |
( .C_MEMORY_SIZE (512) | |
, .DATA_BUS_WIDTH (C_M_AXI_DATA_WIDTH) | |
) fifo | |
( .clk (ACLK) | |
, .rst (r_srst_fifo) | |
, .din (w_din_fifo) | |
, .wr_en (w_wr_en_fifo) | |
, .rd_en (w_rd_en_fifo) | |
, .dout (w_dout_fifo) | |
, .full (w_full_fifo) | |
, .empty (w_empty_fifo) | |
); | |
*/ | |
fifo_32bit fifo | |
( .clk (ACLK) | |
, .srst (r_srst_fifo) | |
, .din (w_din_fifo) | |
, .wr_en (w_wr_en_fifo) | |
, .rd_en (w_rd_en_fifo) | |
, .dout (w_dout_fifo) | |
, .full (w_full_fifo) | |
, .empty (w_empty_fifo) | |
); | |
// state machine | |
localparam IDLE = 3'b000, | |
STT_AR = 3'b001, | |
STT_R = 3'b010, | |
STT_AW = 3'b011, | |
STT_W = 3'b100; | |
reg [2:0] r_stt = IDLE; | |
reg [7:0] r_cnt = 0; | |
always @(posedge ACLK) begin | |
if (!ARESETN) begin | |
r_arvalid <= 0; | |
r_awvalid <= 0; | |
r_addr <= 0; | |
r_srst_fifo <= 1; | |
r_stt <= IDLE; | |
r_cnt <= 0; | |
end | |
else if (r_stt == IDLE) begin | |
r_srst_fifo <= 0; | |
r_cnt <= 0; | |
if (GPI_STT) begin | |
r_addr <= GPI_ADDR; | |
r_arvalid <= 1; | |
r_stt <= STT_AR; | |
end | |
end | |
else if (r_stt == STT_AR) begin | |
if (M_AXI_ARREADY) begin | |
r_arvalid <= 0; | |
r_stt <= STT_R; | |
end | |
end | |
else if (r_stt == STT_R) begin | |
if (M_AXI_RLAST && M_AXI_RVALID && M_AXI_RREADY) begin | |
r_awvalid <= 1; | |
r_stt <= STT_AW; | |
end | |
end | |
else if (r_stt == STT_AW) begin | |
if (M_AXI_AWREADY) begin | |
r_awvalid <= 0; | |
r_stt <= STT_W; | |
end | |
end | |
else if (r_stt == STT_W) begin | |
if (M_AXI_WREADY && M_AXI_WVALID) | |
r_cnt <= r_cnt + 1; | |
if (M_AXI_BVALID) begin | |
r_stt <= IDLE; | |
end | |
end | |
end | |
// GPIO | |
assign GPO_ENA = (r_stt == IDLE) ? 1 : 0; | |
// AXI Addr Read | |
assign M_AXI_ARVALID = r_arvalid; | |
assign M_AXI_ARADDR = r_addr; | |
// AXI Read | |
assign w_din_fifo = M_AXI_RDATA; | |
assign w_wr_en_fifo = M_AXI_RVALID; | |
assign M_AXI_RREADY = (!w_full_fifo) && (r_stt == STT_R); | |
// AXI Addr Write | |
assign M_AXI_AWVALID = r_awvalid; | |
assign M_AXI_AWADDR = r_addr; | |
// AXI Write | |
assign w_rd_en_fifo = M_AXI_WREADY; | |
assign M_AXI_WVALID = (!w_empty_fifo) && M_AXI_WREADY; | |
assign M_AXI_WDATA = w_dout_fifo; | |
assign M_AXI_WLAST = (r_cnt == LENGTH[7:0]) ? 1 : 0; | |
// AXI B | |
assign M_AXI_BREADY = (r_stt == STT_W) ? 1 : 0; | |
endmodule |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
`timescale 1ns / 1ps | |
module test_axi_read_write; | |
parameter integer C_PERIOD = 2; | |
parameter integer C_M_AXI_THREAD_ID_WIDTH = 1; | |
parameter integer C_M_AXI_ADDR_WIDTH = 32; | |
parameter integer C_M_AXI_DATA_WIDTH = 32; | |
parameter integer C_M_AXI_DATA_LENGTH = 256; | |
reg ACLK; | |
reg ARESETN; | |
wire M_AXI_ARVALID; | |
wire M_AXI_ARREADY; | |
wire [C_M_AXI_ADDR_WIDTH-1:0] M_AXI_ARADDR; | |
wire [8-1:0] M_AXI_ARLEN; | |
wire [3-1:0] M_AXI_ARSIZE; | |
wire [2-1:0] M_AXI_ARBURST; | |
wire [2-1:0] M_AXI_ARLOCK; | |
wire [4-1:0] M_AXI_ARCACHE; | |
wire [3-1:0] M_AXI_ARPROT; | |
wire [C_M_AXI_THREAD_ID_WIDTH-1:0] M_AXI_ARID; | |
wire [4-1:0] M_AXI_ARQOS; | |
wire [4-1:0] M_AXI_ARREGION; | |
wire M_AXI_ARUSER; | |
wire M_AXI_RVALID; | |
wire M_AXI_RREADY; | |
wire M_AXI_RLAST; | |
wire [C_M_AXI_DATA_WIDTH-1:0] M_AXI_RDATA; | |
wire [2-1:0] M_AXI_RRESP; | |
wire [C_M_AXI_THREAD_ID_WIDTH-1:0] M_AXI_RID; | |
wire M_AXI_RUSER; | |
wire M_AXI_AWVALID; | |
wire M_AXI_AWREADY; | |
wire [C_M_AXI_ADDR_WIDTH-1:0] M_AXI_AWADDR; | |
wire [8-1:0] M_AXI_AWLEN; | |
wire [3-1:0] M_AXI_AWSIZE; | |
wire [2-1:0] M_AXI_AWBURST; | |
wire [2-1:0] M_AXI_AWLOCK; | |
wire [4-1:0] M_AXI_AWCACHE; | |
wire [3-1:0] M_AXI_AWPROT; | |
wire [C_M_AXI_THREAD_ID_WIDTH-1:0] M_AXI_AWID; | |
wire [4-1:0] M_AXI_AWQOS; | |
wire [4-1:0] M_AXI_AWREGION; | |
wire M_AXI_AWUSER; | |
wire M_AXI_WVALID; | |
wire M_AXI_WREADY; | |
wire M_AXI_WLAST; | |
wire [C_M_AXI_DATA_WIDTH-1:0] M_AXI_WDATA; | |
wire [4-1:0] M_AXI_WSTRB; | |
wire M_AXI_WUSER; | |
wire M_AXI_BVALID; | |
wire M_AXI_BREADY; | |
wire [2-1:0] M_AXI_BRESP; | |
wire M_AXI_BID; | |
wire M_AXI_BUSER; | |
reg GPI_STT; | |
reg [C_M_AXI_ADDR_WIDTH-1:0] GPI_ADDR; | |
wire GPO_ENA; | |
axi_read_write # | |
( .C_M_AXI_ADDR_WIDTH (C_M_AXI_ADDR_WIDTH) | |
, .C_M_AXI_DATA_WIDTH (C_M_AXI_DATA_WIDTH) | |
, .C_M_AXI_DATA_LENGTH (C_M_AXI_DATA_LENGTH) | |
, .C_M_AXI_THREAD_ID_WIDTH (C_M_AXI_THREAD_ID_WIDTH) | |
) master | |
( .ACLK (ACLK) | |
, .ARESETN (ARESETN) | |
, .M_AXI_ARVALID (M_AXI_ARVALID) | |
, .M_AXI_ARREADY (M_AXI_ARREADY) | |
, .M_AXI_ARADDR (M_AXI_ARADDR) | |
, .M_AXI_ARLEN (M_AXI_ARLEN) | |
, .M_AXI_ARSIZE (M_AXI_ARSIZE) | |
, .M_AXI_ARBURST (M_AXI_ARBURST) | |
, .M_AXI_ARLOCK (M_AXI_ARLOCK) | |
, .M_AXI_ARCACHE (M_AXI_ARCACHE) | |
, .M_AXI_ARPROT (M_AXI_ARPROT) | |
, .M_AXI_ARID (M_AXI_ARID) | |
, .M_AXI_ARQOS (M_AXI_ARQOS) | |
, .M_AXI_ARREGION (M_AXI_ARREGION) | |
, .M_AXI_ARUSER (M_AXI_ARUSER) | |
, .M_AXI_RVALID (M_AXI_RVALID) | |
, .M_AXI_RREADY (M_AXI_RREADY) | |
, .M_AXI_RLAST (M_AXI_RLAST) | |
, .M_AXI_RDATA (M_AXI_RDATA) | |
, .M_AXI_RRESP (M_AXI_RRESP) | |
, .M_AXI_RID (M_AXI_RID) | |
, .M_AXI_RUSER (M_AXI_RUSER) | |
, .M_AXI_AWVALID (M_AXI_AWVALID) | |
, .M_AXI_AWREADY (M_AXI_AWREADY) | |
, .M_AXI_AWADDR (M_AXI_AWADDR) | |
, .M_AXI_AWLEN (M_AXI_AWLEN) | |
, .M_AXI_AWSIZE (M_AXI_AWSIZE) | |
, .M_AXI_AWBURST (M_AXI_AWBURST) | |
, .M_AXI_AWLOCK (M_AXI_AWLOCK) | |
, .M_AXI_AWCACHE (M_AXI_AWCACHE) | |
, .M_AXI_AWPROT (M_AXI_AWPROT) | |
, .M_AXI_AWID (M_AXI_AWID) | |
, .M_AXI_AWQOS (M_AXI_AWQOS) | |
, .M_AXI_AWREGION (M_AXI_AWREGION) | |
, .M_AXI_AWUSER (M_AXI_AWUSER) | |
, .M_AXI_WVALID (M_AXI_WVALID) | |
, .M_AXI_WREADY (M_AXI_WREADY) | |
, .M_AXI_WLAST (M_AXI_WLAST) | |
, .M_AXI_WDATA (M_AXI_WDATA) | |
, .M_AXI_WSTRB (M_AXI_WSTRB) | |
, .M_AXI_WUSER (M_AXI_WUSER) | |
, .M_AXI_BVALID (M_AXI_BVALID) | |
, .M_AXI_BREADY (M_AXI_BREADY) | |
, .M_AXI_BRESP (M_AXI_BRESP) | |
, .M_AXI_BID (M_AXI_BID) | |
, .M_AXI_BUSER (M_AXI_BUSER) | |
, .GPI_STT (GPI_STT) | |
, .GPI_ADDR (GPI_ADDR) | |
, .GPO_ENA (GPO_ENA) | |
); | |
axi_slave # | |
( .C_S_AXI_ADDR_WIDTH (C_M_AXI_ADDR_WIDTH) | |
, .C_S_AXI_DATA_WIDTH (C_M_AXI_DATA_WIDTH) | |
, .C_S_AXI_BURST_LEN (C_M_AXI_DATA_LENGTH) | |
, .WRITE_RANDOM_WAIT (1) | |
, .READ_RANDOM_WAIT (1) | |
, .READ_DATA_IS_INCREMENT (0) | |
, .RANDOM_BVALID_WAIT (1) | |
, .AWREADY_IS_USUALLY_HIGH (1) | |
, .ARREADY_IS_USUALLY_HIGH (1) | |
) slave | |
( .ACLK (ACLK) | |
, .ARESETN (ARESETN) | |
, .S_AXI_AWID (M_AXI_AWID) | |
, .S_AXI_AWADDR (M_AXI_AWADDR) | |
, .S_AXI_AWLEN (M_AXI_AWLEN) | |
, .S_AXI_AWSIZE (M_AXI_AWSIZE) | |
, .S_AXI_AWBURST (M_AXI_AWBURST) | |
, .S_AXI_AWLOCK (M_AXI_AWLOCK) | |
, .S_AXI_AWCACHE (M_AXI_AWCACHE) | |
, .S_AXI_AWPROT (M_AXI_AWPROT) | |
, .S_AXI_AWQOS (M_AXI_AWQOS) | |
, .S_AXI_AWUSER (M_AXI_AWUSER) | |
, .S_AXI_AWVALID (M_AXI_AWVALID) | |
, .S_AXI_AWREADY (M_AXI_AWREADY) | |
, .S_AXI_WDATA (M_AXI_WDATA) | |
, .S_AXI_WSTRB (M_AXI_WSTRB) | |
, .S_AXI_WLAST (M_AXI_WLAST) | |
, .S_AXI_WUSER (M_AXI_WUSER) | |
, .S_AXI_WVALID (M_AXI_WVALID) | |
, .S_AXI_WREADY (M_AXI_WREADY) | |
, .S_AXI_BID (M_AXI_BID) | |
, .S_AXI_BRESP (M_AXI_BRESP) | |
, .S_AXI_BUSER (M_AXI_BUSER) | |
, .S_AXI_BVALID (M_AXI_BVALID) | |
, .S_AXI_BREADY (M_AXI_BREADY) | |
, .S_AXI_ARID (M_AXI_ARID) | |
, .S_AXI_ARADDR (M_AXI_ARADDR) | |
, .S_AXI_ARLEN (M_AXI_ARLEN) | |
, .S_AXI_ARSIZE (M_AXI_ARSIZE) | |
, .S_AXI_ARBURST (M_AXI_ARBURST) | |
, .S_AXI_ARLOCK (M_AXI_ARLOCK) | |
, .S_AXI_ARCACHE (M_AXI_ARCACHE) | |
, .S_AXI_ARPROT (M_AXI_ARPROT) | |
, .S_AXI_ARQOS (M_AXI_ARQOS) | |
, .S_AXI_ARUSER (M_AXI_ARUSER) | |
, .S_AXI_ARVALID (M_AXI_ARVALID) | |
, .S_AXI_ARREADY (M_AXI_ARREADY) | |
, .S_AXI_RID (M_AXI_RID) | |
, .S_AXI_RDATA (M_AXI_RDATA) | |
, .S_AXI_RRESP (M_AXI_RRESP) | |
, .S_AXI_RLAST (M_AXI_RLAST) | |
, .S_AXI_RUSER (M_AXI_RUSER) | |
, .S_AXI_RVALID (M_AXI_RVALID) | |
, .S_AXI_RREADY (M_AXI_RREADY) | |
); | |
always #(C_PERIOD/2) ACLK = ~ACLK; | |
integer i; | |
initial begin | |
#0 | |
ACLK = 1'b0; | |
ARESETN = 1'b1; | |
GPI_STT = 1'b0; | |
GPI_ADDR = 0; | |
#(C_PERIOD) | |
ARESETN = 1'b0; | |
#(C_PERIOD) | |
ARESETN = 1'b1; | |
#(C_PERIOD) | |
for (i = GPI_ADDR; i < GPI_ADDR + 256; i = i + 1) begin | |
slave.ram_array[i][7:0] = i[7:0] + 10; | |
slave.ram_array[i][31:8] = 0; | |
end | |
#(C_PERIOD) | |
GPI_STT = 1'b1; | |
#(C_PERIOD) | |
GPI_STT = 1'b0; | |
#(C_PERIOD * 2000) | |
GPI_STT = 1'b1; | |
#(C_PERIOD) | |
GPI_STT = 1'b0; | |
#(C_PERIOD * 2000) | |
$finish; | |
end | |
endmodule |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment