Line 26... |
Line 26... |
// Creator: Dan Gisselquist, Ph.D.
|
// Creator: Dan Gisselquist, Ph.D.
|
// Gisselquist Technology, LLC
|
// Gisselquist Technology, LLC
|
//
|
//
|
////////////////////////////////////////////////////////////////////////////////
|
////////////////////////////////////////////////////////////////////////////////
|
//
|
//
|
// Copyright (C) 2016, Gisselquist Technology, LLC
|
// Copyright (C) 2016-2018, Gisselquist Technology, LLC
|
//
|
//
|
// This program is free software (firmware): you can redistribute it and/or
|
// 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
|
// 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
|
// by the Free Software Foundation, either version 3 of the License, or (at
|
// your option) any later version.
|
// your option) any later version.
|
Line 62... |
Line 62... |
parameter DW = 32, // Wishbone data width
|
parameter DW = 32, // Wishbone data width
|
parameter AW = 26, // Wishbone address width (log wordsize)
|
parameter AW = 26, // Wishbone address width (log wordsize)
|
parameter [0:0] STRICT_ORDER = 1 // Reorder, or not? 0 -> Reorder
|
parameter [0:0] STRICT_ORDER = 1 // Reorder, or not? 0 -> Reorder
|
) (
|
) (
|
input wire i_clk, // System clock
|
input wire i_clk, // System clock
|
// input wire i_reset,// Wishbone reset signal--unused
|
input wire i_reset,// Reset signal,drives AXI rst
|
|
|
// AXI write address channel signals
|
// AXI write address channel signals
|
input wire i_axi_awready, // Slave is ready to accept
|
input wire i_axi_awready, // Slave is ready to accept
|
output reg [C_AXI_ID_WIDTH-1:0] o_axi_awid, // Write ID
|
output reg [C_AXI_ID_WIDTH-1:0] o_axi_awid, // Write ID
|
output reg [C_AXI_ADDR_WIDTH-1:0] o_axi_awaddr, // Write address
|
output reg [C_AXI_ADDR_WIDTH-1:0] o_axi_awaddr, // Write address
|
Line 163... |
Line 163... |
assign o_axi_awprot = 3'b010; // Unpriviledged, unsecure, data access
|
assign o_axi_awprot = 3'b010; // Unpriviledged, unsecure, data access
|
assign o_axi_arprot = 3'b010; // Unpriviledged, unsecure, data access
|
assign o_axi_arprot = 3'b010; // Unpriviledged, unsecure, data access
|
assign o_axi_awqos = 4'h0; // Lowest quality of service (unused)
|
assign o_axi_awqos = 4'h0; // Lowest quality of service (unused)
|
assign o_axi_arqos = 4'h0; // Lowest quality of service (unused)
|
assign o_axi_arqos = 4'h0; // Lowest quality of service (unused)
|
|
|
reg wb_mid_cycle, wb_mid_abort;
|
reg wb_mid_cycle, wb_last_cyc_stb, wb_mid_abort, wb_cyc_stb;
|
wire wb_abort;
|
wire wb_abort;
|
|
|
// Command logic
|
// Command logic
|
// Transaction ID logic
|
// Transaction ID logic
|
wire [(LGFIFOLN-1):0] fifo_head;
|
wire [(LGFIFOLN-1):0] fifo_head;
|
reg [(C_AXI_ID_WIDTH-1):0] transaction_id;
|
reg [(C_AXI_ID_WIDTH-1):0] transaction_id;
|
|
|
initial transaction_id = 0;
|
initial transaction_id = 0;
|
always @(posedge i_clk)
|
always @(posedge i_clk)
|
if ((i_wb_stb)&&(!o_wb_stall))
|
if (i_reset)
|
|
transaction_id <= 0;
|
|
else if ((i_wb_stb)&&(!o_wb_stall))
|
transaction_id <= transaction_id + 1'b1;
|
transaction_id <= transaction_id + 1'b1;
|
|
|
assign fifo_head = transaction_id;
|
assign fifo_head = transaction_id;
|
|
|
wire [(DW/8-1):0] no_sel;
|
wire [(DW/8-1):0] no_sel;
|
Line 188... |
Line 190... |
|
|
// Write address logic
|
// Write address logic
|
|
|
initial o_axi_awvalid = 0;
|
initial o_axi_awvalid = 0;
|
always @(posedge i_clk)
|
always @(posedge i_clk)
|
|
if (i_reset)
|
|
o_axi_awvalid <= 0;
|
|
else
|
o_axi_awvalid <= (!o_wb_stall)&&(i_wb_stb)&&(i_wb_we)
|
o_axi_awvalid <= (!o_wb_stall)&&(i_wb_stb)&&(i_wb_we)
|
||(o_axi_awvalid)&&(!i_axi_awready);
|
||(o_axi_awvalid)&&(!i_axi_awready);
|
|
|
generate
|
generate
|
|
|
initial o_axi_awid = -1;
|
initial o_axi_awid = -1;
|
always @(posedge i_clk)
|
always @(posedge i_clk)
|
if ((i_wb_stb)&&(!o_wb_stall))
|
if (i_reset)
|
|
o_axi_awid <= -1;
|
|
else if ((i_wb_stb)&&(!o_wb_stall))
|
o_axi_awid <= transaction_id;
|
o_axi_awid <= transaction_id;
|
|
|
if (C_AXI_DATA_WIDTH == DW)
|
if (C_AXI_DATA_WIDTH == DW)
|
begin
|
begin
|
always @(posedge i_clk)
|
always @(posedge i_clk)
|
Line 225... |
Line 232... |
assign o_axi_araddr = o_axi_awaddr;
|
assign o_axi_araddr = o_axi_awaddr;
|
assign o_axi_arlen = o_axi_awlen;
|
assign o_axi_arlen = o_axi_awlen;
|
assign o_axi_arsize = 3'b101; // maximum bytes per burst is 32
|
assign o_axi_arsize = 3'b101; // maximum bytes per burst is 32
|
initial o_axi_arvalid = 1'b0;
|
initial o_axi_arvalid = 1'b0;
|
always @(posedge i_clk)
|
always @(posedge i_clk)
|
|
if (i_reset)
|
|
o_axi_arvalid <= 1'b0;
|
|
else
|
o_axi_arvalid <= (!o_wb_stall)&&(i_wb_stb)&&(!i_wb_we)
|
o_axi_arvalid <= (!o_wb_stall)&&(i_wb_stb)&&(!i_wb_we)
|
||(o_axi_arvalid)&&(!i_axi_arready);
|
||(o_axi_arvalid)&&(!i_axi_arready);
|
|
|
// Write data logic
|
// Write data logic
|
generate
|
generate
|
Line 276... |
Line 286... |
end endgenerate
|
end endgenerate
|
|
|
assign o_axi_wlast = 1'b1;
|
assign o_axi_wlast = 1'b1;
|
initial o_axi_wvalid = 0;
|
initial o_axi_wvalid = 0;
|
always @(posedge i_clk)
|
always @(posedge i_clk)
|
|
if (i_reset)
|
|
o_axi_wvalid <= 0;
|
|
else
|
o_axi_wvalid <= ((!o_wb_stall)&&(i_wb_stb)&&(i_wb_we))
|
o_axi_wvalid <= ((!o_wb_stall)&&(i_wb_stb)&&(i_wb_we))
|
||(o_axi_wvalid)&&(!i_axi_wready);
|
||(o_axi_wvalid)&&(!i_axi_wready);
|
|
|
// Read data channel / response logic
|
// Read data channel / response logic
|
assign o_axi_rready = 1'b1;
|
assign o_axi_rready = 1'b1;
|
Line 433... |
Line 446... |
|
|
initial fifo_tail = 0;
|
initial fifo_tail = 0;
|
initial o_wb_ack = 0;
|
initial o_wb_ack = 0;
|
initial o_wb_err = 0;
|
initial o_wb_err = 0;
|
always @(posedge i_clk)
|
always @(posedge i_clk)
|
|
if (i_reset)
|
begin
|
begin
|
|
reorder_fifo_valid <= 0;
|
|
reorder_fifo_err <= 0;
|
|
o_wb_ack <= 0;
|
|
o_wb_err <= 0;
|
|
fifo_tail <= 0;
|
|
end else begin
|
if (axi_rd_ack)
|
if (axi_rd_ack)
|
begin
|
begin
|
reorder_fifo_valid[i_axi_rid] <= 1'b1;
|
reorder_fifo_valid[i_axi_rid] <= 1'b1;
|
reorder_fifo_err[i_axi_rid] <= axi_rd_err;
|
reorder_fifo_err[i_axi_rid] <= axi_rd_err;
|
end
|
end
|
Line 469... |
Line 489... |
end
|
end
|
|
|
reg r_fifo_full;
|
reg r_fifo_full;
|
initial r_fifo_full = 0;
|
initial r_fifo_full = 0;
|
always @(posedge i_clk)
|
always @(posedge i_clk)
|
begin
|
if (i_reset)
|
|
r_fifo_full <= 0;
|
|
else begin
|
if ((i_wb_stb)&&(!o_wb_stall)
|
if ((i_wb_stb)&&(!o_wb_stall)
|
&&(reorder_fifo_valid[fifo_tail]))
|
&&(reorder_fifo_valid[fifo_tail]))
|
r_fifo_full <= (fifo_tail==n_fifo_head);
|
r_fifo_full <= (fifo_tail==n_fifo_head);
|
else if ((i_wb_stb)&&(!o_wb_stall))
|
else if ((i_wb_stb)&&(!o_wb_stall))
|
r_fifo_full <= (fifo_tail==nn_fifo_head);
|
r_fifo_full <= (fifo_tail==nn_fifo_head);
|
Line 491... |
Line 513... |
reg reorder_fifo_err;
|
reg reorder_fifo_err;
|
|
|
initial reorder_fifo_valid = 1'b0;
|
initial reorder_fifo_valid = 1'b0;
|
initial reorder_fifo_err = 1'b0;
|
initial reorder_fifo_err = 1'b0;
|
always @(posedge i_clk)
|
always @(posedge i_clk)
|
|
if (i_reset)
|
|
begin
|
|
reorder_fifo_valid <= 0;
|
|
reorder_fifo_err <= 0;
|
|
end else begin
|
if (axi_rd_ack)
|
if (axi_rd_ack)
|
begin
|
begin
|
reorder_fifo_valid <= 1'b1;
|
reorder_fifo_valid <= 1'b1;
|
reorder_fifo_err <= axi_rd_err;
|
reorder_fifo_err <= axi_rd_err;
|
end else if (axi_wr_ack)
|
end else if (axi_wr_ack)
|
Line 503... |
Line 530... |
reorder_fifo_err <= axi_wr_err;
|
reorder_fifo_err <= axi_wr_err;
|
end else begin
|
end else begin
|
reorder_fifo_valid <= 1'b0;
|
reorder_fifo_valid <= 1'b0;
|
reorder_fifo_err <= 1'b0;
|
reorder_fifo_err <= 1'b0;
|
end
|
end
|
|
end
|
|
|
initial fifo_tail = 0;
|
initial fifo_tail = 0;
|
always @(posedge i_clk)
|
always @(posedge i_clk)
|
if (reorder_fifo_valid)
|
if (i_reset)
|
|
fifo_tail <= 0;
|
|
else if (reorder_fifo_valid)
|
fifo_tail <= fifo_tail + 1'b1;
|
fifo_tail <= fifo_tail + 1'b1;
|
|
|
initial o_wb_ack = 0;
|
initial o_wb_ack = 0;
|
always @(posedge i_clk)
|
always @(posedge i_clk)
|
|
if (i_reset)
|
|
o_wb_ack <= 0;
|
|
else
|
o_wb_ack <= (reorder_fifo_valid)&&(i_wb_cyc)&&(!wb_abort);
|
o_wb_ack <= (reorder_fifo_valid)&&(i_wb_cyc)&&(!wb_abort);
|
|
|
initial o_wb_err = 0;
|
initial o_wb_err = 0;
|
always @(posedge i_clk)
|
always @(posedge i_clk)
|
|
if (i_reset)
|
|
o_wb_err <= 0;
|
|
else
|
o_wb_err <= (reorder_fifo_err)&&(i_wb_cyc)&&(!wb_abort);
|
o_wb_err <= (reorder_fifo_err)&&(i_wb_cyc)&&(!wb_abort);
|
|
|
reg r_fifo_full;
|
reg r_fifo_full;
|
initial r_fifo_full = 0;
|
initial r_fifo_full = 0;
|
always @(posedge i_clk)
|
always @(posedge i_clk)
|
begin
|
if (i_reset)
|
|
r_fifo_full <= 0;
|
|
else begin
|
if ((i_wb_stb)&&(!o_wb_stall)
|
if ((i_wb_stb)&&(!o_wb_stall)
|
&&(reorder_fifo_valid))
|
&&(reorder_fifo_valid))
|
r_fifo_full <= (fifo_tail==n_fifo_head);
|
r_fifo_full <= (fifo_tail==n_fifo_head);
|
else if ((i_wb_stb)&&(!o_wb_stall))
|
else if ((i_wb_stb)&&(!o_wb_stall))
|
r_fifo_full <= (fifo_tail==nn_fifo_head);
|
r_fifo_full <= (fifo_tail==nn_fifo_head);
|
Line 544... |
Line 582... |
|
|
//
|
//
|
// Wishbone abort logic
|
// Wishbone abort logic
|
//
|
//
|
|
|
// Are we mid-cycle?
|
// Did we just accept something?
|
|
initial wb_cyc_stb = 1'b0;
|
|
always @(posedge i_clk)
|
|
if (i_reset)
|
|
wb_cyc_stb <= 1'b0;
|
|
else
|
|
wb_cyc_stb <= (i_wb_cyc)&&(i_wb_stb)&&(!o_wb_stall);
|
|
|
|
// Else, are we mid-cycle?
|
initial wb_mid_cycle = 0;
|
initial wb_mid_cycle = 0;
|
always @(posedge i_clk)
|
always @(posedge i_clk)
|
if ((fifo_head != fifo_tail)
|
if (i_reset)
|
|
wb_mid_cycle <= 0;
|
|
else if ((fifo_head != fifo_tail)
|
||(o_axi_arvalid)||(o_axi_awvalid)
|
||(o_axi_arvalid)||(o_axi_awvalid)
|
||(o_axi_wvalid)
|
||(o_axi_wvalid)
|
||(i_wb_cyc)&&(i_wb_stb)&&(!o_wb_stall))
|
||(i_wb_cyc)&&(i_wb_stb)&&(!o_wb_stall))
|
wb_mid_cycle <= 1'b1;
|
wb_mid_cycle <= 1'b1;
|
else
|
else
|
wb_mid_cycle <= 1'b0;
|
wb_mid_cycle <= 1'b0;
|
|
|
|
initial wb_mid_abort = 0;
|
always @(posedge i_clk)
|
always @(posedge i_clk)
|
if (wb_mid_cycle)
|
if (i_reset)
|
|
wb_mid_abort <= 0;
|
|
else if (wb_mid_cycle)
|
wb_mid_abort <= (wb_mid_abort)||(!i_wb_cyc);
|
wb_mid_abort <= (wb_mid_abort)||(!i_wb_cyc);
|
else
|
else
|
wb_mid_abort <= 1'b0;
|
wb_mid_abort <= 1'b0;
|
|
|
assign wb_abort = ((wb_mid_cycle)&&(!i_wb_cyc))||(wb_mid_abort);
|
assign wb_abort = ((wb_mid_cycle)&&(!i_wb_cyc))||(wb_mid_abort);
|
Line 573... |
Line 624... |
||((o_axi_awvalid)&&(!i_axi_awready))
|
||((o_axi_awvalid)&&(!i_axi_awready))
|
||((o_axi_wvalid )&&(!i_axi_wready ))
|
||((o_axi_wvalid )&&(!i_axi_wready ))
|
||((o_axi_arvalid)&&(!i_axi_arready)));
|
||((o_axi_arvalid)&&(!i_axi_arready)));
|
|
|
|
|
// Make Verilator happy
|
|
// verilator lint_off UNUSED
|
|
wire [2:0] unused;
|
|
assign unused = { i_axi_bresp[0], i_axi_rresp[0], i_axi_rlast };
|
|
// verilator lint_on UNUSED
|
|
|
|
/////////////////////////////////////////////////////////////////////////
|
/////////////////////////////////////////////////////////////////////////
|
//
|
//
|
//
|
//
|
//
|
//
|
// Formal methods section
|
// Formal methods section
|