Last active
November 26, 2018 10:00
-
-
Save ytbilly3636/15789b0a649f1b761fa83066201099b3 to your computer and use it in GitHub Desktop.
指定されたアドレスのメモリからデータ(4バイトx256)を読みこみ(AXI読み込み),4倍したデータを同じアドレスに書き込む(AXI書き込み).
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 | |
////////////////////////////////////////////////////////////////////////////////// | |
// 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