axiTest/Axi4LiteSlave.sv
2022-09-15 18:26:54 +01:00

149 lines
4.2 KiB
Systemverilog

// AXI4-Lite compatible memory module, for testing driver module
// SPDX-FileCopyrightText: © 2022 Aadi Desai <21363892+supleed2@users.noreply.github.com>
// SPDX-License-Identifier: Apache-2.0
`default_nettype none
typedef enum bit [1:0]
{ OKAY = 2'b00
, EXOKAY = 2'b01
, SLVERR = 2'b10
, DECERR = 2'b11
} Response;
typedef enum bit [2:0]
{ UNPRIV_SEC_DATA = 3'b000 // Unprivileged, secure, data access
, PRIV_SEC_DATA = 3'b001 // Privileged, secure, data access
, UNPRIV_NONSEC_DATA = 3'b010 // Unprivileged, non-secure, data access
, PRIV_NONSEC_DATA = 3'b011 // Privileged, non-secure, data access
, UNPRIV_SEC_INSTR = 3'b100 // Unprivileged, secure, instruction access
, PRIV_SEC_INSTR = 3'b101 // Privileged, secure, instruction access
, UNPRIV_NONSEC_INSTR = 3'b110 // Unprivileged, non-secure, instruction access
, PRIV_NONSEC_INSTR = 3'b111 // Privileged, non-secure, instruction access
} Protection;
module Axi4LiteSlave
#(parameter int AWIDTH = 12
, parameter int DWIDTH = 32
, parameter int SWIDTH = DWIDTH / 8
)(input var logic i_aClk
, input var logic i_aResetn
// Read Address Channel (Master -> Slave)
, input var logic i_arValid
, output var logic o_arReady
, input var logic [AWIDTH-1:0] i_arAddr
, input var Protection i_arProt
// Read Data Channel (Slave -> Master)
, output var logic o_rValid
, input var logic i_rReady
, output var logic [DWIDTH-1:0] o_rData
, output var Response o_rResp
// Write Address Channel (Master -> Slave)
, input var logic i_awValid
, output var logic o_awReady
, input var logic [AWIDTH-1:0] i_awAddr
, input var Protection i_awProt
// Write Data Channel (Master -> Slave)
, input var logic i_wValid
, output var logic o_wReady
, input var logic [DWIDTH-1:0] i_wData
, input var logic [SWIDTH-1:0] i_wStrb
// Write Response Channel (Slave -> Master)
, output var logic o_bValid
, input var logic i_bReady
, output var Response o_bResp
);
logic [DWIDTH-1:0] mem [4096];
logic [DWIDTH-1:0] wDataStrb;
for (genvar i = 0; i < SWIDTH; i++) begin : la_StrobedWriteData
assign wDataStrb[8*i+7:8*i] = i_wStrb[i] ? i_wData[8*i+7:8*i] : mem[i_awAddr][8*i+7:8*i];
end
enum bit [0:0]
{ IDLE
, READ
} rState;
enum bit [2:0]
{ IDLE
, WRITE
} wState;
always_ff @(posedge i_aClk)
if (!i_aResetn) begin
o_arReady <= '0;
o_rValid <= '0;
o_rData <= '0;
o_rResp <= '0;
end else
case (rState)
IDLE: begin
if (i_arValid) begin
o_arReady <= '1;
o_rValid <= '1;
o_rData <= mem[i_arAddr];
o_rResp <= Response'(OKAY);
rState <= READ;
end else
rState <= IDLE;
end
READ: begin
o_arReady <= '0;
if (i_rReady) begin
o_rValid <= '0;
o_rData <= '0;
o_rResp <= '0;
rState <= IDLE;
end else
rState <= READ;
end
default: begin
o_arReady <= '0;
o_rValid <= '0;
o_rData <= '0;
o_rResp <= '0;
end
endcase
always_ff @(posedge i_aClk)
if (!i_aResetn) begin
o_awReady <= '0;
o_wReady <= '0;
o_bValid <= '0;
o_bResp <= '0;
end else
case (wState)
IDLE: begin
if (i_awValid && i_wValid) begin
o_awReady <= '1;
mem[i_awAddr] <= wDataStrb;
o_wReady <= '1;
o_bValid <= '1;
o_bResp <= Response'(OKAY);
wState <= WRITE;
end else
wState <= IDLE;
end
WRITE: begin
o_awReady <= '0;
o_wReady <= '0;
if (i_bReady) begin
o_bValid <= '0;
o_bResp <= '0;
wState <= IDLE;
end else
wState <= WRITE;
end
default: begin
o_awReady <= '0;
o_wReady <= '0;
o_bValid <= '0;
o_bResp <= '0;
end
endcase
endmodule
`resetall