axi_hp_dma_writer.sv (2794B)
1 // Copyright 2014 Brian Swetland <swetland@frotz.net> 2 // 3 // Licensed under the Apache License, Version 2.0 (the "License"); 4 // you may not use this file except in compliance with the License. 5 // You may obtain a copy of the License at 6 // 7 // http://www.apache.org/licenses/LICENSE-2.0 8 // 9 // Unless required by applicable law or agreed to in writing, software 10 // distributed under the License is distributed on an "AS IS" BASIS, 11 // WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 12 // See the License for the specific language governing permissions and 13 // limitations under the License. 14 15 `timescale 1ns / 1ps 16 17 module axi_hp_dma_writer( 18 input clk, 19 axi_ifc.writer m, 20 21 // control interface 22 input [31:0]txn_addr, // bits 6:0 ignored 23 input [31:0]txn_count, // bits 6:0 ignored 24 input txn_start, 25 output reg txn_busy = 0, 26 output reg [31:0]cyc_count = 0, 27 28 // data interface 29 input [DWIDTH-1:0]data, 30 input valid, 31 output ready 32 ); 33 34 // TODO: make 32bit work 35 parameter DWIDTH = 64; 36 37 assign m.awid = 0; 38 assign m.awlen = 15; 39 assign m.awsize = 2'b11; // dword 40 assign m.awburst = 2'b01; // incr 41 assign m.awlock = 0; 42 assign m.awcache = 0; 43 assign m.wstrb = 8'b11111111; 44 assign m.bready = 1; 45 46 logic [31:0]cyc_count_next; 47 48 logic txn_busy_next; 49 50 logic [31:0]awaddr = 0; 51 logic [31:0]awaddr_next; 52 53 logic [15:0]awcount = 0; 54 logic [15:0]awcount_next; 55 56 logic [15:0]bcount = 0; 57 logic [15:0]bcount_next; 58 59 logic [19:0]wcount = 0; 60 logic [19:0]wcount_next; 61 62 wire awcount_is_zero = (awcount == 0); 63 wire wcount_is_zero = (wcount == 0); 64 wire bcount_is_zero = (bcount == 0); 65 66 assign m.awaddr = awaddr; 67 assign m.awvalid = (~awcount_is_zero); 68 69 assign m.wvalid = (~wcount_is_zero) & valid; 70 assign m.wlast = (wcount[3:0] == 4'd1); 71 assign m.wdata = data; 72 73 assign ready = (~wcount_is_zero) & m.wready; 74 75 always_comb begin 76 cyc_count_next = cyc_count; 77 awaddr_next = awaddr; 78 awcount_next = awcount; 79 bcount_next = bcount; 80 wcount_next = wcount; 81 txn_busy_next = txn_busy; 82 83 if ( m.wready & m.wvalid ) begin 84 wcount_next = wcount - 1; 85 end 86 87 if ( m.bvalid ) begin 88 bcount_next = bcount - 1; 89 end 90 91 if ( m.awvalid & m.awready) begin 92 awcount_next = awcount - 1; 93 awaddr_next = awaddr + 128; 94 end 95 96 if (txn_busy) begin 97 cyc_count_next = cyc_count + 1; 98 if (wcount_is_zero & awcount_is_zero & bcount_is_zero) begin 99 txn_busy_next = 0; 100 end 101 end else begin 102 if (txn_start) begin 103 cyc_count_next = 0; 104 awaddr_next = { txn_addr[31:7], 7'd0 }; 105 awcount_next = txn_count[22:7]; 106 bcount_next = txn_count[22:7]; 107 wcount_next = { txn_count[22:7], 4'd0 }; 108 txn_busy_next = 1; 109 end 110 end 111 end 112 113 always_ff @(posedge clk) begin 114 awaddr <= awaddr_next; 115 awcount <= awcount_next; 116 bcount <= bcount_next; 117 wcount <= wcount_next; 118 txn_busy <= txn_busy_next; 119 cyc_count <= cyc_count_next; 120 end 121 122 endmodule