1
  2
  3
  4
  5
  6
  7
  8
  9
 10
 11
 12
 13
 14
 15
 16
 17
 18
 19
 20
 21
 22
 23
 24
 25
 26
 27
 28
 29
 30
 31
 32
 33
 34
 35
 36
 37
 38
 39
 40
 41
 42
 43
 44
 45
 46
 47
 48
 49
 50
 51
 52
 53
 54
 55
 56
 57
 58
 59
 60
 61
 62
 63
 64
 65
 66
 67
 68
 69
 70
 71
 72
 73
 74
 75
 76
 77
 78
 79
 80
 81
 82
 83
 84
 85
 86
 87
 88
 89
 90
 91
 92
 93
 94
 95
 96
 97
 98
 99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
use crate::core::ast::VerilogLiteral;
use crate::core::bits::{bit_cast, clog2, Bit, Bits};
use crate::core::synth::{Synth, VCDValue};

#[derive(Clone, Copy, Debug, PartialEq, Eq)]
enum CmdType {
    Noop,
    Read,
    Write,
}

pub fn raw_cast<S: Synth, T: Synth + From<S>>(x: S) -> T {
    x.into()
}

// Auto generated (?)
impl Default for CmdType {
    fn default() -> Self {
        CmdType::Noop
    }
}

// Auto generated
impl Synth for CmdType {
    const BITS: usize = clog2(3);
    fn vcd(self) -> VCDValue {
        match self {
            CmdType::Noop => VCDValue::String("Noop".into()),
            CmdType::Read => VCDValue::String("Read".into()),
            CmdType::Write => VCDValue::String("Write".into()),
        }
    }
    fn verilog(self) -> VerilogLiteral {
        match self {
            CmdType::Noop => 0_u32.into(),
            CmdType::Read => 1_u32.into(),
            CmdType::Write => 2_u32.into(),
        }
    }
}

// Auto generated
impl From<CmdType> for Bits<2> {
    fn from(x: CmdType) -> Self {
        match x {
            CmdType::Noop => 0_usize.into(),
            CmdType::Read => 1_usize.into(),
            CmdType::Write => 2_usize.into(),
        }
    }
}

// Auto generated
impl From<Bits<2>> for CmdType {
    fn from(x: Bits<2>) -> Self {
        let xval: usize = x.into();
        match xval {
            0 => CmdType::Noop,
            1 => CmdType::Read,
            2 => CmdType::Write,
            _ => panic!("Illegal conversion"),
        }
    }
}

#[test]
fn test_struct_value() {
    let states = [CmdType::Noop, CmdType::Read, CmdType::Write];
    for state in states {
        let b: Bits<2> = state.into();
        let c: CmdType = b.into();
        assert_eq!(c, state);
    }

    for state in states {
        let b = raw_cast::<CmdType, Bits<2>>(state);
        let c = raw_cast::<Bits<2>, CmdType>(b);
        assert_eq!(c, state);
    }
}

#[derive(Copy, Clone, Default, Debug, PartialEq, Eq)]
struct MIGCmd {
    pub cmd: CmdType,
    pub active: Bit,
    pub len: Bits<6>,
}

impl Synth for MIGCmd {
    const BITS: usize = CmdType::BITS + Bit::BITS + Bits::<6>::BITS;

    fn vcd(self) -> VCDValue {
        let t: Bits<{ MIGCmd::BITS }> = self.into();
        t.into()
    }

    fn verilog(self) -> VerilogLiteral {
        let t: Bits<{ MIGCmd::BITS }> = self.into();
        t.into()
    }
}

// Auto generated
impl From<MIGCmd> for Bits<{ MIGCmd::BITS }> {
    fn from(x: MIGCmd) -> Self {
        let x2 = bit_cast::<{ MIGCmd::BITS }, { Bits::<6>::BITS }>(x.len.into());
        let x1 =
            bit_cast::<{ MIGCmd::BITS }, { bool::BITS }>(x.active.into()) | x2 << { bool::BITS };
        let x0 =
            bit_cast::<{ MIGCmd::BITS }, { CmdType::BITS }>(x.cmd.into()) | x1 << { CmdType::BITS };
        x0
    }
}

// Auto generated
impl From<Bits<{ MIGCmd::BITS }>> for MIGCmd {
    fn from(x: Bits<{ MIGCmd::BITS }>) -> Self {
        let cmd: CmdType = x.get_bits::<{ CmdType::BITS }>(0).into();
        let x = x >> { CmdType::BITS };
        let active: bool = x.get_bits::<{ bool::BITS }>(0).into();
        let x = x >> { bool::BITS };
        let len: Bits<6> = x.get_bits::<{ Bits::<6>::BITS }>(0).into();
        MIGCmd { cmd, active, len }
    }
}

#[test]
fn test_composite() {
    assert_eq!(MIGCmd::BITS, 9);
    let x = MIGCmd {
        cmd: CmdType::Read,
        active: true,
        len: 35_usize.into(),
    };

    let y: Bits<9> = x.into();
    assert_eq!(y.get_bits::<{ CmdType::BITS }>(0), 1u32);
    assert_eq!(y.get_bits::<{ bool::BITS }>(2), true);
    assert_eq!(y.get_bits::<6>(3), 35_u32);

    let z0: Bits<9> = 2_usize.into();
    let z1: Bits<9> = 0_usize.into();
    let z2: Bits<9> = 42_usize.into();
    let z: Bits<9> = z0 | z1 << 2_usize | z2 << 3_usize;
    let x: MIGCmd = z.into();
    assert_eq!(x.active, false);
    assert_eq!(x.cmd, CmdType::Write);
    assert_eq!(x.len, 42_u32);
}