forked from libre-chip/cpu
add address_range to MemoryInterfaceConfig and add support to simple_uart
This commit is contained in:
parent
2c8de5bec4
commit
3080ea4ce2
5 changed files with 169 additions and 50 deletions
|
|
@ -3,16 +3,110 @@
|
|||
|
||||
use crate::{config::CpuConfig, next_pc::FETCH_BLOCK_ID_WIDTH, util::array_vec::ArrayVec};
|
||||
use fayalite::{prelude::*, util::ready_valid::ReadyValid};
|
||||
use std::num::NonZeroUsize;
|
||||
use std::num::{NonZeroU64, NonZeroUsize, Wrapping};
|
||||
|
||||
pub mod simple_uart;
|
||||
|
||||
#[derive(Clone, Eq, PartialEq, Hash, Debug, serde::Serialize, serde::Deserialize)]
|
||||
#[derive(Copy, Clone, Eq, PartialEq, Hash, Debug, serde::Serialize, serde::Deserialize)]
|
||||
pub enum AddressRange {
|
||||
Full,
|
||||
Limited {
|
||||
start: Wrapping<u64>,
|
||||
size: NonZeroU64,
|
||||
},
|
||||
}
|
||||
|
||||
impl AddressRange {
|
||||
pub const fn from_wrapping_range_inclusive(range: std::ops::RangeInclusive<u64>) -> Self {
|
||||
let start = Wrapping(*range.start());
|
||||
let Some(size) = NonZeroU64::new(range.end().wrapping_sub(start.0).wrapping_add(1)) else {
|
||||
return Self::Full;
|
||||
};
|
||||
Self::Limited { start, size }
|
||||
}
|
||||
pub const fn try_from_range(range: std::ops::Range<u64>) -> Option<Self> {
|
||||
let start = Wrapping(range.start);
|
||||
let Some(size) = NonZeroU64::new(range.end.saturating_sub(range.start)) else {
|
||||
return None;
|
||||
};
|
||||
Some(Self::Limited { start, size })
|
||||
}
|
||||
#[track_caller]
|
||||
pub const fn from_range(range: std::ops::Range<u64>) -> Self {
|
||||
Self::try_from_range(range).expect("range must not be empty")
|
||||
}
|
||||
pub const fn try_from_range_inclusive(range: std::ops::RangeInclusive<u64>) -> Option<Self> {
|
||||
let start = Wrapping(*range.start());
|
||||
let Some(end_minus_start) = range.end().checked_sub(start.0) else {
|
||||
return None;
|
||||
};
|
||||
let Some(size) = end_minus_start.checked_add(1) else {
|
||||
return Some(Self::Full);
|
||||
};
|
||||
let Some(size) = NonZeroU64::new(size) else {
|
||||
unreachable!();
|
||||
};
|
||||
Some(Self::Limited { start, size })
|
||||
}
|
||||
#[track_caller]
|
||||
pub const fn from_range_inclusive(range: std::ops::RangeInclusive<u64>) -> Self {
|
||||
Self::try_from_range_inclusive(range).expect("range must not be empty")
|
||||
}
|
||||
pub const fn start(self) -> Wrapping<u64> {
|
||||
match self {
|
||||
Self::Full => Wrapping(0),
|
||||
Self::Limited { start, .. } => start,
|
||||
}
|
||||
}
|
||||
pub const fn size(self) -> Option<NonZeroU64> {
|
||||
match self {
|
||||
Self::Full => None,
|
||||
Self::Limited { size, .. } => Some(size),
|
||||
}
|
||||
}
|
||||
pub const fn size_minus_one(self) -> u64 {
|
||||
match self {
|
||||
AddressRange::Full => u64::MAX,
|
||||
AddressRange::Limited { size, .. } => size.get() - 1,
|
||||
}
|
||||
}
|
||||
/// last address contained in `self`
|
||||
pub const fn last(self) -> u64 {
|
||||
self.start().0.wrapping_add(self.size_minus_one())
|
||||
}
|
||||
pub const fn contains(self, address: u64) -> bool {
|
||||
match self {
|
||||
Self::Full => true,
|
||||
Self::Limited { start, size } => address.wrapping_sub(start.0) < size.get(),
|
||||
}
|
||||
}
|
||||
pub const fn wrapping_add(self, offset: u64) -> Self {
|
||||
match self {
|
||||
Self::Full => Self::Full,
|
||||
Self::Limited { start, size } => Self::Limited {
|
||||
start: Wrapping(start.0.wrapping_add(offset)),
|
||||
size,
|
||||
},
|
||||
}
|
||||
}
|
||||
pub const fn wrapping_sub(self, offset: u64) -> Self {
|
||||
match self {
|
||||
Self::Full => Self::Full,
|
||||
Self::Limited { start, size } => Self::Limited {
|
||||
start: Wrapping(start.0.wrapping_sub(offset)),
|
||||
size,
|
||||
},
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
#[derive(Copy, Clone, Eq, PartialEq, Hash, Debug, serde::Serialize, serde::Deserialize)]
|
||||
#[non_exhaustive]
|
||||
pub struct MemoryInterfaceConfig {
|
||||
pub log2_bus_width_in_bytes: u8,
|
||||
pub queue_capacity: NonZeroUsize,
|
||||
pub op_id_width: usize,
|
||||
pub address_range: AddressRange,
|
||||
}
|
||||
|
||||
impl MemoryInterfaceConfig {
|
||||
|
|
@ -21,6 +115,7 @@ impl MemoryInterfaceConfig {
|
|||
log2_bus_width_in_bytes: config.log2_fetch_width_in_bytes,
|
||||
queue_capacity: config.max_fetches_in_flight,
|
||||
op_id_width: FETCH_BLOCK_ID_WIDTH,
|
||||
address_range: AddressRange::Full,
|
||||
}
|
||||
}
|
||||
pub const fn bus_width_in_bytes(&self) -> usize {
|
||||
|
|
|
|||
|
|
@ -1,12 +1,13 @@
|
|||
// SPDX-License-Identifier: LGPL-3.0-or-later
|
||||
// See Notices.txt for copyright information
|
||||
|
||||
use std::num::NonZeroUsize;
|
||||
use std::num::{NonZeroU64, NonZeroUsize, Wrapping};
|
||||
|
||||
use crate::{
|
||||
main_memory_and_io::{
|
||||
MemoryInterface, MemoryInterfaceConfig, MemoryOperationErrorKind, MemoryOperationFinish,
|
||||
MemoryOperationFinishKind, MemoryOperationKind, MemoryOperationStart,
|
||||
AddressRange, MemoryInterface, MemoryInterfaceConfig, MemoryOperationErrorKind,
|
||||
MemoryOperationFinish, MemoryOperationFinishKind, MemoryOperationKind,
|
||||
MemoryOperationStart,
|
||||
},
|
||||
util::array_vec::ArrayVec,
|
||||
};
|
||||
|
|
@ -357,7 +358,8 @@ pub fn receiver(queue_capacity: NonZeroUsize) {
|
|||
pub const SIMPLE_UART_RECEIVE_OFFSET: u64 = 0;
|
||||
pub const SIMPLE_UART_TRANSMIT_OFFSET: u64 = 0;
|
||||
pub const SIMPLE_UART_STATUS_OFFSET: u64 = 1;
|
||||
pub const SIMPLE_UART_SIZE: u64 = 1 << SIMPLE_UART_LOG2_SIZE;
|
||||
pub const SIMPLE_UART_SIZE: NonZeroU64 =
|
||||
NonZeroU64::new(1 << SIMPLE_UART_LOG2_SIZE).expect("known to be non-zero");
|
||||
pub const SIMPLE_UART_LOG2_SIZE: u8 = 1;
|
||||
|
||||
#[hdl(no_static)]
|
||||
|
|
@ -366,11 +368,22 @@ struct Operation<C: PhantomConstGet<MemoryInterfaceConfig>> {
|
|||
finish: HdlOption<MemoryOperationFinish<C>>,
|
||||
}
|
||||
|
||||
pub const fn simple_uart_memory_interface_config(op_id_width: usize) -> MemoryInterfaceConfig {
|
||||
pub const fn simple_uart_memory_interface_config(
|
||||
op_id_width: usize,
|
||||
start_address: Wrapping<u64>,
|
||||
) -> MemoryInterfaceConfig {
|
||||
assert!(
|
||||
start_address.0 % SIMPLE_UART_SIZE.get() == 0,
|
||||
"start_address must be properly aligned"
|
||||
);
|
||||
MemoryInterfaceConfig {
|
||||
log2_bus_width_in_bytes: SIMPLE_UART_LOG2_SIZE,
|
||||
queue_capacity: const { NonZeroUsize::new(1).unwrap() },
|
||||
op_id_width,
|
||||
address_range: AddressRange::Limited {
|
||||
start: start_address,
|
||||
size: SIMPLE_UART_SIZE,
|
||||
},
|
||||
}
|
||||
}
|
||||
|
||||
|
|
@ -381,9 +394,10 @@ pub fn simple_uart(
|
|||
baud_rate: f64,
|
||||
receiver_queue_size: NonZeroUsize,
|
||||
) {
|
||||
let start_address = config.get().address_range.start();
|
||||
assert_eq!(
|
||||
*config.get(),
|
||||
simple_uart_memory_interface_config(config.get().op_id_width),
|
||||
simple_uart_memory_interface_config(config.get().op_id_width, start_address),
|
||||
);
|
||||
#[hdl]
|
||||
let cd: ClockDomain = m.input();
|
||||
|
|
@ -486,14 +500,18 @@ pub fn simple_uart(
|
|||
match kind {
|
||||
MemoryOperationKind::Read => {
|
||||
#[hdl]
|
||||
if byte_addr.cmp_eq(SIMPLE_UART_RECEIVE_OFFSET) {
|
||||
if byte_addr
|
||||
.cmp_eq(start_address.0.wrapping_add(SIMPLE_UART_RECEIVE_OFFSET))
|
||||
{
|
||||
connect(receiver.output_byte.ready, valid_addr);
|
||||
#[hdl]
|
||||
if let HdlSome(byte) = receiver.output_byte.data {
|
||||
connect(read_data, byte);
|
||||
}
|
||||
// if there is no byte ready yet, we read a zero to avoid blocking the CPU on external inputs.
|
||||
} else if byte_addr.cmp_eq(SIMPLE_UART_STATUS_OFFSET) {
|
||||
} else if byte_addr
|
||||
.cmp_eq(start_address.0.wrapping_add(SIMPLE_UART_STATUS_OFFSET))
|
||||
{
|
||||
connect(
|
||||
read_data,
|
||||
receiver
|
||||
|
|
@ -507,7 +525,9 @@ pub fn simple_uart(
|
|||
}
|
||||
MemoryOperationKind::Write => {
|
||||
#[hdl]
|
||||
if byte_addr.cmp_eq(SIMPLE_UART_TRANSMIT_OFFSET) {
|
||||
if byte_addr
|
||||
.cmp_eq(start_address.0.wrapping_add(SIMPLE_UART_TRANSMIT_OFFSET))
|
||||
{
|
||||
#[hdl]
|
||||
if !transmitter.input_byte.ready {
|
||||
connect(all_ready, false);
|
||||
|
|
|
|||
48
crates/cpu/tests/expected/fetch.vcd
generated
48
crates/cpu/tests/expected/fetch.vcd
generated
|
|
@ -3633,7 +3633,7 @@ b0 UA{3,"
|
|||
0mS#3<"
|
||||
0^qjb["
|
||||
b0 tN>yu"
|
||||
sPhantomConst({\"log2_bus_width_in_bytes\":3,\"queue_capacity\":16,\"op_id_width\":8}) '@T[?"
|
||||
sPhantomConst({\"log2_bus_width_in_bytes\":3,\"queue_capacity\":16,\"op_id_width\":8,\"address_range\":\"Full\"}) '@T[?"
|
||||
0BXk&["
|
||||
sHdlNone\x20(0) &wG|&"
|
||||
sSuccess\x20(0) ^F2z4"
|
||||
|
|
@ -3647,7 +3647,7 @@ b0 VXdV?"
|
|||
b0 =`@6L"
|
||||
b0 e2JF6"
|
||||
b0 ]ocL{"
|
||||
sPhantomConst({\"log2_bus_width_in_bytes\":3,\"queue_capacity\":16,\"op_id_width\":8}) ^<ah9"
|
||||
sPhantomConst({\"log2_bus_width_in_bytes\":3,\"queue_capacity\":16,\"op_id_width\":8,\"address_range\":\"Full\"}) ^<ah9"
|
||||
02sb.i"
|
||||
sHdlNone\x20(0) JC:kM"
|
||||
b0 .*4N""
|
||||
|
|
@ -3668,7 +3668,7 @@ b0 huWrb"
|
|||
b0 EO39y"
|
||||
b0 |d_{U"
|
||||
sPhantomConst(\"0..=16\") 3(idJ"
|
||||
sPhantomConst({\"log2_bus_width_in_bytes\":3,\"queue_capacity\":16,\"op_id_width\":8}) P'(UK"
|
||||
sPhantomConst({\"log2_bus_width_in_bytes\":3,\"queue_capacity\":16,\"op_id_width\":8,\"address_range\":\"Full\"}) P'(UK"
|
||||
sHdlSome\x20(1) N^Lck"
|
||||
b1000000000000 q3ltq"
|
||||
b0 zZOnr"
|
||||
|
|
@ -3756,7 +3756,7 @@ b0 46)Xi"
|
|||
0"(@LS"
|
||||
0&NGtM"
|
||||
b0 "tB6}"
|
||||
sPhantomConst({\"log2_bus_width_in_bytes\":3,\"queue_capacity\":16,\"op_id_width\":8}) Hn\.r"
|
||||
sPhantomConst({\"log2_bus_width_in_bytes\":3,\"queue_capacity\":16,\"op_id_width\":8,\"address_range\":\"Full\"}) Hn\.r"
|
||||
0jbUZ8"
|
||||
sHdlNone\x20(0) NcD^Z"
|
||||
sSuccess\x20(0) X3rb0"
|
||||
|
|
@ -3770,7 +3770,7 @@ b0 vyE_1"
|
|||
b0 D}2RZ"
|
||||
b0 \XUCp"
|
||||
b0 [^@q%"
|
||||
sPhantomConst({\"log2_bus_width_in_bytes\":3,\"queue_capacity\":16,\"op_id_width\":8}) G4KC#"
|
||||
sPhantomConst({\"log2_bus_width_in_bytes\":3,\"queue_capacity\":16,\"op_id_width\":8,\"address_range\":\"Full\"}) G4KC#"
|
||||
01thaQ"
|
||||
sHdlNone\x20(0) +5LtZ"
|
||||
b0 {6^Pl"
|
||||
|
|
@ -3791,7 +3791,7 @@ b0 iB{BF"
|
|||
b0 eR=Hx"
|
||||
b0 8!8=?"
|
||||
sPhantomConst(\"0..=16\") V?X!X"
|
||||
sPhantomConst({\"log2_bus_width_in_bytes\":3,\"queue_capacity\":16,\"op_id_width\":8}) T-cQB"
|
||||
sPhantomConst({\"log2_bus_width_in_bytes\":3,\"queue_capacity\":16,\"op_id_width\":8,\"address_range\":\"Full\"}) T-cQB"
|
||||
sHdlSome\x20(1) JqP67"
|
||||
b1000000000000 iRy|N"
|
||||
b0 IIeMq"
|
||||
|
|
@ -4439,7 +4439,7 @@ b0 H{?Xz"
|
|||
03\z-w"
|
||||
00^&W_"
|
||||
b0 n/%-/"
|
||||
sPhantomConst({\"log2_bus_width_in_bytes\":3,\"queue_capacity\":16,\"op_id_width\":8}) ./0U4"
|
||||
sPhantomConst({\"log2_bus_width_in_bytes\":3,\"queue_capacity\":16,\"op_id_width\":8,\"address_range\":\"Full\"}) ./0U4"
|
||||
0NE4rt"
|
||||
sHdlNone\x20(0) :GU,#"
|
||||
sSuccess\x20(0) D87*9"
|
||||
|
|
@ -4453,7 +4453,7 @@ b0 d%H]f"
|
|||
b0 zgzi@"
|
||||
b0 7B-!)"
|
||||
b0 Y1Qf)"
|
||||
sPhantomConst({\"log2_bus_width_in_bytes\":3,\"queue_capacity\":16,\"op_id_width\":8}) a.$Aw"
|
||||
sPhantomConst({\"log2_bus_width_in_bytes\":3,\"queue_capacity\":16,\"op_id_width\":8,\"address_range\":\"Full\"}) a.$Aw"
|
||||
0*d$ca"
|
||||
sHdlNone\x20(0) /N@6H"
|
||||
b0 '10Cg"
|
||||
|
|
@ -4474,7 +4474,7 @@ b0 hn|]["
|
|||
b0 bWF^\"
|
||||
b0 -"k'e"
|
||||
sPhantomConst(\"0..=16\") uoZP0"
|
||||
sPhantomConst({\"log2_bus_width_in_bytes\":3,\"queue_capacity\":16,\"op_id_width\":8}) /KK^t"
|
||||
sPhantomConst({\"log2_bus_width_in_bytes\":3,\"queue_capacity\":16,\"op_id_width\":8,\"address_range\":\"Full\"}) /KK^t"
|
||||
sHdlSome\x20(1) e\)?v"
|
||||
b1000000000000 %G_Dt"
|
||||
b0 E7iTa"
|
||||
|
|
@ -4919,7 +4919,7 @@ b0 H{?Xz
|
|||
03\z-w
|
||||
00^&W_
|
||||
b0 n/%-/
|
||||
sPhantomConst({\"log2_bus_width_in_bytes\":3,\"queue_capacity\":16,\"op_id_width\":8}) ./0U4
|
||||
sPhantomConst({\"log2_bus_width_in_bytes\":3,\"queue_capacity\":16,\"op_id_width\":8,\"address_range\":\"Full\"}) ./0U4
|
||||
0NE4rt
|
||||
sHdlNone\x20(0) :GU,#
|
||||
sSuccess\x20(0) D87*9
|
||||
|
|
@ -4933,7 +4933,7 @@ b0 d%H]f
|
|||
b0 zgzi@
|
||||
b0 7B-!)
|
||||
b0 Y1Qf)
|
||||
sPhantomConst({\"log2_bus_width_in_bytes\":3,\"queue_capacity\":16,\"op_id_width\":8}) a.$Aw
|
||||
sPhantomConst({\"log2_bus_width_in_bytes\":3,\"queue_capacity\":16,\"op_id_width\":8,\"address_range\":\"Full\"}) a.$Aw
|
||||
0*d$ca
|
||||
sHdlNone\x20(0) /N@6H
|
||||
b0 '10Cg
|
||||
|
|
@ -4954,7 +4954,7 @@ b0 hn|][
|
|||
b0 bWF^\
|
||||
b0 -"k'e
|
||||
sPhantomConst(\"0..=16\") uoZP0
|
||||
sPhantomConst({\"log2_bus_width_in_bytes\":3,\"queue_capacity\":16,\"op_id_width\":8}) /KK^t
|
||||
sPhantomConst({\"log2_bus_width_in_bytes\":3,\"queue_capacity\":16,\"op_id_width\":8,\"address_range\":\"Full\"}) /KK^t
|
||||
sHdlSome\x20(1) e\)?v
|
||||
b1000000000000 %G_Dt
|
||||
b0 E7iTa
|
||||
|
|
@ -5399,7 +5399,7 @@ b0 46)Xi
|
|||
0"(@LS
|
||||
0&NGtM
|
||||
b0 "tB6}
|
||||
sPhantomConst({\"log2_bus_width_in_bytes\":3,\"queue_capacity\":16,\"op_id_width\":8}) Hn\.r
|
||||
sPhantomConst({\"log2_bus_width_in_bytes\":3,\"queue_capacity\":16,\"op_id_width\":8,\"address_range\":\"Full\"}) Hn\.r
|
||||
0jbUZ8
|
||||
sHdlNone\x20(0) NcD^Z
|
||||
sSuccess\x20(0) X3rb0
|
||||
|
|
@ -5413,7 +5413,7 @@ b0 vyE_1
|
|||
b0 D}2RZ
|
||||
b0 \XUCp
|
||||
b0 [^@q%
|
||||
sPhantomConst({\"log2_bus_width_in_bytes\":3,\"queue_capacity\":16,\"op_id_width\":8}) G4KC#
|
||||
sPhantomConst({\"log2_bus_width_in_bytes\":3,\"queue_capacity\":16,\"op_id_width\":8,\"address_range\":\"Full\"}) G4KC#
|
||||
01thaQ
|
||||
sHdlNone\x20(0) +5LtZ
|
||||
b0 {6^Pl
|
||||
|
|
@ -5434,7 +5434,7 @@ b0 iB{BF
|
|||
b0 eR=Hx
|
||||
b0 8!8=?
|
||||
sPhantomConst(\"0..=16\") V?X!X
|
||||
sPhantomConst({\"log2_bus_width_in_bytes\":3,\"queue_capacity\":16,\"op_id_width\":8}) T-cQB
|
||||
sPhantomConst({\"log2_bus_width_in_bytes\":3,\"queue_capacity\":16,\"op_id_width\":8,\"address_range\":\"Full\"}) T-cQB
|
||||
sHdlSome\x20(1) JqP67
|
||||
b1000000000000 iRy|N
|
||||
b0 IIeMq
|
||||
|
|
@ -5522,7 +5522,7 @@ b0 UA{3,
|
|||
0mS#3<
|
||||
0^qjb[
|
||||
b0 tN>yu
|
||||
sPhantomConst({\"log2_bus_width_in_bytes\":3,\"queue_capacity\":16,\"op_id_width\":8}) '@T[?
|
||||
sPhantomConst({\"log2_bus_width_in_bytes\":3,\"queue_capacity\":16,\"op_id_width\":8,\"address_range\":\"Full\"}) '@T[?
|
||||
0BXk&[
|
||||
sHdlNone\x20(0) &wG|&
|
||||
sSuccess\x20(0) ^F2z4
|
||||
|
|
@ -5536,7 +5536,7 @@ b0 VXdV?
|
|||
b0 =`@6L
|
||||
b0 e2JF6
|
||||
b0 ]ocL{
|
||||
sPhantomConst({\"log2_bus_width_in_bytes\":3,\"queue_capacity\":16,\"op_id_width\":8}) ^<ah9
|
||||
sPhantomConst({\"log2_bus_width_in_bytes\":3,\"queue_capacity\":16,\"op_id_width\":8,\"address_range\":\"Full\"}) ^<ah9
|
||||
02sb.i
|
||||
sHdlNone\x20(0) JC:kM
|
||||
b0 .*4N"
|
||||
|
|
@ -5557,7 +5557,7 @@ b0 huWrb
|
|||
b0 EO39y
|
||||
b0 |d_{U
|
||||
sPhantomConst(\"0..=16\") 3(idJ
|
||||
sPhantomConst({\"log2_bus_width_in_bytes\":3,\"queue_capacity\":16,\"op_id_width\":8}) P'(UK
|
||||
sPhantomConst({\"log2_bus_width_in_bytes\":3,\"queue_capacity\":16,\"op_id_width\":8,\"address_range\":\"Full\"}) P'(UK
|
||||
sHdlSome\x20(1) N^Lck
|
||||
b1000000000000 q3ltq
|
||||
b0 zZOnr
|
||||
|
|
@ -5645,7 +5645,7 @@ b0 %poA2"
|
|||
0Bw<V4"
|
||||
0'@.QH"
|
||||
b0 !3G%M"
|
||||
sPhantomConst({\"log2_bus_width_in_bytes\":3,\"queue_capacity\":16,\"op_id_width\":8}) nRws$"
|
||||
sPhantomConst({\"log2_bus_width_in_bytes\":3,\"queue_capacity\":16,\"op_id_width\":8,\"address_range\":\"Full\"}) nRws$"
|
||||
0";E`m"
|
||||
sHdlNone\x20(0) QVVGm"
|
||||
sSuccess\x20(0) H{!U&"
|
||||
|
|
@ -5659,7 +5659,7 @@ b0 hCJZ("
|
|||
b0 yV&`["
|
||||
b0 o&C+Q"
|
||||
b0 :R>Z\"
|
||||
sPhantomConst({\"log2_bus_width_in_bytes\":3,\"queue_capacity\":16,\"op_id_width\":8}) %zH|b"
|
||||
sPhantomConst({\"log2_bus_width_in_bytes\":3,\"queue_capacity\":16,\"op_id_width\":8,\"address_range\":\"Full\"}) %zH|b"
|
||||
0'(8m+"
|
||||
sHdlNone\x20(0) MMwRE"
|
||||
b0 96-j|"
|
||||
|
|
@ -5680,7 +5680,7 @@ b0 n:O1E"
|
|||
b0 \TnT)"
|
||||
b0 %KEY#"
|
||||
sPhantomConst(\"0..=16\") 2S<L;"
|
||||
sPhantomConst({\"log2_bus_width_in_bytes\":3,\"queue_capacity\":16,\"op_id_width\":8}) <f)US"
|
||||
sPhantomConst({\"log2_bus_width_in_bytes\":3,\"queue_capacity\":16,\"op_id_width\":8,\"address_range\":\"Full\"}) <f)US"
|
||||
b0 i/#1{"
|
||||
b0 $/d2*"
|
||||
b0 mdUW+"
|
||||
|
|
@ -5753,7 +5753,7 @@ b0 %poA2
|
|||
0Bw<V4
|
||||
0'@.QH
|
||||
b0 !3G%M
|
||||
sPhantomConst({\"log2_bus_width_in_bytes\":3,\"queue_capacity\":16,\"op_id_width\":8}) nRws$
|
||||
sPhantomConst({\"log2_bus_width_in_bytes\":3,\"queue_capacity\":16,\"op_id_width\":8,\"address_range\":\"Full\"}) nRws$
|
||||
0";E`m
|
||||
sHdlNone\x20(0) QVVGm
|
||||
sSuccess\x20(0) H{!U&
|
||||
|
|
@ -5767,7 +5767,7 @@ b0 hCJZ(
|
|||
b0 yV&`[
|
||||
b0 o&C+Q
|
||||
b0 :R>Z\
|
||||
sPhantomConst({\"log2_bus_width_in_bytes\":3,\"queue_capacity\":16,\"op_id_width\":8}) %zH|b
|
||||
sPhantomConst({\"log2_bus_width_in_bytes\":3,\"queue_capacity\":16,\"op_id_width\":8,\"address_range\":\"Full\"}) %zH|b
|
||||
0'(8m+
|
||||
sHdlNone\x20(0) MMwRE
|
||||
b0 96-j|
|
||||
|
|
@ -5788,7 +5788,7 @@ b0 n:O1E
|
|||
b0 \TnT)
|
||||
b0 %KEY#
|
||||
sPhantomConst(\"0..=16\") 2S<L;
|
||||
sPhantomConst({\"log2_bus_width_in_bytes\":3,\"queue_capacity\":16,\"op_id_width\":8}) <f)US
|
||||
sPhantomConst({\"log2_bus_width_in_bytes\":3,\"queue_capacity\":16,\"op_id_width\":8,\"address_range\":\"Full\"}) <f)US
|
||||
b0 i/#1{
|
||||
b0 $/d2*
|
||||
b0 mdUW+
|
||||
|
|
|
|||
22
crates/cpu/tests/expected/simple_uart.vcd
generated
22
crates/cpu/tests/expected/simple_uart.vcd
generated
|
|
@ -549,7 +549,7 @@ b0 YK<TM
|
|||
0dM>i/
|
||||
0f><7V
|
||||
b0 #+y/d
|
||||
sPhantomConst({\"log2_bus_width_in_bytes\":1,\"queue_capacity\":1,\"op_id_width\":8}) k$)j$
|
||||
sPhantomConst({\"log2_bus_width_in_bytes\":1,\"queue_capacity\":1,\"op_id_width\":8,\"address_range\":{\"Limited\":{\"start\":0,\"size\":2}}}) k$)j$
|
||||
1z'<O{
|
||||
sHdlNone\x20(0) kC4Z@
|
||||
sSuccess\x20(0) DSj6>
|
||||
|
|
@ -557,13 +557,13 @@ sRead\x20(0) i8%Hy
|
|||
sGeneric\x20(0) }u<b|
|
||||
b0 [i|C-
|
||||
b0 NB*xP
|
||||
sPhantomConst({\"log2_bus_width_in_bytes\":1,\"queue_capacity\":1,\"op_id_width\":8}) b|P(G
|
||||
sPhantomConst({\"log2_bus_width_in_bytes\":1,\"queue_capacity\":1,\"op_id_width\":8,\"address_range\":{\"Limited\":{\"start\":0,\"size\":2}}}) b|P(G
|
||||
0p\ULz
|
||||
sHdlSome\x20(1) $x:NB
|
||||
b0 E*{c-
|
||||
0:C'8U
|
||||
sPhantomConst(\"0..=1\") E=NM+
|
||||
sPhantomConst({\"log2_bus_width_in_bytes\":1,\"queue_capacity\":1,\"op_id_width\":8}) eQf|o
|
||||
sPhantomConst({\"log2_bus_width_in_bytes\":1,\"queue_capacity\":1,\"op_id_width\":8,\"address_range\":{\"Limited\":{\"start\":0,\"size\":2}}}) eQf|o
|
||||
1-x}z)
|
||||
0*K&(X
|
||||
1N12hA
|
||||
|
|
@ -575,7 +575,7 @@ b0 ^'LkA
|
|||
0LMy1=
|
||||
0YG=uN
|
||||
b0 ),#g]
|
||||
sPhantomConst({\"log2_bus_width_in_bytes\":1,\"queue_capacity\":1,\"op_id_width\":8}) pukV=
|
||||
sPhantomConst({\"log2_bus_width_in_bytes\":1,\"queue_capacity\":1,\"op_id_width\":8,\"address_range\":{\"Limited\":{\"start\":0,\"size\":2}}}) pukV=
|
||||
1\u*{A
|
||||
sHdlNone\x20(0) ax>!d
|
||||
sSuccess\x20(0) $TH!~
|
||||
|
|
@ -583,13 +583,13 @@ sRead\x20(0) @nru
|
|||
sGeneric\x20(0) =rNet
|
||||
b0 _aF6z
|
||||
b0 fBY~q
|
||||
sPhantomConst({\"log2_bus_width_in_bytes\":1,\"queue_capacity\":1,\"op_id_width\":8}) 3Cr%:
|
||||
sPhantomConst({\"log2_bus_width_in_bytes\":1,\"queue_capacity\":1,\"op_id_width\":8,\"address_range\":{\"Limited\":{\"start\":0,\"size\":2}}}) 3Cr%:
|
||||
0jP_rY
|
||||
sHdlSome\x20(1) fl1G|
|
||||
b0 >-gg}
|
||||
0d2Gl|
|
||||
sPhantomConst(\"0..=1\") |@PWl
|
||||
sPhantomConst({\"log2_bus_width_in_bytes\":1,\"queue_capacity\":1,\"op_id_width\":8}) 7A<7@
|
||||
sPhantomConst({\"log2_bus_width_in_bytes\":1,\"queue_capacity\":1,\"op_id_width\":8,\"address_range\":{\"Limited\":{\"start\":0,\"size\":2}}}) 7A<7@
|
||||
1?:DT^
|
||||
1*V%!4
|
||||
01-L[%
|
||||
|
|
@ -730,14 +730,14 @@ b0 &]$B;
|
|||
0N-YM;
|
||||
0R,uS'
|
||||
b0 GEq-0
|
||||
sPhantomConst({\"log2_bus_width_in_bytes\":1,\"queue_capacity\":1,\"op_id_width\":8}) ,;U@A
|
||||
sPhantomConst({\"log2_bus_width_in_bytes\":1,\"queue_capacity\":1,\"op_id_width\":8,\"address_range\":{\"Limited\":{\"start\":0,\"size\":2}}}) ,;U@A
|
||||
sHdlNone\x20(0) 0?MV,
|
||||
sSuccess\x20(0) D>VoK
|
||||
sRead\x20(0) d8ku7
|
||||
sGeneric\x20(0) Y[<1d
|
||||
b0 .^N`/
|
||||
b0 'ThQe
|
||||
sPhantomConst({\"log2_bus_width_in_bytes\":1,\"queue_capacity\":1,\"op_id_width\":8}) 8pZSz
|
||||
sPhantomConst({\"log2_bus_width_in_bytes\":1,\"queue_capacity\":1,\"op_id_width\":8,\"address_range\":{\"Limited\":{\"start\":0,\"size\":2}}}) 8pZSz
|
||||
1'LW/7
|
||||
1(+=/^
|
||||
b0 Whx|K
|
||||
|
|
@ -752,7 +752,7 @@ b0 qwy9i
|
|||
044.En
|
||||
0Pq(.9
|
||||
b0 4zG]Q
|
||||
sPhantomConst({\"log2_bus_width_in_bytes\":1,\"queue_capacity\":1,\"op_id_width\":8}) MTVBb
|
||||
sPhantomConst({\"log2_bus_width_in_bytes\":1,\"queue_capacity\":1,\"op_id_width\":8,\"address_range\":{\"Limited\":{\"start\":0,\"size\":2}}}) MTVBb
|
||||
1IifsN
|
||||
sHdlNone\x20(0) EA1Ra
|
||||
sSuccess\x20(0) [<sgF
|
||||
|
|
@ -760,13 +760,13 @@ sRead\x20(0) j.}nI
|
|||
sGeneric\x20(0) z\\(W
|
||||
b0 Z*eyX
|
||||
b0 MRBv>
|
||||
sPhantomConst({\"log2_bus_width_in_bytes\":1,\"queue_capacity\":1,\"op_id_width\":8}) {[zRy
|
||||
sPhantomConst({\"log2_bus_width_in_bytes\":1,\"queue_capacity\":1,\"op_id_width\":8,\"address_range\":{\"Limited\":{\"start\":0,\"size\":2}}}) {[zRy
|
||||
0q2OoF
|
||||
sHdlSome\x20(1) d#Of8
|
||||
b0 J4y0s
|
||||
0vC#Sj
|
||||
sPhantomConst(\"0..=1\") ye/Gl
|
||||
sPhantomConst({\"log2_bus_width_in_bytes\":1,\"queue_capacity\":1,\"op_id_width\":8}) bH=hU
|
||||
sPhantomConst({\"log2_bus_width_in_bytes\":1,\"queue_capacity\":1,\"op_id_width\":8,\"address_range\":{\"Limited\":{\"start\":0,\"size\":2}}}) bH=hU
|
||||
1"QAdC
|
||||
1K%|4s
|
||||
$end
|
||||
|
|
|
|||
|
|
@ -21,7 +21,11 @@ use fayalite::{
|
|||
sim::vcd::VcdWriterDecls,
|
||||
util::{RcWriter, ready_valid::ReadyValid},
|
||||
};
|
||||
use std::{borrow::BorrowMut, marker::PhantomData, num::NonZeroUsize};
|
||||
use std::{
|
||||
borrow::BorrowMut,
|
||||
marker::PhantomData,
|
||||
num::{NonZeroUsize, Wrapping},
|
||||
};
|
||||
|
||||
const fn half_period(frequency: f64) -> SimDuration {
|
||||
SimDuration::from_attos((SimDuration::from_secs(1).as_attos() as f64 / frequency / 2.0) as u128)
|
||||
|
|
@ -603,7 +607,7 @@ fn simple_uart_loopback(
|
|||
}
|
||||
|
||||
const SIMPLE_UART_MEMORY_INTERFACE_CONFIG: MemoryInterfaceConfig =
|
||||
simple_uart_memory_interface_config(FETCH_BLOCK_ID_WIDTH);
|
||||
simple_uart_memory_interface_config(FETCH_BLOCK_ID_WIDTH, Wrapping(0));
|
||||
|
||||
struct MemoryOperationRunner<Sim: BorrowMut<Simulation<T>>, T: BundleType> {
|
||||
sim: Sim,
|
||||
|
|
@ -916,10 +920,10 @@ fn test_simple_uart() {
|
|||
|
||||
for i in 0..2 * BUS_WIDTH_IN_BYTES as u64 {
|
||||
mem_op_runner
|
||||
.read_bytes::<1>(SIMPLE_UART_SIZE + i, 1)
|
||||
.read_bytes::<1>(SIMPLE_UART_SIZE.get() + i, 1)
|
||||
.unwrap_err();
|
||||
mem_op_runner
|
||||
.write_bytes(SIMPLE_UART_SIZE + i, [0], 1)
|
||||
.write_bytes(SIMPLE_UART_SIZE.get() + i, [0], 1)
|
||||
.unwrap_err();
|
||||
}
|
||||
|
||||
|
|
|
|||
Loading…
Add table
Add a link
Reference in a new issue