|
|
@@ -0,0 +1,462 @@ |
|
|
|
`timescale 1 ns / 1 ps |
|
|
|
|
|
|
|
module axi4_lite_v1_0_S_AXI_1 # |
|
|
|
( |
|
|
|
// Users to add parameters here |
|
|
|
|
|
|
|
// User parameters ends |
|
|
|
// Do not modify the parameters beyond this line |
|
|
|
|
|
|
|
// Width of S_AXI data bus |
|
|
|
parameter integer C_S_AXI_DATA_WIDTH = 32, |
|
|
|
// Width of S_AXI address bus |
|
|
|
parameter integer C_S_AXI_ADDR_WIDTH = 18 //4 |
|
|
|
) |
|
|
|
( |
|
|
|
// Users to add ports here |
|
|
|
|
|
|
|
// User ports ends |
|
|
|
// Do not modify the ports beyond this line |
|
|
|
|
|
|
|
// Global Clock Signal |
|
|
|
input wire S_AXI_ACLK, |
|
|
|
// Global Reset Signal. This Signal is Active LOW |
|
|
|
input wire S_AXI_ARESETN, |
|
|
|
// Write address (issued by master, acceped by Slave) |
|
|
|
input wire [C_S_AXI_ADDR_WIDTH-1 : 0] S_AXI_AWADDR, |
|
|
|
// Write address valid. This signal indicates that the master signaling |
|
|
|
// valid write address and control information. |
|
|
|
input wire S_AXI_AWVALID, |
|
|
|
// Write address ready. This signal indicates that the slave is ready |
|
|
|
// to accept an address and associated control signals. |
|
|
|
output wire S_AXI_AWREADY, |
|
|
|
// Write data (issued by master, acceped by Slave) |
|
|
|
input wire [C_S_AXI_DATA_WIDTH-1 : 0] S_AXI_WDATA, |
|
|
|
// Write valid. This signal indicates that valid write |
|
|
|
// data and strobes are available. |
|
|
|
input wire S_AXI_WVALID, |
|
|
|
// Write ready. This signal indicates that the slave |
|
|
|
// can accept the write data. |
|
|
|
output wire S_AXI_WREADY, |
|
|
|
// Write response valid. This signal indicates that the channel |
|
|
|
// is signaling a valid write response. |
|
|
|
output wire S_AXI_BVALID, |
|
|
|
// Response ready. This signal indicates that the master |
|
|
|
// can accept a write response. |
|
|
|
input wire S_AXI_BREADY, |
|
|
|
// Read address (issued by master, acceped by Slave) |
|
|
|
input wire [C_S_AXI_ADDR_WIDTH-1 : 0] S_AXI_ARADDR, |
|
|
|
// Read address valid. This signal indicates that the channel |
|
|
|
// is signaling valid read address and control information. |
|
|
|
input wire S_AXI_ARVALID, |
|
|
|
// Read address ready. This signal indicates that the slave is |
|
|
|
// ready to accept an address and associated control signals. |
|
|
|
output wire S_AXI_ARREADY, |
|
|
|
// Read data (issued by slave) |
|
|
|
output wire [C_S_AXI_DATA_WIDTH-1 : 0] S_AXI_RDATA, |
|
|
|
// Read response. This signal indicates the status of the |
|
|
|
// read transfer. |
|
|
|
//output wire [1 : 0] S_AXI_RRESP, |
|
|
|
// Read valid. This signal indicates that the channel is |
|
|
|
// signaling the required read data. |
|
|
|
output wire S_AXI_RVALID, |
|
|
|
// Read ready. This signal indicates that the master can |
|
|
|
// accept the read data and response information. |
|
|
|
input wire S_AXI_RREADY |
|
|
|
); |
|
|
|
|
|
|
|
// AXI4LITE signals |
|
|
|
reg [C_S_AXI_ADDR_WIDTH-1 : 0] axi_awaddr; |
|
|
|
reg axi_awready; |
|
|
|
reg axi_wready; |
|
|
|
// reg [1 : 0] axi_bresp; |
|
|
|
reg axi_bvalid; |
|
|
|
reg [C_S_AXI_ADDR_WIDTH-1 : 0] axi_araddr; |
|
|
|
reg axi_arready; |
|
|
|
reg [C_S_AXI_DATA_WIDTH-1 : 0] axi_rdata; |
|
|
|
//reg [1 : 0] axi_rresp; |
|
|
|
reg axi_rvalid; |
|
|
|
|
|
|
|
// Example-specific design signals |
|
|
|
// local parameter for addressing 32 bit / 64 bit C_S_AXI_DATA_WIDTH |
|
|
|
// ADDR_LSB is used for addressing 32/64 bit registers/memories |
|
|
|
// ADDR_LSB = 2 for 32 bits (n downto 2) |
|
|
|
// ADDR_LSB = 3 for 64 bits (n downto 3) |
|
|
|
localparam integer ADDR_LSB = (C_S_AXI_DATA_WIDTH/32) + 1; |
|
|
|
localparam integer OPT_MEM_ADDR_BITS = 1; |
|
|
|
//---------------------------------------------- |
|
|
|
//-- Signals for user logic register space example |
|
|
|
//------------------------------------------------ |
|
|
|
//-- Number of Slave Registers 4 |
|
|
|
/* reg [C_S_AXI_DATA_WIDTH-1:0] slv_reg0; |
|
|
|
reg [C_S_AXI_DATA_WIDTH-1:0] slv_reg1; |
|
|
|
reg [C_S_AXI_DATA_WIDTH-1:0] slv_reg2; |
|
|
|
reg [C_S_AXI_DATA_WIDTH-1:0] slv_reg3;*/ |
|
|
|
(* ram_style="register" *) |
|
|
|
reg [(C_S_AXI_DATA_WIDTH/4)-1:0] slv_reg0 [0:3]; |
|
|
|
reg [(C_S_AXI_DATA_WIDTH/4)-1:0] slv_reg1 [0:3]; |
|
|
|
|
|
|
|
integer i; |
|
|
|
wire slv_reg_rden; |
|
|
|
wire slv_reg_wren; |
|
|
|
|
|
|
|
reg [(C_S_AXI_DATA_WIDTH/4)-1:0] reg_data_out; |
|
|
|
integer byte_index; |
|
|
|
|
|
|
|
|
|
|
|
// USER ADDED SIGNALS |
|
|
|
wire[C_S_AXI_ADDR_WIDTH-1:0] ram_awddrin; |
|
|
|
wire[C_S_AXI_ADDR_WIDTH-1:0] ram_arddrin; |
|
|
|
|
|
|
|
wire wadr_dne; // Write Address Done |
|
|
|
wire radr_dne; // Read Address Done |
|
|
|
|
|
|
|
// wire [7:0]di; |
|
|
|
wire [1:0]count; |
|
|
|
reg [1:0]count_1; |
|
|
|
reg [1:0]count_2; |
|
|
|
wire [1:0]rcount; |
|
|
|
//wire we; |
|
|
|
//wire en; |
|
|
|
//wire [1:0]select; |
|
|
|
reg [(C_S_AXI_DATA_WIDTH/4)-1:0] temp_slv_reg; |
|
|
|
reg s_data_done,s_data_done_1; // Enable when all the data written in slv_reg0 |
|
|
|
wire read_en; // Enable when address is valid |
|
|
|
reg read_en2; // Enable when address is valid |
|
|
|
reg [1:0]ram_arddrin_1; |
|
|
|
reg radr_dne1;// radr_dne2; // Delayed Read Address Reached used for S_AXI_RDATA Latching |
|
|
|
// reg [C_S_AXI_ADDR_WIDTH-1:0] ram_addrin1; |
|
|
|
|
|
|
|
// I/O Connections assignments |
|
|
|
|
|
|
|
assign S_AXI_AWREADY= axi_awready; |
|
|
|
assign S_AXI_WREADY = axi_wready; |
|
|
|
//assign S_AXI_BRESP = axi_bresp; |
|
|
|
assign S_AXI_BVALID = axi_bvalid; |
|
|
|
assign S_AXI_ARREADY= axi_arready; |
|
|
|
assign S_AXI_RDATA = axi_rdata; |
|
|
|
//assign S_AXI_RRESP = axi_rresp; |
|
|
|
assign S_AXI_RVALID = axi_rvalid; |
|
|
|
|
|
|
|
|
|
|
|
// Implement axi_awready generation |
|
|
|
// axi_awready is asserted for one S_AXI_ACLK clock cycle when both |
|
|
|
// S_AXI_AWVALID and S_AXI_WVALID are asserted. axi_awready is |
|
|
|
// de-asserted when reset is low. |
|
|
|
|
|
|
|
always @( posedge S_AXI_ACLK ) |
|
|
|
begin |
|
|
|
if ( S_AXI_ARESETN == 1'b0 ) |
|
|
|
begin |
|
|
|
axi_awready <= 1'b0; |
|
|
|
end |
|
|
|
else |
|
|
|
begin |
|
|
|
if (~axi_awready && S_AXI_AWVALID && S_AXI_WVALID) |
|
|
|
begin |
|
|
|
// slave is ready to accept write address when |
|
|
|
// there is a valid write address and write data |
|
|
|
// on the write address and data bus. This design |
|
|
|
// expects no outstanding transactions. |
|
|
|
axi_awready <= 1'b1; |
|
|
|
end |
|
|
|
else |
|
|
|
begin |
|
|
|
axi_awready <= 1'b0; |
|
|
|
end |
|
|
|
end |
|
|
|
end |
|
|
|
|
|
|
|
// Implement axi_awaddr latching |
|
|
|
// This process is used to latch the address when both |
|
|
|
// S_AXI_AWVALID and S_AXI_WVALID are valid. |
|
|
|
|
|
|
|
always @( posedge S_AXI_ACLK ) |
|
|
|
begin |
|
|
|
if ( S_AXI_ARESETN == 1'b0 ) |
|
|
|
begin |
|
|
|
axi_awaddr <= 0; |
|
|
|
end |
|
|
|
else |
|
|
|
begin |
|
|
|
if (~axi_awready && S_AXI_AWVALID && S_AXI_WVALID) |
|
|
|
begin |
|
|
|
// Write Address latching |
|
|
|
axi_awaddr <= S_AXI_AWADDR; |
|
|
|
end |
|
|
|
end |
|
|
|
end |
|
|
|
|
|
|
|
// Implement axi_wready generation |
|
|
|
// axi_wready is asserted for one S_AXI_ACLK clock cycle when both |
|
|
|
// S_AXI_AWVALID and S_AXI_WVALID are asserted. axi_wready is |
|
|
|
// de-asserted when reset is low. |
|
|
|
|
|
|
|
always @( posedge S_AXI_ACLK ) |
|
|
|
begin |
|
|
|
if ( S_AXI_ARESETN == 1'b0 ) |
|
|
|
begin |
|
|
|
axi_wready <= 1'b0; |
|
|
|
end |
|
|
|
else |
|
|
|
begin |
|
|
|
if (~axi_wready && S_AXI_WVALID && S_AXI_AWVALID) |
|
|
|
begin |
|
|
|
// slave is ready to accept write data when |
|
|
|
// there is a valid write address and write data |
|
|
|
// on the write address and data bus. This design |
|
|
|
// expects no outstanding transactions. |
|
|
|
axi_wready <= 1'b1; |
|
|
|
end |
|
|
|
else |
|
|
|
begin |
|
|
|
axi_wready <= 1'b0; |
|
|
|
end |
|
|
|
end |
|
|
|
end |
|
|
|
|
|
|
|
// Implement memory mapped register select and write logic generation |
|
|
|
// The write data is accepted and written to memory mapped registers when |
|
|
|
// axi_awready, S_AXI_AWVALID, axi_wready and S_AXI_WVALID are asserted. Write strobes are used to |
|
|
|
// select byte enables of slave registers while writing. |
|
|
|
// These registers are cleared when reset (active low) is applied. |
|
|
|
// Slave register write enable is asserted when valid address and data are available |
|
|
|
// and the slave is ready to accept the write address and write data. |
|
|
|
assign slv_reg_wren = axi_wready && S_AXI_WVALID && axi_awready && S_AXI_AWVALID; // Slave Register Write Enable |
|
|
|
|
|
|
|
always @( posedge S_AXI_ACLK ) |
|
|
|
begin |
|
|
|
if ( S_AXI_ARESETN == 1'b0 ) |
|
|
|
begin |
|
|
|
s_data_done <= 1'b0; |
|
|
|
|
|
|
|
for(i = 0; i <= 3 ; i = i+1) |
|
|
|
slv_reg0[i] <= 0; |
|
|
|
end |
|
|
|
else begin |
|
|
|
if (slv_reg_wren) |
|
|
|
begin |
|
|
|
// case ( axi_awaddr[ADDR_LSB+OPT_MEM_ADDR_BITS:ADDR_LSB] ) |
|
|
|
// 2'h0: begin |
|
|
|
for ( byte_index = 0; byte_index <= (C_S_AXI_DATA_WIDTH/8)-1; byte_index = byte_index+1 )//begin |
|
|
|
//if ( S_AXI_WSTRB[byte_index] == 1 ) begin |
|
|
|
// Respective byte enables are asserted as per write strobes |
|
|
|
// Slave register 0 |
|
|
|
slv_reg0[byte_index] <= S_AXI_WDATA[(byte_index*8) +: 8]; |
|
|
|
|
|
|
|
if(byte_index <= 3) //= 4) |
|
|
|
s_data_done <= 1'b0; //1'b1; |
|
|
|
else |
|
|
|
s_data_done <= 1'b1; //1'b0; |
|
|
|
//end |
|
|
|
end |
|
|
|
// default : begin |
|
|
|
// slv_reg0 <= slv_reg0; |
|
|
|
// end |
|
|
|
// endcase |
|
|
|
// end |
|
|
|
end |
|
|
|
end |
|
|
|
|
|
|
|
// Implement write response logic generation |
|
|
|
// The write response and response valid signals are asserted by the slave |
|
|
|
// when axi_awready, S_AXI_AWVALID, axi_wready and S_AXI_WVALID are asserted. |
|
|
|
// This marks the acceptance of address and indicates the status of |
|
|
|
// write transaction. |
|
|
|
|
|
|
|
always @( posedge S_AXI_ACLK ) |
|
|
|
begin |
|
|
|
if ( S_AXI_ARESETN == 1'b0 ) |
|
|
|
begin |
|
|
|
axi_bvalid <= 0; |
|
|
|
// axi_bresp <= 2'b0; |
|
|
|
end |
|
|
|
else |
|
|
|
begin |
|
|
|
if (axi_awready && S_AXI_AWVALID && ~axi_bvalid && axi_wready && S_AXI_WVALID) |
|
|
|
begin |
|
|
|
// indicates a valid write response is available |
|
|
|
axi_bvalid <= 1'b1; |
|
|
|
// axi_bresp <= 2'b0; // 'OKAY' response |
|
|
|
end // work error responses in future |
|
|
|
else |
|
|
|
begin |
|
|
|
if (S_AXI_BREADY && axi_bvalid) |
|
|
|
//check if bready is asserted while bvalid is high) |
|
|
|
//(there is a possibility that bready is always asserted high) |
|
|
|
begin |
|
|
|
axi_bvalid <= 1'b0; |
|
|
|
end |
|
|
|
end |
|
|
|
end |
|
|
|
end |
|
|
|
|
|
|
|
// Implement axi_arready generation |
|
|
|
// axi_arready is asserted for one S_AXI_ACLK clock cycle when |
|
|
|
// S_AXI_ARVALID is asserted. axi_awready is |
|
|
|
// de-asserted when reset (active low) is asserted. |
|
|
|
// The read address is also latched when S_AXI_ARVALID is |
|
|
|
// asserted. axi_araddr is reset to zero on reset assertion. |
|
|
|
|
|
|
|
always @( posedge S_AXI_ACLK ) |
|
|
|
begin |
|
|
|
if ( S_AXI_ARESETN == 1'b0 ) |
|
|
|
begin |
|
|
|
axi_arready <= 1'b0; |
|
|
|
axi_araddr <= 32'b0; |
|
|
|
// read_en <= 1'b0; // User Logic |
|
|
|
end |
|
|
|
else |
|
|
|
begin |
|
|
|
// USER LOGIC |
|
|
|
/* if(S_AXI_ARVALID) |
|
|
|
// Assert read enable when ARADDR is Valid |
|
|
|
read_en <= 1'b1; |
|
|
|
else |
|
|
|
read_en <= 1'b0; |
|
|
|
*/ if (~axi_arready && S_AXI_ARVALID) |
|
|
|
begin |
|
|
|
// indicates that the slave has acceped the valid read address |
|
|
|
axi_arready <= 1'b1; |
|
|
|
// Read address latching |
|
|
|
axi_araddr <= S_AXI_ARADDR; |
|
|
|
|
|
|
|
end |
|
|
|
else |
|
|
|
begin |
|
|
|
axi_arready <= 1'b0; |
|
|
|
end |
|
|
|
end |
|
|
|
end |
|
|
|
|
|
|
|
// Implement axi_arvalid generation |
|
|
|
// axi_rvalid is asserted for one S_AXI_ACLK clock cycle when both |
|
|
|
// S_AXI_ARVALID and axi_arready are asserted. The slave registers |
|
|
|
// data are available on the axi_rdata bus at this instance. The |
|
|
|
// assertion of axi_rvalid marks the validity of read data on the |
|
|
|
// bus and axi_rresp indicates the status of read transaction.axi_rvalid |
|
|
|
// is deasserted on reset (active low). axi_rresp and axi_rdata are |
|
|
|
// cleared to zero on reset (active low). |
|
|
|
always @( posedge S_AXI_ACLK ) |
|
|
|
begin |
|
|
|
if ( S_AXI_ARESETN == 1'b0 ) |
|
|
|
begin |
|
|
|
axi_rvalid <= 0; |
|
|
|
// axi_rresp <= 0; |
|
|
|
end |
|
|
|
else |
|
|
|
begin |
|
|
|
if (axi_arready && S_AXI_ARVALID && ~axi_rvalid) |
|
|
|
begin |
|
|
|
// Valid read data is available at the read data bus |
|
|
|
axi_rvalid <= 1'b1; |
|
|
|
// axi_rresp <= 2'b0; // 'OKAY' response |
|
|
|
end |
|
|
|
else if (axi_rvalid && S_AXI_RREADY) |
|
|
|
begin |
|
|
|
// Read data is accepted by the master |
|
|
|
axi_rvalid <= 1'b0; |
|
|
|
end |
|
|
|
end |
|
|
|
end |
|
|
|
|
|
|
|
// Implement memory mapped register select and read logic generation |
|
|
|
// Slave register read enable is asserted when valid address is available |
|
|
|
// and the slave is ready to accept the read address. |
|
|
|
assign slv_reg_rden = axi_arready & S_AXI_ARVALID & ~axi_rvalid; |
|
|
|
|
|
|
|
always @(*) |
|
|
|
begin |
|
|
|
// Address decoding for reading registers |
|
|
|
/* case ( axi_araddr[ADDR_LSB+OPT_MEM_ADDR_BITS:ADDR_LSB] ) |
|
|
|
2'h0 : reg_data_out <= slv_reg0; |
|
|
|
2'h1 : reg_data_out <= slv_reg1; |
|
|
|
2'h2 : reg_data_out <= slv_reg2; |
|
|
|
2'h3 : reg_data_out <= slv_reg3; |
|
|
|
default : reg_data_out <= 0; |
|
|
|
endcase */ |
|
|
|
end |
|
|
|
|
|
|
|
// Output register or memory read data |
|
|
|
always @( posedge S_AXI_ACLK ) |
|
|
|
begin |
|
|
|
if ( S_AXI_ARESETN == 1'b0 ) |
|
|
|
begin |
|
|
|
axi_rdata <= 0; |
|
|
|
end |
|
|
|
else |
|
|
|
begin |
|
|
|
// When there is a valid read address (S_AXI_ARVALID) with |
|
|
|
// acceptance of read address by the slave (axi_arready), |
|
|
|
// output the read dada |
|
|
|
//if (slv_reg_rden) |
|
|
|
if (radr_dne1)//(read_en2) |
|
|
|
begin |
|
|
|
// axi_rdata <= reg_data_out; // register read data |
|
|
|
//for ( byte_index = 0; byte_index <= (C_S_AXI_DATA_WIDTH/8)-1; byte_index = byte_index+1 )//begin |
|
|
|
//axi_rdata[(byte_index*8) +: 8] <= slv_reg1[byte_index] ; |
|
|
|
//slv_reg1[byte_index] = reg_data_out; |
|
|
|
|
|
|
|
axi_rdata <= {slv_reg1[3],slv_reg1[2],slv_reg1[1],slv_reg1[0]}; |
|
|
|
|
|
|
|
end |
|
|
|
end |
|
|
|
end |
|
|
|
|
|
|
|
// Add user logic here |
|
|
|
always @ (posedge S_AXI_ACLK) |
|
|
|
begin |
|
|
|
if ( S_AXI_ARESETN == 1'b0 ) |
|
|
|
begin |
|
|
|
s_data_done_1 <= 'd0; |
|
|
|
count_1 <= 'd0; |
|
|
|
count_2 <= 'd0; |
|
|
|
radr_dne1 <= 'd0; |
|
|
|
//radr_dne2 <= 'd0; |
|
|
|
read_en2 <= 'd0; |
|
|
|
ram_arddrin_1 <= 'd0; |
|
|
|
end |
|
|
|
else |
|
|
|
begin |
|
|
|
s_data_done_1 <= s_data_done; |
|
|
|
count_1 <= count; |
|
|
|
count_2 <= count_1; |
|
|
|
read_en2 <= read_en; |
|
|
|
radr_dne1 <= radr_dne; |
|
|
|
//radr_dne2 <= radr_dne1; |
|
|
|
ram_arddrin_1 <= ram_arddrin[1:0]; |
|
|
|
end |
|
|
|
|
|
|
|
end |
|
|
|
|
|
|
|
//Enable_gen READ_ADDR_EN(.clk(S_AXI_ACLK),.rst(radr_dne),.en_in(slv_reg_rden),.en_out(read_en)); |
|
|
|
Enable_gen READ_ADDR_EN(.clk(S_AXI_ACLK),.sys_rst_n(S_AXI_ARESETN),.stop(radr_dne),.en_in(slv_reg_rden),.en_out(read_en)); |
|
|
|
Enable_gen WRITE_ADDR_EN(.clk(S_AXI_ACLK),.sys_rst_n(S_AXI_ARESETN),.stop(wadr_dne),.en_in(s_data_done),.en_out(write_en)); |
|
|
|
|
|
|
|
|
|
|
|
always_comb |
|
|
|
case(count_1) |
|
|
|
2'b00: temp_slv_reg <= slv_reg0[0]; |
|
|
|
2'b01: temp_slv_reg <= slv_reg0[1]; |
|
|
|
2'b10: temp_slv_reg <= slv_reg0[2]; |
|
|
|
2'b11: temp_slv_reg <= slv_reg0[3]; |
|
|
|
endcase |
|
|
|
|
|
|
|
always_comb |
|
|
|
case(ram_arddrin_1) |
|
|
|
2'b00: slv_reg1[0] <= reg_data_out; |
|
|
|
2'b01: slv_reg1[1] <= reg_data_out; |
|
|
|
2'b10: slv_reg1[2] <= reg_data_out; |
|
|
|
2'b11: slv_reg1[3] <= reg_data_out; |
|
|
|
endcase |
|
|
|
// Register_Space Write Address Generation. |
|
|
|
adderss_gen1 WRITE_ADDR( .core_clk(S_AXI_ACLK),.rst_n(S_AXI_ARESETN),.en_cnt(write_en),.count(count),.addr_in(axi_awaddr),.addrs_out(ram_awddrin),.adr_rchd(wadr_dne)); |
|
|
|
|
|
|
|
// Register_Space Read Address Generation. |
|
|
|
adderss_gen1 READ_ADDR( .core_clk(S_AXI_ACLK),.rst_n(S_AXI_ARESETN),.en_cnt(read_en),.count(rcount),.addr_in(axi_araddr),.addrs_out(ram_arddrin),.adr_rchd(radr_dne)); |
|
|
|
|
|
|
|
// Regstr_space reg_space(.clk(S_AXI_ACLK), .we(s_data_done_1), .en(s_data_done_1), .addr(ram_addrin), .di(temp_slv_reg), .dout(reg_data_out)); |
|
|
|
simple_dual_Port_1clock #(32,18) REG_SAPCE(.clk(S_AXI_ACLK),.ena(s_data_done_1),.rd_enb(read_en),.wea(s_data_done_1),.addra(ram_awddrin),.addrb(ram_arddrin),.din(temp_slv_reg),.dout(reg_data_out)); |
|
|
|
|
|
|
|
|
|
|
|
endmodule |