Skip to content
Draft
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
41 changes: 15 additions & 26 deletions bittide-instances/src/Bittide/Instances/Hitl/SoftUgnDemo/Core.hs
Original file line number Diff line number Diff line change
Expand Up @@ -7,11 +7,10 @@ import Clash.Explicit.Prelude
import Clash.Prelude (HiddenClockResetEnable, withClockResetEnable)
import Protocols

import Bittide.Calendar (CalendarConfig (..), ValidEntry (..))
import Bittide.CaptureUgn (captureUgn)
import Bittide.ClockControl (SpeedChange)
import Bittide.ClockControl.CallistoSw (SwcccInternalBusses, callistoSwClockControlC)
import Bittide.DoubleBufferedRam (wbStorage)
import Bittide.DoubleBufferedRam (blockRamByteAddressableU, wbStorage)
import Bittide.ElasticBuffer (xilinxElasticBufferWb)
import Bittide.Instances.Domains (Basic125, Bittide, GthRx)
import Bittide.Instances.Hitl.Setup (LinkCount)
Expand All @@ -23,7 +22,7 @@ import Bittide.ProcessingElement (
RemainingBusWidth,
processingElement,
)
import Bittide.ScatterGather
import Bittide.Ringbuffer (receiveRingbufferWb, transmitRingbufferWb)
import Bittide.SharedTypes (Bitbone, BitboneMm)
import Bittide.Sync (Sync)
import Bittide.Wishbone (readDnaPortE2WbWorker, timeWb, uartBytes, uartInterfaceWb)
Expand Down Expand Up @@ -56,12 +55,10 @@ type NmuInternalBusses = 3 + PeInternalBusses
{- Busses per link:
- UGN component
- Elastic buffer
- Scatter unit
- Scatter calendar
- Gather unit
- Gather calendar
- Receive ringbuffer
- Transmit ringbuffer
-}
type PeripheralsPerLink = 6
type PeripheralsPerLink = 4

