Skip to content

Commit 17ffbaa

Browse files
committed
OBI: Fix missing intf definition. Adjust coding style. #157
1 parent 0c29f9a commit 17ffbaa

File tree

6 files changed

+132
-72
lines changed

6 files changed

+132
-72
lines changed

docs/cpuif/obi.rst

Lines changed: 18 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,18 @@
1+
Open Bus Interface (OBI)
2+
========================
3+
4+
Implements the register block using an `OBI <https://github.com/openhwgroup/obi>`_
5+
CPU interface.
6+
7+
The OBI interface comes in two i/o port flavors:
8+
9+
SystemVerilog Interface
10+
* Command line: ``--cpuif obi``
11+
* Interface Definition: :download:`obi_intf.sv <../../hdl-src/obi_intf.sv>`
12+
* Class: :class:`peakrdl_regblock.cpuif.obi.OBI_Cpuif`
13+
14+
Flattened inputs/outputs
15+
Flattens the interface into discrete input and output ports.
16+
17+
* Command line: ``--cpuif obi-flat``
18+
* Class: :class:`peakrdl_regblock.cpuif.obi.OBI_Cpuif_flattened`

docs/index.rst

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -62,6 +62,7 @@ Links
6262
cpuif/apb
6363
cpuif/axi4lite
6464
cpuif/avalon
65+
cpuif/obi
6566
cpuif/passthrough
6667
cpuif/internal_protocol
6768
cpuif/customizing

hdl-src/obi_intf.sv

Lines changed: 51 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,51 @@
1+
interface obi_intf #(
2+
parameter DATA_WIDTH = 32,
3+
parameter ADDR_WIDTH = 32,
4+
parameter ID_WIDTH = 1
5+
);
6+
logic req;
7+
logic gnt;
8+
logic [ADDR_WIDTH-1:0] addr;
9+
logic we;
10+
logic [DATA_WIDTH/8-1:0] be;
11+
logic [DATA_WIDTH-1:0] wdata;
12+
logic [ID_WIDTH-1:0] aid;
13+
14+
logic rvalid;
15+
logic rready;
16+
logic [DATA_WIDTH-1:0] rdata;
17+
logic err;
18+
logic [ID_WIDTH-1:0] rid;
19+
20+
modport manager (
21+
output req,
22+
input gnt,
23+
output addr,
24+
output we,
25+
output be,
26+
output wdata,
27+
output aid,
28+
29+
input rvalid,
30+
output rready,
31+
input rdata,
32+
input err,
33+
input rid
34+
);
35+
36+
modport subordinate (
37+
input req,
38+
output gnt,
39+
input addr,
40+
input we,
41+
input be,
42+
input wdata,
43+
input aid,
44+
45+
output rvalid,
46+
input rready,
47+
output rdata,
48+
output err,
49+
output rid
50+
);
51+
endinterface

src/peakrdl_regblock/cpuif/base.py

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -37,8 +37,8 @@ def port_declaration(self) -> str:
3737
@property
3838
def parameters(self) -> List[str]:
3939
"""
40-
Optional list of additional parameters this CPU interface provides to
41-
the module's definition
40+
Optional list of additional parameter declarations this CPU interface
41+
provides to the module's definition
4242
"""
4343
return []
4444

src/peakrdl_regblock/cpuif/obi/__init__.py

Lines changed: 9 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -1,3 +1,5 @@
1+
from typing import List
2+
13
from ..base import CpuifBase
24

