Skip to content

Instantly share code, notes, and snippets.

@ytbilly3636
Last active November 26, 2018 10:00
Show Gist options
  • Save ytbilly3636/15789b0a649f1b761fa83066201099b3 to your computer and use it in GitHub Desktop.
Save ytbilly3636/15789b0a649f1b761fa83066201099b3 to your computer and use it in GitHub Desktop.
指定されたアドレスのメモリからデータ(4バイトx256)を読みこみ(AXI読み込み),4倍したデータを同じアドレスに書き込む(AXI書き込み).
`timescale 1ns / 1ps
//////////////////////////////////////////////////////////////////////////////////
// Company:
// Engineer:
//
// Create Date: 2018/11/16 14:00:00
// Design Name:
// Module Name: axi_read_write
// Project Name:
// Target Devices:
// Tool Versions:
// Description:
// 指定されたアドレスのメモリからデータ(4バイトx256)を読みこみ,4倍したデータを同じアドレスに書き込む.
// ZYNQで動かすための手順
// 1:IP catalogからFIFO(32bit,長さは256以上)を生成する(名前はfifo_32bitにする)
// 2:これをTOPモジュールにしてIPを作る
// 3:別のプロジェクトからブロックデザインを作る.
// 4:ZYNQと先程作ったIPをブロックデザインに配置して繋ぐ.
// 5:AXI GPIOを4つ用意してiwSTT,iwADDR_SRC,iwADDR_DST,orEXEにつないでおく.
// 6:Bitstreamを生成して,export hardwareしておく.
// 7:SDKにつづく…
// Dependencies:
//
// Revision:
// Revision 0.01 - File Created
// Additional Comments:
//
//////////////////////////////////////////////////////////////////////////////////
module axi_read_write #(
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_STATE_SEND = 6
)(
input wire ACLK,
input wire ARESETN,
output reg M_AXI_ARVALID,
input wire M_AXI_ARREADY,
output reg [C_M_AXI_ADDR_WIDTH-1:0] M_AXI_ARADDR,
output reg [8-1:0] M_AXI_ARLEN,
output wire [3-1:0] M_AXI_ARSIZE, // fixed: 32bit
output wire [2-1:0] M_AXI_ARBURST, // fixed: INCR
output wire [2-1:0] M_AXI_ARLOCK, // not used
output wire [4-1:0] M_AXI_ARCACHE, // not used
output wire [3-1:0] M_AXI_ARPROT, // not used
output wire [C_M_AXI_THREAD_ID_WIDTH-1:0] M_AXI_ARID, // not used
output wire [4-1:0] M_AXI_ARQOS, // not used
output wire [4-1:0] M_AXI_ARREGION, // not used
output wire M_AXI_ARUSER, // not used
input wire M_AXI_RVALID,
output reg M_AXI_RREADY,
input wire M_AXI_RLAST,
input wire [C_M_AXI_DATA_WIDTH-1:0] M_AXI_RDATA,
input wire [2-1:0] M_AXI_RRESP, // not used
input wire [C_M_AXI_THREAD_ID_WIDTH-1:0] M_AXI_RID, // not used
input wire M_AXI_RUSER, // not used
output reg M_AXI_AWVALID,
input wire M_AXI_AWREADY,
output reg [C_M_AXI_ADDR_WIDTH-1:0] M_AXI_AWADDR,
output reg [8-1:0] M_AXI_AWLEN,
output wire [3-1:0] M_AXI_AWSIZE, // fixed: 32bit
output wire [2-1:0] M_AXI_AWBURST, // fixed: INCR
output wire [2-1:0] M_AXI_AWLOCK, // not used
output wire [4-1:0] M_AXI_AWCACHE, // not used
output wire [3-1:0] M_AXI_AWPROT, // not used
output wire [C_M_AXI_THREAD_ID_WIDTH-1:0] M_AXI_AWID, // not used
output wire [4-1:0] M_AXI_AWQOS, // not used
output wire [4-1:0] M_AXI_AWREGION, // not used
output wire M_AXI_AWUSER, // not used
output reg M_AXI_WVALID,
input wire M_AXI_WREADY,
output reg M_AXI_WLAST,
output reg [C_M_AXI_DATA_WIDTH-1:0] M_AXI_WDATA,
output wire [4-1:0] M_AXI_WSTRB, // fixed: 1111
output wire M_AXI_WUSER, // not used
input wire M_AXI_BVALID,
output reg M_AXI_BREADY,
input wire [2-1:0] M_AXI_BRESP,
input wire M_AXI_BID, // not used
input wire M_AXI_BUSER, // not used
input wire iwSTT,
input wire [C_M_AXI_ADDR_WIDTH-1:0] iwADDR_SRC,
input wire [C_M_AXI_ADDR_WIDTH-1:0] iwADDR_DST,
output reg orEXE,
output reg [8-1:0] orSTATE
);
// Fixed port
assign M_AXI_ARSIZE = 3'b010;
assign M_AXI_ARBURST = 2'b01;
assign M_AXI_AWSIZE = 3'b010;
assign M_AXI_AWBURST = 2'b01;
assign M_AXI_WSTRB = 4'b1111;
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_RRESP = 2'b00;
assign M_AXI_RID = 1'b0;
assign M_AXI_RUSER = 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_WUSER = 1'b0;
assign M_AXI_BID = 1'b0;
assign M_AXI_BUSER = 1'b0;
reg r_srst;
reg [31:0] r_din;
reg r_wr_en;
reg r_rd_en;
wire [31:0] w_dout;
wire w_full;
wire w_empty;
fifo_32bit fifo_in(
.clk (ACLK),
.srst (r_srst),
.din (r_din),
.wr_en (r_wr_en),
.rd_en (r_rd_en),
.dout (w_dout),
.full (w_full),
.empty (w_empty)
);
reg r_srst_out;
reg [31:0] r_din_out;
reg r_wr_en_out;
reg r_rd_en_out;
wire [31:0] w_dout_out;
wire w_full_out;
wire w_empty_out;
fifo_32bit fifo_out(
.clk (ACLK),
.srst (r_srst_out),
.din (r_din_out),
.wr_en (r_wr_en_out),
.rd_en (r_rd_en_out),
.dout (w_dout_out),
.full (w_full_out),
.empty (w_empty_out)
);
reg r_axi_rlast_dly;
reg [31:0] r_axi_wdata_buf;
reg [7:0] r_count;
always @ (posedge ACLK) begin
if (!ARESETN) begin
M_AXI_ARVALID <= 1'b0;
M_AXI_ARADDR <= 0;
M_AXI_ARLEN <= 0;
M_AXI_RREADY <= 1'b0;
M_AXI_AWVALID <= 1'b0;
M_AXI_AWADDR <= 0;
M_AXI_AWLEN <= 0;
M_AXI_WVALID <= 1'b0;
M_AXI_WLAST <= 1'b0;
M_AXI_WDATA <= 0;
M_AXI_BREADY <= 1'b0;
r_srst <= 1'b1;
r_din <= 0;
r_wr_en <= 1'b0;
r_rd_en <= 1'b0;
r_srst_out <= 1'b1;
r_din_out <= 0;
r_wr_en_out <= 1'b0;
r_rd_en_out <= 1'b0;
r_axi_rlast_dly <= 1'b0;
r_axi_wdata_buf <= 0;
r_count <= 0;
orEXE <= 1'b0;
orSTATE <= 0;
end
else if (orSTATE == 0) begin
r_srst <= 1'b0;
r_srst_out <= 1'b0;
if (!iwSTT) begin
orEXE <= 1'b0;
end
else begin
M_AXI_ARVALID <= 1'b1;
M_AXI_ARADDR <= iwADDR_SRC;
M_AXI_ARLEN <= 8'hff;
M_AXI_AWADDR <= iwADDR_DST;
M_AXI_AWLEN <= 8'hff;
orEXE <= 1'b1;
orSTATE <= 1;
end
end
// RECEIVE
else if (orSTATE == 1) begin
if (M_AXI_ARREADY) begin
M_AXI_ARVALID <= 1'b0;
end
if (!M_AXI_RVALID) begin
M_AXI_RREADY <= 1'b0;
end
else begin
M_AXI_RREADY <= 1'b1;
r_din <= M_AXI_RDATA;
if (M_AXI_RLAST) begin
r_axi_rlast_dly <= 1'b1;
end
end
r_wr_en <= M_AXI_RREADY && M_AXI_RVALID;
if (r_axi_rlast_dly) begin
M_AXI_RREADY <= 1'b0;
r_axi_rlast_dly <= 1'b0;
orSTATE <= 2;
end
end
// START
else if (orSTATE == 2) begin
r_wr_en <= 1'b0;
r_rd_en <= 1'b1;
orSTATE <= 3;
end
else if (orSTATE == 3) begin
orSTATE <= 4;
end
// PROC
else if (orSTATE == 4) begin
r_wr_en_out <= 1'b1;
r_din_out <= w_dout << 2;
if (w_empty) begin
r_rd_en <= 1'b0;
orSTATE <= 5;
end
end
// FINISH
else if (orSTATE == 5) begin
r_wr_en_out <= 1'b0;
orSTATE <= C_STATE_SEND;
end
// SEND-0
else if (orSTATE == C_STATE_SEND) begin
r_count <= 0;
r_rd_en_out <= 1'b1;
orSTATE <= C_STATE_SEND + 1;
end
// SEND-1
else if (orSTATE == C_STATE_SEND + 1) begin
orSTATE <= C_STATE_SEND + 2;
end
// SEND-2
else if (orSTATE == C_STATE_SEND + 2) begin
M_AXI_WDATA <= w_dout_out;
orSTATE <= C_STATE_SEND + 3;
end
// SEND-3
else if (orSTATE == C_STATE_SEND + 3) begin
r_rd_en_out <= 1'b0;
r_axi_wdata_buf <= w_dout_out;
orSTATE <= C_STATE_SEND + 4;
end
// SEND-4
else if (orSTATE == C_STATE_SEND + 4) begin
M_AXI_AWVALID <= 1'b1;
M_AXI_BREADY <= 1'b1;
orSTATE <= C_STATE_SEND + 5;
end
// SEND-5
else if (orSTATE == C_STATE_SEND + 5) begin
if (M_AXI_AWREADY) begin
M_AXI_AWVALID <= 1'b0;
orSTATE <= C_STATE_SEND + 6;
end
end
// SEND-6
else if (orSTATE == C_STATE_SEND + 6) begin
M_AXI_WVALID <= 1'b1;
if (r_count == 256) begin
M_AXI_WLAST <= 1'b1;
r_count <= 254;
orSTATE <= C_STATE_SEND + 8;
end
else begin
orSTATE <= C_STATE_SEND + 7;
end
end
// SEND-7
else if (orSTATE == C_STATE_SEND + 7) begin
if (M_AXI_WREADY) begin
r_count <= r_count + 1;
if (r_count == 254)
M_AXI_WLAST <= 1'b1;
M_AXI_WDATA <= r_axi_wdata_buf;
r_rd_en_out <= 1'b1;
orSTATE <= C_STATE_SEND + 8;
end
end
// SEND-8
else if (orSTATE == C_STATE_SEND + 8) begin
M_AXI_WDATA <= w_dout_out;
r_axi_wdata_buf <= M_AXI_WDATA;
// SEND-8-1
if (!M_AXI_WREADY) begin
M_AXI_WVALID <= 1'b0;
r_rd_en_out <= 1'b0;
orSTATE <= C_STATE_SEND + 9;
// SEND-8-2からSEND-8-3に移行しなかったとき
if (r_count == 255) begin
M_AXI_WLAST <= 1'b0;
r_count <= 256;
end
end
// SEND-8-2
else if (r_count <= 254) begin
r_count <= r_count + 1;
if (r_count == 254)
M_AXI_WLAST <= 1'b1;
end
// SEND-8-3
else begin
M_AXI_WVALID <= 1'b0;
M_AXI_WLAST <= 1'b0;
r_rd_en_out <= 1'b0;
orSTATE <= C_STATE_SEND + 10;
end
end
// SEND-9
else if (orSTATE == C_STATE_SEND + 9) begin
M_AXI_WDATA <= r_axi_wdata_buf;
r_axi_wdata_buf <= M_AXI_WDATA;
orSTATE <= C_STATE_SEND + 6;
end
// SEND-10
else if (orSTATE == C_STATE_SEND + 10) begin
if (M_AXI_BVALID) begin
M_AXI_BREADY <= 1'b0;
orSTATE <= 0;
end
end
end
endmodule
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment