OpenCores
URL https://opencores.org/ocsvn/wb2axip/wb2axip/trunk

Subversion Repositories wb2axip

[/] [wb2axip/] [trunk/] [rtl/] [axim2wbsp.v] - Rev 15

Go to most recent revision | Compare with Previous | Blame | View Log

////////////////////////////////////////////////////////////////////////////////
//
// Filename: 	axim2wbsp.v
//
// Project:	Pipelined Wishbone to AXI converter
//
// Purpose:	So ... this converter works in the other direction.  This 
//		converter takes AXI commands, and organizes them into pipelined
//	wishbone commands.
//
//
//	We'll treat AXI as two separate busses: one for writes, another for
//	reads, further, we'll insist that the two channels AXI uses for writes
//	combine into one channel for our purposes.
//
//
// Creator:	Dan Gisselquist, Ph.D.
//		Gisselquist Technology, LLC
//
////////////////////////////////////////////////////////////////////////////////
//
// Copyright (C) 2016, Gisselquist Technology, LLC
//
// This program is free software (firmware): you can redistribute it and/or
// modify it under the terms of  the GNU General Public License as published
// by the Free Software Foundation, either version 3 of the License, or (at
// your option) any later version.
//
// This program is distributed in the hope that it will be useful, but WITHOUT
// ANY WARRANTY; without even the implied warranty of MERCHANTIBILITY or
// FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License
// for more details.
//
// You should have received a copy of the GNU General Public License along
// with this program.  (It's in the $(ROOT)/doc directory, run make with no
// target there if the PDF file isn't present.)  If not, see
// <http://www.gnu.org/licenses/> for a copy.
//
// License:	GPL, v3, as defined and found on www.gnu.org,
//		http://www.gnu.org/licenses/gpl.html
//
//
////////////////////////////////////////////////////////////////////////////////
//
//
module axim2wbsp( i_clk, i_axi_reset_n,
	//
	o_axi_awready, // Slave is ready to accept
	i_axi_awid, i_axi_awaddr, i_axi_awlen, i_axi_awsize, i_axi_awburst,
	i_axi_awlock, i_axi_awcache, i_axi_awprot, i_axi_awqos, i_axi_awvalid,
	//
	o_axi_wready, i_axi_wdata, i_axi_wstrb, i_axi_wlast, i_axi_wvalid,
	//
	o_axi_bid, o_axi_bresp, o_axi_bvalid, i_axi_bready,
	//
	o_axi_arready,	// Read address ready
	i_axi_arid,	// Read ID
	i_axi_araddr,	// Read address
	i_axi_arlen,	// Read Burst Length
	i_axi_arsize,	// Read Burst size
	i_axi_arburst,	// Read Burst type
	i_axi_arlock,	// Read lock type
	i_axi_arcache,	// Read Cache type
	i_axi_arprot,	// Read Protection type
	i_axi_arqos,	// Read Protection type
	i_axi_arvalid,	// Read address valid
	//
	o_axi_rid,     // Response ID
	o_axi_rresp,   // Read response
	o_axi_rvalid,  // Read reponse valid
	o_axi_rdata,    // Read data
	o_axi_rlast,    // Read last
	i_axi_rready,  // Read Response ready
	// Wishbone interface
	o_reset, o_wb_cyc, o_wb_stb, o_wb_we, o_wb_addr, o_wb_data, o_wb_sel,
	i_wb_ack, i_wb_stall, i_wb_data, i_wb_err);
	//
	parameter C_AXI_ID_WIDTH	= 6; // The AXI id width used for R&W
                                             // This is an int between 1-16
	parameter C_AXI_DATA_WIDTH	= 32;// Width of the AXI R&W data
	parameter C_AXI_ADDR_WIDTH	= 28;	// AXI Address width
	localparam DW = C_AXI_DATA_WIDTH;
	localparam AW =   (C_AXI_DATA_WIDTH==  8) ? (C_AXI_ADDR_WIDTH)
			:((C_AXI_DATA_WIDTH== 16) ? (C_AXI_ADDR_WIDTH-1)
			:((C_AXI_DATA_WIDTH== 32) ? (C_AXI_ADDR_WIDTH-2)
			:((C_AXI_DATA_WIDTH== 64) ? (C_AXI_ADDR_WIDTH-3)
			:((C_AXI_DATA_WIDTH==128) ? (C_AXI_ADDR_WIDTH-4)
			:(C_AXI_ADDR_WIDTH-5)))));
	//
	input	wire			i_clk;	// System clock
	input	wire			i_axi_reset_n;
 
// AXI write address channel signals
	output	wire			o_axi_awready; // Slave is ready to accept
	input	wire	[C_AXI_ID_WIDTH-1:0]	i_axi_awid;	// Write ID
	input	wire	[C_AXI_ADDR_WIDTH-1:0]	i_axi_awaddr;	// Write address
	input	wire	[7:0]		i_axi_awlen;	// Write Burst Length
	input	wire	[2:0]		i_axi_awsize;	// Write Burst size
	input	wire	[1:0]		i_axi_awburst;	// Write Burst type
	input	wire	[0:0]		i_axi_awlock;	// Write lock type
	input	wire	[3:0]		i_axi_awcache;	// Write Cache type
	input	wire	[2:0]		i_axi_awprot;	// Write Protection type
	input	wire	[3:0]		i_axi_awqos;	// Write Quality of Svc
	input	wire			i_axi_awvalid;	// Write address valid
 
// AXI write data channel signals
	output	wire			o_axi_wready;  // Write data ready
	input	wire	[C_AXI_DATA_WIDTH-1:0]	i_axi_wdata;	// Write data
	input	wire	[C_AXI_DATA_WIDTH/8-1:0] i_axi_wstrb;	// Write strobes
	input	wire			i_axi_wlast;	// Last write transaction   
	input	wire			i_axi_wvalid;	// Write valid
 
// AXI write response channel signals
	output	wire [C_AXI_ID_WIDTH-1:0] o_axi_bid;	// Response ID
	output	wire [1:0]		o_axi_bresp;	// Write response
	output	wire 			o_axi_bvalid;  // Write reponse valid
	input	wire			i_axi_bready;  // Response ready
 
// AXI read address channel signals
	output	wire			o_axi_arready;	// Read address ready
	input	wire	[C_AXI_ID_WIDTH-1:0]	i_axi_arid;	// Read ID
	input	wire	[C_AXI_ADDR_WIDTH-1:0]	i_axi_araddr;	// Read address
	input	wire	[7:0]		i_axi_arlen;	// Read Burst Length
	input	wire	[2:0]		i_axi_arsize;	// Read Burst size
	input	wire	[1:0]		i_axi_arburst;	// Read Burst type
	input	wire	[0:0]		i_axi_arlock;	// Read lock type
	input	wire	[3:0]		i_axi_arcache;	// Read Cache type
	input	wire	[2:0]		i_axi_arprot;	// Read Protection type
	input	wire	[3:0]		i_axi_arqos;	// Read Protection type
	input	wire			i_axi_arvalid;	// Read address valid
 
