Skip to content

Commit 0f244e8

Browse files
committed
Replace scatter unit and gather unit in softUgnDemo with ringbuffers
1 parent 7afc39e commit 0f244e8

14 files changed

Lines changed: 372 additions & 213 deletions

File tree

bittide-instances/src/Bittide/Instances/Hitl/SoftUgnDemo/Core.hs

Lines changed: 15 additions & 26 deletions
Original file line numberDiff line numberDiff line change
@@ -7,11 +7,10 @@ import Clash.Explicit.Prelude
77
import Clash.Prelude (HiddenClockResetEnable, withClockResetEnable)
88
import Protocols
99

10-
import Bittide.Calendar (CalendarConfig (..), ValidEntry (..))
1110
import Bittide.CaptureUgn (captureUgn)
1211
import Bittide.ClockControl (SpeedChange)
1312
import Bittide.ClockControl.CallistoSw (SwcccInternalBusses, callistoSwClockControlC)
14-
import Bittide.DoubleBufferedRam (wbStorage)
13+
import Bittide.DoubleBufferedRam (blockRamByteAddressableU, wbStorage)
1514
import Bittide.ElasticBuffer (xilinxElasticBufferWb)
1615
import Bittide.Instances.Domains (Basic125, Bittide, GthRx)
1716
import Bittide.Instances.Hitl.Setup (LinkCount)
@@ -23,7 +22,7 @@ import Bittide.ProcessingElement (
2322
RemainingBusWidth,
2423
processingElement,
2524
)
26-
import Bittide.ScatterGather
25+
import Bittide.Ringbuffer (receiveRingbufferWb, transmitRingbufferWb)
2726
import Bittide.SharedTypes (Bitbone, BitboneMm)
2827
import Bittide.Sync (Sync)
2928
import Bittide.Wishbone (readDnaPortE2WbWorker, timeWb, uartBytes, uartInterfaceWb)
@@ -56,12 +55,10 @@ type NmuInternalBusses = 3 + PeInternalBusses
5655
{- Busses per link:
5756
- UGN component
5857
- Elastic buffer
59-
- Scatter unit
60-
- Scatter calendar
61-
- Gather unit
62-
- Gather calendar
58+
- Receive ringbuffer
59+
- Transmit ringbuffer
6360
-}
64-
type PeripheralsPerLink = 6
61+
type PeripheralsPerLink = 4
6562

