axi_registers_test.sv (5428B)
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 `ifdef verilator 18 module testbench(input clk); 19 `else 20 module testbench(); 21 reg clk = 0; 22 always #5 clk = ~clk; 23 `endif 24 25 axi_ifc axi0(); 26 27 `ifdef SIMPLE_REGS 28 wire [1:0]rreg; 29 wire [1:0]wreg; 30 reg [31:0]rdata = 32'hdeadbeef; 31 wire [31:0]wdata; 32 wire rrd; 33 wire rwr; 34 35 axi_registers regs( 36 .clk(clk), 37 .s(axi0), 38 .o_rreg(rreg), 39 .o_wreg(wreg), 40 .i_rdata(rdata), 41 .o_wdata(wdata), 42 .o_rd(rrd), 43 .o_wr(rwr) 44 ); 45 reg [31:0]tmp = 32'heeeeeeee; 46 47 always_ff @(posedge clk) begin 48 if (rrd) case(rreg) 49 0: rdata <= 32'h10101010; 50 1: rdata <= 32'h20202020; 51 2: rdata <= 32'h30303030; 52 3: rdata <= tmp; 53 endcase 54 if (rwr & (wreg == 3)) 55 tmp <= wdata; 56 end 57 58 `else 59 reg_ifc ri0(); 60 reg_ifc ri1(); 61 reg_ifc ri2(); 62 reg_ifc ri3(); 63 reg_ifc ri4(); 64 reg_ifc ri5(); 65 reg_ifc ri6(); 66 reg_ifc ri7(); 67 68 axi_to_reg_x8 bridge0( 69 .clk(clk), 70 .axi(axi0), 71 .bank0(ri0), 72 .bank1(ri1), 73 .bank2(ri2), 74 .bank3(ri3), 75 .bank4(ri4), 76 .bank5(ri5), 77 .bank6(ri6), 78 .bank7(ri7) 79 ); 80 81 reg [31:0]tmp = 32'heeeeeeee; 82 83 always_ff @(posedge clk) begin 84 if (ri1.rd) case(ri1.raddr) 85 0: ri1.rdata <= 32'h10101010; 86 1: ri1.rdata <= 32'h20202020; 87 2: ri1.rdata <= 32'h30303030; 88 3: ri1.rdata <= tmp; 89 endcase 90 if (ri1.wr & (ri1.waddr == 3)) 91 tmp <= ri1.wdata; 92 end 93 94 assign ri3.rdata = 32'h33303330; 95 96 `endif 97 98 99 integer tick = 0; 100 reg [31:0]addr = 32'hffffffff; 101 reg [31:0]next_addr; 102 reg [31:0]data = 32'hffffffff; 103 reg [31:0]next_data; 104 reg do_rd = 0; 105 reg next_do_rd; 106 reg do_wr = 0; 107 reg next_do_wr; 108 109 axi_rw_engine engine0( 110 .clk(clk), 111 .m(axi0), 112 .rd(do_rd), 113 .wr(do_wr), 114 .addr(addr), 115 .data(data) 116 ); 117 118 integer BASE = 32'h00100000; 119 120 always_comb begin 121 next_do_rd = 0; 122 next_do_wr = 0; 123 next_addr = 32'hffffffff; 124 next_data = 32'hffffffff; 125 if (tick == 10) begin 126 next_do_rd = 1; 127 next_addr = BASE + 4; 128 end else if (tick == 20) begin 129 next_do_rd = 1; 130 next_addr = 32'h00300000; //BASE + 0; 131 end else if (tick == 30) begin 132 next_do_wr = 1; 133 next_data = 32'haabbccdd; 134 next_addr = BASE + 12; 135 end else if (tick == 40) begin 136 next_do_rd = 1; 137 next_addr = BASE + 4; 138 end else if (tick == 50) begin 139 next_do_rd = 1; 140 next_addr = BASE + 12; 141 end else if (tick == 60) begin 142 $finish; 143 end 144 end 145 146 always_ff @(posedge clk) begin 147 do_rd <= next_do_rd; 148 do_wr <= next_do_wr; 149 addr <= next_addr; 150 data <= next_data; 151 tick <= tick + 1; 152 end 153 154 endmodule 155 156 157 module axi_rw_engine( 158 input clk, 159 axi_ifc.master m, 160 input rd, 161 input wr, 162 input [31:0]addr, 163 input [31:0]data 164 ); 165 166 typedef enum { IDLE, RADDR, RDATA, WADDR, WDATA, WRESP } state_t; 167 state_t state = IDLE; 168 state_t next_state; 169 170 reg [31:0]awaddr = 0; 171 reg [31:0]next_awaddr; 172 reg [31:0]wdata = 0; 173 reg [31:0]next_wdata; 174 reg [31:0]araddr = 0; 175 reg [31:0]next_araddr; 176 reg arvalid = 0; 177 reg next_arvalid; 178 reg rready = 0; 179 reg next_rready; 180 reg awvalid = 0; 181 reg next_awvalid; 182 reg wvalid = 0; 183 reg next_wvalid; 184 reg bready = 0; 185 reg next_bready; 186 187 always_comb begin 188 next_state = state; 189 next_araddr = araddr; 190 next_awaddr = awaddr; 191 next_wdata = wdata; 192 next_awvalid = 0; 193 next_wvalid = 0; 194 next_bready = 0; 195 next_arvalid = 0; 196 next_rready = 0; 197 case (state) 198 IDLE: begin 199 if (rd) begin 200 next_state = RADDR; 201 next_araddr = addr; 202 next_arvalid = 1; 203 end else if (wr) begin 204 next_state = WADDR; 205 next_awaddr = addr; 206 next_wdata = data; 207 next_awvalid = 1; 208 end 209 end 210 WADDR: begin 211 if (m.awready) begin 212 next_state = WDATA; 213 next_wvalid = 1; 214 end else begin 215 next_awvalid = 1; 216 end 217 end 218 WDATA: begin 219 if (m.wready) begin 220 next_state = WRESP; 221 next_bready = 1; 222 end else begin 223 next_wvalid = 1; 224 end 225 end 226 WRESP: begin 227 if (m.bvalid) begin 228 next_state = IDLE; 229 $display("wr %x -> %x (status %x)", wdata, awaddr, m.bresp); 230 end else begin 231 next_bready = 1; 232 end 233 end 234 RADDR: begin 235 if (m.arready) begin 236 next_state = RDATA; 237 next_rready = 1; 238 end else begin 239 next_arvalid = 1; 240 end 241 end 242 RDATA: begin 243 if (m.rvalid) begin 244 next_state = IDLE; 245 $display("rd %x <- %x (status %x)", m.rdata, m.araddr, m.rresp); 246 end else begin 247 next_rready = 1; 248 end 249 end 250 endcase 251 end 252 253 always_ff @(posedge clk) begin 254 state <= next_state; 255 araddr <= next_araddr; 256 awaddr <= next_awaddr; 257 arvalid <= next_arvalid; 258 awvalid <= next_awvalid; 259 rready <= next_rready; 260 wvalid <= next_wvalid; 261 bready <= next_bready; 262 wdata <= next_wdata; 263 end 264 265 assign m.awid = 0; 266 assign m.awaddr = awaddr; 267 assign m.awvalid = awvalid; 268 assign m.wdata = wdata; 269 assign m.wstrb = 4'b1111; 270 assign m.wvalid = wvalid; 271 assign m.bready = bready; 272 assign m.awburst = 1; // INCR 273 assign m.awcache = 0; 274 assign m.awlen = 0; 275 assign m.awsize = 2; // 4 bytes 276 assign m.awlock = 0; 277 assign m.wlast = 1; 278 279 assign m.arid = 0; 280 assign m.araddr = araddr; 281 assign m.arvalid = arvalid; 282 assign m.rready = rready; 283 assign m.arburst = 1; // INCR 284 assign m.arcache = 0; 285 assign m.arlen = 0; 286 assign m.arsize = 2; // 4 bytes 287 assign m.arlock = 0; 288 289 endmodule 290 291