35
class OBI_Cpuif(CpuifBase):
@@ -32,25 +34,25 @@ def port_declaration(self) -> str:
3234
lines = [
3335
# OBI Request Channel (A)
3436
"input wire " + self.signal("req"),
37+
"output logic " + self.signal("gnt"),
3538
f"input wire [{self.addr_width-1}:0] " + self.signal("addr"),
3639
"input wire " + self.signal("we"),
3740
f"input wire [{self.data_width//8-1}:0] " + self.signal("be"),
3841
f"input wire [{self.data_width-1}:0] " + self.signal("wdata"),
39-
f"input wire [{self.id_width-1}:0] " + self.signal("aid"),
40-
42+
"input wire [ID_WIDTH-1:0] " + self.signal("aid"),
43+
4144
# OBI Response Channel (R)
42-
"output logic " + self.signal("gnt"),
4345
"output logic " + self.signal("rvalid"),
46+
"input wire " + self.signal("rready"),
4447
f"output logic [{self.data_width-1}:0] " + self.signal("rdata"),
45-
f"output logic [{self.id_width-1}:0] " + self.signal("rid"),
4648
"output logic " + self.signal("err"),
47-
"input wire " + self.signal("rready"),
49+
"output logic [ID_WIDTH-1:0] " + self.signal("rid"),
4850
]
4951
return ",\n".join(lines)
5052

5153
def signal(self, name: str) -> str:
5254
return "obi_" + name
5355

5456
@property
55-
def id_width(self) -> int:
56-
return 1 # Default ID width
57+
def parameters(self) -> List[str]:
58+
return ["parameter ID_WIDTH = 1"]

src/peakrdl_regblock/cpuif/obi/obi_tmpl.sv

