1use crate::bidi::{BidiBusM, BidiMaster};
2use crate::bus::FIFOWriteController;
3use crate::bus::{FIFOReadController, SoCBusController};
4use crate::controller::BaseController;
5use crate::cross_fifo::{CrossNarrow, CrossWiden};
6use rust_hdl_core::prelude::*;
7use rust_hdl_widgets::prelude::*;
8
9#[derive(LogicBlock, Default)]
12pub struct Host<const A: usize> {
13 pub bidi_bus: BidiBusM<Bits<8>>,
14 pub bus: SoCBusController<16, A>,
15 pub sys_clock: Signal<In, Clock>,
16 pub bidi_clock: Signal<In, Clock>,
17 bidi_master: BidiMaster<Bits<8>>,
18 bus_to_controller: CrossWiden<8, 4, 5, 16, 3, 4>,
19 controller_to_bus: CrossNarrow<16, 3, 4, 8, 4, 5>,
20 controller: BaseController<A>,
21}
22
23impl<const A: usize> Host<A> {
24 pub fn new(order: WordOrder) -> Self {
25 Self {
26 bus_to_controller: CrossWiden::new(order),
27 controller_to_bus: CrossNarrow::new(order),
28 ..Default::default()
29 }
30 }
31}
32
33impl<const A: usize> Logic for Host<A> {
34 #[hdl_gen]
35 fn update(&mut self) {
36 BidiBusM::<Bits<8>>::link(&mut self.bidi_bus, &mut self.bidi_master.bus);
37 clock!(self, bidi_clock, bidi_master);
38 FIFOWriteController::<Bits<8>>::join(
39 &mut self.bidi_master.data_from_bus,
40 &mut self.bus_to_controller.narrow_bus,
41 );
42 self.bus_to_controller.narrow_clock.next = self.bidi_clock.val();
43 self.bus_to_controller.wide_clock.next = self.sys_clock.val();
44 FIFOReadController::<Bits<8>>::join(
45 &mut self.bidi_master.data_to_bus,
46 &mut self.controller_to_bus.narrow_bus,
47 );
48 self.controller_to_bus.narrow_clock.next = self.bidi_clock.val();
49 self.controller_to_bus.wide_clock.next = self.sys_clock.val();
50 FIFOReadController::<Bits<16>>::join(
51 &mut self.controller.from_cpu,
52 &mut self.bus_to_controller.wide_bus,
53 );
54 FIFOWriteController::<Bits<16>>::join(
55 &mut self.controller.to_cpu,
56 &mut self.controller_to_bus.wide_bus,
57 );
58 clock!(self, sys_clock, controller);
59 SoCBusController::<16, A>::link(&mut self.bus, &mut self.controller.bus);
60 }
61}
62
63#[test]
64fn test_host_synthesizes() {
65 let mut uut = Host::<8>::default();
66 uut.connect_all();
67 let vlog = generate_verilog(&uut);
68 yosys_validate("host", &vlog).unwrap();
69}