litex/
litex_registers.rs

1// Licensed under the Apache License, Version 2.0 or the MIT License.
2// SPDX-License-Identifier: Apache-2.0 OR MIT
3// Copyright Tock Contributors 2022.
4
5//! LiteX register abstraction types
6//!
7//! LiteX is able to generate vastly different SoC with different
8//! buswidths, CSR widths and configurations
9//!
10//! This module defines interfaces very similar to `tock_registers`
11//! (and based on `tock_registers`) for various register- and
12//! bus-width configurations
13//!
14//! Essentially, the bus data width (default 32 bit), the CSR data
15//! width, the CSR byte ordering and naturally the desired register
16//! width can change. This module defines generic traits for accessing
17//! registers and register abstraction structs.
18//!
19//! The different register types of a specific SoC configuration are
20//! combined using a
21//! [`LiteXSoCRegisterConfiguration`]
22//! structure, which can be used to adapt the register interfaces of
23//! peripherals to the different configurations.
24//!
25//! ## Naming Scheme
26//!
27//! The generated register abstractions follow the naming scheme
28//!
29//! ```text
30//! <AccessTypes><RegisterWidth>C<CSRDataWidth>B<BaseWidth>
31//! ```
32//!
33//! where `AccessType` in `{ ReadOnly, WriteOnly, ReadWrite }`,
34//! `RegisterWidth` in `{ 8, 16, 32, 64 }`, `CSRDataWidth` in `{ 8, 32
35//! }`, `BaseWidth` in `{ 32 }`.
36
37use core::marker::PhantomData;
38use tock_registers::fields::{Field, FieldValue, TryFromValue};
39use tock_registers::interfaces::{Readable, Writeable};
40pub use tock_registers::register_bitfields;
41use tock_registers::registers::{
42    ReadOnly as TRReadOnly, ReadWrite as TRReadWrite, WriteOnly as TRWriteOnly,
43};
44use tock_registers::{LocalRegisterCopy, RegisterLongName, UIntLike as TRUIntLike};
45
46/// Extension of the `tock_registers` `UIntLike` trait.
47///
48/// This extends the `UIntLike` trait of `tock_registers` to also
49/// provide the `1` and maximum (all bits set) values of the
50/// respective integer type
51///
52/// This allows for peripherals to be written generic over the
53/// underlying CSR width (as in the case of event managers, LEDs,
54/// etc.), manipulating bitmaps
55pub trait UIntLike: TRUIntLike {
56    fn one() -> Self;
57    fn max() -> Self {
58        !Self::zero()
59    }
60    fn trailing_zeros(self) -> u32;
61    fn into_usize(self) -> usize;
62}
63
64// Implement the custom UIntLike trait for all required base integer
65// types
66impl UIntLike for u8 {
67    fn one() -> Self {
68        1
69    }
70
71    fn trailing_zeros(self) -> u32 {
72        self.trailing_zeros()
73    }
74
75    fn into_usize(self) -> usize {
76        self as usize
77    }
78}
79impl UIntLike for u16 {
80    fn one() -> Self {
81        1
82    }
83
84    fn trailing_zeros(self) -> u32 {
85        self.trailing_zeros()
86    }
87
88    fn into_usize(self) -> usize {
89        self as usize
90    }
91}
92impl UIntLike for u32 {
93    fn one() -> Self {
94        1
95    }
96
97    fn trailing_zeros(self) -> u32 {
98        self.trailing_zeros()
99    }
100
101    fn into_usize(self) -> usize {
102        self as usize
103    }
104}
105impl UIntLike for u64 {
106    fn one() -> Self {
107        1
108    }
109
110    fn trailing_zeros(self) -> u32 {
111        self.trailing_zeros()
112    }
113
114    fn into_usize(self) -> usize {
115        self as usize
116    }
117}
118impl UIntLike for u128 {
119    fn one() -> Self {
120        1
121    }
122
123    fn trailing_zeros(self) -> u32 {
124        self.trailing_zeros()
125    }
126
127    fn into_usize(self) -> usize {
128        self as usize
129    }
130}
131
132/// Trait to be implemented by custom register structs that support
133/// reading the current value
134///
135/// # DO NOT USE DIRECTLY
136///
137/// This must be public to prevent generating a `private_in_public`
138/// but really should not be used directly. Use `Read` instead, which
139/// also incorporates this functionality.
140pub trait BaseReadableRegister<T: UIntLike> {
141    type Reg: RegisterLongName;
142    const REG_WIDTH: usize;
143
144    /// Get the raw register value
145    fn base_get(&self) -> T;
146}
147
148/// Trait to be implemented by custom register structs that support
149/// writing to them
150///
151/// ## DO NOT USE DIRECTLY
152///
153/// This must be public to prevent generating a `private_in_public`
154/// but really should not be used directly. Use `Write` instead, which
155/// also incorporates this functionality.
156pub trait BaseWriteableRegister<T: UIntLike> {
157    type Reg: RegisterLongName;
158    const REG_WIDTH: usize;
159
160    /// Set the raw register value
161    fn base_set(&self, value: T);
162}
163
164/// Readable register
165///
166/// This interface is analogous to the methods supported on
167/// `tock_registers::registers::{ReadOnly, ReadWrite}` types
168///
169/// It is automatically implemented for all `BaseReadableRegister`s
170pub trait Read<T: UIntLike> {
171    type Reg: RegisterLongName;
172    const REG_WIDTH: usize;
173
174    /// Get the raw register value
175    fn get(&self) -> T;
176
177    /// Read the value of the given field
178    fn read(&self, field: Field<T, Self::Reg>) -> T;
179
180    /// Read value of the given field as an enum member
181    fn read_as_enum<E: TryFromValue<T, EnumType = E>>(
182        &self,
183        field: Field<T, Self::Reg>,
184    ) -> Option<E>;
185
186    /// Make a local copy of the register
187    fn extract(&self) -> LocalRegisterCopy<T, Self::Reg>;
188
189    /// Check if one or more bits in a field are set
190    fn is_set(&self, field: Field<T, Self::Reg>) -> bool;
191
192    /// Check if any specified parts of a field match
193    fn any_matching_bits_set(&self, field: FieldValue<T, Self::Reg>) -> bool;
194
195    /// Check if all specified parts of a field match
196    fn matches_all(&self, field: FieldValue<T, Self::Reg>) -> bool;
197}
198
199/// Writeable register
200///
201/// This interface is analogous to the methods supported on
202/// `tock_registers::registers::{WriteOnly, ReadWrite}` types
203///
204/// It is automatically implemented for all `BaseWriteableRegister`s
205pub trait Write<T: UIntLike> {
206    type Reg: RegisterLongName;
207    const REG_WIDTH: usize;
208
209    /// Set the raw register value
210    fn set(&self, value: T);
211
212    /// Write the value of one or more fields, overwriting the other
213    /// fields with zero
214    fn write(&self, field: FieldValue<T, Self::Reg>);
215}
216
217/// Readable and writable register
218///
219/// This interface is analogous to the methods supported on
220/// `tock_registers::registers::ReadWrite` types
221///
222/// It is automatically implemented for all types that are both
223/// `BaseReadableRegister` and `BaseWriteableRegister`s
224pub trait ReadWrite<T: UIntLike>: Read<T> + Write<T> {
225    const REG_WIDTH: usize;
226
227    /// Write the value of one or more fields, leaving the other
228    /// fields unchanged
229    fn modify(&self, field: FieldValue<T, <Self as Read<T>>::Reg>);
230
231    /// Write the value of one or more fields, maintaining the value
232    /// of unchanged fields via a provided original value, rather than
233    /// a register read.
234    fn modify_no_read(
235        &self,
236        original: LocalRegisterCopy<T, <Self as Read<T>>::Reg>,
237        field: FieldValue<T, <Self as Read<T>>::Reg>,
238    );
239}
240
241// Implement the [`Read`] trait (providing high-level methods to read
242// specific fields of a register) for every type implementing the
243// [`BaseReadableRegister`] trait.
244impl<R, T: UIntLike> Read<T> for R
245where
246    R: BaseReadableRegister<T>,
247{
248    type Reg = <Self as BaseReadableRegister<T>>::Reg;
249    const REG_WIDTH: usize = R::REG_WIDTH;
250
251    #[inline]
252    fn get(&self) -> T {
253        self.base_get()
254    }
255
256    #[inline]
257    fn read(&self, field: Field<T, Self::Reg>) -> T {
258        field.read(self.get())
259    }
260
261    #[inline]
262    fn read_as_enum<E: TryFromValue<T, EnumType = E>>(
263        &self,
264        field: Field<T, Self::Reg>,
265    ) -> Option<E> {
266        field.read_as_enum(self.get())
267    }
268
269    #[inline]
270    fn extract(&self) -> LocalRegisterCopy<T, Self::Reg> {
271        LocalRegisterCopy::new(self.get())
272    }
273
274    #[inline]
275    fn is_set(&self, field: Field<T, Self::Reg>) -> bool {
276        field.is_set(self.get())
277    }
278
279    #[inline]
280    fn any_matching_bits_set(&self, field: FieldValue<T, Self::Reg>) -> bool {
281        field.any_matching_bits_set(self.get())
282    }
283
284    #[inline]
285    fn matches_all(&self, field: FieldValue<T, Self::Reg>) -> bool {
286        field.matches_all(self.get())
287    }
288}
289
290// Implement the [`Write`] trait (providing high-level methods to set
291// specific fields of a register) for every type implementing the
292// [`BaseWritableRegister`] trait.
293impl<R, T: UIntLike> Write<T> for R
294where
295    R: BaseWriteableRegister<T>,
296{
297    type Reg = <Self as BaseWriteableRegister<T>>::Reg;
298    const REG_WIDTH: usize = R::REG_WIDTH;
299
300    #[inline]
301    fn set(&self, value: T) {
302        self.base_set(value)
303    }
304
305    #[inline]
306    fn write(&self, field: FieldValue<T, Self::Reg>) {
307        self.set(field.value)
308    }
309}
310
311// Implement the [`ReadWrite`] trait (providing high-level methods to
312// update specific fields of a register) for every type implementing
313// both the [`Read`] and [`Write`] trait.
314impl<R, T: UIntLike> ReadWrite<T> for R
315where
316    R: Read<T> + Write<T>,
317{
318    const REG_WIDTH: usize = <R as Read<T>>::REG_WIDTH;
319
320    #[inline]
321    fn modify(&self, field: FieldValue<T, <Self as Read<T>>::Reg>) {
322        self.set(field.modify(self.get()));
323    }
324
325    #[inline]
326    fn modify_no_read(
327        &self,
328        original: LocalRegisterCopy<T, <Self as Read<T>>::Reg>,
329        field: FieldValue<T, <Self as Read<T>>::Reg>,
330    ) {
331        self.set(field.modify(original.get()));
332    }
333}
334
335// ---------- COLLECTION OF REGISTER TYPES FOR A SPECIFIC LITEX CONFIGURATION ----------
336
337/// Register abstraction types collection
338///
339/// This trait defines a collection of types for a certain set of
340/// LiteX configuration options. It provides types with all
341/// accessibility constraints ([`Read`], [`Write`], [`ReadWrite`]) for
342/// every defined register width.
343///
344/// All types must be over a common register layout configuration, having identical
345///
346/// - base integer width
347/// - CSR data width
348/// - endianness
349///
350/// ## Generic Register Type Arguments
351///
352/// Usually registers are generic over a [`RegisterLongName`] type
353/// arguments, such that the [`Field`] and [`FieldValue`] arguments of
354/// the various methods make sense.
355///
356/// Unfortunately, those generic type arguments cannot be passed
357/// through associated types in traits until [generic associated
358/// types](https://github.com/rust-lang/rust/issues/44265) stabilize.
359///
360/// In the meantime, the types [`ReadRegWrapper`], [`WriteRegWrapper`]
361/// and [`ReadWriteRegWrapper`] can be used to access fields in a
362/// register as commonly done in tock-registers:
363///
364/// ```rust
365/// # // This is a dummy setup to make the doctests pass
366/// # use tock_registers::register_bitfields;
367/// # use kernel::utilities::StaticRef;
368/// # use litex::litex_registers::{
369/// #   LiteXSoCRegisterConfiguration,
370/// #   LiteXSoCRegistersC8B32,
371/// #   Read,
372/// #   ReadRegWrapper,
373/// # };
374/// #
375/// pub struct LiteXUartRegisters<R: LiteXSoCRegisterConfiguration> {
376///   txfull: R::ReadOnly8,
377/// }
378///
379/// register_bitfields![u8,
380///   txfull [
381///     full OFFSET(0) NUMBITS(1) []
382///   ],
383/// ];
384///
385/// # static mut testregs: u32 = 0;
386/// #
387/// # fn main() {
388/// #   let regs = unsafe {
389/// #     StaticRef::new(&mut testregs as *mut u32 as *mut LiteXUartRegisters<LiteXSoCRegistersC8B32>)
390/// #   };
391/// #   let _ =
392/// ReadRegWrapper::wrap(&regs.txfull).is_set(txfull::full)
393/// #   ;
394/// # }
395/// ```
396pub trait LiteXSoCRegisterConfiguration {
397    type ReadOnly8: BaseReadableRegister<u8, Reg = ()>;
398    type WriteOnly8: BaseWriteableRegister<u8, Reg = ()>;
399    type ReadWrite8: BaseReadableRegister<u8, Reg = ()> + BaseWriteableRegister<u8, Reg = ()>;
400
401    type ReadOnly16: BaseReadableRegister<u16, Reg = ()>;
402    type WriteOnly16: BaseWriteableRegister<u16, Reg = ()>;
403    type ReadWrite16: BaseReadableRegister<u16, Reg = ()> + BaseWriteableRegister<u16, Reg = ()>;
404
405    type ReadOnly32: BaseReadableRegister<u32, Reg = ()>;
406    type WriteOnly32: BaseWriteableRegister<u32, Reg = ()>;
407    type ReadWrite32: BaseReadableRegister<u32, Reg = ()> + BaseWriteableRegister<u32, Reg = ()>;
408
409    type ReadOnly64: BaseReadableRegister<u64, Reg = ()>;
410    type WriteOnly64: BaseWriteableRegister<u64, Reg = ()>;
411    type ReadWrite64: BaseReadableRegister<u64, Reg = ()> + BaseWriteableRegister<u64, Reg = ()>;
412}
413
414/// Collection of LiteX register abstraction types
415///
416/// This collection of LiteX registers has the following configuration:
417///
418/// - base integer width: 32 bit
419/// - csr data width: 8 bit
420/// - endianness: big
421///
422/// For documentation on the usage of these types, refer to the
423/// [`LiteXSoCRegisterConfiguration`] trait documentation.
424pub enum LiteXSoCRegistersC8B32 {}
425impl LiteXSoCRegisterConfiguration for LiteXSoCRegistersC8B32 {
426    type ReadOnly8 = ReadOnly8C8B32;
427    type WriteOnly8 = WriteOnly8C8B32;
428    type ReadWrite8 = ReadWrite8C8B32;
429
430    type ReadOnly16 = ReadOnly16C8B32;
431    type WriteOnly16 = WriteOnly16C8B32;
432    type ReadWrite16 = ReadWrite16C8B32;
433
434    type ReadOnly32 = ReadOnly32C8B32;
435    type WriteOnly32 = WriteOnly32C8B32;
436    type ReadWrite32 = ReadWrite32C8B32;
437
438    type ReadOnly64 = ReadOnly64C8B32;
439    type WriteOnly64 = WriteOnly64C8B32;
440    type ReadWrite64 = ReadWrite64C8B32;
441}
442
443/// Collection of LiteX register abstraction types
444///
445/// This collection of LiteX registers has the following configuration:
446///
447/// - base integer width: 32 bit
448/// - csr data width: 32 bit
449/// - endianness: big
450///
451/// For documentation on the usage of these types, refer to the
452/// [`LiteXSoCRegisterConfiguration`] trait documentation.
453pub enum LiteXSoCRegistersC32B32 {}
454impl LiteXSoCRegisterConfiguration for LiteXSoCRegistersC32B32 {
455    type ReadOnly8 = ReadOnly8C32B32;
456    type WriteOnly8 = WriteOnly8C32B32;
457    type ReadWrite8 = ReadWrite8C32B32;
458
459    type ReadOnly16 = ReadOnly16C32B32;
460    type WriteOnly16 = WriteOnly16C32B32;
461    type ReadWrite16 = ReadWrite16C32B32;
462
463    type ReadOnly32 = ReadOnly32C32B32;
464    type WriteOnly32 = WriteOnly32C32B32;
465    type ReadWrite32 = ReadWrite32C32B32;
466
467    type ReadOnly64 = ReadOnly64C32B32;
468    type WriteOnly64 = WriteOnly64C32B32;
469    type ReadWrite64 = ReadWrite64C32B32;
470}
471
472// ---------- WRAPPERS AROUND READ,WRITE,READWRITE TRAITS WITH GENERIC REGISTER NAMES ----------
473/// Workaround-wrapper for readable LiteX registers
474///
475/// This workaround-wrapper is required to make an associated type of
476/// [`LiteXSoCRegisterConfiguration`] generic over the
477/// [`RegisterLongName`] until generic associated types stabilize in
478/// Rust. Please see the [`LiteXSoCRegisterConfiguration`]
479/// documentation for more information.
480pub struct ReadRegWrapper<'a, T: UIntLike, N: RegisterLongName, R: BaseReadableRegister<T>>(
481    &'a R,
482    PhantomData<T>,
483    PhantomData<N>,
484);
485impl<'a, T: UIntLike, N: RegisterLongName, R: BaseReadableRegister<T>> ReadRegWrapper<'a, T, N, R> {
486    #[inline]
487    pub fn wrap(reg: &'a R) -> Self {
488        ReadRegWrapper(reg, PhantomData, PhantomData)
489    }
490}
491
492impl<T: UIntLike, N: RegisterLongName, R: BaseReadableRegister<T>> BaseReadableRegister<T>
493    for ReadRegWrapper<'_, T, N, R>
494{
495    type Reg = N;
496    const REG_WIDTH: usize = R::REG_WIDTH;
497
498    #[inline]
499    fn base_get(&self) -> T {
500        self.0.base_get()
501    }
502}
503
504/// Workaround-wrapper for writable LiteX registers
505///
506/// This workaround-wrapper is required to make an associated type of
507/// [`LiteXSoCRegisterConfiguration`] generic over the
508/// [`RegisterLongName`] until generic associated types stabilize in
509/// Rust. Please see the [`LiteXSoCRegisterConfiguration`]
510/// documentation for more information.
511pub struct WriteRegWrapper<'a, T: UIntLike, N: RegisterLongName, R: BaseWriteableRegister<T>>(
512    &'a R,
513    PhantomData<T>,
514    PhantomData<N>,
515);
516impl<'a, T: UIntLike, N: RegisterLongName, R: BaseWriteableRegister<T>>
517    WriteRegWrapper<'a, T, N, R>
518{
519    #[inline]
520    pub fn wrap(reg: &'a R) -> Self {
521        WriteRegWrapper(reg, PhantomData, PhantomData)
522    }
523}
524
525impl<T: UIntLike, N: RegisterLongName, R: BaseWriteableRegister<T>> BaseWriteableRegister<T>
526    for WriteRegWrapper<'_, T, N, R>
527{
528    type Reg = N;
529    const REG_WIDTH: usize = R::REG_WIDTH;
530
531    #[inline]
532    fn base_set(&self, value: T) {
533        self.0.base_set(value)
534    }
535}
536
537/// Workaround-wrapper for read- and writable LiteX registers
538///
539/// This workaround-wrapper is required to make an associated type of
540/// [`LiteXSoCRegisterConfiguration`] generic over the
541/// [`RegisterLongName`] until generic associated types stabilize in
542/// Rust. Please see the [`LiteXSoCRegisterConfiguration`]
543/// documentation for more information.
544pub struct ReadWriteRegWrapper<
545    'a,
546    T: UIntLike,
547    N: RegisterLongName,
548    R: BaseReadableRegister<T> + BaseWriteableRegister<T>,
549>(&'a R, PhantomData<T>, PhantomData<N>);
550impl<
551        'a,
552        T: UIntLike,
553        N: RegisterLongName,
554        R: BaseReadableRegister<T> + BaseWriteableRegister<T>,
555    > ReadWriteRegWrapper<'a, T, N, R>
556{
557    #[inline]
558    pub fn wrap(reg: &'a R) -> Self {
559        ReadWriteRegWrapper(reg, PhantomData, PhantomData)
560    }
561}
562
563impl<T: UIntLike, N: RegisterLongName, R: BaseReadableRegister<T> + BaseWriteableRegister<T>>
564    BaseReadableRegister<T> for ReadWriteRegWrapper<'_, T, N, R>
565{
566    type Reg = N;
567    const REG_WIDTH: usize = <R as BaseReadableRegister<T>>::REG_WIDTH;
568
569    #[inline]
570    fn base_get(&self) -> T {
571        self.0.base_get()
572    }
573}
574
575impl<T: UIntLike, N: RegisterLongName, R: BaseReadableRegister<T> + BaseWriteableRegister<T>>
576    BaseWriteableRegister<T> for ReadWriteRegWrapper<'_, T, N, R>
577{
578    type Reg = N;
579    const REG_WIDTH: usize = <R as BaseWriteableRegister<T>>::REG_WIDTH;
580
581    #[inline]
582    fn base_set(&self, value: T) {
583        self.0.base_set(value)
584    }
585}
586
587// ---------- AUTOMATICALLY GENERATED CODE ----------
588//
589// The following code has been gerated by the `litex-register-gen`
590// procedural macro, which is not yet included with Tock.
591//
592// The following arguments to the macro produced the results below:
593//
594// litex_register_abstraction!(ReadOnly8C8B32 {
595//     access_type: "read_only",
596//     value_width: 8,
597//     wishbone_data_width: 8,
598//     base_width: 32,
599//     endianness: "big",
600// });
601//
602// litex_register_abstraction!(WriteOnly8C8B32 {
603//     access_type: "write_only",
604//     value_width: 8,
605//     wishbone_data_width: 8,
606//     base_width: 32,
607//     endianness: "big",
608// });
609//
610// litex_register_abstraction!(ReadWrite8C8B32 {
611//     access_type: "read_write",
612//     value_width: 8,
613//     wishbone_data_width: 8,
614//     base_width: 32,
615//     endianness: "big",
616// });
617//
618// litex_register_abstraction!(ReadOnly16C8B32 {
619//     access_type: "read_only",
620//     value_width: 16,
621//     wishbone_data_width: 8,
622//     base_width: 32,
623//     endianness: "big",
624// });
625//
626// litex_register_abstraction!(WriteOnly16C8B32 {
627//     access_type: "write_only",
628//     value_width: 16,
629//     wishbone_data_width: 8,
630//     base_width: 32,
631//     endianness: "big",
632// });
633//
634// litex_register_abstraction!(ReadWrite16C8B32 {
635//     access_type: "read_write",
636//     value_width: 16,
637//     wishbone_data_width: 8,
638//     base_width: 32,
639//     endianness: "big",
640// });
641//
642// litex_register_abstraction!(ReadOnly32C8B32 {
643//     access_type: "read_only",
644//     value_width: 32,
645//     wishbone_data_width: 8,
646//     base_width: 32,
647//     endianness: "big",
648// });
649//
650// litex_register_abstraction!(WriteOnly32C8B32 {
651//     access_type: "write_only",
652//     value_width: 32,
653//     wishbone_data_width: 8,
654//     base_width: 32,
655//     endianness: "big",
656// });
657//
658// litex_register_abstraction!(ReadWrite32C8B32 {
659//     access_type: "read_write",
660//     value_width: 32,
661//     wishbone_data_width: 8,
662//     base_width: 32,
663//     endianness: "big",
664// });
665//
666// litex_register_abstraction!(ReadOnly64C8B32 {
667//     access_type: "read_only",
668//     value_width: 64,
669//     wishbone_data_width: 8,
670//     base_width: 32,
671//     endianness: "big",
672// });
673//
674// litex_register_abstraction!(WriteOnly64C8B32 {
675//     access_type: "write_only",
676//     value_width: 64,
677//     wishbone_data_width: 8,
678//     base_width: 32,
679//     endianness: "big",
680// });
681//
682// litex_register_abstraction!(ReadWrite64C8B32 {
683//     access_type: "read_write",
684//     value_width: 64,
685//     wishbone_data_width: 8,
686//     base_width: 32,
687//     endianness: "big",
688// });
689//
690//
691// litex_register_abstraction!(ReadOnly8C32B32 {
692//     access_type: "read_only",
693//     value_width: 8,
694//     wishbone_data_width: 32,
695//     base_width: 32,
696//     endianness: "big",
697// });
698//
699// litex_register_abstraction!(WriteOnly8C32B32 {
700//     access_type: "write_only",
701//     value_width: 8,
702//     wishbone_data_width: 32,
703//     base_width: 32,
704//     endianness: "big",
705// });
706//
707// litex_register_abstraction!(ReadWrite8C32B32 {
708//     access_type: "read_write",
709//     value_width: 8,
710//     wishbone_data_width: 32,
711//     base_width: 32,
712//     endianness: "big",
713// });
714//
715// litex_register_abstraction!(ReadOnly16C32B32 {
716//     access_type: "read_only",
717//     value_width: 16,
718//     wishbone_data_width: 32,
719//     base_width: 32,
720//     endianness: "big",
721// });
722//
723// litex_register_abstraction!(WriteOnly16C32B32 {
724//     access_type: "write_only",
725//     value_width: 16,
726//     wishbone_data_width: 32,
727//     base_width: 32,
728//     endianness: "big",
729// });
730//
731// litex_register_abstraction!(ReadWrite16C32B32 {
732//     access_type: "read_write",
733//     value_width: 16,
734//     wishbone_data_width: 32,
735//     base_width: 32,
736//     endianness: "big",
737// });
738//
739// litex_register_abstraction!(ReadOnly32C32B32 {
740//     access_type: "read_only",
741//     value_width: 32,
742//     wishbone_data_width: 32,
743//     base_width: 32,
744//     endianness: "big",
745// });
746//
747// litex_register_abstraction!(WriteOnly32C32B32 {
748//     access_type: "write_only",
749//     value_width: 32,
750//     wishbone_data_width: 32,
751//     base_width: 32,
752//     endianness: "big",
753// });
754//
755// litex_register_abstraction!(ReadWrite32C32B32 {
756//     access_type: "read_write",
757//     value_width: 32,
758//     wishbone_data_width: 32,
759//     base_width: 32,
760//     endianness: "big",
761// });
762//
763// litex_register_abstraction!(ReadOnly64C32B32 {
764//     access_type: "read_only",
765//     value_width: 64,
766//     wishbone_data_width: 32,
767//     base_width: 32,
768//     endianness: "big",
769// });
770//
771// litex_register_abstraction!(WriteOnly64C32B32 {
772//     access_type: "write_only",
773//     value_width: 64,
774//     wishbone_data_width: 32,
775//     base_width: 32,
776//     endianness: "big",
777// });
778//
779// litex_register_abstraction!(ReadWrite64C32B32 {
780//     access_type: "read_write",
781//     value_width: 64,
782//     wishbone_data_width: 32,
783//     base_width: 32,
784//     endianness: "big",
785// });
786
787#[repr(C)]
788pub struct ReadOnly8C8B32<N: RegisterLongName = ()> {
789    reg_p0: TRReadOnly<u8>,
790    _reserved_0: [u8; 3usize],
791    _regname: PhantomData<N>,
792}
793impl<N: RegisterLongName> BaseReadableRegister<u8> for ReadOnly8C8B32<N> {
794    type Reg = N;
795    const REG_WIDTH: usize = 8usize;
796    #[inline]
797    fn base_get(&self) -> u8 {
798        let reg_p0_val: [u8; 1usize] = u8::to_be_bytes(self.reg_p0.get());
799        u8::from_be_bytes([reg_p0_val[0usize]])
800    }
801}
802#[repr(C)]
803pub struct WriteOnly8C8B32<N: RegisterLongName = ()> {
804    reg_p0: TRWriteOnly<u8>,
805    _reserved_0: [u8; 3usize],
806    _regname: PhantomData<N>,
807}
808impl<N: RegisterLongName> BaseWriteableRegister<u8> for WriteOnly8C8B32<N> {
809    type Reg = N;
810    const REG_WIDTH: usize = 8usize;
811    #[inline]
812    fn base_set(&self, value: u8) {
813        let bytes: [u8; 1usize] = u8::to_be_bytes(value);
814        self.reg_p0.set(u8::from_be_bytes([bytes[0usize]]));
815    }
816}
817#[repr(C)]
818pub struct ReadWrite8C8B32<N: RegisterLongName = ()> {
819    reg_p0: TRReadWrite<u8>,
820    _reserved_0: [u8; 3usize],
821    _regname: PhantomData<N>,
822}
823impl<N: RegisterLongName> BaseReadableRegister<u8> for ReadWrite8C8B32<N> {
824    type Reg = N;
825    const REG_WIDTH: usize = 8usize;
826    #[inline]
827    fn base_get(&self) -> u8 {
828        let reg_p0_val: [u8; 1usize] = u8::to_be_bytes(self.reg_p0.get());
829        u8::from_be_bytes([reg_p0_val[0usize]])
830    }
831}
832impl<N: RegisterLongName> BaseWriteableRegister<u8> for ReadWrite8C8B32<N> {
833    type Reg = N;
834    const REG_WIDTH: usize = 8usize;
835    #[inline]
836    fn base_set(&self, value: u8) {
837        let bytes: [u8; 1usize] = u8::to_be_bytes(value);
838        self.reg_p0.set(u8::from_be_bytes([bytes[0usize]]));
839    }
840}
841#[repr(C)]
842pub struct ReadOnly16C8B32<N: RegisterLongName = ()> {
843    reg_p0: TRReadOnly<u8>,
844    _reserved_0: [u8; 3usize],
845    reg_p1: TRReadOnly<u8>,
846    _reserved_1: [u8; 3usize],
847    _regname: PhantomData<N>,
848}
849impl<N: RegisterLongName> BaseReadableRegister<u16> for ReadOnly16C8B32<N> {
850    type Reg = N;
851    const REG_WIDTH: usize = 16usize;
852    #[inline]
853    fn base_get(&self) -> u16 {
854        let reg_p0_val: [u8; 1usize] = u8::to_be_bytes(self.reg_p0.get());
855        let reg_p1_val: [u8; 1usize] = u8::to_be_bytes(self.reg_p1.get());
856        u16::from_be_bytes([reg_p0_val[0usize], reg_p1_val[0usize]])
857    }
858}
859#[repr(C)]
860pub struct WriteOnly16C8B32<N: RegisterLongName = ()> {
861    reg_p0: TRWriteOnly<u8>,
862    _reserved_0: [u8; 3usize],
863    reg_p1: TRWriteOnly<u8>,
864    _reserved_1: [u8; 3usize],
865    _regname: PhantomData<N>,
866}
867impl<N: RegisterLongName> BaseWriteableRegister<u16> for WriteOnly16C8B32<N> {
868    type Reg = N;
869    const REG_WIDTH: usize = 16usize;
870    #[inline]
871    fn base_set(&self, value: u16) {
872        let bytes: [u8; 2usize] = u16::to_be_bytes(value);
873        self.reg_p0.set(u8::from_be_bytes([bytes[0usize]]));
874        self.reg_p1.set(u8::from_be_bytes([bytes[1usize]]));
875    }
876}
877#[repr(C)]
878pub struct ReadWrite16C8B32<N: RegisterLongName = ()> {
879    reg_p0: TRReadWrite<u8>,
880    _reserved_0: [u8; 3usize],
881    reg_p1: TRReadWrite<u8>,
882    _reserved_1: [u8; 3usize],
883    _regname: PhantomData<N>,
884}
885impl<N: RegisterLongName> BaseReadableRegister<u16> for ReadWrite16C8B32<N> {
886    type Reg = N;
887    const REG_WIDTH: usize = 16usize;
888    #[inline]
889    fn base_get(&self) -> u16 {
890        let reg_p0_val: [u8; 1usize] = u8::to_be_bytes(self.reg_p0.get());
891        let reg_p1_val: [u8; 1usize] = u8::to_be_bytes(self.reg_p1.get());
892        u16::from_be_bytes([reg_p0_val[0usize], reg_p1_val[0usize]])
893    }
894}
895impl<N: RegisterLongName> BaseWriteableRegister<u16> for ReadWrite16C8B32<N> {
896    type Reg = N;
897    const REG_WIDTH: usize = 16usize;
898    #[inline]
899    fn base_set(&self, value: u16) {
900        let bytes: [u8; 2usize] = u16::to_be_bytes(value);
901        self.reg_p0.set(u8::from_be_bytes([bytes[0usize]]));
902        self.reg_p1.set(u8::from_be_bytes([bytes[1usize]]));
903    }
904}
905#[repr(C)]
906pub struct ReadOnly32C8B32<N: RegisterLongName = ()> {
907    reg_p0: TRReadOnly<u8>,
908    _reserved_0: [u8; 3usize],
909    reg_p1: TRReadOnly<u8>,
910    _reserved_1: [u8; 3usize],
911    reg_p2: TRReadOnly<u8>,
912    _reserved_2: [u8; 3usize],
913    reg_p3: TRReadOnly<u8>,
914    _reserved_3: [u8; 3usize],
915    _regname: PhantomData<N>,
916}
917impl<N: RegisterLongName> BaseReadableRegister<u32> for ReadOnly32C8B32<N> {
918    type Reg = N;
919    const REG_WIDTH: usize = 32usize;
920    #[inline]
921    fn base_get(&self) -> u32 {
922        let reg_p0_val: [u8; 1usize] = u8::to_be_bytes(self.reg_p0.get());
923        let reg_p1_val: [u8; 1usize] = u8::to_be_bytes(self.reg_p1.get());
924        let reg_p2_val: [u8; 1usize] = u8::to_be_bytes(self.reg_p2.get());
925        let reg_p3_val: [u8; 1usize] = u8::to_be_bytes(self.reg_p3.get());
926        u32::from_be_bytes([
927            reg_p0_val[0usize],
928            reg_p1_val[0usize],
929            reg_p2_val[0usize],
930            reg_p3_val[0usize],
931        ])
932    }
933}
934#[repr(C)]
935pub struct WriteOnly32C8B32<N: RegisterLongName = ()> {
936    reg_p0: TRWriteOnly<u8>,
937    _reserved_0: [u8; 3usize],
938    reg_p1: TRWriteOnly<u8>,
939    _reserved_1: [u8; 3usize],
940    reg_p2: TRWriteOnly<u8>,
941    _reserved_2: [u8; 3usize],
942    reg_p3: TRWriteOnly<u8>,
943    _reserved_3: [u8; 3usize],
944    _regname: PhantomData<N>,
945}
946impl<N: RegisterLongName> BaseWriteableRegister<u32> for WriteOnly32C8B32<N> {
947    type Reg = N;
948    const REG_WIDTH: usize = 32usize;
949    #[inline]
950    fn base_set(&self, value: u32) {
951        let bytes: [u8; 4usize] = u32::to_be_bytes(value);
952        self.reg_p0.set(u8::from_be_bytes([bytes[0usize]]));
953        self.reg_p1.set(u8::from_be_bytes([bytes[1usize]]));
954        self.reg_p2.set(u8::from_be_bytes([bytes[2usize]]));
955        self.reg_p3.set(u8::from_be_bytes([bytes[3usize]]));
956    }
957}
958#[repr(C)]
959pub struct ReadWrite32C8B32<N: RegisterLongName = ()> {
960    reg_p0: TRReadWrite<u8>,
961    _reserved_0: [u8; 3usize],
962    reg_p1: TRReadWrite<u8>,
963    _reserved_1: [u8; 3usize],
964    reg_p2: TRReadWrite<u8>,
965    _reserved_2: [u8; 3usize],
966    reg_p3: TRReadWrite<u8>,
967    _reserved_3: [u8; 3usize],
968    _regname: PhantomData<N>,
969}
970impl<N: RegisterLongName> BaseReadableRegister<u32> for ReadWrite32C8B32<N> {
971    type Reg = N;
972    const REG_WIDTH: usize = 32usize;
973    #[inline]
974    fn base_get(&self) -> u32 {
975        let reg_p0_val: [u8; 1usize] = u8::to_be_bytes(self.reg_p0.get());
976        let reg_p1_val: [u8; 1usize] = u8::to_be_bytes(self.reg_p1.get());
977        let reg_p2_val: [u8; 1usize] = u8::to_be_bytes(self.reg_p2.get());
978        let reg_p3_val: [u8; 1usize] = u8::to_be_bytes(self.reg_p3.get());
979        u32::from_be_bytes([
980            reg_p0_val[0usize],
981            reg_p1_val[0usize],
982            reg_p2_val[0usize],
983            reg_p3_val[0usize],
984        ])
985    }
986}
987impl<N: RegisterLongName> BaseWriteableRegister<u32> for ReadWrite32C8B32<N> {
988    type Reg = N;
989    const REG_WIDTH: usize = 32usize;
990    #[inline]
991    fn base_set(&self, value: u32) {
992        let bytes: [u8; 4usize] = u32::to_be_bytes(value);
993        self.reg_p0.set(u8::from_be_bytes([bytes[0usize]]));
994        self.reg_p1.set(u8::from_be_bytes([bytes[1usize]]));
995        self.reg_p2.set(u8::from_be_bytes([bytes[2usize]]));
996        self.reg_p3.set(u8::from_be_bytes([bytes[3usize]]));
997    }
998}
999#[repr(C)]
1000pub struct ReadOnly64C8B32<N: RegisterLongName = ()> {
1001    reg_p0: TRReadOnly<u8>,
1002    _reserved_0: [u8; 3usize],
1003    reg_p1: TRReadOnly<u8>,
1004    _reserved_1: [u8; 3usize],
1005    reg_p2: TRReadOnly<u8>,
1006    _reserved_2: [u8; 3usize],
1007    reg_p3: TRReadOnly<u8>,
1008    _reserved_3: [u8; 3usize],
1009    reg_p4: TRReadOnly<u8>,
1010    _reserved_4: [u8; 3usize],
1011    reg_p5: TRReadOnly<u8>,
1012    _reserved_5: [u8; 3usize],
1013    reg_p6: TRReadOnly<u8>,
1014    _reserved_6: [u8; 3usize],
1015    reg_p7: TRReadOnly<u8>,
1016    _reserved_7: [u8; 3usize],
1017    _regname: PhantomData<N>,
1018}
1019impl<N: RegisterLongName> BaseReadableRegister<u64> for ReadOnly64C8B32<N> {
1020    type Reg = N;
1021    const REG_WIDTH: usize = 64usize;
1022    #[inline]
1023    fn base_get(&self) -> u64 {
1024        let reg_p0_val: [u8; 1usize] = u8::to_be_bytes(self.reg_p0.get());
1025        let reg_p1_val: [u8; 1usize] = u8::to_be_bytes(self.reg_p1.get());
1026        let reg_p2_val: [u8; 1usize] = u8::to_be_bytes(self.reg_p2.get());
1027        let reg_p3_val: [u8; 1usize] = u8::to_be_bytes(self.reg_p3.get());
1028        let reg_p4_val: [u8; 1usize] = u8::to_be_bytes(self.reg_p4.get());
1029        let reg_p5_val: [u8; 1usize] = u8::to_be_bytes(self.reg_p5.get());
1030        let reg_p6_val: [u8; 1usize] = u8::to_be_bytes(self.reg_p6.get());
1031        let reg_p7_val: [u8; 1usize] = u8::to_be_bytes(self.reg_p7.get());
1032        u64::from_be_bytes([
1033            reg_p0_val[0usize],
1034            reg_p1_val[0usize],
1035            reg_p2_val[0usize],
1036            reg_p3_val[0usize],
1037            reg_p4_val[0usize],
1038            reg_p5_val[0usize],
1039            reg_p6_val[0usize],
1040            reg_p7_val[0usize],
1041        ])
1042    }
1043}
1044#[repr(C)]
1045pub struct WriteOnly64C8B32<N: RegisterLongName = ()> {
1046    reg_p0: TRWriteOnly<u8>,
1047    _reserved_0: [u8; 3usize],
1048    reg_p1: TRWriteOnly<u8>,
1049    _reserved_1: [u8; 3usize],
1050    reg_p2: TRWriteOnly<u8>,
1051    _reserved_2: [u8; 3usize],
1052    reg_p3: TRWriteOnly<u8>,
1053    _reserved_3: [u8; 3usize],
1054    reg_p4: TRWriteOnly<u8>,
1055    _reserved_4: [u8; 3usize],
1056    reg_p5: TRWriteOnly<u8>,
1057    _reserved_5: [u8; 3usize],
1058    reg_p6: TRWriteOnly<u8>,
1059    _reserved_6: [u8; 3usize],
1060    reg_p7: TRWriteOnly<u8>,
1061    _reserved_7: [u8; 3usize],
1062    _regname: PhantomData<N>,
1063}
1064impl<N: RegisterLongName> BaseWriteableRegister<u64> for WriteOnly64C8B32<N> {
1065    type Reg = N;
1066    const REG_WIDTH: usize = 64usize;
1067    #[inline]
1068    fn base_set(&self, value: u64) {
1069        let bytes: [u8; 8usize] = u64::to_be_bytes(value);
1070        self.reg_p0.set(u8::from_be_bytes([bytes[0usize]]));
1071        self.reg_p1.set(u8::from_be_bytes([bytes[1usize]]));
1072        self.reg_p2.set(u8::from_be_bytes([bytes[2usize]]));
1073        self.reg_p3.set(u8::from_be_bytes([bytes[3usize]]));
1074        self.reg_p4.set(u8::from_be_bytes([bytes[4usize]]));
1075        self.reg_p5.set(u8::from_be_bytes([bytes[5usize]]));
1076        self.reg_p6.set(u8::from_be_bytes([bytes[6usize]]));
1077        self.reg_p7.set(u8::from_be_bytes([bytes[7usize]]));
1078    }
1079}
1080#[repr(C)]
1081pub struct ReadWrite64C8B32<N: RegisterLongName = ()> {
1082    reg_p0: TRReadWrite<u8>,
1083    _reserved_0: [u8; 3usize],
1084    reg_p1: TRReadWrite<u8>,
1085    _reserved_1: [u8; 3usize],
1086    reg_p2: TRReadWrite<u8>,
1087    _reserved_2: [u8; 3usize],
1088    reg_p3: TRReadWrite<u8>,
1089    _reserved_3: [u8; 3usize],
1090    reg_p4: TRReadWrite<u8>,
1091    _reserved_4: [u8; 3usize],
1092    reg_p5: TRReadWrite<u8>,
1093    _reserved_5: [u8; 3usize],
1094    reg_p6: TRReadWrite<u8>,
1095    _reserved_6: [u8; 3usize],
1096    reg_p7: TRReadWrite<u8>,
1097    _reserved_7: [u8; 3usize],
1098    _regname: PhantomData<N>,
1099}
1100impl<N: RegisterLongName> BaseReadableRegister<u64> for ReadWrite64C8B32<N> {
1101    type Reg = N;
1102    const REG_WIDTH: usize = 64usize;
1103    #[inline]
1104    fn base_get(&self) -> u64 {
1105        let reg_p0_val: [u8; 1usize] = u8::to_be_bytes(self.reg_p0.get());
1106        let reg_p1_val: [u8; 1usize] = u8::to_be_bytes(self.reg_p1.get());
1107        let reg_p2_val: [u8; 1usize] = u8::to_be_bytes(self.reg_p2.get());
1108        let reg_p3_val: [u8; 1usize] = u8::to_be_bytes(self.reg_p3.get());
1109        let reg_p4_val: [u8; 1usize] = u8::to_be_bytes(self.reg_p4.get());
1110        let reg_p5_val: [u8; 1usize] = u8::to_be_bytes(self.reg_p5.get());
1111        let reg_p6_val: [u8; 1usize] = u8::to_be_bytes(self.reg_p6.get());
1112        let reg_p7_val: [u8; 1usize] = u8::to_be_bytes(self.reg_p7.get());
1113        u64::from_be_bytes([
1114            reg_p0_val[0usize],
1115            reg_p1_val[0usize],
1116            reg_p2_val[0usize],
1117            reg_p3_val[0usize],
1118            reg_p4_val[0usize],
1119            reg_p5_val[0usize],
1120            reg_p6_val[0usize],
1121            reg_p7_val[0usize],
1122        ])
1123    }
1124}
1125impl<N: RegisterLongName> BaseWriteableRegister<u64> for ReadWrite64C8B32<N> {
1126    type Reg = N;
1127    const REG_WIDTH: usize = 64usize;
1128    #[inline]
1129    fn base_set(&self, value: u64) {
1130        let bytes: [u8; 8usize] = u64::to_be_bytes(value);
1131        self.reg_p0.set(u8::from_be_bytes([bytes[0usize]]));
1132        self.reg_p1.set(u8::from_be_bytes([bytes[1usize]]));
1133        self.reg_p2.set(u8::from_be_bytes([bytes[2usize]]));
1134        self.reg_p3.set(u8::from_be_bytes([bytes[3usize]]));
1135        self.reg_p4.set(u8::from_be_bytes([bytes[4usize]]));
1136        self.reg_p5.set(u8::from_be_bytes([bytes[5usize]]));
1137        self.reg_p6.set(u8::from_be_bytes([bytes[6usize]]));
1138        self.reg_p7.set(u8::from_be_bytes([bytes[7usize]]));
1139    }
1140}
1141#[repr(C)]
1142pub struct ReadOnly8C32B32<N: RegisterLongName = ()> {
1143    reg_p0: TRReadOnly<u8>,
1144    _reserved_0: [u8; 3usize],
1145    _regname: PhantomData<N>,
1146}
1147impl<N: RegisterLongName> BaseReadableRegister<u8> for ReadOnly8C32B32<N> {
1148    type Reg = N;
1149    const REG_WIDTH: usize = 8usize;
1150    fn base_get(&self) -> u8 {
1151        self.reg_p0.get()
1152    }
1153}
1154#[repr(C)]
1155pub struct WriteOnly8C32B32<N: RegisterLongName = ()> {
1156    reg_p0: TRWriteOnly<u8>,
1157    _reserved_0: [u8; 3usize],
1158    _regname: PhantomData<N>,
1159}
1160impl<N: RegisterLongName> BaseWriteableRegister<u8> for WriteOnly8C32B32<N> {
1161    type Reg = N;
1162    const REG_WIDTH: usize = 8usize;
1163    #[inline]
1164    fn base_set(&self, value: u8) {
1165        self.reg_p0.set(value)
1166    }
1167}
1168#[repr(C)]
1169pub struct ReadWrite8C32B32<N: RegisterLongName = ()> {
1170    reg_p0: TRReadWrite<u8>,
1171    _reserved_0: [u8; 3usize],
1172    _regname: PhantomData<N>,
1173}
1174impl<N: RegisterLongName> BaseReadableRegister<u8> for ReadWrite8C32B32<N> {
1175    type Reg = N;
1176    const REG_WIDTH: usize = 8usize;
1177    fn base_get(&self) -> u8 {
1178        self.reg_p0.get()
1179    }
1180}
1181impl<N: RegisterLongName> BaseWriteableRegister<u8> for ReadWrite8C32B32<N> {
1182    type Reg = N;
1183    const REG_WIDTH: usize = 8usize;
1184    #[inline]
1185    fn base_set(&self, value: u8) {
1186        self.reg_p0.set(value)
1187    }
1188}
1189#[repr(C)]
1190pub struct ReadOnly16C32B32<N: RegisterLongName = ()> {
1191    reg_p0: TRReadOnly<u16>,
1192    _reserved_0: [u8; 2usize],
1193    _regname: PhantomData<N>,
1194}
1195impl<N: RegisterLongName> BaseReadableRegister<u16> for ReadOnly16C32B32<N> {
1196    type Reg = N;
1197    const REG_WIDTH: usize = 16usize;
1198    fn base_get(&self) -> u16 {
1199        self.reg_p0.get()
1200    }
1201}
1202#[repr(C)]
1203pub struct WriteOnly16C32B32<N: RegisterLongName = ()> {
1204    reg_p0: TRWriteOnly<u16>,
1205    _reserved_0: [u8; 2usize],
1206    _regname: PhantomData<N>,
1207}
1208impl<N: RegisterLongName> BaseWriteableRegister<u16> for WriteOnly16C32B32<N> {
1209    type Reg = N;
1210    const REG_WIDTH: usize = 16usize;
1211    #[inline]
1212    fn base_set(&self, value: u16) {
1213        self.reg_p0.set(value)
1214    }
1215}
1216#[repr(C)]
1217pub struct ReadWrite16C32B32<N: RegisterLongName = ()> {
1218    reg_p0: TRReadWrite<u16>,
1219    _reserved_0: [u8; 2usize],
1220    _regname: PhantomData<N>,
1221}
1222impl<N: RegisterLongName> BaseReadableRegister<u16> for ReadWrite16C32B32<N> {
1223    type Reg = N;
1224    const REG_WIDTH: usize = 16usize;
1225    fn base_get(&self) -> u16 {
1226        self.reg_p0.get()
1227    }
1228}
1229impl<N: RegisterLongName> BaseWriteableRegister<u16> for ReadWrite16C32B32<N> {
1230    type Reg = N;
1231    const REG_WIDTH: usize = 16usize;
1232    #[inline]
1233    fn base_set(&self, value: u16) {
1234        self.reg_p0.set(value)
1235    }
1236}
1237#[repr(C)]
1238pub struct ReadOnly32C32B32<N: RegisterLongName = ()> {
1239    reg_p0: TRReadOnly<u32>,
1240    _reserved_0: [u8; 0usize],
1241    _regname: PhantomData<N>,
1242}
1243impl<N: RegisterLongName> BaseReadableRegister<u32> for ReadOnly32C32B32<N> {
1244    type Reg = N;
1245    const REG_WIDTH: usize = 32usize;
1246    #[inline]
1247    fn base_get(&self) -> u32 {
1248        let reg_p0_val: [u8; 4usize] = u32::to_be_bytes(self.reg_p0.get());
1249        u32::from_be_bytes([
1250            reg_p0_val[0usize],
1251            reg_p0_val[1usize],
1252            reg_p0_val[2usize],
1253            reg_p0_val[3usize],
1254        ])
1255    }
1256}
1257#[repr(C)]
1258pub struct WriteOnly32C32B32<N: RegisterLongName = ()> {
1259    reg_p0: TRWriteOnly<u32>,
1260    _reserved_0: [u8; 0usize],
1261    _regname: PhantomData<N>,
1262}
1263impl<N: RegisterLongName> BaseWriteableRegister<u32> for WriteOnly32C32B32<N> {
1264    type Reg = N;
1265    const REG_WIDTH: usize = 32usize;
1266    #[inline]
1267    fn base_set(&self, value: u32) {
1268        let bytes: [u8; 4usize] = u32::to_be_bytes(value);
1269        self.reg_p0.set(u32::from_be_bytes([
1270            bytes[0usize],
1271            bytes[1usize],
1272            bytes[2usize],
1273            bytes[3usize],
1274        ]));
1275    }
1276}
1277#[repr(C)]
1278pub struct ReadWrite32C32B32<N: RegisterLongName = ()> {
1279    reg_p0: TRReadWrite<u32>,
1280    _reserved_0: [u8; 0usize],
1281    _regname: PhantomData<N>,
1282}
1283impl<N: RegisterLongName> BaseReadableRegister<u32> for ReadWrite32C32B32<N> {
1284    type Reg = N;
1285    const REG_WIDTH: usize = 32usize;
1286    #[inline]
1287    fn base_get(&self) -> u32 {
1288        let reg_p0_val: [u8; 4usize] = u32::to_be_bytes(self.reg_p0.get());
1289        u32::from_be_bytes([
1290            reg_p0_val[0usize],
1291            reg_p0_val[1usize],
1292            reg_p0_val[2usize],
1293            reg_p0_val[3usize],
1294        ])
1295    }
1296}
1297impl<N: RegisterLongName> BaseWriteableRegister<u32> for ReadWrite32C32B32<N> {
1298    type Reg = N;
1299    const REG_WIDTH: usize = 32usize;
1300    #[inline]
1301    fn base_set(&self, value: u32) {
1302        let bytes: [u8; 4usize] = u32::to_be_bytes(value);
1303        self.reg_p0.set(u32::from_be_bytes([
1304            bytes[0usize],
1305            bytes[1usize],
1306            bytes[2usize],
1307            bytes[3usize],
1308        ]));
1309    }
1310}
1311#[repr(C)]
1312pub struct ReadOnly64C32B32<N: RegisterLongName = ()> {
1313    reg_p0: TRReadOnly<u32>,
1314    _reserved_0: [u8; 0usize],
1315    reg_p1: TRReadOnly<u32>,
1316    _reserved_1: [u8; 0usize],
1317    _regname: PhantomData<N>,
1318}
1319impl<N: RegisterLongName> BaseReadableRegister<u64> for ReadOnly64C32B32<N> {
1320    type Reg = N;
1321    const REG_WIDTH: usize = 64usize;
1322    #[inline]
1323    fn base_get(&self) -> u64 {
1324        let reg_p0_val: [u8; 4usize] = u32::to_be_bytes(self.reg_p0.get());
1325        let reg_p1_val: [u8; 4usize] = u32::to_be_bytes(self.reg_p1.get());
1326        u64::from_be_bytes([
1327            reg_p0_val[0usize],
1328            reg_p0_val[1usize],
1329            reg_p0_val[2usize],
1330            reg_p0_val[3usize],
1331            reg_p1_val[0usize],
1332            reg_p1_val[1usize],
1333            reg_p1_val[2usize],
1334            reg_p1_val[3usize],
1335        ])
1336    }
1337}
1338#[repr(C)]
1339pub struct WriteOnly64C32B32<N: RegisterLongName = ()> {
1340    reg_p0: TRWriteOnly<u32>,
1341    _reserved_0: [u8; 0usize],
1342    reg_p1: TRWriteOnly<u32>,
1343    _reserved_1: [u8; 0usize],
1344    _regname: PhantomData<N>,
1345}
1346impl<N: RegisterLongName> BaseWriteableRegister<u64> for WriteOnly64C32B32<N> {
1347    type Reg = N;
1348    const REG_WIDTH: usize = 64usize;
1349    #[inline]
1350    fn base_set(&self, value: u64) {
1351        let bytes: [u8; 8usize] = u64::to_be_bytes(value);
1352        self.reg_p0.set(u32::from_be_bytes([
1353            bytes[0usize],
1354            bytes[1usize],
1355            bytes[2usize],
1356            bytes[3usize],
1357        ]));
1358        self.reg_p1.set(u32::from_be_bytes([
1359            bytes[4usize],
1360            bytes[5usize],
1361            bytes[6usize],
1362            bytes[7usize],
1363        ]));
1364    }
1365}
1366#[repr(C)]
1367pub struct ReadWrite64C32B32<N: RegisterLongName = ()> {
1368    reg_p0: TRReadWrite<u32>,
1369    _reserved_0: [u8; 0usize],
1370    reg_p1: TRReadWrite<u32>,
1371    _reserved_1: [u8; 0usize],
1372    _regname: PhantomData<N>,
1373}
1374impl<N: RegisterLongName> BaseReadableRegister<u64> for ReadWrite64C32B32<N> {
1375    type Reg = N;
1376    const REG_WIDTH: usize = 64usize;
1377    #[inline]
1378    fn base_get(&self) -> u64 {
1379        let reg_p0_val: [u8; 4usize] = u32::to_be_bytes(self.reg_p0.get());
1380        let reg_p1_val: [u8; 4usize] = u32::to_be_bytes(self.reg_p1.get());
1381        u64::from_be_bytes([
1382            reg_p0_val[0usize],
1383            reg_p0_val[1usize],
1384            reg_p0_val[2usize],
1385            reg_p0_val[3usize],
1386            reg_p1_val[0usize],
1387            reg_p1_val[1usize],
1388            reg_p1_val[2usize],
1389            reg_p1_val[3usize],
1390        ])
1391    }
1392}
1393impl<N: RegisterLongName> BaseWriteableRegister<u64> for ReadWrite64C32B32<N> {
1394    type Reg = N;
1395    const REG_WIDTH: usize = 64usize;
1396    #[inline]
1397    fn base_set(&self, value: u64) {
1398        let bytes: [u8; 8usize] = u64::to_be_bytes(value);
1399        self.reg_p0.set(u32::from_be_bytes([
1400            bytes[0usize],
1401            bytes[1usize],
1402            bytes[2usize],
1403            bytes[3usize],
1404        ]));
1405        self.reg_p1.set(u32::from_be_bytes([
1406            bytes[4usize],
1407            bytes[5usize],
1408            bytes[6usize],
1409            bytes[7usize],
1410        ]));
1411    }
1412}