diff --git a/hdl/ip/bsv/ignition/Ignition Controller Receiver.drawio.svg b/hdl/ip/bsv/ignition/Ignition Controller Receiver.drawio.svg new file mode 100644 index 00000000..93d652b5 --- /dev/null +++ b/hdl/ip/bsv/ignition/Ignition Controller Receiver.drawio.svg @@ -0,0 +1,4 @@ + + + +
Deserializer Mux
Write Back
Receive
Decode (8B10)
Wait
DeserializerChannel 0
deserializer_events_l2[0]
FIFO(1)
deserializer_events_l2[1]
FIFO(1)
deserializer_events_l2[8]
FIFO(1)
deserializer_events_l1[0]
FIFO(1)
DeserializerChannel 4
DeserializerChannel 7
DeserializerChannel 3
DeserializerEvent
DeserializerEvent
deserializer_events_l1[1]
FIFO(1)
deserializer_events_l1[2]
FIFO(1)
deserializer_events_l0
FIFO(1)
DeserializerChannel 36
DeserializerEvent
receive_state_1
deserializer_event
BRAM(ReceiveState1 x 36)
DeserializerEvent
decode(..)
Reg#(Maybe#(DeserializerEvent))
decoder_event
Reg#(Maybe#(DecoderEvent))
DecoderEvent
read(id)
Parse
parse(..)
receive_state_2
BRAM(ReceiveState2 x 36)
read(id)
parser_event
Reg#(Maybe#(ParserEvent))
ParserEvent
receive(..)
ReceiverEvent
receiver_events
BRAMFIFO(1023)
ReceiverEvent
Next Receiver State
Write(..)
Reg#(Maybe#(...))
Controller (N)
...
...
...
...
set_polarity_inverted(...)
set_search_for_comma(...)
request_reset()
Sampler 0
Sampler 3
Sampler 4
Sampler 7
Sampler 36
Receiver Watchdog
tick_1khz
receiver_locked
\ No newline at end of file diff --git a/hdl/ip/bsv/ignition/Ignition Controller.drawio.svg b/hdl/ip/bsv/ignition/Ignition Controller.drawio.svg new file mode 100644 index 00000000..be172cd6 --- /dev/null +++ b/hdl/ip/bsv/ignition/Ignition Controller.drawio.svg @@ -0,0 +1,4 @@ + + + +
receiver_events
3
N
.
.
.
.
.
.
.
TickEvent
0
1
2
.
.
.
.
Timer Wheel
Generates a TickEvent at 1Hz for each Controller ID, at even spaced intervals. This ensures no conflicting or overlapping TickEvents (ticks are offset in phase) and avoids dense bursts of events downstream of tick event driven logic.
ReceiverEvent
ControllerReceiver(N)
tick_events
software_request
SPI
SoftwareRequest
FIFO(1)
FIFO(1)
FIFO(1)
0
1
...
N
presence
0
1
...
N
transceiver
0
1
...
N
hello_timer
0
1
...
N
target_system_type
0
1
...
N
target_system_status
0
1
...
N
target_system_events
0
1
...
N
target_system_power_request_status
0
1
...
N
target_link0_status
0
1
...
N
target_link0_events
0
1
...
N
target_link1_status
0
1
...
N
target_link1_events
Register File
Controller ID
controller_id
ControllerID
event_handler_select
HandlingTickEvent
HandlingReceiverEvent
HandlingSoftwareRequest
AwaitingControllerDataValid
AwaitingEvent
  • Read event data
  • Read controller data from registers
  • Update controller data with event data
  • Write controller data back to registers
  • Enqueue software response or transceiver event
  • Update counters
  • Set controller_id from event
  • Set handler based on event source
  • Select registers for controller with ID

State

Event Handler Logic

Event Sources

software_response
FIFO(1)
SoftwareResponse
Events handled in urgency/probability of occurrence; software requests first, followed by ticks and receiver events.
transmitter_events
TransmitterEvent
FIFO(1)
TransmitterEvent
ControllerTransmitter (N)
Countable*Events
ControllerCounters

Event Sinks

