Skip to content

Commit

Permalink
Retrieve latest updates and apply verible formatting
Browse files Browse the repository at this point in the history
  • Loading branch information
OlivierBetschi committed Oct 3, 2024
1 parent d8b7f5c commit 66dc8f9
Show file tree
Hide file tree
Showing 5 changed files with 114 additions and 181 deletions.
16 changes: 8 additions & 8 deletions core/ahb_adapter/ahb_master_adapter.sv
Original file line number Diff line number Diff line change
Expand Up @@ -50,8 +50,8 @@ module ahb_master_adapter
SINGLE,
PIPELINE_STALL,
SINGLE_STALL
} ahb_ctrl_e;
ahb_ctrl_e ahb_ctrl_fsm;
} ahb_ctrl_m_e;
ahb_ctrl_m_e ahb_ctrl_fsm;

// Not supported
assign req_port_o.data_ruser = '0;
Expand Down Expand Up @@ -157,23 +157,23 @@ module ahb_master_adapter
assign ahb_p_req_o.hprot = ahb_pkg::AHBProtWidth'('b0011);

always_comb begin
htrans_d = '0;
htrans_d = ahb_pkg::AhbTransIdle;
haddr_d = '0;
hsize_d = '0;
hsize_d = ahb_pkg::AhbSizeByte;
hwrite_d = '0;
if (ahb_ctrl_fsm == PIPELINE_STALL) begin //send the registered value during stall
htrans_d = ahb_pkg::AHB_TRANS_NONSEQ;
htrans_d = ahb_pkg::AhbTransNonseq;
haddr_d = haddr_q;
hsize_d = hsize_q;
hwrite_d = hwrite_q;
end else begin // send the value directly otherwise
haddr_d = req_port_i.vaddr;
hsize_d = {1'b0, req_port_i.data_size};
hwrite_d = req_port_i.data_we;
if (req_port_i.data_req) begin
htrans_d = ahb_pkg::AHB_TRANS_NONSEQ;
if (transfer_req) begin
htrans_d = ahb_pkg::AhbTransNonseq;
end else begin
htrans_d = ahb_pkg::AHB_TRANS_IDLE;
htrans_d = ahb_pkg::AhbTransIdle;
end
end
end
Expand Down
191 changes: 69 additions & 122 deletions core/ahb_adapter/ahb_slave_adapter.sv
Original file line number Diff line number Diff line change
Expand Up @@ -23,41 +23,38 @@ module ahb_slave_adapter
output ahb_resp_t ahb_s_resp_o,
input ahb_req_t ahb_s_req_i,

// Request from AHB acknowledged
input logic req_ack_i,
output logic ahb_burst_o,

// dreq Interface translation
input dcache_req_o_t req_port_i,
output scratchpad_req_i_t req_port_o
);

// AHB signals
logic hready_d;
logic hresp_d;
logic [CVA6Cfg.XLEN-1:0] hrdata_d;
// Req port signals
logic [CVA6Cfg.VLEN-1:0] vaddr_d, vaddr_q;
logic [CVA6Cfg.XLEN-1:0] wdata_d, wdata_q;
logic [1:0] size_d, size_q;
logic data_be_d, data_we_d, data_req_d;
logic [1:0] size_q;
logic data_we_d, data_req_d;
logic [CVA6Cfg.XLEN/8-1:0] data_be_d;
// helper signal
logic ahb_transfer_req;

// htrans values
typedef enum logic [2:0] {
typedef enum logic [1:0] {
S_IDLE,
S_BUSY,
S_NONSEQ_READ,
S_NONSEQ_WRITE,
S_SEQ_READ,
S_SEQ_WRITE
} ahb_ctrl_e;
ahb_ctrl_e state_q, state_d;
S_WRITE,
S_READ,
S_READ_DATA
} ahb_ctrl_s_e;
ahb_ctrl_s_e state_q, state_d;

assign ahb_transfer_req = (hready_d && (ahb_s_req_i.htrans == AhbTransNonseq || ahb_s_req_i.htrans == AhbTransSeq)) ? 1'b1 : 1'b0;

// -------------------
// FSM: Current State
// -------------------

always_ff @(posedge clk_i or negedge rst_ni) begin : p_next_state
always_ff @(posedge clk_i or negedge rst_ni) begin : p_fsm_state
if (~rst_ni) begin
state_q <= S_IDLE;
end else begin
Expand All @@ -68,71 +65,36 @@ module ahb_slave_adapter
// --------------------
// FSM: Next State
// --------------------
// Busy value of htrans is handled implicitely like an idle state
//

always_comb begin : p_current_state
always_comb begin : p_fsm_next
state_d = state_q;

