Skip to content

Commit 2dacd2c

Browse files
committed
PWM restructuring and resource reduction
Migrate the tlul_adapter_reg into the pwm_wrapper itself to clean the sonata_system top-level. Migrate the PWM logic into an ip folder of its own. Simplify the address decoding and the read data path (never used). Reduce the AccessLatency to zero because the PWM has never required a cycle of access latency anyway; it only supports writes. If reads are added later, the read data path should just be expressed combinationally without a register delay, since there is a register delay in the tlul_adapter_reg anyway.
1 parent 83685d8 commit 2dacd2c

File tree

6 files changed

+137
-139
lines changed

6 files changed

+137
-139
lines changed

rtl/ip/pwm/pwm.core

Lines changed: 21 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,21 @@
1+
CAPI=2:
2+
# Copyright lowRISC contributors.
3+
# Licensed under the Apache License, Version 2.0, see LICENSE for details.
4+
# SPDX-License-Identifier: Apache-2.0
5+
name: "lowrisc:ip:pwm:0.1"
6+
description: "PWM"
7+
filesets:
8+
files_rtl:
9+
depend:
10+
- lowrisc:prim:mubi
11+
- lowrisc:tlul:adapter_reg
12+
files:
13+
- rtl/pwm.sv
14+
- rtl/pwm_wrapper.sv
15+
file_type: systemVerilogSource
16+
17+
targets:
18+
default: &default_target
19+
filesets:
20+
- files_rtl
21+
toplevel: pwm_wrapper
File renamed without changes.

rtl/ip/pwm/rtl/pwm_wrapper.sv

