Skip to content

Commit cd43ee5

Browse files
adding back obi2ahbm example
1 parent 42f76f4 commit cd43ee5

File tree

2 files changed

+283
-0
lines changed

2 files changed

+283
-0
lines changed
452 KB
Binary file not shown.
Lines changed: 283 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,283 @@
1+
// Copyright 2023 Intrinsix Corp.
2+
// SPDX-License-Identifier: Apache-2.0 WITH SHL-2.0
3+
4+
// ============================================================================
5+
//
6+
// Description : OBI to AHB-Lite Master Adaptor
7+
// This adapter accepts OBI v1.5.0 transfers and translates them into
8+
// AHB-lite (ARM IHI 0033C) transfers.
9+
10+
module obi2ahbm_adapter (
11+
// Clock and reset
12+
input hclk_i, // (I) AHB clock
13+
input hresetn_i, // (I) AHB reset, active LOW
14+
15+
// AHB master interface
16+
output logic [31:0] haddr_o, // (O) 32-bit AHB system address bus
17+
output logic [2:0] hburst_o, // (O) Burst type
18+
output logic hmastlock_o, // (O) Sequence lock
19+
output logic [3:0] hprot_o, // (O) Protection control
20+
output logic [2:0] hsize_o, // (O) Transfer size
21+
output logic [1:0] htrans_o, // (O) Transfer type
22+
output logic [31:0] hwdata_o, // (O) 32-bit AHB write data bus
23+
output logic hwrite_o, // (O) Transfer direction
24+
input logic [31:0] hrdata_i, // (I) 32-bit AHB read data bus
25+
input logic hready_i, // (I) Status of transfer
26+
input logic hresp_i, // (I) Transfer response
27+
28+
// Data interface from core
29+
input logic data_req_i, // (I) Request ready
30+
output logic data_gnt_o, // (O) The other side accepted the request
31+
output logic data_rvalid_o, // (O) Read data valid when high
32+
input logic data_we_i, // (I) Write enable (active HIGH)
33+
input logic [3:0] data_be_i, // (I) Byte enable
34+
input logic [31:0] data_addr_i, // (I) Address
35+
input logic [31:0] data_wdata_i, // (I) Write data
36+
output logic [31:0] data_rdata_o, // (O) Read data
37+
output logic data_err_o, // (O) Error
38+
input logic pending_dbus_xfer_i, // (I) Asserted if data bus is busy from other transactions
39+
40+
// Miscellaneous
41+
input logic priv_mode_i // (I) Privilege mode (from core. 1=machine mode, 0=user mode)
42+
);
43+
44+
// ********** //
45+
// Parameters //
46+
// ********** //
47+
parameter HPROT_NONCACHEABLE = 1'b0;
48+
parameter HPROT_NONBUFFERABLE = 1'b0;
49+
parameter HPROT_DATAACCESS = 1'b1;
50+
51+
parameter MACHINE_MODE = 1'b1;
52+
53+
parameter HBURST_SINGLE = 3'b000;
54+
55+
parameter TIE_LO = 1'b0;
56+
57+
parameter AHB_FSM_WAIT = 2'b00;
58+
parameter AHB_FSM_DATA = 2'b10;
59+
60+
// ********** //
61+
// Wires/Regs //
62+
// ********** //
63+
64+
logic [1:0] ahb_fsm_reg;
65+
logic [1:0] ahb_fsm_reg_nxt;
66+
67+
logic [31:0] haddr_m_reg;
68+
logic [3:0] hprot_m_reg;
69+
logic [2:0] hsize_m_reg;
70+
logic hwrite_m_reg;
71+
72+
73+
logic data_err_o_nxt;
74+
75+
logic [31:0] data_rdata_o_reg;
76+
77+
logic [31:0] hwdata_m_nxt;
78+
79+
logic prev_data_gnt_o;
80+
// ********************** //
81+
// Continuous assignments //
82+
// ********************** //
83+
84+
// These signals are unused, so OK that they are tied to a constant
85+
// lint_checking TIELOG off
86+
// Only single bursts are supported
87+
assign hburst_o = HBURST_SINGLE;
88+
89+
// hmastlock_o is not used, so it is tied low
90+
assign hmastlock_o = TIE_LO;
91+
// lint_checking TIELOG on
92+
93+
// A grant should only happen on a request, and if the AHB side is ready
94+
// to respond. Don't initiate an AHB xfer if the data bus is busy from
95+
// other pending xfers
96+
assign data_gnt_o = hready_i && data_req_i && !pending_dbus_xfer_i;
97+
98+
// The valid signal should only assert when transitioning to the DATA state
99+
assign data_rvalid_o = ahb_fsm_reg == AHB_FSM_DATA ? hready_i : 1'b0;
100+
101+
// ************* //
102+
// Clocked Logic //
103+
// ************* //
104+
always @ (posedge hclk_i or negedge hresetn_i) begin
105+
if (!hresetn_i) begin
106+
data_err_o <= 1'b0;
107+
data_rdata_o_reg <= 32'h00000000;
108+
109+
haddr_m_reg <= 32'h00000000;
110+
hprot_m_reg <= {HPROT_NONCACHEABLE, HPROT_NONBUFFERABLE, MACHINE_MODE, HPROT_DATAACCESS};
111+
hsize_m_reg <= 3'b000;
112+
113+
// Write data needs to come one cycle after per AHB protocol
114+
hwdata_o <= 32'h00000000;
115+
116+
hwrite_m_reg <= 1'b0;
117+
118+
ahb_fsm_reg <= AHB_FSM_WAIT;
119+
120+
prev_data_gnt_o <= 1'b0;
121+
end
122+
else begin
123+
data_err_o <= data_err_o_nxt;
124+
data_rdata_o_reg <= data_rdata_o;
125+
126+
haddr_m_reg <= haddr_o;
127+
hprot_m_reg <= hprot_o;
128+
hsize_m_reg <= hsize_o;
129+
130+
hwdata_o <= hwdata_m_nxt;
131+
132+
hwrite_m_reg <= hwrite_o;
133+
134+
ahb_fsm_reg <= ahb_fsm_reg_nxt;
135+
if (!data_rvalid_o) begin
136+
prev_data_gnt_o <= data_gnt_o | prev_data_gnt_o;
137+
end else begin
138+
prev_data_gnt_o <= data_gnt_o;
139+
end
140+
end
141+
end
142+
143+
144+
// ******************* //
145+
// Combinational Logic //
146+
// ******************* //
147+
// Signal that the current request errored out and the read is invalid if
148+
// an AHB error response is received
149+
assign data_err_o_nxt = hresp_i;
150+
151+
//AHB Logic
152+
always_comb begin
153+
hprot_o = hprot_m_reg;
154+
haddr_o = haddr_m_reg;
155+
hwrite_o = hwrite_m_reg;
156+
// lint_checking TIELOG off
157+
// If htrans_m is not driven to non-seq while data_gnt_o is set
158+
// then it should be idle and set to (2'b00)
159+
htrans_o = 2'b00;
160+
// lint_checking TIELOG on
161+
hwdata_m_nxt = hwdata_o;
162+
hsize_o = hsize_m_reg;
163+
164+
unique case (ahb_fsm_reg)
165+
AHB_FSM_WAIT: begin
166+
// Idles until data_gnt_o is received
167+
// Once data_gnt_o is received, this is the address phase of AHB
168+
// and all ahb signals are fed through from the core
169+
if (data_gnt_o) begin
170+
// lint_checking TIELOG off
171+
// Non-bufferable, non-cacheable data accesses are supported. The
172+
// privilege bit, hprot_o[1], is driven by the privilege mode
173+
// that the core is currently in (1 for machine, 0 for user)
174+
hprot_o = {HPROT_NONCACHEABLE, HPROT_NONBUFFERABLE, priv_mode_i, HPROT_DATAACCESS};
175+
// lint_checking TIELOG on
176+
177+
// The address, transfer request, and write enable can be fed
178+
// through from the core to the corresponding AHB signals. For
179+
// htrans_o, if data_gnt_o is given, the ahb is in address phase,
180+
// and the transaction is non-sequential (1'b10).
181+
haddr_o = data_addr_i;
182+
hwrite_o = data_we_i;
183+
184+
// lint_checking TIELOG off
185+
htrans_o = 2'b10;
186+
// lint_checking TIELOG on
187+
188+
// Write data needs to be in data phase (After data_gnt_o is de-asserted)
189+
// So the data fromthe core is registered to save it for completing the transaction
190+
hwdata_m_nxt = data_wdata_i;
191+
192+
// lint_checking TIELOG off
193+
// Only word (32-bit), half-word (16-bit), or byte (8-bit)
194+
// aligned transfers are supported. Invalid responses default to
195+
hsize_o[2] = TIE_LO;
196+
// lint_checking TIELOG on
197+
hsize_o[1] = &data_be_i;
198+
hsize_o[0] = (data_be_i[3] & data_be_i[2]) ^ (data_be_i[1] & data_be_i[0]);
199+
end
200+
end
201+
AHB_FSM_DATA: begin
202+
// DATA phase
203+
// read data is fed through from the core
204+
data_rdata_o = hrdata_i;
205+
206+
// If data_gnt_o is also given during the data phase, then it is also
207+
// the subsequent address phase, so the necessary signals get
208+
// passed through from the core
209+
if (data_gnt_o) begin
210+
// lint_checking TIELOG off
211+
// Non-bufferable, non-cacheable data accesses are supported. The
212+
// privilege bit, hprot_o[1], is driven by the privilege mode
213+
// that the core is currently in (1 for machine, 0 for user)
214+
hprot_o = {HPROT_NONCACHEABLE, HPROT_NONBUFFERABLE, priv_mode_i, HPROT_DATAACCESS};
215+
// lint_checking TIELOG on
216+
// The address, transfer request, and write enable can be fed
217+
// through from the core to the corresponding AHB signals. For
218+
// htrans_o, if data_gnt_o is given, the ahb is in address phase,
219+
// and the transaction is non-sequential (1'b10).
220+
haddr_o = data_addr_i;
221+
hwrite_o = data_we_i;
222+
223+
// lint_checking TIELOG off
224+
htrans_o = 2'b10;
225+
// lint_checking TIELOG on
226+
227+
// Write data needs to be in data phase (After data_gnt_o is de-asserted)
228+
// So the data fromthe core is registered to save it for completing the transaction
229+
hwdata_m_nxt = data_wdata_i;
230+
231+
// lint_checking TIELOG off
232+
// Only word (32-bit), half-word (16-bit), or byte (8-bit)
233+
// aligned transfers are supported. Invalid responses default to
234+
hsize_o[2] = TIE_LO;
235+
// lint_checking TIELOG on
236+
hsize_o[1] = &data_be_i;
237+
hsize_o[0] = (data_be_i[3] & data_be_i[2]) ^ (data_be_i[1] & data_be_i[0]);
238+
end
239+
end
240+
default: begin
241+
hprot_o = {HPROT_NONCACHEABLE, HPROT_NONBUFFERABLE, priv_mode_i, HPROT_DATAACCESS};
242+
haddr_o = data_addr_i;
243+
hwrite_o = data_we_i;
244+
htrans_o = 2'b00;
245+
hsize_o = {TIE_LO,TIE_LO,TIE_LO};
246+
end
247+
endcase
248+
end
249+
250+
//FSM
251+
always_comb begin
252+
253+
ahb_fsm_reg_nxt = ahb_fsm_reg;
254+
255+
unique case (ahb_fsm_reg)
256+
// IDLE/ADDRESS phase
257+
// Waits until "ADDRESS Phase" occurs during data_gnt_o
258+
AHB_FSM_WAIT: begin
259+
if (data_gnt_o) begin
260+
ahb_fsm_reg_nxt = AHB_FSM_DATA;
261+
end
262+
end
263+
// DATA/ADDRESS phase
264+
// DATA phase for alread started transaction.
265+
// If data_gnt_o it is also the ADDRESS phase for the next set of data so it stays
266+
// in the data phase on the next cycle
267+
AHB_FSM_DATA: begin
268+
if (data_rvalid_o) begin
269+
if (data_gnt_o) begin
270+
ahb_fsm_reg_nxt = AHB_FSM_DATA;
271+
end else begin
272+
ahb_fsm_reg_nxt = AHB_FSM_WAIT;
273+
end
274+
end
275+
end
276+
default: begin
277+
ahb_fsm_reg_nxt = ahb_fsm_reg;
278+
end
279+
endcase
280+
end
281+
// lint_checking TRNMBT on
282+
// lint_checking HASUPC on
283+
endmodule : obi2ahbm_adapter

0 commit comments

Comments
 (0)