case (state_q)
S_IDLE: begin
state_d = S_IDLE;
if (ahb_s_req_i.htrans == AHB_TRANS_NONSEQ) begin
if (ahb_s_req_i.hwrite) state_d = S_NONSEQ_WRITE;
else state_d = S_NONSEQ_READ;
if (ahb_transfer_req) begin
if (ahb_s_req_i.hwrite) state_d = S_WRITE;
else state_d = S_READ;
end
end

S_NONSEQ_READ, S_NONSEQ_WRITE: begin
// BUSY should not happen when NONSEQ ongoing
// Default is then IDLE (no transfer after current one)
state_d = AHB_TRANS_IDLE;

// If current request not served, should stay in NONSEQ
if (~req_ack_i) state_d = state_q;
// Stay in NONSEQ if one is following
else if (ahb_s_req_i.htrans == AHB_TRANS_NONSEQ) begin
if (ahb_s_req_i.hwrite) state_d = S_NONSEQ_WRITE;
else state_d = S_NONSEQ_READ;
end
// Go to SEQ if this becomes a BURST
else if (ahb_s_req_i.htrans == AHB_TRANS_SEQ) begin
if (ahb_s_req_i.hwrite) state_d = S_SEQ_WRITE;
else state_d = S_SEQ_READ;
end
S_WRITE: begin
if (req_port_i.data_gnt == 1'b1) state_d = S_IDLE; // Write completed
end

S_SEQ_READ, S_SEQ_WRITE: begin
// BURST is conneced to every state
// Change state accoding to next transfer type
state_d = AHB_TRANS_IDLE;
if (ahb_s_req_i.htrans == AHB_TRANS_SEQ) begin
if (ahb_s_req_i.hwrite) state_d = S_SEQ_WRITE;
else state_d = S_SEQ_READ;
end
else if (ahb_s_req_i.htrans == AHB_TRANS_BUSY) state_d = S_BUSY;
else if (ahb_s_req_i.htrans == AHB_TRANS_NONSEQ) begin
if (ahb_s_req_i.hwrite) state_d = S_NONSEQ_WRITE;
else state_d = S_NONSEQ_READ;
end
S_READ: begin
if (req_port_i.data_gnt == 1'b1) state_d = S_READ_DATA; // Read command accepted
end

S_BUSY: begin
// BUSY can then go IDLE and SINGLE only if the current burst size is undefined
if (ahb_s_req_i.htrans == AHB_TRANS_BUSY) state_d = S_BUSY;
else if (ahb_s_req_i.htrans == AHB_TRANS_SEQ) begin
if (ahb_s_req_i.hwrite) state_d = S_SEQ_WRITE;
else state_d = S_SEQ_READ;
end
else if (ahb_s_req_i.hburst == AHB_BURST_INCR) begin
if (ahb_s_req_i.htrans == AHB_TRANS_IDLE) state_d = S_IDLE;
else if (ahb_s_req_i.htrans == AHB_TRANS_NONSEQ) begin
if (ahb_s_req_i.hwrite) state_d = S_NONSEQ_WRITE;
else state_d = S_NONSEQ_READ;
end
end

// TODO: Assert when IDLE or NONSEQ for a non undefined length burst
S_READ_DATA: begin
if ((req_port_i.data_rvalid == 1'b1) && ahb_transfer_req) begin // pipeline transfer
if (ahb_s_req_i.hwrite) state_d = S_WRITE;
else state_d = S_READ;
end else if (req_port_i.data_rvalid == 1'b1) state_d = S_IDLE; // no pipeline transfer
end

// TODO: Assert when IDLE or NONSEQ for a non undefined length burst
default: state_d = S_IDLE;
endcase
end
Expand All @@ -143,24 +105,25 @@ module ahb_slave_adapter

assign ahb_s_resp_o.hrdata = hrdata_d;
assign ahb_s_resp_o.hready = hready_d;
assign ahb_s_resp_o.hresp = hresp_d;
assign ahb_s_resp_o.hresp = 1'b0; // Exception not yet supported, no errors are sent to AHB BUS

always_comb begin : p_ahb_outputs
hready_d = 1'b1;
hresp_d = 1'b0; // Exception not yet supported, no errors are sent to AHB BUS
hrdata_d = '0;

case (state_q)
S_NONSEQ_READ, S_SEQ_READ: begin
S_IDLE: begin
hready_d = 1'b1;
end
S_READ: begin
hready_d = 1'b0;
end
S_READ_DATA: begin
hready_d = req_port_i.data_rvalid;
if (req_port_i.data_rvalid) hrdata_d = req_port_i.data_rdata;
else hready_d = 1'b0;
end

S_NONSEQ_WRITE, S_SEQ_WRITE: begin
if (~req_ack_i) hready_d = 1'b0;
S_WRITE: begin
hready_d = 1'b0;
end

// IDLE and BUSY are in default
default: ;
endcase
end
Expand All @@ -169,59 +132,46 @@ module ahb_slave_adapter
// FSM: Outputs for DREQ interface
// --------------------------------

assign req_port_o.vaddr = vaddr_q;
assign req_port_o.data_wdata = ahb_s_req_i.hwdata;
assign req_port_o.data_req = data_req_d;
assign req_port_o.data_we = data_we_d;
assign req_port_o.data_be = data_be_d;
assign req_port_o.data_size = size_q;
assign req_port_o.data_id = '0; // Not supported: next req is sent when previous one is done
assign req_port_o.kill_req = '0; // Not supported: AHB master cannot kill a req

always_comb begin : p_dreq_outputs
vaddr_d = vaddr_q;
wdata_d = wdata_q;
data_req_d = 1'b0;
data_we_d = 1'b0;
data_be_d = '0; // TODO: Determine if should be set depending of size or not?
size_d = size_q;
ahb_burst_o = 1'b0;

case (state_q)
S_IDLE: begin
// Next state is NONSEQ, then a new request after IDLE juste arrived
// Can send request to ask ARBITER
// Nothing to do if request is write... should wait for wdata before sending)
if (state_d == S_NONSEQ_READ) begin
vaddr_d = CVA6Cfg.VLEN'(ahb_s_req_i.haddr);
data_req_d = 1'b1;
size_d = ahb_s_req_i.hsize[1:0];
end
end
S_IDLE: ;

S_NONSEQ_READ, S_SEQ_READ: begin
if (req_ack_i && (state_d == S_NONSEQ_READ || state_d == S_SEQ_READ)) begin
vaddr_d = CVA6Cfg.VLEN'(ahb_s_req_i.haddr);
data_req_d = 1'b1;
size_d = ahb_s_req_i.hsize[1:0];
end else if (~req_ack_i) data_req_d = 1'b1;

if (state_d == S_SEQ_READ) ahb_burst_o = 1'b1;
S_WRITE: begin
data_req_d = 1'b1;
data_we_d = 1'b1;
end

S_NONSEQ_WRITE, S_SEQ_WRITE: begin
data_we_d = 1'b1;
if (req_ack_i && (state_d == S_NONSEQ_WRITE || state_d == S_SEQ_WRITE)) data_req_d = 1'b1;

if (state_d == S_SEQ_WRITE) ahb_burst_o = 1'b1;
S_READ: begin
data_req_d = 1'b1;
end

S_BUSY: begin
S_READ_DATA: begin
data_req_d = 1'b0;
end

default: ;
endcase
end

assign req_port_o.vaddr = vaddr_d;
assign req_port_o.data_wdata = wdata_d;
assign req_port_o.data_req = data_req_d;
assign req_port_o.data_we = data_we_d;
assign req_port_o.data_be = data_be_d;
assign req_port_o.data_size = size_d;
assign req_port_o.data_id = '0; // Not supported: next req is sent when previous one is done
assign req_port_o.kill_req = '0; // Not supported: AHB master cannot kill a req
always_comb begin : p_data_be_gen
if (ahb_s_req_i.hwrite) begin
if (ahb_s_req_i.hsize[1:0] == 3'b000) data_be_d = 4'b0001;
else if (ahb_s_req_i.hsize[1:0] == 3'b001) data_be_d = 4'b0011;
else if (ahb_s_req_i.hsize[1:0] == 3'b010) data_be_d = 4'b1111;
else data_be_d = 4'b1111;
end else data_be_d = 4'h0;
end

// ----------------------------
// Req port register process
Expand All @@ -230,15 +180,12 @@ module ahb_slave_adapter
always_ff @(posedge clk_i or negedge rst_ni) begin : p_req_port_regs
if (~rst_ni) begin
vaddr_q <= '0;
wdata_q <= '0;
size_q <= '0;
end else begin
// TODO: Find enable
if (req_ack_i || ((state_d == S_NONSEQ_READ || state_d == S_NONSEQ_WRITE) && state_q == S_IDLE)) begin
vaddr_q <= vaddr_d;
size_q <= size_d;
if (ahb_transfer_req) begin
vaddr_q <= ahb_s_req_i.haddr;
size_q <= ahb_s_req_i.hsize[1:0];
end
if (state_q == S_NONSEQ_WRITE || state_q == S_SEQ_WRITE) wdata_q <= wdata_d;
end
end

Expand Down
Loading

0 comments on commit 66dc8f9

Please sign in to comment.