\ No newline at end of file diff --git a/hdl/ip/bsv/ignition/IgnitionController.bsv b/hdl/ip/bsv/ignition/IgnitionController.bsv index 15be349f..a0126ba6 100644 --- a/hdl/ip/bsv/ignition/IgnitionController.bsv +++ b/hdl/ip/bsv/ignition/IgnitionController.bsv @@ -277,7 +277,7 @@ module mkController #( // Event handler state Reg#(EventHandlerState) event_handler_state <- mkReg(AwaitingEvent); Reg#(EventHandlerState) event_handler_select <- mkRegU(); - Reg#(ControllerId#(n)) current_controller <- mkRegU(); + Reg#(ControllerId#(n)) controller_id <- mkRegU(); PulseWire tick <- mkPulseWire(); Reg#(UInt#(10)) tick_count <- mkReg(0); @@ -384,11 +384,11 @@ module mkController #( function Action count_application_events( CountableApplicationEvents events) = - event_counters.count_application_events(current_controller, events); + event_counters.count_application_events(controller_id, events); function Action count_transceiver_events( CountableTransceiverEvents events) = - event_counters.count_transceiver_events(current_controller, events); + event_counters.count_transceiver_events(controller_id, events); (* fire_when_enabled *) rule do_start_event_handler ( @@ -416,7 +416,7 @@ module mkController #( // setting the id in all register files. This will automatically cause a // read of each register file on the next clock cycle. if (maybe_controller_id matches tagged Valid .id) begin - current_controller <= id; + controller_id <= id; presence.select(id); transceiver.select(id); @@ -431,14 +431,14 @@ module mkController #( target_link1_status.select(id); target_link1_events.select(id); - event_handler_state <= ReadingRegisters; + event_handler_state <= AwaitingControllerDataValid; end endrule (* fire_when_enabled *) rule do_read_registers ( init_complete && - event_handler_state == ReadingRegisters); + event_handler_state == AwaitingControllerDataValid); // Select the appropriate handler. event_handler_state <= event_handler_select; endrule @@ -515,20 +515,20 @@ module mkController #( $display("%5t [Controller %02d] Transmitter output enable mode ", $time, - current_controller, + controller_id, fshow(transceiver_.transmitter_output_enable_mode)); if (transceiver.transmitter_output_enabled && !transceiver_.transmitter_output_enabled) begin $display("%5t [Controller %02d] Transmitter output disabled", $time, - current_controller); + controller_id); end else if (!transceiver.transmitter_output_enabled && transceiver_.transmitter_output_enabled) begin $display("%5t [Controller %02d] Transmitter output enabled", $time, - current_controller); + controller_id); end // Update the transceiver register. Any changes are applied on @@ -565,11 +565,11 @@ module mkController #( maybe_request matches tagged Valid .request) begin $display("%5t [Controller %02d] Requesting ", $time, - current_controller, fshow(request)); + controller_id, fshow(request)); transmitter_events.enq( TransmitterEvent { - id: current_controller, + id: controller_id, ev: tagged Message tagged Request request}); count_application_events( @@ -612,7 +612,7 @@ module mkController #( if (presence.status_message_timeout_ticks_remaining == 0) begin $display("%5t [Controller %02d] Target Status timeout", $time, - current_controller); + controller_id); // Add a timeout to the presence history. presence_.history = shiftInAt0(presence.history, False); @@ -633,7 +633,7 @@ module mkController #( if (pack(presence_.history) == 'b000 && presence.present) begin $display("%5t [Controller %02d] Target not present", $time, - current_controller); + controller_id); target_timeout = True; presence_.present = False; @@ -641,7 +641,7 @@ module mkController #( // Write back the presence state. presence <= presence_; - presence_summary_r[current_controller] <= presence_.present; + presence_summary_r[controller_id] <= presence_.present; // Count down until the next Hello. if (hello_timer.ticks_remaining == 0) begin @@ -675,7 +675,7 @@ module mkController #( transceiver.transmitter_output_disable_timeout_ticks_remaining == 1) begin $display("%5t [Controller %02d] Transmitter output disabled", $time, - current_controller); + controller_id); transceiver_.transmitter_output_enabled = False; end @@ -687,11 +687,11 @@ module mkController #( if (hello_timer.ticks_remaining == 0) begin $display("%5t [Controller %02d] Hello", $time, - current_controller); + controller_id); transmitter_events.enq( TransmitterEvent { - id: current_controller, + id: controller_id, ev: tagged Message tagged Hello}); hello_sent = True; @@ -703,7 +703,7 @@ module mkController #( else begin transmitter_events.enq( TransmitterEvent { - id: current_controller, + id: controller_id, ev: tagged OutputEnabled transceiver_.transmitter_output_enabled}); end @@ -734,7 +734,7 @@ module mkController #( tagged TargetStatusReceived: begin $display("%5t [Controller %02d] Received Status", $time, - current_controller); + controller_id); PresenceRegister presence_ = presence; Bool target_present = False; @@ -755,7 +755,7 @@ module mkController #( !presence.present) begin $display("%5t [Controller %02d] Target present", $time, - current_controller); + controller_id); presence_.present = True; target_present = True; @@ -763,7 +763,7 @@ module mkController #( // Write back the presence state. presence <= presence_; - presence_summary_r[current_controller] <= presence_.present; + presence_summary_r[controller_id] <= presence_.present; // Update the transmitter output enabled state if configured. // The actual TransmitterEvent will be sent on the next tick. @@ -776,7 +776,7 @@ module mkController #( presence_.present) begin $display("%5t [Controller %02d] Transmitter output enabled", $time, - current_controller); + controller_id); transceiver_.transmitter_output_enabled = True; transceiver_.transmitter_output_disable_timeout_ticks_remaining = 0; @@ -798,7 +798,7 @@ module mkController #( let current = presence_.current_status_message; event_counters.count_target_link0_events( - current_controller, + controller_id, determine_transceiver_events( target_link0_status[previous], target_link0_status[current], @@ -815,7 +815,7 @@ module mkController #( True)); event_counters.count_target_link1_events( - current_controller, + controller_id, determine_transceiver_events( target_link1_status[previous], target_link1_status[current], @@ -890,7 +890,7 @@ module mkController #( tagged ReceiverReset: begin $display("%5t [Controller %02d] Receiver reset", $time, - current_controller); + controller_id); TransceiverRegister transceiver_ = transceiver; @@ -924,7 +924,7 @@ module mkController #( current_status.receiver_aligned) begin $display("%5t [Controller %02d] Transmitter output enabled", $time, - current_controller); + controller_id); transceiver_.transmitter_output_enabled = True; transceiver_.transmitter_output_disable_timeout_ticks_remaining = 0; @@ -1053,7 +1053,7 @@ typedef struct { typedef enum { AwaitingEvent = 0, - ReadingRegisters, + AwaitingControllerDataValid, HandlingSoftwareRequest, HandlingTickEvent, HandlingReceiverEvent diff --git a/hdl/ip/bsv/ignition/IgnitionReceiver.bsv b/hdl/ip/bsv/ignition/IgnitionReceiver.bsv index 85ad2da8..e4fe6edf 100644 --- a/hdl/ip/bsv/ignition/IgnitionReceiver.bsv +++ b/hdl/ip/bsv/ignition/IgnitionReceiver.bsv @@ -5,7 +5,17 @@ export mkReceiver; export ControllerReceiver(..); export mkControllerReceiver; +export mkControllerReceiver36; +export mkDeserializerEventMux1; +export mkDeserializerEventMux2; +export mkDeserializerEventMux4; +export mkDeserializerEventMux36; +export mkDeserializerEventMux36Alt; + export StatusMessageFragment(..); +export DeserializerEvent(..); +export DeserializerEvent_$ev(..); +export DeserializerEventFIFOs(..); export ReceiverEvent(..); export ReceiverEvent_$ev(..); @@ -660,10 +670,13 @@ endmodule typedef Vector#(m, FIFOF#(DeserializerEvent#(n))) DeserializerEventFIFOs#(numeric type m, numeric type n); -module mkControllerReceiver (ControllerReceiver#(n)) - provisos ( - Add#(4, _, n), - NumAlias#(TLog#(n), id_sz)); +module mkControllerReceiver #( + function module#(Empty) mkDeserializerEventMux( + Vector#(n, FIFOF#(DeserializerEvent#(n))) sources, + FIFOF#(DeserializerEvent#(n)) sink)) + (ControllerReceiver#(n)) + provisos ( + NumAlias#(TLog#(n), id_sz)); Vector#(n, DeserializerChannel#(n)) channels <- mapM(mkDeserializerChannel, genVector); Vector#(n, Reg#(Bool)) channels_locked <- replicateM(mkReg(False)); @@ -677,141 +690,7 @@ module mkControllerReceiver (ControllerReceiver#(n)) // ability to process a receiver event very cycle. FIFOF#(DeserializerEvent#(n)) deserializer_events_l0 <- mkGFIFOF(False, True); - // - // Deserializer mux stage(s) - // - - function Rules do_forward_event( - Get#(DeserializerEvent#(n)) source, - Put#(DeserializerEvent#(n)) sink, - Bool sink_selected, - Reg#(Bit#(demux_sz)) grant_base, - Bit#(demux_sz) grant); - return ( - rules - (* fire_when_enabled *) - rule do_forward_receiver_event (sink_selected); - let e <- source.get; - sink.put(e); - grant_base <= rotateBitsBy(grant, 1); - endrule - endrules); - endfunction - - if (valueof(n) == 36) begin - Reg#(Bit#(3)) grant_base_l0 <- mkReg(1); - - Vector#(3, FIFOF#(DeserializerEvent#(n))) - deserializer_events_l1 <- replicateM(mkLFIFOF()); - Vector#(3, Reg#(Bit#(3))) grant_base_l1 <- replicateM(mkReg(1)); - - Vector#(9, FIFOF#(DeserializerEvent#(n))) - deserializer_events_l2 <- replicateM(mkLFIFOF()); - Vector#(9, Reg#(Bit#(4))) grant_base_l2 <- replicateM(mkReg(1)); - - begin - let sink = deserializer_events_l0; - let sources = deserializer_events_l1; - let not_empty = map(notEmpty, sources); - let grant = select_fifo(not_empty, grant_base_l0); - - Vector#(3, Rules) forwarding_rules; - - for (Integer j = 0; j < 3; j = j + 1) begin - forwarding_rules[j] = - do_forward_event( - toGet(sources[j]), - toPut(sink), - not_empty[j] && grant[j], - asIfc(grant_base_l0), - pack(grant)); - end - - addRules(foldr( - rJoinMutuallyExclusive, - emptyRules, - forwarding_rules)); - end - - for (Integer i = 0; i < 3; i = i + 1) begin - let sink = deserializer_events_l1[i]; - let sources = DeserializerEventFIFOs#(3, n)'(takeAt(3 * i, deserializer_events_l2)); - let not_empty = map(notEmpty, sources); - let grant = select_fifo(not_empty, grant_base_l1[i]); - - Vector#(3, Rules) forwarding_rules; - - for (Integer j = 0; j < 3; j = j + 1) begin - forwarding_rules[j] = - do_forward_event( - toGet(sources[j]), - toPut(sink), - not_empty[j] && grant[j], - asIfc(grant_base_l1[i]), - pack(grant)); - end - - addRules(foldr( - rJoinMutuallyExclusive, - emptyRules, - forwarding_rules)); - end - - for (Integer i = 0; i < 9; i = i + 1) begin - let sink = deserializer_events_l2[i]; - let sources = DeserializerEventFIFOs#(4, n)'(takeAt(4 * i, map(events, channels))); - let not_empty = map(notEmpty, sources); - let grant = select_fifo(not_empty, grant_base_l2[i]); - - Vector#(4, Rules) forwarding_rules; - - for (Integer j = 0; j < 4; j = j + 1) begin - forwarding_rules[j] = - do_forward_event( - toGet(sources[j]), - toPut(sink), - not_empty[j] && grant[j], - asIfc(grant_base_l2[i]), - pack(grant)); - end - - addRules(foldr( - rJoinMutuallyExclusive, - emptyRules, - forwarding_rules)); - end - end - - // With up to four receiver channels there is no need for intermediate mux - // stages. Instead deserializers should forward directly to - // `deserializer_events_l0`. - else if (valueof(n) <= 4) begin - Reg#(Bit#(n)) grant_base_l0 <- mkReg(1); - - begin - let sink = deserializer_events_l0; - let sources = DeserializerEventFIFOs#(n, n)'(map(events, channels)); - let not_empty = map(notEmpty, sources); - let grant = select_fifo(not_empty, grant_base_l0); - - Vector#(n, Rules) forwarding_rules; - - for (Integer j = 0; j < valueof(n); j = j + 1) begin - forwarding_rules[j] = - do_forward_event( - toGet(sources[j]), - toPut(sink), - not_empty[j] && grant[j], - asIfc(grant_base_l0), - pack(grant)); - end - - addRules(foldr( - rJoinMutuallyExclusive, - emptyRules, - forwarding_rules)); - end - end + mkDeserializerEventMux(map(events, channels), deserializer_events_l0); // // Receive Phase @@ -1342,4 +1221,100 @@ function Vector#(n, Bool) select_fifo( return unpack(left | right); endfunction +module mkRoundRobinFIFOFMux #( + Vector#(n, FIFOF#(t)) sources, + FIFOF#(t) sink) + (Empty); + Reg#(Bit#(n)) grant_base <- mkReg(1); + + // Determine which source should be selected next. + let grant = select_fifo(map(notEmpty, sources), grant_base); + + function Rules forwardRule(Integer i) = + rules + (* fire_when_enabled *) + rule do_forward (grant[i]); + sources[i].deq(); + sink.enq(sources[i].first); + grant_base <= rotateBitsBy(pack(grant), 1); + endrule + endrules; + + // The `select_fifo` function guarantees only a single bit will be set. + // These bits in the grant vector are used as guards on the rules above, but + // the compiler can not determine this. Add all the rules to the module and + // annotate them as mutually exclusive, allowing the compiler to schedule + // them as intended. + addRules(foldr( + rJoinMutuallyExclusive, + emptyRules, + map(forwardRule, Vector#(n, Integer)'(genVector)))); +endmodule + +function Vector#(y, Vector#(TDiv#(x, y), t)) + chunks( + Vector#(x, t) sources, + Vector#(y, t) sinks) + provisos (Add#(TDiv#(x, y), a__, x)); + function chunk(i) = takeAt(valueof(TDiv#(x, y)) * i, sources); + return map(chunk, genVector); +endfunction + +function module#(Empty) mkDeserializerEventMux1( + DeserializerEventFIFOs#(1, 1) deserializers, + FIFOF#(DeserializerEvent#(1)) deserializer_events_l0) = + mkRoundRobinFIFOFMux(deserializers, deserializer_events_l0); + +function module#(Empty) mkDeserializerEventMux2( + DeserializerEventFIFOs#(2, 2) deserializers, + FIFOF#(DeserializerEvent#(2)) deserializer_events_l0) = + mkRoundRobinFIFOFMux(deserializers, deserializer_events_l0); + +function module#(Empty) mkDeserializerEventMux4( + DeserializerEventFIFOs#(4, 4) deserializers, + FIFOF#(DeserializerEvent#(4)) deserializer_events_l0) = + mkRoundRobinFIFOFMux(deserializers, deserializer_events_l0); + +module mkDeserializerEventMux36 #( + DeserializerEventFIFOs#(36, 36) deserializers, + FIFOF#(DeserializerEvent#(36)) deserializer_events_l0) + (Empty); + Vector#(9, FIFOF#(DeserializerEvent#(36))) + deserializer_events_l2 <- replicateM(mkLFIFOF()); + zipWithM( + mkRoundRobinFIFOFMux, + chunks(deserializers, deserializer_events_l2), + deserializer_events_l2); + + Vector#(3, FIFOF#(DeserializerEvent#(36))) + deserializer_events_l1 <- replicateM(mkLFIFOF()); + zipWithM( + mkRoundRobinFIFOFMux, + chunks(deserializer_events_l2, deserializer_events_l1), + deserializer_events_l1); + + mkRoundRobinFIFOFMux(deserializer_events_l1, deserializer_events_l0); +endmodule + +// A 36:6:1 alternative mux, using only a single layer of 6 intermediate queues. +// This implementation seems to reduce utilization without any significant +// impact in timing and could be worth using instead of the 36:9:3:1 +// implementation above. +module mkDeserializerEventMux36Alt #( + DeserializerEventFIFOs#(36, 36) deserializers, + FIFOF#(DeserializerEvent#(36)) deserializer_events_l0) + (Empty); + Vector#(6, FIFOF#(DeserializerEvent#(36))) + deserializer_events_l1 <- replicateM(mkLFIFOF()); + zipWithM( + mkRoundRobinFIFOFMux, + chunks(deserializers, deserializer_events_l1), + deserializer_events_l1); + + mkRoundRobinFIFOFMux(deserializer_events_l1, deserializer_events_l0); +endmodule + +function module#(ControllerReceiver#(36)) mkControllerReceiver36() = + mkControllerReceiver(mkDeserializerEventMux36); + endpackage diff --git a/hdl/ip/bsv/ignition/IgnitionTransceiver.bsv b/hdl/ip/bsv/ignition/IgnitionTransceiver.bsv index 2e4f36e5..c81f61df 100644 --- a/hdl/ip/bsv/ignition/IgnitionTransceiver.bsv +++ b/hdl/ip/bsv/ignition/IgnitionTransceiver.bsv @@ -20,11 +20,16 @@ export mkLinkStatusLED; export ControllerTransceiver(..); export ControllerTransceiverClient(..); export mkControllerTransceiver; +export mkControllerTransceiver1; +export mkControllerTransceiver2; +export mkControllerTransceiver4; +export mkControllerTransceiver36; import BuildVector::*; import ConfigReg::*; import Connectable::*; import FIFO::*; +import FIFOF::*; import GetPut::*; import RevertingVirtualReg::*; import Vector::*; @@ -380,10 +385,13 @@ interface ControllerTransceiverClient#(numeric type n); interface Get#(TransmitterEvent#(n)) tx; endinterface -module mkControllerTransceiver (ControllerTransceiver#(n)) - provisos (Add#(4, a__, n)); +module mkControllerTransceiver #( + function module#(Empty) mkDeserializerEventMux( + Vector#(n, FIFOF#(DeserializerEvent#(n))) sources, + FIFOF#(DeserializerEvent#(n)) sink)) + (ControllerTransceiver#(n)); Vector#(n, Deserializer) deserializers <- replicateM(mkDeserializer); - ControllerReceiver#(n) receiver <- mkControllerReceiver(); + ControllerReceiver#(n) receiver <- mkControllerReceiver(mkDeserializerEventMux); zipWithM(mkConnection, deserializers, receiver.rx); @@ -429,10 +437,17 @@ module mkControllerTransceiver (ControllerTransceiver#(n)) method tick_1khz = receiver.tick_1khz; endmodule -module mkControllerTransceiver36 (ControllerTransceiver#(36)); - (* hide *) ControllerTransceiver#(36) _txr <- mkControllerTransceiver(); - return _txr; -endmodule +function module#(ControllerTransceiver#(1)) mkControllerTransceiver1() = + mkControllerTransceiver(mkDeserializerEventMux1); + +function module#(ControllerTransceiver#(2)) mkControllerTransceiver2() = + mkControllerTransceiver(mkDeserializerEventMux2); + +function module#(ControllerTransceiver#(4)) mkControllerTransceiver4() = + mkControllerTransceiver(mkDeserializerEventMux4); + +function module#(ControllerTransceiver#(36)) mkControllerTransceiver36() = + mkControllerTransceiver(mkDeserializerEventMux36); instance Connectable#( ControllerTransceiver#(n), diff --git a/hdl/ip/bsv/ignition/test/IgnitionControllerAndTargetBench.bsv b/hdl/ip/bsv/ignition/test/IgnitionControllerAndTargetBench.bsv index 39dd4e5c..1570ee24 100644 --- a/hdl/ip/bsv/ignition/test/IgnitionControllerAndTargetBench.bsv +++ b/hdl/ip/bsv/ignition/test/IgnitionControllerAndTargetBench.bsv @@ -17,6 +17,7 @@ import TestUtils::*; import IgnitionController::*; import IgnitionProtocol::*; +import IgnitionReceiver::*; import IgnitionTarget::*; import IgnitionTransceiver::*; @@ -32,7 +33,7 @@ endinterface interface IgnitionControllerAndTargetBench; interface Target target; - interface Controller#(4) controller; + interface Controller#(1) controller; interface Link controller_to_target; interface Link target_to_controller; @@ -151,8 +152,8 @@ module mkIgnitionControllerAndTargetBench #( // // Controller, transceiver and IO adapter. // - Controller#(4) controller_ <- mkController(parameters.controller, True); - ControllerTransceiver#(4) controller_txr <- mkControllerTransceiver(); + Controller#(1) controller_ <- mkController(parameters.controller, True); + ControllerTransceiver#(1) controller_txr <- mkControllerTransceiver1(); mkConnection(asIfc(tick), asIfc(controller_.tick_1mhz)); mkConnection(asIfc(tick), asIfc(controller_txr.tick_1khz)); @@ -175,8 +176,8 @@ module mkIgnitionControllerAndTargetBench #( target_io.rx, parameters.invert_link_polarity, // Mimic the hardware implementation where the output buffer of the - // Controller transmitter is only enabled if a Target is present or - // the `always_transmit` bit has been set. + // Controller transmitter is enabled depending on the configured + // output enable mode. controller_txr.serial[0].fst); Link target_to_controller_link <- @@ -202,23 +203,6 @@ module mkIgnitionControllerAndTargetBench #( False, //controller_txr.receiver_locked_timeout, False); - // Discard transmitted bits from the remaining three Controllers in order to - // not stall the shared transmitter FIFO. - (* fire_when_enabled *) - rule do_discard_controller_1; - let _ <- controller_txr.serial[1].snd.fst.get; - endrule - - (* fire_when_enabled *) - rule do_discard_controller_2; - let _ <- controller_txr.serial[2].snd.fst.get; - endrule - - (* fire_when_enabled *) - rule do_discard_controller_3; - let _ <- controller_txr.serial[3].snd.fst.get; - endrule - // Generate single cycle timeout strobes on the positive edge for both // receivers. Reg#(Bool) past_controller_receiver_locked_timeout <- mkReg(False); @@ -246,11 +230,6 @@ module mkIgnitionControllerAndTargetBench #( end endrule - // (* fire_when_enabled *) - // rule do_display_tick (tick); - // $display("%5t [Bench] Tick", $time); - // endrule - TestWatchdog wd <- mkTestWatchdog( parameters.controller.tick_period * diff --git a/hdl/ip/bsv/ignition/test/ReceiverTests.bsv b/hdl/ip/bsv/ignition/test/ReceiverTests.bsv index 01897b3e..e9476d59 100644 --- a/hdl/ip/bsv/ignition/test/ReceiverTests.bsv +++ b/hdl/ip/bsv/ignition/test/ReceiverTests.bsv @@ -305,7 +305,7 @@ module mkMockTransmitter #( endmodule module mkControllerReceiverTest (Empty); - ControllerReceiver#(36) receiver <- mkControllerReceiver(); + ControllerReceiver#(36) receiver <- mkControllerReceiver36(); FIFO#(Message) message <- mkLFIFO(); Transmitter tx <- mkTransmitter(); diff --git a/hdl/projects/sidecar/mainboard/SidecarMainboardControllerTop.bsv b/hdl/projects/sidecar/mainboard/SidecarMainboardControllerTop.bsv index 900cd04c..7bfb651f 100644 --- a/hdl/projects/sidecar/mainboard/SidecarMainboardControllerTop.bsv +++ b/hdl/projects/sidecar/mainboard/SidecarMainboardControllerTop.bsv @@ -518,7 +518,7 @@ module mkSidecarMainboardControllerTop // ControllerTransceiver#(36) - ignition_txr <- mkControllerTransceiver(reset_by reset_sync); + ignition_txr <- mkControllerTransceiver36(reset_by reset_sync); mkConnection(ignition_txr, controller.ignition_controller.txr); diff --git a/hdl/projects/sidecar/mainboard/emulator/SidecarMainboardEmulator.bsv b/hdl/projects/sidecar/mainboard/emulator/SidecarMainboardEmulator.bsv index 072a4317..4337f0fb 100644 --- a/hdl/projects/sidecar/mainboard/emulator/SidecarMainboardEmulator.bsv +++ b/hdl/projects/sidecar/mainboard/emulator/SidecarMainboardEmulator.bsv @@ -185,9 +185,7 @@ module mkSidecarMainboardEmulator (SidecarMainboardEmulatorTop) // Instantiate Transceivers, IO adapters and connect them to the Ignition // Controllers. - //Transceivers#(n_ignition_controllers) controller_txrs <- mkTransceivers(); - - ControllerTransceiver#(4) controller_txrs <- mkControllerTransceiver(); + ControllerTransceiver#(4) controller_txrs <- mkControllerTransceiver4(); mkConnection(controller_txrs, controller.ignition_controller.txr); //mkConnection(asIfc(tick_1khz), asIfc(controller_txrs.tick_1khz)); @@ -264,14 +262,14 @@ module mkSidecarMainboardEmulator (SidecarMainboardEmulatorTop) ReadOnly#(Bit#(1)) ignition_link2_status_led <- mkLinkStatusLED( - False, //controller.ignition_controllers[2].status.target_present, + controller.ignition_controller.presence_summary[2], link_status_disconnected, //controller_txrs.txrs[2].status, False, //controller_txrs.txrs[2].receiver_locked_timeout, False); ReadOnly#(Bit#(1)) ignition_link3_status_led <- mkLinkStatusLED( - False, //controller.ignition_controllers[3].status.target_present, + controller.ignition_controller.presence_summary[3], link_status_disconnected, //controller_txrs.txrs[3].status, False, //controller_txrs.txrs[3].receiver_locked_timeout, False);