Lines changed: 51 additions & 63 deletions
Original file line numberDiff line numberDiff line change
@@ -7,85 +7,73 @@
77
else $error("Interface data width of %0d is incorrect. Shall be %0d bits", $bits({{cpuif.signal("wdata")}}), {{ds.package_name}}::{{ds.module_name.upper()}}_DATA_WIDTH);
88
end
99
`endif
10-
{% endif -%}
11-
12-
// OBI Interface Implementation
13-
// This register block acts as an OBI subordinate
1410

15-
localparam int unsigned DATA_WIDTH = {{ds.package_name}}::{{ds.module_name.upper()}}_DATA_WIDTH;
16-
localparam int unsigned BYTES = DATA_WIDTH/8;
11+
{% endif -%}
1712

1813
// State & holding regs
19-
logic is_active; // A request is being served (not yet fully responded)
20-
logic gnt_q; // one-cycle grant for A-channel
21-
logic rsp_pending; // response ready but not yet accepted by manager
22-
logic [DATA_WIDTH-1:0] rsp_rdata_q;
23-
logic rsp_err_q;
24-
logic [$bits({{cpuif.signal("aid")}})-1:0] rid_q;
14+
logic is_active; // A request is being served (not yet fully responded)
15+
logic gnt_q; // one-cycle grant for A-channel
16+
logic rsp_pending; // response ready but not yet accepted by manager
17+
logic [{{cpuif.data_width-1}}:0] rsp_rdata_q;
18+
logic rsp_err_q;
19+
logic [$bits({{cpuif.signal("rid")}})-1:0] rid_q;
2520

2621
// Latch AID on accept to echo back the response
2722
always_ff {{get_always_ff_event(cpuif.reset)}} begin
28-
if ({{get_resetsignal(cpuif.reset)}}) begin
29-
is_active <= 1'b0;
30-
gnt_q <= 1'b0;
31-
rsp_pending <= 1'b0;
32-
rsp_rdata_q <= '0;
33-
rsp_err_q <= 1'b0;
34-
rid_q <= '0;
23+
if ({{get_resetsignal(cpuif.reset)}}) begin
24+
is_active <= 1'b0;
25+
gnt_q <= 1'b0;
26+
rsp_pending <= 1'b0;
27+
rsp_rdata_q <= '0;
28+
rsp_err_q <= 1'b0;
29+
rid_q <= '0;
3530

36-
cpuif_req <= '0;
37-
cpuif_req_is_wr <= '0;
38-
cpuif_addr <= '0;
39-
cpuif_wr_data <= '0;
40-
cpuif_wr_biten <= '0;
41-
end else begin
42-
// defaults
43-
cpuif_req <= 1'b0;
44-
gnt_q <= {{cpuif.signal("req")}} & ~is_active;
31+
cpuif_req <= '0;
32+
cpuif_req_is_wr <= '0;
33+
cpuif_addr <= '0;
34+
cpuif_wr_data <= '0;
35+
cpuif_wr_biten <= '0;
36+
end else begin
37+
// defaults
38+
cpuif_req <= 1'b0;
39+
gnt_q <= {{cpuif.signal("req")}} & ~is_active;
4540

46-
// Accept new request when idle
47-
if (~is_active) begin
48-
if ({{cpuif.signal("req")}}) begin
49-
is_active <= 1'b1;
50-
cpuif_req <= 1'b1;
51-
cpuif_req_is_wr <= {{cpuif.signal("we")}};
52-
cpuif_addr <= {{cpuif.signal("addr")}};
53-
cpuif_wr_data <= {{cpuif.signal("wdata")}};
54-
rid_q <= {{cpuif.signal("aid")}};
55-
for (int i = 0; i < BYTES; i++) begin
56-
cpuif_wr_biten[i*8 +: 8] <= {8{ {{cpuif.signal("be")}}[i] }};
41+
// Accept new request when idle
42+
if (~is_active) begin
43+
if ({{cpuif.signal("req")}}) begin
44+
is_active <= 1'b1;
45+
cpuif_req <= 1'b1;
46+
cpuif_req_is_wr <= {{cpuif.signal("we")}};
47+
cpuif_addr <= {{cpuif.signal("addr")}};
48+
cpuif_wr_data <= {{cpuif.signal("wdata")}};
49+
rid_q <= {{cpuif.signal("aid")}};
50+
for (int i = 0; i < {{cpuif.data_width_bytes}}; i++) begin
51+
cpuif_wr_biten[i*8 +: 8] <= {8{ {{cpuif.signal("be")}}[i] }};
52+
end
53+
end
5754
end
58-
end
59-
end
6055

61-
// Capture response
62-
if (is_active && (cpuif_rd_ack || cpuif_wr_ack)) begin
63-
rsp_pending <= 1'b1;
64-
rsp_rdata_q <= cpuif_rd_data;
65-
rsp_err_q <= cpuif_rd_err | cpuif_wr_err;
66-
// NOTE: Keep 'is_active' asserted until the external R handshake completes
67-
end
56+
// Capture response
57+
if (is_active && (cpuif_rd_ack || cpuif_wr_ack)) begin
58+
rsp_pending <= 1'b1;
59+
rsp_rdata_q <= cpuif_rd_data;
60+
rsp_err_q <= cpuif_rd_err | cpuif_wr_err;
61+
// NOTE: Keep 'is_active' asserted until the external R handshake completes
62+
end
6863

69-
// Complete external R-channel handshake only if manager ready
70-
if (rsp_pending && {{cpuif.signal("rvalid")}} && {{cpuif.signal("rready")}}) begin
71-
rsp_pending <= 1'b0;
72-
is_active <= 1'b0; // free to accept the next request
64+
// Complete external R-channel handshake only if manager ready
65+
if (rsp_pending && {{cpuif.signal("rvalid")}} && {{cpuif.signal("rready")}}) begin
66+
rsp_pending <= 1'b0;
67+
is_active <= 1'b0; // free to accept the next request
68+
end
7369
end
74-
end
7570
end
7671

7772
// R-channel outputs (held stable while rsp_pending=1)
7873
assign {{cpuif.signal("rvalid")}} = rsp_pending;
79-
assign {{cpuif.signal("rdata")}} = rsp_rdata_q;
80-
assign {{cpuif.signal("err")}} = rsp_err_q;
81-
assign {{cpuif.signal("rid")}} = rid_q;
74+
assign {{cpuif.signal("rdata")}} = rsp_rdata_q;
75+
assign {{cpuif.signal("err")}} = rsp_err_q;
76+
assign {{cpuif.signal("rid")}} = rid_q;
8277

8378
// A-channel grant (registered one-cycle pulse when we accept a request)
8479
assign {{cpuif.signal("gnt")}} = gnt_q;
85-
86-
// If OBI config RReady is disabled, tie it high in the top-level/TB.
87-
// `ifndef SYNTHESIS
88-
// initial begin
89-
// if (0) $display("RReady supported; tie high if unused.");
90-
// end
91-
// `endif

0 commit comments

Comments
 (0)