zynq-sandbox

old FPGA projects for ZYNQ
git clone http://frotz.net/git/zynq-sandbox.git
Log | Files | Refs | README

axi_registers_v2.sv (3671B)


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