modify the cfg_noc_axi_bridge

This commit is contained in:
leeyunlong 2025-06-24 14:04:01 +08:00
parent 81a438f142
commit 41b613f5f7
1 changed files with 365 additions and 0 deletions

View File

@ -0,0 +1,365 @@
//======================================================================
// Self-Defined Bus to AXI4.0 Protocol Bridge
// Features:
// - Full duplex read/write operations
// - Pipeline optimization for back-to-back transactions
// - AXI4.0 burst mode support (single transaction per request)
// - Configurable address mapping
// - Error handling with AXI-compatible response codes
//======================================================================
module cfg_noc_axi_bridge #(
parameter DATA_WID = 32,
parameter ID_WID = 5,
parameter NODE_ID_WID = 5,
parameter SUB_ADDR_WID = 22,
parameter ERR_WID = 2,
parameter ADDR_WID = 32,
parameter REQ_FLIT_WID = 1
+ ID_WID
+ NODE_ID_WID
+ SUB_ADDR_WID
+ DATA_WID ,
parameter RSP_FLIT_WID = 1
+ ID_WID
+ ERR_WID
+ DATA_WID
)(
// Global signals
input wire clk,
input wire rst_n,
// Self-defined Bus Request Interface
output wire bridge_req_rdy,
input wire bridge_req_vld,
input wire [REQ_FLIT_WID-1:0] bridge_req_flit,
// Self-defined Bus Response Interface
input wire bridge_rsp_rdy,
output wire bridge_rsp_vld,
output wire [RSP_FLIT_WID-1:0] bridge_rsp_flit,
// AXI4.0 Master Interface
// Write Address Channel
output wire m_axi_awvalid,
output wire [ID_WID-1:0] m_axi_awid,
output wire [ADDR_WID-1:0] m_axi_awaddr,
output wire [7:0] m_axi_awlen,
output wire [2:0] m_axi_awsize,
output wire [1:0] m_axi_awburst,
input wire m_axi_awready,
// Write Data Channel
output wire m_axi_wvalid,
output wire [ID_WID-1:0] m_axi_wid,
output wire [DATA_WID-1:0] m_axi_wdata,
output wire [DATA_WID/8-1:0] m_axi_wstrb,
output wire m_axi_wlast,
input wire m_axi_wready,
// Write Response Channel
input wire m_axi_bvalid,
input wire [ID_WID-1:0] m_axi_bid,
input wire [1:0] m_axi_bresp,
output wire m_axi_bready,
// Read Address Channel
output wire [ID_WID-1:0] m_axi_arid,
output wire [ADDR_WID-1:0] m_axi_araddr,
output wire [7:0] m_axi_arlen,
output wire [2:0] m_axi_arsize,
output wire [1:0] m_axi_arburst,
output wire m_axi_arvalid,
input wire m_axi_arready,
// Read Data Channel
input wire [ID_WID-1:0] m_axi_rid,
input wire [DATA_WID-1:0] m_axi_rdata,
input wire [1:0] m_axi_rresp,
input wire m_axi_rlast,
input wire m_axi_rvalid,
output wire m_axi_rready
);
//----------------------------------------------------------------------
// Parameters
//----------------------------------------------------------------------
localparam BYTE_EN_WID = DATA_WID/8;
//----------------------------------------------------------------------
// Request Flit Decomposition (Structure matching your spec)
//----------------------------------------------------------------------
wire bridge_req_type; // 0:Read, 1:Write
wire [ID_WID-1:0] bridge_req_id;
wire [NODE_ID_WID-1:0] bridge_req_node_id;
wire [SUB_ADDR_WID-1:0] bridge_req_sub_addr;
wire [DATA_WID-1:0] bridge_req_wdata; // Valid for write requests
assign {
bridge_req_type, // 1 bit
bridge_req_id, // ID_WID
bridge_req_node_id, // NODE_ID_WID
bridge_req_sub_addr, // SUB_ADDR_WID
bridge_req_wdata // DATA_WID
} = bridge_req_flit;
//----------------------------------------------------------------------
// FSM Declaration (Handling read/write transactions)
//----------------------------------------------------------------------
localparam IDLE = 3'b000;
localparam HOLD_REQ = 3'b001;
localparam AW_W_CHAN = 3'b010;
localparam AR_CHAN = 3'b011;
localparam WR_RESP_CHAN = 3'b100;
localparam RD_DATA_CHAN = 3'b110;
//localparam ERROR = 3'b111;
reg [2:0] curr_state;
reg [2:0] next_state;
//----------------------------------------------------------------------
// FSM-1 FSM transition logic
//----------------------------------------------------------------------
always @(posedge clk or negedge rst_n) begin
if (!rst_n) begin
curr_state <= IDLE;
end else begin
curr_state <= next_state;
end
end
//----------------------------------------------------------------------
// FSM-2 FSM Jump condition logic
//----------------------------------------------------------------------
reg hold_req_vld; // Hold current request
reg hold_req_type; // Hold current request
reg [ID_WID-1:0] hold_req_id; // Transaction ID in progress
reg [SUB_ADDR_WID-1:0] hold_req_sub_addr;
reg [DATA_WID-1:0] hold_req_wdata; // Valid for write requests
always @(*) begin
if (!rst_n) begin
next_state = IDLE;
end else begin
case (curr_state)
IDLE: begin
next_state = (bridge_req_vld) ? HOLD_REQ : IDLE;
end
HOLD_REQ: begin
if(hold_req_type && m_axi_awready && m_axi_wready) begin
next_state = AW_W_CHAN;
end else if (!hold_req_type && m_axi_arready) begin
next_state = AR_CHAN;
end else begin
next_state = HOLD_REQ;
end
end
AW_W_CHAN: begin
next_state = WR_RESP_CHAN;
end
AR_CHAN: begin
next_state = RD_DATA_CHAN;
end
WR_RESP_CHAN: begin
next_state = (m_axi_bvalid && m_axi_rlast) ? IDLE : WR_RESP_CHAN;
end
RD_DATA_CHAN: begin
next_state = (m_axi_rvalid) ? IDLE : RD_DATA_CHAN;
end
endcase
end
end
//----------------------------------------------------------------------
// FSM-3 :FSM Action Logic
//----------------------------------------------------------------------
//reg req_vld;
//reg req_type; // 0:Read, 1:Write
//reg [ID_WID-1:0] req_id;
//reg [NODE_ID_WID-1:0] req_node_id;
//reg [SUB_ADDR_WID-1:0] req_sub_addr;
//reg [DATA_WID-1:0] req_wdata; // Valid for write requests
//
//always @(posedge clk or negedge rst_n) begin
// if (!rst_n) begin
// req_vld <= 1'b0;
// req_type <= 1'b0;
// req_id <= 'b0;
// req_sub_addr <= 'b0;
// req_data <= 'b0;
// req_err <= 'b0;
// end else if (bridge_req_vld && !req_vld) begin
// req_vld <= 1'b1;
// req_type <= bridge_req_type;
// req_id <= bridge_req_id;
// req_addr <= bridge_req_sub_addr;
// req_wdata <=bridge_req_wdata;
// end else begin
// req_vld <= 1'b0;
// end
//end
assign bridge_req_rdy = (curr_state == IDLE);
//----------------------------------------------------------------------
// Transaction Processing
//----------------------------------------------------------------------
reg reg_rsp_vld;
reg reg_rsp_type;
reg [2 -1:0] reg_rsp_resp;
reg [ID_WID -1:0] reg_rsp_id; // Transaction ID in progress
reg [DATA_WID-1:0] reg_rsp_rdata;
always_ff @(posedge clk or negedge rst_n) begin
if (!rst_n) begin
hold_req_vld <= 1'b0;
hold_req_type <= 1'b0;
hold_req_id <= 'b0;
reg_rsp_vld <= 'b0;
reg_rsp_type <= 'b0;
reg_rsp_id <= 'b0;
reg_rsp_resp <= 'b0;
reg_rsp_rdata <= 'b0;
//====current_req
end
else begin
case (curr_state)
IDLE: begin
if (bridge_req_vld) begin
hold_req_vld <= 1'b1;
hold_req_type <= bridge_req_type;
hold_req_id <= bridge_req_id;
hold_req_sub_addr<=bridge_req_sub_addr;
hold_req_wdata <= bridge_req_wdata;
end else begin
hold_req_vld <= 'b0;
hold_req_type <= 'b0;
hold_req_id <= 'b0;
hold_req_sub_addr<='b0;
hold_req_wdata <= 'b0;
end
reg_rsp_vld <= 'b0;
reg_rsp_type <= 'b0;
reg_rsp_id <= 'b0;
reg_rsp_resp <= 'b0;
reg_rsp_rdata <= 'b0;
end
HOLD_REQ: begin
hold_req_vld <= hold_req_vld;
hold_req_type <= hold_req_vld;
hold_req_id <= hold_req_id;
hold_req_sub_addr<=hold_req_sub_addr;
hold_req_wdata <= hold_req_wdata;
end
AW_W_CHAN: begin
end
AR_CHAN: begin
end
WR_RESP_CHAN: begin
if (m_axi_bvalid==1'b1) begin
reg_rsp_vld <= 1'b1;
reg_rsp_type<= 'b1;
reg_rsp_id <= m_axi_bid;
reg_rsp_resp<= m_axi_bresp;
reg_rsp_rdata<= 'b0;
end else begin
end
end
RD_DATA_CHAN: begin
if (m_axi_rvalid==1'b1) begin
reg_rsp_vld <= 1'b1;
reg_rsp_type<= 1'b0;
reg_rsp_id <= m_axi_rid;
reg_rsp_resp<= m_axi_rresp;
reg_rsp_rdata<=m_axi_rdata;
end
end
default: begin
end
endcase
end
end
//----------------------------------------------------------------------
// AXI control signals
//----------------------------------------------------------------------
// AXI signal assignments
assign m_axi_awvalid = (curr_state == AW_W_CHAN);
assign m_axi_awaddr = (curr_state == AW_W_CHAN) ? {10'b0,hold_req_sub_addr} : 'b0;
assign m_axi_awid = (curr_state == AW_W_CHAN) ? hold_req_id : 'b0;
assign m_axi_awlen = 8'h00; // Single transaction
assign m_axi_awsize = 3'b100; // 4 bytes (DATA_WID/8)
assign m_axi_awburst = 2'b01; // INCR burst type
assign m_axi_wvalid = (curr_state == AW_W_CHAN);
assign m_axi_wid = (curr_state == AW_W_CHAN) ? hold_req_id : 'b0;
assign m_axi_wdata = (curr_state == AW_W_CHAN) ? hold_req_wdata : 'b0;
assign m_axi_wstrb = {BYTE_EN_WID{1'b1}}; // All bytes enabled
assign m_axi_wlast = 1'b1;
assign m_axi_arvalid = (curr_state == AR_CHAN);
assign m_axi_arid = (curr_state == AR_CHAN) ? hold_req_id : 'b0;
assign m_axi_araddr = (curr_state == AR_CHAN) ? {10'b0,hold_req_sub_addr} : 'b0;
assign m_axi_arlen = 8'h00;
assign m_axi_arsize = 3'b100;
assign m_axi_arburst = 2'b01;
assign m_axi_bready = 1'b1; // Always ready for write responses
//assign m_axi_rready = 1'b1;
assign m_axi_rready = bridge_rsp_rdy;
//----------------------------------------------------------------------
// Response Packet Formatting
//----------------------------------------------------------------------
assign bridge_rsp_vld = reg_rsp_vld;
// Response format: [type(1)|ID(5)|ERR(2)|DATA(32)]
assign bridge_rsp_flit = {
reg_rsp_type, // type bit
reg_rsp_id, // ID_WID
reg_rsp_resp, // ERR_WID
reg_rsp_rdata // DATA_WID
};
//----------------------------------------------------------------------
// Timeout Protection (Prevent transaction hangs)
//----------------------------------------------------------------------
// localparam TIMEOUT_VALUE = 1023;
// reg [9:0] timeout_counter;
//
// always_ff @(posedge clk or negedge rst_n) begin
// if (!rst_n)
// timeout_counter <= '0;
// else if (curr_state != next_state)
// timeout_counter <= '0;
// else if (curr_state != IDLE)
// timeout_counter <= timeout_counter + 1;
// end
endmodule