Lines changed: 109 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,109 @@
1+
// Copyright lowRISC contributors.
2+
// Licensed under the Apache License, Version 2.0, see LICENSE for details.
3+
// SPDX-License-Identifier: Apache-2.0
4+
5+
// This wrapper instantiates a series of PWMs and distributes requests from the device bus.
6+
module pwm_wrapper #(
7+
parameter int unsigned PwmWidth = 12,
8+
parameter int unsigned PwmCtrSize = 8,
9+
parameter int unsigned DataWidth = 32,
10+
parameter int unsigned RegAddrWidth = 12
11+
) (
12+
input logic clk_i,
13+
input logic rst_ni,
14+
15+
// TileLink interface to registers.
16+
input tlul_pkg::tl_h2d_t tl_i,
17+
output tlul_pkg::tl_d2h_t tl_o,
18+
19+
// Collected output of all PWMs.
20+
output logic [PwmWidth-1:0] pwm_o
21+
);
22+
23+
localparam int unsigned PwmIdxOffset = $clog2(DataWidth / 8) + 1;
24+
localparam int unsigned PwmIdxWidth = RegAddrWidth - PwmIdxOffset;
25+
26+
// IO for device bus.
27+
logic [RegAddrWidth-1:0] device_addr;
28+
logic device_we;
29+
logic [DataWidth/8-1:0] device_be;
30+
logic [DataWidth-1:0] device_wdata;
31+
logic [DataWidth-1:0] device_rdata;
32+
33+
tlul_adapter_reg #(
34+
.AccessLatency ( 0 ),
35+
.RegAw ( RegAddrWidth )
36+
) pwm_device_adapter (
37+
.clk_i (clk_i),
38+
.rst_ni (rst_ni),
39+
40+
// TL-UL interface.
41+
.tl_i (tl_i),
42+
.tl_o (tl_o),
43+
44+
// Control interface.
45+
.en_ifetch_i (prim_mubi_pkg::MuBi4False),
46+
.intg_error_o (),
47+
48+
// Register interface.
49+
.re_o (), // Not readable.
50+
.we_o (device_we),
51+
.addr_o (device_addr),
52+
.wdata_o (device_wdata),
53+
.be_o (device_be),
54+
.busy_i ('0),
55+
.rdata_i (device_rdata),
56+
.error_i ('0)
57+
);
58+
59+
// Generate PwmWidth number of PWMs.
60+
for (genvar i = 0; i < PwmWidth; i++) begin : gen_pwm
61+
logic [PwmCtrSize-1:0] data_d;
62+
logic [PwmCtrSize-1:0] counter_q;
63+
logic [PwmCtrSize-1:0] pulse_width_q;
64+
logic counter_en;
65+
logic pulse_width_en;
66+
logic [PwmIdxWidth-1:0] pwm_idx;
67+
68+
assign pwm_idx = i;
69+
70+
// Byte enables are currently unsupported for PWM.
71+
assign data_d = device_wdata[PwmCtrSize-1:0]; // Only take PwmCtrSize LSBs.
72+
// Each PWM has a 64-bit block. The most significant 32 bits are the counter and the least
73+
// significant 32 bits are the pulse width.
74+
assign counter_en = device_we & (device_addr[RegAddrWidth-1:PwmIdxOffset] == pwm_idx)
75+
& device_addr[PwmIdxOffset-1];
76+
assign pulse_width_en = device_we & (device_addr[RegAddrWidth-1:PwmIdxOffset] == pwm_idx)
77+
& ~device_addr[PwmIdxOffset-1];
78+
79+
always @(posedge clk_i or negedge rst_ni) begin
80+
if (!rst_ni) begin
81+
counter_q <= '0;
82+
pulse_width_q <= '0;
83+
end else begin
84+
if (counter_en) begin
85+
counter_q <= data_d;
86+
end
87+
if (pulse_width_en) begin
88+
pulse_width_q <= data_d;
89+
end
90+
end
91+
end
92+
pwm #(
93+
.CtrSize( PwmCtrSize )
94+
) u_pwm (
95+
.clk_i (clk_i),
96+
.rst_ni (rst_ni),
97+
.pulse_width_i(pulse_width_q),
98+
.max_counter_i(counter_q),
99+
.modulated_o (pwm_o[i])
100+
);
101+
end : gen_pwm
102+
103+
// Generating the device bus output.
104+
// TODO: Reading from PWM currently not possible.
105+
assign device_rdata = '0;
106+
107+
logic _unused;
108+
assign _unused = ^{device_be, device_wdata};
109+
endmodule

rtl/system/pwm_wrapper.sv

Lines changed: 0 additions & 92 deletions
This file was deleted.

rtl/system/sonata_system.sv

Lines changed: 6 additions & 45 deletions
Original file line numberDiff line numberDiff line change
@@ -123,7 +123,6 @@ module sonata_system
123123
localparam int unsigned BusAddrWidth = 32;
124124
localparam int unsigned BusByteEnable = 4;
125125
localparam int unsigned BusDataWidth = 32;
126-
localparam int unsigned PRegAddrWidth = 8; // PWM uses only 8 bits of addressing.
127126
localparam int unsigned DRegAddrWidth = 12; // Debug module uses 12 bits of addressing.
128127
localparam int unsigned TRegAddrWidth = 16; // Timer uses more address bits.
129128
localparam int unsigned GRegAddrWidth = 9; // GPIO array uses 9 bits of addressing.
@@ -147,13 +146,12 @@ module sonata_system
147146
} bus_host_e;
148147

149148
typedef enum int {
150-
Pwm,
151149
Timer,
152150
RevTags,
153151
DbgDev
154152
} bus_device_e;
155153

156-
localparam int NrDevices = 4;
154+
localparam int NrDevices = 3;
157155
localparam int NrHosts = 2;
158156

159157
// Signals for hardware revoker
@@ -257,7 +255,6 @@ module sonata_system
257255
logic device_err [NrDevices];
258256

259257
// Generate requests from read and write enables.
260-
assign device_req[Pwm] = device_re[Pwm] | device_we[Pwm];
261258
assign device_req[Timer] = device_re[Timer] | device_we[Timer];
262259
assign device_req[DbgDev] = device_re[DbgDev] | device_we[DbgDev];
263260