// AXI read data channel signals   
	output	wire [C_AXI_ID_WIDTH-1:0] o_axi_rid;     // Response ID
	output	wire [1:0]		o_axi_rresp;   // Read response
	output	wire			o_axi_rvalid;  // Read reponse valid
	output	wire [C_AXI_DATA_WIDTH-1:0] o_axi_rdata;    // Read data
	output	wire			o_axi_rlast;    // Read last
	input	wire			i_axi_rready;  // Read Response ready
 
	// We'll share the clock and the reset
	output	wire			o_reset;
	output	wire			o_wb_cyc;
	output	wire			o_wb_stb;
	output	wire			o_wb_we;
	output	wire [(AW-1):0]	o_wb_addr;
	output	wire [(C_AXI_DATA_WIDTH-1):0]	o_wb_data;
	output	wire [(C_AXI_DATA_WIDTH/8-1):0]	o_wb_sel;
	input	wire			i_wb_ack;
	input	wire			i_wb_stall;
	input	wire [(C_AXI_DATA_WIDTH-1):0]	i_wb_data;
	input	wire			i_wb_err;
 
 
	//
	//
	//
 
 
	wire	[(AW-1):0]			w_wb_addr, r_wb_addr;
	wire	[(C_AXI_DATA_WIDTH-1):0]	w_wb_data;
	wire	[(C_AXI_DATA_WIDTH/8-1):0]	w_wb_sel;
	wire	r_wb_err, r_wb_cyc, r_wb_stb, r_wb_stall, r_wb_ack;
	wire	w_wb_err, w_wb_cyc, w_wb_stb, w_wb_stall, w_wb_ack;
 
	// verilator lint_off UNUSED
	wire	r_wb_we, w_wb_we;
 
	assign	r_wb_we = 1'b0;
	assign	w_wb_we = 1'b1;
	// verilator lint_on  UNUSED
 
	aximwr2wbsp #(
		.C_AXI_ID_WIDTH(C_AXI_ID_WIDTH),
		.C_AXI_DATA_WIDTH(C_AXI_DATA_WIDTH),
		.C_AXI_ADDR_WIDTH(C_AXI_ADDR_WIDTH), .AW(AW))
		axi_write_decoder(
			.i_axi_clk(i_clk), .i_axi_reset_n(i_axi_reset_n),
			//
			.o_axi_awready(o_axi_awready),
			.i_axi_awid(   i_axi_awid),
			.i_axi_awaddr( i_axi_awaddr),
			.i_axi_awlen(  i_axi_awlen),
			.i_axi_awsize( i_axi_awsize),
			.i_axi_awburst(i_axi_awburst),
			.i_axi_awlock( i_axi_awlock),
			.i_axi_awcache(i_axi_awcache),
			.i_axi_awprot( i_axi_awprot),
			.i_axi_awqos(  i_axi_awqos),
			.i_axi_awvalid(i_axi_awvalid),
			//
			.o_axi_wready( o_axi_wready),
			.i_axi_wdata(  i_axi_wdata),
			.i_axi_wstrb(  i_axi_wstrb),
			.i_axi_wlast(  i_axi_wlast),
			.i_axi_wvalid( i_axi_wvalid),
			//
			.o_axi_bid(o_axi_bid),
			.o_axi_bresp(o_axi_bresp),
			.o_axi_bvalid(o_axi_bvalid),
			.i_axi_bready(i_axi_bready),
			//
			.o_wb_cyc(  w_wb_cyc),
			.o_wb_stb(  w_wb_stb),
			.o_wb_addr( w_wb_addr),
			.o_wb_data( w_wb_data),
			.o_wb_sel(  w_wb_sel),
			.i_wb_ack(  w_wb_ack),
			.i_wb_stall(w_wb_stall),
			.i_wb_err(  w_wb_err));
	assign	w_wb_we = 1'b1;
 
	aximrd2wbsp #(
		.C_AXI_ID_WIDTH(C_AXI_ID_WIDTH),
		.C_AXI_DATA_WIDTH(C_AXI_DATA_WIDTH),
		.C_AXI_ADDR_WIDTH(C_AXI_ADDR_WIDTH), .AW(AW))
		axi_read_decoder(
			.i_axi_clk(i_clk), .i_axi_reset_n(i_axi_reset_n),
			//
			.o_axi_arready(o_axi_arready),
			.i_axi_arid(   i_axi_arid),
			.i_axi_araddr( i_axi_araddr),
			.i_axi_arlen(  i_axi_arlen),
			.i_axi_arsize( i_axi_arsize),
			.i_axi_arburst(i_axi_arburst),
			.i_axi_arlock( i_axi_arlock),
			.i_axi_arcache(i_axi_arcache),
			.i_axi_arprot( i_axi_arprot),
			.i_axi_arqos(  i_axi_arqos),
			.i_axi_arvalid(i_axi_arvalid),
			//
			.o_axi_rid(   o_axi_rid),
			.o_axi_rresp( o_axi_rresp),
			.o_axi_rvalid(o_axi_rvalid),
			.o_axi_rdata( o_axi_rdata),
			.o_axi_rlast( o_axi_rlast),
			.i_axi_rready(i_axi_rready),
			//
			.o_wb_cyc(  r_wb_cyc),
			.o_wb_stb(  r_wb_stb),
			.o_wb_addr( r_wb_addr),
			.i_wb_ack(  r_wb_ack),
			.i_wb_stall(r_wb_stall),
			.i_wb_data( i_wb_data),
			.i_wb_err(  r_wb_err));
 
	wbarbiter	#(