6663
{- External busses:
6764
- Transceivers
@@ -176,8 +173,8 @@ core (refClk, refRst) (bitClk, bitRst, bitEna) rxClocks rxResets =
176173
withBittideClockResetEnable managementUnit localCounter maybeDna -< (muMm, muJtag)
177174
(ugnWbs, muWbs1) <- Vec.split -< muWbAll
178175
(ebWbs, muWbs2) <- Vec.split -< muWbs1
179-
(scatterBusses, scatterCalendarBusses, muWbs3) <- Vec.split3 -< muWbs2
180-
(gatherBusses, gatherCalendarBusses, muWbs4) <- Vec.split3 -< muWbs3
176+
(rxBufferBusses, muWbs3) <- Vec.split -< muWbs2
177+
(txBufferBusses, muWbs4) <- Vec.split -< muWbs3
181178
[muTransceiverBus, muCallistoBus] <- idC -< muWbs4
182179
-- Stop management unit
183180

@@ -198,33 +195,25 @@ core (refClk, refRst) (bitClk, bitRst, bitEna) rxClocks rxResets =
198195

199196
-- Use of `dflipflop` to add pipelining should be replaced by
200197
-- https://github.com/bittide/bittide-hardware/pull/1134
201-
Fwd rxs2 <-
198+
rxs2 <-
202199
withBittideClockResetEnable
203200
$ Vec.vecCircuits ((captureUgn localCounter . dflipflop bitClk) <$> rxs1)
204201
-< ugnWbs
205202
-- Stop internal links
206203

207204
-- Start ringbuffers
208205
let
209-
maxCalDepth = SNat @4000
210-
scatterConfig = ScatterConfig maxCalDepth (CalendarConfig maxCalDepth repetitionBits sgCal sgCal)
211-
gatherConfig = GatherConfig maxCalDepth (CalendarConfig maxCalDepth repetitionBits sgCal sgCal)
212-
repetitionBits = d16
213-
sgCal = ValidEntry 0 (snatToNum maxCalDepth - 1) :> Nil
214-
215-
scatterCalendarBussesDelayed <-
216-
repeatC (fmapC $ withBittideClockResetEnable delayWishbone) -< scatterCalendarBusses
217-
gatherCalendarBussesDelayed <-
218-
repeatC (fmapC $ withBittideClockResetEnable delayWishbone) -< gatherCalendarBusses
206+
bufferDepth = SNat @4000
207+
rxPrim ena = blockRamU bitClk bitRst ena NoClearOnReset bufferDepth
208+
txPrim ena = withClockResetEnable bitClk bitRst ena blockRamByteAddressableU
219209

220210
idleSink
221-
<| Vec.vecCircuits (fmap (withBittideClockResetEnable (scatterUnitWbC scatterConfig)) rxs2)
211+
<| fmapC (withBittideClockResetEnable receiveRingbufferWb rxPrim bufferDepth)
222212
<| Vec.zip
223-
-< (scatterBusses, scatterCalendarBussesDelayed)
213+
-< (rxBufferBusses, rxs2)
224214
Fwd txs <-
225-
repeatC (withBittideClockResetEnable (gatherUnitWbC gatherConfig))
226-
<| Vec.zip
227-
-< (gatherBusses, gatherCalendarBussesDelayed)
215+
fmapC (withBittideClockResetEnable transmitRingbufferWb txPrim bufferDepth) -< txBufferBusses
216+
228217
-- Stop ringbuffers
229218

230219
-- Start clock control

bittide/src/Bittide/DoubleBufferedRam.hs

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -7,7 +7,7 @@ module Bittide.DoubleBufferedRam where
77

88
import Clash.Prelude
99

10-
import Protocols (ToConstBwd, Circuit, toSignals, (<|))
10+
import Protocols (Circuit, ToConstBwd, toSignals, (<|))
1111
import Protocols.Wishbone
1212

1313
import Bittide.Extra.Maybe

firmware-binaries/demos/soft-ugn-mu/src/main.c

Lines changed: 17 additions & 15 deletions
Original file line numberDiff line numberDiff line change
@@ -5,10 +5,10 @@
55
#include "hals/soft_ugn_demo_mu/device_instances.h"
66

77
#include "bittide_dna.h"
8-
#include "bittide_gather.h" // Linter says we dont need this include, but we do
9-
#include "bittide_scatter.h" // Linter says we dont need this include, but we do
8+
#include "bittide_ring_receive.h"
9+
#include "bittide_ring_transmit.h"
1010
#include "bittide_timer.h"
11-
#include "bittide_ugn.h" // Requires the `bittide_scatter.h` and `bittide_gather.h`
11+
#include "bittide_ugn.h"
1212

1313
#include "messages.h"
1414
#include "priority_queue.h"
@@ -21,7 +21,6 @@
2121
// Application Configuration
2222
// ============================================================================
2323

24-
ScatterUnit su;
2524
// Number of event loop iterations
2625
#define NUM_PERIODS 1000
2726
#define NUM_PORTS 7
@@ -57,15 +56,17 @@ int c_main(void) {
5756
// Initialize all peripherals
5857

5958
Uart uart = hal.uart;
60-
ScatterUnit scatter_units[NUM_PORTS] = {
61-
hal.scatter_unit_0, hal.scatter_unit_1, hal.scatter_unit_2,
62-
hal.scatter_unit_3, hal.scatter_unit_4, hal.scatter_unit_5,
63-
hal.scatter_unit_6};
64-
65-
GatherUnit gather_units[NUM_PORTS] = {hal.gather_unit_0, hal.gather_unit_1,
66-
hal.gather_unit_2, hal.gather_unit_3,
67-
hal.gather_unit_4, hal.gather_unit_5,
68-
hal.gather_unit_6};
59+
ReceiveRingbuffer receive_ringbuffers[NUM_PORTS] = {
60+
hal.receive_ringbuffer_0, hal.receive_ringbuffer_1,
61+
hal.receive_ringbuffer_2, hal.receive_ringbuffer_3,
62+
hal.receive_ringbuffer_4, hal.receive_ringbuffer_5,
63+
hal.receive_ringbuffer_6};
64+
65+
TransmitRingbuffer transmit_ringbuffers[NUM_PORTS] = {
66+
hal.transmit_ringbuffer_0, hal.transmit_ringbuffer_1,
67+
hal.transmit_ringbuffer_2, hal.transmit_ringbuffer_3,
68+
hal.transmit_ringbuffer_4, hal.transmit_ringbuffer_5,
69+
hal.transmit_ringbuffer_6};
6970
Timer timer = hal.timer;
7071
dna_t dna;
7172
dna_read(hal.dna, dna);
@@ -84,8 +85,9 @@ int c_main(void) {
8485
UgnEdge outgoing_link_ugn_list[NUM_PORTS];
8586

8687
UgnContext ugn_ctx;
87-
ugn_context_init(&ugn_ctx, scatter_units, gather_units, NUM_PORTS, node_id,
88-
incoming_link_ugn_list, outgoing_link_ugn_list, NUM_PORTS);
88+
ugn_context_init(&ugn_ctx, receive_ringbuffers, transmit_ringbuffers,
89+
NUM_PORTS, node_id, incoming_link_ugn_list,
90+
outgoing_link_ugn_list, NUM_PORTS);
8991

9092
// Print consolidated initialization information
9193
PRINT_INIT_INFO(uart, &ugn_ctx, BUFFER_SIZE, SEND_PERIOD, RECEIVE_PERIOD,

firmware-binaries/demos/soft-ugn-mu/src/main.rs

Lines changed: 0 additions & 43 deletions
Original file line numberDiff line numberDiff line change
@@ -6,8 +6,6 @@
66
// SPDX-License-Identifier: Apache-2.0
77

88
use bittide_hal::hals::soft_ugn_demo_mu::DeviceInstances;
9-
use bittide_hal::manual_additions::calendar::RingbufferCalendar;
10-
use bittide_hal::shared_devices::Uart;
119
use bittide_sys::link_startup::LinkStartup;
1210
use bittide_sys::stability_detector::Stability;
1311
use core::panic::PanicInfo;
@@ -23,41 +21,6 @@ extern "C" {
2321
fn c_main() -> !;
2422
}
2523

26-
/// Initialize scatter and gather calendars with incrementing counter entries.
27-
/// Each calendar entry has a duration of 0 (no repeat), with 4000 entries total.
28-
#[no_mangle]
29-
#[inline(never)]
30-
fn initialize_calendars(uart: &mut Uart) {
31-
const NUM_ENTRIES: usize = 4000;
32-
33-
let calendars = [
34-
// Scatter calendars
35-
&INSTANCES.scatter_calendar_0,
36-
&INSTANCES.scatter_calendar_1,
37-
&INSTANCES.scatter_calendar_2,
38-
&INSTANCES.scatter_calendar_3,
39-
&INSTANCES.scatter_calendar_4,
40-
&INSTANCES.scatter_calendar_5,
41-
&INSTANCES.scatter_calendar_6,
42-
// Gather calendars
43-
&INSTANCES.gather_calendar_0,
44-
&INSTANCES.gather_calendar_1,
45-
&INSTANCES.gather_calendar_2,
46-
&INSTANCES.gather_calendar_3,
47-
&INSTANCES.gather_calendar_4,
48-
&INSTANCES.gather_calendar_5,
49-
&INSTANCES.gather_calendar_6,
50-
];
51-
uwriteln!(uart, " Initializing {} calendars", calendars.len()).unwrap();
52-
let mut i = 0;
53-
calendars.map(|cal| {
54-
cal.initialize_as_ringbuffer(NUM_ENTRIES);
55-
uwriteln!(uart, " Initialized calendar {}", i).unwrap();
56-
i += 1;
57-
});
58-
uwriteln!(uart, "All calendars initialized").unwrap();
59-
}
60-
6124
#[cfg_attr(not(test), entry)]
6225
fn main() -> ! {
6326
let mut uart = INSTANCES.uart;
@@ -135,12 +98,6 @@ fn main() -> ! {
13598
.unwrap();
13699
}
137100
uwriteln!(uart, "Printed all hardware UGNs").unwrap();
138-
139-
// Initialize scatter/gather calendars with incrementing counters
140-
uwriteln!(uart, "Initializing scatter/gather calendars").unwrap();
141-
initialize_calendars(&mut uart);
142-
uwriteln!(uart, "All calendars initialized").unwrap();
143-
144101
uwriteln!(uart, "Calling C..").unwrap();
145102
unsafe { c_main() }
146103
}

firmware-binaries/demos/soft-ugn-mu/src/ringbuffer_align.c

Lines changed: 26 additions & 28 deletions
Original file line numberDiff line numberDiff line change
@@ -4,8 +4,8 @@
44

55
#include "hals/soft_ugn_demo_mu/device_instances.h"
66

7-
#include "bittide_gather.h"
8-
#include "bittide_scatter.h"
7+
#include "bittide_ring_receive.h"
8+
#include "bittide_ring_transmit.h"
99
#include "bittide_timer.h"
1010
#include "bittide_uart.h"
1111
#include "bittide_ugn.h"
@@ -16,21 +16,21 @@
1616
#include "ringbuffer_align.h"
1717

1818
// ============================================================================
19-
// Gather Unit Functions (TX/Outgoing)
19+
// Transmit Ringbuffer Functions (TX/Outgoing)
2020
// ============================================================================
2121

22-
void ringbuffer_set_alignment(GatherUnit gather,
22+
void ringbuffer_set_alignment(TransmitRingbuffer tx_ring,
2323
enum RingbufferAlignState state) {
2424
uint64_t encoded_msg = (uint64_t)(state);
25-
gather_unit_set_gather_memory_unchecked(gather, 0,
26-
(uint8_t const *)&encoded_msg);
25+
transmit_ringbuffer_set_data_unchecked(tx_ring, 0,
26+
(uint8_t const *)&encoded_msg);
2727
}
2828

2929
// ============================================================================
30-
// Scatter Unit Functions (RX/Incoming)
30+
// Receive Ringbuffer Functions (RX/Incoming)
3131
// ============================================================================
3232

33-
bool ringbuffer_find_alignment(ScatterUnit scatter, int16_t buffer_size,
33+
bool ringbuffer_find_alignment(ReceiveRingbuffer rx_ring, int16_t buffer_size,
3434
int16_t *found_offset,
3535
enum RingbufferAlignState *found_state) {
3636
// Initialize outputs
@@ -39,11 +39,10 @@ bool ringbuffer_find_alignment(ScatterUnit scatter, int16_t buffer_size,
3939

4040
// Scan the entire ringbuffer
4141
for (int16_t rx_idx = 0; rx_idx < buffer_size; rx_idx++) {
42-
uint64_t scatter_data;
43-
scatter_unit_get_scatter_memory_unchecked(scatter, rx_idx,
44-
(uint8_t *)&scatter_data);
42+
uint64_t rx_data;
43+
receive_ringbuffer_get_data_unchecked(rx_ring, rx_idx, (uint8_t *)&rx_data);
4544

46-
enum RingbufferAlignState state = (enum RingbufferAlignState)(scatter_data);
45+
enum RingbufferAlignState state = (enum RingbufferAlignState)(rx_data);
4746

4847
// Check if we found an alignment message
4948
if (state == RINGBUFFER_ALIGN_ANNOUNCE ||
@@ -58,11 +57,10 @@ bool ringbuffer_find_alignment(ScatterUnit scatter, int16_t buffer_size,
5857
}
5958

6059
enum RingbufferAlignState
61-
ringbuffer_get_alignment_at_offset(ScatterUnit scatter, int16_t offset) {
62-
uint64_t scatter_data;
63-
scatter_unit_get_scatter_memory_unchecked(scatter, offset,
64-
(uint8_t *)&scatter_data);
65-
return (enum RingbufferAlignState)(scatter_data);
60+
ringbuffer_get_alignment_at_offset(ReceiveRingbuffer rx_ring, int16_t offset) {
61+
uint64_t rx_data;
62+
receive_ringbuffer_get_data_unchecked(rx_ring, offset, (uint8_t *)&rx_data);
63+
return (enum RingbufferAlignState)(rx_data);
6664
}
6765

6866
// ============================================================================
@@ -85,17 +83,17 @@ void align_ringbuffers(UgnContext *ugn_ctx, int16_t *incoming_offsets,
8583

8684
// Step 2: Initialize - Write ALIGNMENT_ANNOUNCE to TX index 0, clear rest
8785
for (int32_t port = 0; port < num_ports; port++) {
88-
GatherUnit gather = ugn_ctx->gather_units[port];
86+
TransmitRingbuffer tx_ring = ugn_ctx->transmit_ringbuffers[port];
8987

9088
// Clear rest of buffer
9189
uint64_t empty_msg = (uint64_t)(RINGBUFFER_ALIGN_EMPTY);
92-
for (int16_t i = 1; i < GATHER_UNIT_GATHER_MEMORY_LEN; i++) {
93-
gather_unit_set_gather_memory_unchecked(gather, i,
94-
(uint8_t const *)&empty_msg);
90+
for (int16_t i = 1; i < TRANSMIT_RINGBUFFER_DATA_LEN; i++) {
91+
transmit_ringbuffer_set_data_unchecked(tx_ring, i,
92+
(uint8_t const *)&empty_msg);
9593
}
9694

9795
// Write ALIGNMENT_ANNOUNCE at index 0
98-
ringbuffer_set_alignment(gather, RINGBUFFER_ALIGN_ANNOUNCE);
96+
ringbuffer_set_alignment(tx_ring, RINGBUFFER_ALIGN_ANNOUNCE);
9997
}
10098

10199
// ========================================================================
@@ -112,12 +110,12 @@ void align_ringbuffers(UgnContext *ugn_ctx, int16_t *incoming_offsets,
112110
continue; // Already found offset for this port
113111
}
114112

115-
ScatterUnit scatter = ugn_ctx->scatter_units[port];
113+
ReceiveRingbuffer rx_ring = ugn_ctx->receive_ringbuffers[port];
116114

117115
// Use the scan function to search for alignment messages
118116
int16_t found_offset;
119117
enum RingbufferAlignState found_state;
120-
if (ringbuffer_find_alignment(scatter, 4000, &found_offset,
118+
if (ringbuffer_find_alignment(rx_ring, 4000, &found_offset,
121119
&found_state)) {
122120
// Found message
123121
if (found_state == RINGBUFFER_ALIGN_ACKNOWLEDGE) {
@@ -149,8 +147,8 @@ void align_ringbuffers(UgnContext *ugn_ctx, int16_t *incoming_offsets,
149147

150148
// Change all outgoing messages to ACKNOWLEDGE
151149
for (int32_t port = 0; port < num_ports; port++) {
152-
GatherUnit gather = ugn_ctx->gather_units[port];
153-
ringbuffer_set_alignment(gather, RINGBUFFER_ALIGN_ACKNOWLEDGE);
150+
TransmitRingbuffer tx_ring = ugn_ctx->transmit_ringbuffers[port];
151+
ringbuffer_set_alignment(tx_ring, RINGBUFFER_ALIGN_ACKNOWLEDGE);
154152
}
155153

156154
// Wait for all partners to send ACKNOWLEDGE
@@ -163,11 +161,11 @@ void align_ringbuffers(UgnContext *ugn_ctx, int16_t *incoming_offsets,
163161
continue; // Already received ACK for this port
164162
}
165163

166-
ScatterUnit scatter = ugn_ctx->scatter_units[port];
164+
ReceiveRingbuffer rx_ring = ugn_ctx->receive_ringbuffers[port];
167165

168166
// Check at the known position for ACKNOWLEDGE
169167
enum RingbufferAlignState state =
170-
ringbuffer_get_alignment_at_offset(scatter, incoming_offsets[port]);
168+
ringbuffer_get_alignment_at_offset(rx_ring, incoming_offsets[port]);
171169

172170
if (state == RINGBUFFER_ALIGN_ACKNOWLEDGE) {
173171
received_ack[port] = true;

0 commit comments

Comments
 (0)