@@ -284,9 +281,6 @@ module sonata_system
284281

285282
logic debug_req;
286283

287-
// Tie-off unused error signals.
288-
assign device_err[Pwm] = 1'b0;
289-
290284
//////////////////////////////////////////////
291285
// Instantiate TL-UL crossbar and adapters. //
292286
//////////////////////////////////////////////
@@ -623,34 +617,6 @@ module sonata_system
623617
// Set upper bits of address.
624618
assign device_addr[DbgDev][BusAddrWidth-1:DRegAddrWidth] = tl_ifetch_pkg::ADDR_SPACE_DBG_DEV[BusAddrWidth-1:DRegAddrWidth];
625619

626-
tlul_adapter_reg #(
627-
.AccessLatency ( 1 )
628-
) pwm_device_adapter (
629-
.clk_i (clk_sys_i),
630-
.rst_ni (rst_sys_ni),
631-
632-
// TL-UL interface.
633-
.tl_i (tl_pwm_h2d),
634-
.tl_o (tl_pwm_d2h),
635-
636-
// Control interface.
637-
.en_ifetch_i (prim_mubi_pkg::MuBi4False),
638-
.intg_error_o (),
639-
640-
// Register interface.
641-
.re_o (device_re[Pwm]),
642-
.we_o (device_we[Pwm]),
643-
.addr_o (device_addr[Pwm][PRegAddrWidth-1:0]),
644-
.wdata_o (device_wdata[Pwm]),
645-
.be_o (device_be[Pwm]),
646-
.busy_i ('0),
647-
.rdata_i (device_rdata[Pwm]),
648-
.error_i (device_err[Pwm])
649-
);
650-
651-
// Tie off upper bits of address.
652-
assign device_addr[Pwm][BusAddrWidth-1:PRegAddrWidth] = '0;
653-
654620
tlul_adapter_reg #(
655621
.RegAw ( TRegAddrWidth ),
656622
.AccessLatency ( 1 )
@@ -976,18 +942,13 @@ module sonata_system
976942
.PwmWidth ( PWM_OUT_WIDTH ),
977943
.PwmCtrSize ( PwmCtrSize )
978944
) u_pwm (
979-
.clk_i (clk_sys_i),
980-
.rst_ni (rst_sys_ni),
945+
.clk_i (clk_sys_i),
946+
.rst_ni (rst_sys_ni),
981947

982-
.device_req_i (device_req[Pwm]),
983-
.device_addr_i (device_addr[Pwm]),
984-
.device_we_i (device_we[Pwm]),
985-
.device_be_i (device_be[Pwm]),
986-
.device_wdata_i (device_wdata[Pwm]),
987-
.device_rvalid_o (device_rvalid[Pwm]),
988-
.device_rdata_o (device_rdata[Pwm]),
948+
.tl_i (tl_pwm_h2d),
949+
.tl_o (tl_pwm_d2h),
989950

990-
.pwm_o (pwm_modulated)
951+
.pwm_o (pwm_modulated)
991952
);
992953

993954
// UARTs

sonata_system.core

Lines changed: 1 addition & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -17,6 +17,7 @@ filesets:
1717
- lowrisc:ip:xbar_ifetch
1818
- lowrisc:ip:spi
1919
- lowrisc:ip:gpio
20+
- lowrisc:ip:pwm
2021
- lowrisc:ip:rev_ctl
2122
- lowrisc:ip:rgbled_ctrl
2223
- lowrisc:ip:hyperram
@@ -34,8 +35,6 @@ filesets:
3435
- rtl/system/dm_top.sv
3536
- rtl/system/debounce.sv
3637
- rtl/system/pinmux.sv
37-
- rtl/system/pwm.sv
38-
- rtl/system/pwm_wrapper.sv
3938
- rtl/system/pwm_fade.sv
4039
- rtl/system/sram.sv
4140
- rtl/system/rst_sync.sv

0 commit comments

Comments
 (0)