`ifdef	FORMAL
		.F_LGDEPTH(C_AXI_DATA_WIDTH),
`endif
		.DW(C_AXI_DATA_WIDTH),
		.AW(AW))
		readorwrite(i_clk, !i_axi_reset_n,
		r_wb_cyc, r_wb_stb, 1'b0, r_wb_addr, w_wb_data, w_wb_sel,
			r_wb_ack, r_wb_stall, r_wb_err,
		w_wb_cyc, w_wb_stb, 1'b1, w_wb_addr, w_wb_data, w_wb_sel,
			w_wb_ack, w_wb_stall, w_wb_err,
		o_wb_cyc, o_wb_stb, o_wb_we, o_wb_addr, o_wb_data, o_wb_sel,
			i_wb_ack, i_wb_stall, i_wb_err);
 
	assign	o_reset = (i_axi_reset_n == 1'b0);
 
`ifdef	FORMAL
 
`ifdef	AXIM2WBSP
	reg	f_last_clk;
 
	initial	f_last_clk = 0;
	always @($global_clock)
	begin
		assume(i_clk == f_last_clk);
		f_last_clk <= !f_last_clk;
	end
`else
`endif
 
	reg	f_past_valid;
 
	initial	f_past_valid = 1'b0;
	always @(posedge i_clk)
		f_past_valid = 1'b1;
 
	wire	[(C_AXI_ID_WIDTH-1):0]		f_axi_rd_outstanding,
						f_axi_wr_outstanding,
						f_axi_awr_outstanding;
	wire	[((1<<C_AXI_ID_WIDTH)-1):0]	f_axi_rd_id_outstanding,
						f_axi_awr_id_outstanding,
						f_axi_wr_id_outstanding;
	wire	[(C_AXI_ID_WIDTH-1):0]		f_wb_nreqs,
						f_wb_nacks, f_wb_outstanding;
	wire	[(C_AXI_ID_WIDTH-1):0]		f_wb_wr_nreqs,
						f_wb_wr_nacks, f_wb_wr_outstanding;
	wire	[(C_AXI_ID_WIDTH-1):0]		f_wb_rd_nreqs,
						f_wb_rd_nacks, f_wb_rd_outstanding;
 
	fwb_slave #(.DW(DW), .AW(AW),
			.F_MAX_STALL(0),
			.F_MAX_ACK_DELAY(0),
			.F_LGDEPTH(C_AXI_ID_WIDTH),
			.F_OPT_RMW_BUS_OPTION(1),
			.F_OPT_DISCONTINUOUS(1))
		f_wb_wr(i_clk, !i_axi_reset_n,
			w_wb_cyc, w_wb_stb, w_wb_we, w_wb_addr, w_wb_data,
				w_wb_sel,
			w_wb_ack, w_wb_stall, i_wb_data, w_wb_err,
			f_wb_wr_nreqs, f_wb_wr_nacks, f_wb_wr_outstanding);
 
	fwb_slave #(.DW(DW), .AW(AW),
			.F_MAX_STALL(0),
			.F_MAX_ACK_DELAY(0),
			.F_LGDEPTH(C_AXI_ID_WIDTH),
			.F_OPT_RMW_BUS_OPTION(1),
			.F_OPT_DISCONTINUOUS(1))
		f_wb_rd(i_clk, !i_axi_reset_n,
			r_wb_cyc, r_wb_stb, r_wb_we, r_wb_addr, w_wb_data, w_wb_sel,
				r_wb_ack, r_wb_stall, i_wb_data, r_wb_err,
			f_wb_rd_nreqs, f_wb_rd_nacks, f_wb_rd_outstanding);
 
	fwb_master #(.DW(DW), .AW(AW),
			.F_MAX_STALL(3),
			.F_MAX_ACK_DELAY(3),
			.F_LGDEPTH(C_AXI_ID_WIDTH))
		f_wb(i_clk, !i_axi_reset_n,
			o_wb_cyc, o_wb_stb, o_wb_we, o_wb_addr, o_wb_data,
				o_wb_sel,
			i_wb_ack, i_wb_stall, i_wb_data, i_wb_err,
			f_wb_nreqs, f_wb_nacks, f_wb_outstanding);
 
	always @(*)
		assume(i_axi_awlen < 8'h4);
 
	always @(*)
		assume(i_axi_arlen < 8'h4);
 
	always @(*)
		assume(i_axi_arvalid == 0);
 
	faxi_slave #(
			.C_AXI_ID_WIDTH(C_AXI_ID_WIDTH),
			.C_AXI_DATA_WIDTH(C_AXI_DATA_WIDTH),
			.C_AXI_ADDR_WIDTH(C_AXI_ADDR_WIDTH),
			.F_AXI_MAXSTALL(0),
			.F_AXI_MAXDELAY(0))
		f_axi(.i_clk(i_clk), .i_axi_reset_n(i_axi_reset_n),
			// AXI write address channnel
			.i_axi_awready(o_axi_awready),
			.i_axi_awid(   i_axi_awid),
			.i_axi_awaddr( i_axi_awaddr),
			.i_axi_awlen(  i_axi_awlen),
			.i_axi_awsize( i_axi_awsize),
			.i_axi_awburst(i_axi_awburst),
			.i_axi_awlock( i_axi_awlock),
			.i_axi_awcache(i_axi_awcache),
			.i_axi_awprot( i_axi_awprot),
			.i_axi_awqos(  i_axi_awqos),
			.i_axi_awvalid(i_axi_awvalid),
			// AXI write data channel
			.i_axi_wready( o_axi_wready),
			.i_axi_wdata(  i_axi_wdata),
			.i_axi_wstrb(  i_axi_wstrb),
			.i_axi_wlast(  i_axi_wlast),
			.i_axi_wvalid( i_axi_wvalid),
			// AXI write acknowledgement channel
			.i_axi_bid(   o_axi_bid),	// Response ID
			.i_axi_bresp( o_axi_bresp),	// Write response
			.i_axi_bvalid(o_axi_bvalid),  // Write reponse valid
			.i_axi_bready(i_axi_bready),  // Response ready
			// AXI read address channel
			.i_axi_arready(o_axi_arready),	// Read address ready
			.i_axi_arid(   i_axi_arid),	// Read ID
			.i_axi_araddr( i_axi_araddr),	// Read address
			.i_axi_arlen(  i_axi_arlen),	// Read Burst Length
			.i_axi_arsize( i_axi_arsize),	// Read Burst size
			.i_axi_arburst(i_axi_arburst),	// Read Burst type
			.i_axi_arlock( i_axi_arlock),	// Read lock type
			.i_axi_arcache(i_axi_arcache),	// Read Cache type
			.i_axi_arprot( i_axi_arprot),	// Read Protection type
			.i_axi_arqos(  i_axi_arqos),	// Read Protection type
			.i_axi_arvalid(i_axi_arvalid),	// Read address valid
			// AXI read data return
			.i_axi_rid(    o_axi_rid),     // Response ID
			.i_axi_rresp(  o_axi_rresp),   // Read response
			.i_axi_rvalid( o_axi_rvalid),  // Read reponse valid
			.i_axi_rdata(  o_axi_rdata),    // Read data
			.i_axi_rlast(  o_axi_rlast),    // Read last
			.i_axi_rready( i_axi_rready),  // Read Response ready
			// Quantify where we are within a transaction
			.f_axi_rd_outstanding( f_axi_rd_outstanding),
			.f_axi_wr_outstanding( f_axi_wr_outstanding),
			.f_axi_awr_outstanding(f_axi_awr_outstanding),
			.f_axi_rd_id_outstanding(f_axi_rd_id_outstanding),
			.f_axi_awr_id_outstanding(f_axi_awr_id_outstanding),
			.f_axi_wr_id_outstanding(f_axi_wr_id_outstanding));
 
`endif
endmodule
 
 

Go to most recent revision | Compare with Previous | Blame | View Log

powered by: WebSVN 2.1.0

© copyright 1999-2024 OpenCores.org, equivalent to Oliscience, all rights reserved. OpenCores®, registered trademark.