axi_registers.sv (3862B)
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 // AXI Register Bridge 18 // 19 // Reads and Writes may happen simultaneously 20 // 21 // Reads: 22 // o_rd=1 o_rreg=n on posedge clk 23 // i_rdata sampled on next posedge clk 24 // Writes: 25 // o_wr=1 o_wreg=n o_wdata=w on posedge clk 26 27 // TODO: deal with non-length-1 bursts 28 29 module axi_registers ( 30 input clk, 31 32 // AXI Interface 33 axi_ifc.slave s, 34 35 // Register File Interface 36 output reg [R_ADDR_WIDTH-1:0]o_rreg = 0, 37 output reg [R_ADDR_WIDTH-1:0]o_wreg = 0, 38 input wire [31:0]i_rdata, 39 output wire [31:0]o_wdata, 40 output reg o_rd = 0, 41 output wire o_wr 42 ); 43 44 parameter integer R_ADDR_WIDTH = 2; 45 46 `define IWIDTH $bits(s.awid) 47 48 typedef enum { W_ADDR, W_DATA, W_RESP } wstate_t; 49 50 assign s.bresp = 0; 51 assign s.rresp = 0; 52 53 //reg [31:0]wdata = 0; 54 //reg [31:0]wdata_next; 55 56 wstate_t wstate = W_ADDR; 57 wstate_t wstate_next; 58 59 reg awready_next; 60 reg wready_next; 61 reg bvalid_next; 62 63 reg [R_ADDR_WIDTH-1:0]wreg_next; 64 reg [R_ADDR_WIDTH-1:0]rreg_next; 65 66 assign o_wdata = s.wdata; 67 assign o_wr = (s.wvalid & s.wready); 68 69 reg [`IWIDTH-1:0]twid = 0; 70 reg [`IWIDTH-1:0]twid_next; 71 72 assign s.bid = twid; 73 74 always_comb begin 75 wstate_next = wstate; 76 //wdata_next = wdata; 77 wreg_next = o_wreg; 78 twid_next = twid; 79 awready_next = 0; 80 wready_next = 0; 81 bvalid_next = 0; 82 case (wstate) 83 W_ADDR: if (s.awvalid) begin 84 wstate_next = W_DATA; 85 wready_next = 1; 86 twid_next = s.awid; 87 wreg_next = s.awaddr[R_ADDR_WIDTH+1:2]; 88 end else begin 89 awready_next = 1; 90 end 91 W_DATA: if (s.wvalid) begin 92 wstate_next = W_RESP; 93 bvalid_next = 1; 94 end else begin 95 wready_next = 1; 96 end 97 W_RESP: if (s.bready) begin 98 wstate_next = W_ADDR; 99 awready_next = 1; 100 end else begin 101 bvalid_next = 1; 102 end 103 endcase 104 end 105 106 typedef enum { R_ADDR, R_CAPTURE, R_CAPTURE2, R_DATA } rstate_t; 107 108 rstate_t rstate = R_ADDR; 109 rstate_t rstate_next; 110 111 reg arready_next; 112 reg rvalid_next; 113 reg rlast_next; 114 115 reg [31:0]rdata = 0; 116 reg [31:0]rdata_next; 117 assign s.rdata = rdata; 118 119 reg rd_next; 120 121 reg [`IWIDTH-1:0]trid = 0; 122 reg [`IWIDTH-1:0]trid_next; 123 assign s.rid = trid; 124 125 always_comb begin 126 rstate_next = rstate; 127 rdata_next = rdata; 128 rreg_next = o_rreg; 129 trid_next = trid; 130 arready_next = 0; 131 rvalid_next = 0; 132 rlast_next = 0; 133 rd_next = 0; 134 case (rstate) 135 R_ADDR: if (s.arvalid) begin 136 // accept address from AXI 137 rstate_next = R_CAPTURE; 138 trid_next = s.arid; 139 rreg_next = s.araddr[R_ADDR_WIDTH+1:2]; 140 rd_next = 1; 141 end else begin 142 arready_next = 1; 143 end 144 R_CAPTURE: begin 145 // present address and rd to register file 146 rstate_next = R_CAPTURE2; 147 end 148 R_CAPTURE2: begin 149 // capture register file output 150 rstate_next = R_DATA; 151 rvalid_next = 1; 152 rlast_next = 1; 153 rdata_next = i_rdata; 154 end 155 R_DATA: if (s.rready) begin 156 // present register data to AXI 157 rstate_next = R_ADDR; 158 arready_next = 1; 159 end else begin 160 rvalid_next = 1; 161 rlast_next = 1; 162 end 163 endcase 164 end 165 166 always_ff @(posedge clk) begin 167 wstate <= wstate_next; 168 //wdata <= wdata_next; 169 twid <= twid_next; 170 s.awready <= awready_next; 171 s.wready <= wready_next; 172 s.bvalid <= bvalid_next; 173 o_wreg <= wreg_next; 174 175 rstate <= rstate_next; 176 rdata <= rdata_next; 177 trid <= trid_next; 178 s.arready <= arready_next; 179 s.rvalid <= rvalid_next; 180 s.rlast <= rlast_next; 181 o_rreg <= rreg_next; 182 o_rd <= rd_next; 183 end 184 185 endmodule