{- External busses:
- Transceivers
Expand Down Expand Up @@ -176,8 +173,8 @@ core (refClk, refRst) (bitClk, bitRst, bitEna) rxClocks rxResets =
withBittideClockResetEnable managementUnit localCounter maybeDna -< (muMm, muJtag)
(ugnWbs, muWbs1) <- Vec.split -< muWbAll
(ebWbs, muWbs2) <- Vec.split -< muWbs1
(scatterBusses, scatterCalendarBusses, muWbs3) <- Vec.split3 -< muWbs2
(gatherBusses, gatherCalendarBusses, muWbs4) <- Vec.split3 -< muWbs3
(rxBufferBusses, muWbs3) <- Vec.split -< muWbs2
(txBufferBusses, muWbs4) <- Vec.split -< muWbs3
[muTransceiverBus, muCallistoBus] <- idC -< muWbs4
-- Stop management unit

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

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

-- Start ringbuffers
let
maxCalDepth = SNat @4000
scatterConfig = ScatterConfig maxCalDepth (CalendarConfig maxCalDepth repetitionBits sgCal sgCal)
gatherConfig = GatherConfig maxCalDepth (CalendarConfig maxCalDepth repetitionBits sgCal sgCal)
repetitionBits = d16
sgCal = ValidEntry 0 (snatToNum maxCalDepth - 1) :> Nil

scatterCalendarBussesDelayed <-
repeatC (fmapC $ withBittideClockResetEnable delayWishbone) -< scatterCalendarBusses
gatherCalendarBussesDelayed <-
repeatC (fmapC $ withBittideClockResetEnable delayWishbone) -< gatherCalendarBusses
bufferDepth = SNat @4000
rxPrim ena = blockRamU bitClk bitRst ena NoClearOnReset bufferDepth
txPrim ena = withClockResetEnable bitClk bitRst ena blockRamByteAddressableU

idleSink
<| Vec.vecCircuits (fmap (withBittideClockResetEnable (scatterUnitWbC scatterConfig)) rxs2)
<| fmapC (withBittideClockResetEnable receiveRingbufferWb rxPrim bufferDepth)
<| Vec.zip
-< (scatterBusses, scatterCalendarBussesDelayed)
-< (rxBufferBusses, rxs2)
Fwd txs <-
repeatC (withBittideClockResetEnable (gatherUnitWbC gatherConfig))
<| Vec.zip
-< (gatherBusses, gatherCalendarBussesDelayed)
fmapC (withBittideClockResetEnable transmitRingbufferWb txPrim bufferDepth) -< txBufferBusses

-- Stop ringbuffers

-- Start clock control
Expand Down
32 changes: 17 additions & 15 deletions firmware-binaries/demos/soft-ugn-mu/src/main.c
Original file line number Diff line number Diff line change
Expand Up @@ -5,10 +5,10 @@
#include "hals/soft_ugn_demo_mu/device_instances.h"

#include "bittide_dna.h"
#include "bittide_gather.h" // Linter says we dont need this include, but we do
#include "bittide_scatter.h" // Linter says we dont need this include, but we do
#include "bittide_ring_receive.h"
#include "bittide_ring_transmit.h"
#include "bittide_timer.h"
#include "bittide_ugn.h" // Requires the `bittide_scatter.h` and `bittide_gather.h`
#include "bittide_ugn.h"

#include "messages.h"
#include "priority_queue.h"
Expand All @@ -21,7 +21,6 @@
// Application Configuration
// ============================================================================

ScatterUnit su;
// Number of event loop iterations
#define NUM_PERIODS 1000
#define NUM_PORTS 7
Expand Down Expand Up @@ -57,15 +56,17 @@ int c_main(void) {
// Initialize all peripherals

Uart uart = hal.uart;
ScatterUnit scatter_units[NUM_PORTS] = {
hal.scatter_unit_0, hal.scatter_unit_1, hal.scatter_unit_2,
hal.scatter_unit_3, hal.scatter_unit_4, hal.scatter_unit_5,
hal.scatter_unit_6};

GatherUnit gather_units[NUM_PORTS] = {hal.gather_unit_0, hal.gather_unit_1,
hal.gather_unit_2, hal.gather_unit_3,
hal.gather_unit_4, hal.gather_unit_5,
hal.gather_unit_6};
ReceiveRingbuffer receive_ringbuffers[NUM_PORTS] = {
hal.receive_ringbuffer_0, hal.receive_ringbuffer_1,
hal.receive_ringbuffer_2, hal.receive_ringbuffer_3,
hal.receive_ringbuffer_4, hal.receive_ringbuffer_5,
hal.receive_ringbuffer_6};

TransmitRingbuffer transmit_ringbuffers[NUM_PORTS] = {
hal.transmit_ringbuffer_0, hal.transmit_ringbuffer_1,
hal.transmit_ringbuffer_2, hal.transmit_ringbuffer_3,
hal.transmit_ringbuffer_4, hal.transmit_ringbuffer_5,
hal.transmit_ringbuffer_6};
Timer timer = hal.timer;
dna_t dna;
dna_read(hal.dna, dna);
Expand All @@ -84,8 +85,9 @@ int c_main(void) {
UgnEdge outgoing_link_ugn_list[NUM_PORTS];

UgnContext ugn_ctx;
ugn_context_init(&ugn_ctx, scatter_units, gather_units, NUM_PORTS, node_id,
incoming_link_ugn_list, outgoing_link_ugn_list, NUM_PORTS);
ugn_context_init(&ugn_ctx, receive_ringbuffers, transmit_ringbuffers,
NUM_PORTS, node_id, incoming_link_ugn_list,
outgoing_link_ugn_list, NUM_PORTS);

// Print consolidated initialization information
PRINT_INIT_INFO(uart, &ugn_ctx, BUFFER_SIZE, SEND_PERIOD, RECEIVE_PERIOD,
Expand Down
43 changes: 0 additions & 43 deletions firmware-binaries/demos/soft-ugn-mu/src/main.rs
Original file line number Diff line number Diff line change
Expand Up @@ -6,8 +6,6 @@
// SPDX-License-Identifier: Apache-2.0

use bittide_hal::hals::soft_ugn_demo_mu::DeviceInstances;
use bittide_hal::manual_additions::calendar::RingbufferCalendar;
use bittide_hal::shared_devices::Uart;
use bittide_sys::link_startup::LinkStartup;
use bittide_sys::stability_detector::Stability;
use core::panic::PanicInfo;
Expand All @@ -23,41 +21,6 @@ extern "C" {
fn c_main() -> !;
}

/// Initialize scatter and gather calendars with incrementing counter entries.
/// Each calendar entry has a duration of 0 (no repeat), with 4000 entries total.
#[no_mangle]
#[inline(never)]
fn initialize_calendars(uart: &mut Uart) {
const NUM_ENTRIES: usize = 4000;

let calendars = [
// Scatter calendars
&INSTANCES.scatter_calendar_0,
&INSTANCES.scatter_calendar_1,
&INSTANCES.scatter_calendar_2,
&INSTANCES.scatter_calendar_3,
&INSTANCES.scatter_calendar_4,
&INSTANCES.scatter_calendar_5,
&INSTANCES.scatter_calendar_6,
// Gather calendars
&INSTANCES.gather_calendar_0,
&INSTANCES.gather_calendar_1,
&INSTANCES.gather_calendar_2,
&INSTANCES.gather_calendar_3,
&INSTANCES.gather_calendar_4,
&INSTANCES.gather_calendar_5,
&INSTANCES.gather_calendar_6,
];
uwriteln!(uart, " Initializing {} calendars", calendars.len()).unwrap();
let mut i = 0;
calendars.map(|cal| {
cal.initialize_as_ringbuffer(NUM_ENTRIES);
uwriteln!(uart, " Initialized calendar {}", i).unwrap();
i += 1;
});
uwriteln!(uart, "All calendars initialized").unwrap();
}

#[cfg_attr(not(test), entry)]
fn main() -> ! {
let mut uart = INSTANCES.uart;
Expand Down Expand Up @@ -135,12 +98,6 @@ fn main() -> ! {
.unwrap();
}
uwriteln!(uart, "Printed all hardware UGNs").unwrap();

// Initialize scatter/gather calendars with incrementing counters
uwriteln!(uart, "Initializing scatter/gather calendars").unwrap();
initialize_calendars(&mut uart);
uwriteln!(uart, "All calendars initialized").unwrap();

uwriteln!(uart, "Calling C..").unwrap();
unsafe { c_main() }
}
Expand Down
54 changes: 26 additions & 28 deletions firmware-binaries/demos/soft-ugn-mu/src/ringbuffer_align.c
Original file line number Diff line number Diff line change
Expand Up @@ -4,8 +4,8 @@

#include "hals/soft_ugn_demo_mu/device_instances.h"

#include "bittide_gather.h"
#include "bittide_scatter.h"
#include "bittide_ring_receive.h"
#include "bittide_ring_transmit.h"
#include "bittide_timer.h"
#include "bittide_uart.h"
#include "bittide_ugn.h"
Expand All @@ -16,21 +16,21 @@
#include "ringbuffer_align.h"

// ============================================================================
// Gather Unit Functions (TX/Outgoing)
// Transmit Ringbuffer Functions (TX/Outgoing)
// ============================================================================

void ringbuffer_set_alignment(GatherUnit gather,
void ringbuffer_set_alignment(TransmitRingbuffer tx_ring,
enum RingbufferAlignState state) {
uint64_t encoded_msg = (uint64_t)(state);
gather_unit_set_gather_memory_unchecked(gather, 0,
(uint8_t const *)&encoded_msg);
transmit_ringbuffer_set_data_unchecked(tx_ring, 0,
(uint8_t const *)&encoded_msg);
}

// ============================================================================
// Scatter Unit Functions (RX/Incoming)
// Receive Ringbuffer Functions (RX/Incoming)
// ============================================================================

bool ringbuffer_find_alignment(ScatterUnit scatter, int16_t buffer_size,
bool ringbuffer_find_alignment(ReceiveRingbuffer rx_ring, int16_t buffer_size,
int16_t *found_offset,
enum RingbufferAlignState *found_state) {
// Initialize outputs
Expand All @@ -39,11 +39,10 @@ bool ringbuffer_find_alignment(ScatterUnit scatter, int16_t buffer_size,

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

enum RingbufferAlignState state = (enum RingbufferAlignState)(scatter_data);
enum RingbufferAlignState state = (enum RingbufferAlignState)(rx_data);

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

enum RingbufferAlignState
ringbuffer_get_alignment_at_offset(ScatterUnit scatter, int16_t offset) {
uint64_t scatter_data;
scatter_unit_get_scatter_memory_unchecked(scatter, offset,
(uint8_t *)&scatter_data);
return (enum RingbufferAlignState)(scatter_data);
ringbuffer_get_alignment_at_offset(ReceiveRingbuffer rx_ring, int16_t offset) {
uint64_t rx_data;
receive_ringbuffer_get_data_unchecked(rx_ring, offset, (uint8_t *)&rx_data);
return (enum RingbufferAlignState)(rx_data);
}

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

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

// Clear rest of buffer
uint64_t empty_msg = (uint64_t)(RINGBUFFER_ALIGN_EMPTY);
for (int16_t i = 1; i < GATHER_UNIT_GATHER_MEMORY_LEN; i++) {
gather_unit_set_gather_memory_unchecked(gather, i,
(uint8_t const *)&empty_msg);
for (int16_t i = 1; i < TRANSMIT_RINGBUFFER_DATA_LEN; i++) {
transmit_ringbuffer_set_data_unchecked(tx_ring, i,
(uint8_t const *)&empty_msg);
}

// Write ALIGNMENT_ANNOUNCE at index 0
ringbuffer_set_alignment(gather, RINGBUFFER_ALIGN_ANNOUNCE);
ringbuffer_set_alignment(tx_ring, RINGBUFFER_ALIGN_ANNOUNCE);
}

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

ScatterUnit scatter = ugn_ctx->scatter_units[port];
ReceiveRingbuffer rx_ring = ugn_ctx->receive_ringbuffers[port];

// Use the scan function to search for alignment messages
int16_t found_offset;
enum RingbufferAlignState found_state;
if (ringbuffer_find_alignment(scatter, 4000, &found_offset,
if (ringbuffer_find_alignment(rx_ring, 4000, &found_offset,
&found_state)) {
// Found message
if (found_state == RINGBUFFER_ALIGN_ACKNOWLEDGE) {
Expand Down Expand Up @@ -149,8 +147,8 @@ void align_ringbuffers(UgnContext *ugn_ctx, int16_t *incoming_offsets,

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

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

ScatterUnit scatter = ugn_ctx->scatter_units[port];
ReceiveRingbuffer rx_ring = ugn_ctx->receive_ringbuffers[port];

// Check at the known position for ACKNOWLEDGE
enum RingbufferAlignState state =
ringbuffer_get_alignment_at_offset(scatter, incoming_offsets[port]);
ringbuffer_get_alignment_at_offset(rx_ring, incoming_offsets[port]);

if (state == RINGBUFFER_ALIGN_ACKNOWLEDGE) {
received_ack[port] = true;
Expand Down
Loading
Loading