logicaffeine_compile/codegen_sva/hart/
rtl.rs1use super::soc;
6
7pub fn core_files() -> Vec<(&'static str, String)> {
9 vec![
10 ("hart_rvc.v", include_str!("rtl/hart_rvc.v").to_string()),
11 ("hart_muldiv.v", include_str!("rtl/hart_muldiv.v").to_string()),
12 ("hart_core.v", include_str!("rtl/hart_core.v").to_string()),
13 ]
14}
15
16pub fn cpu_files() -> Vec<(&'static str, String)> {
19 let mut files = core_files();
20 files.extend([
21 ("hart_icache.v", include_str!("rtl/hart_icache.v").to_string()),
22 ("hart_dcache.v", include_str!("rtl/hart_dcache.v").to_string()),
23 ("hart_mem.v", include_str!("rtl/hart_mem.v").to_string()),
24 ("hart_cpu.v", include_str!("rtl/hart_cpu.v").to_string()),
25 ]);
26 files
27}
28
29pub const DEFINES: &str = "soc_defines.vh";
31
32pub fn soc_files() -> Vec<(&'static str, String)> {
36 let mut files = cpu_files();
37 files.extend([
38 ("hart_rom.v", include_str!("rtl/hart_rom.v").to_string()),
39 ("hart_sram.v", include_str!("rtl/hart_sram.v").to_string()),
40 ("hart_fifo.v", include_str!("rtl/hart_fifo.v").to_string()),
41 ("hart_qspi.v", include_str!("rtl/hart_qspi.v").to_string()),
42 ("hart_io.v", include_str!("rtl/hart_io.v").to_string()),
43 ("hart_soc.v", include_str!("rtl/hart_soc.v").to_string()),
44 (DEFINES, soc::verilog_defines()),
45 ]);
46 files
47}
48
49pub const DDR2_PARAMS: &str = "hart_ddr2_params.vh";
51
52pub fn ddr2_files() -> Vec<(&'static str, String)> {
55 vec![
56 ("hart_ddr2.v", include_str!("rtl/hart_ddr2.v").to_string()),
57 (DDR2_PARAMS, super::ddr2::verilog_params(&super::ddr2::MT47H64M16)),
58 ("hart_ddr2_phy.v", include_str!("rtl/hart_ddr2_phy.v").to_string()),
59 ]
60}
61
62pub fn board_files() -> Vec<(&'static str, String)> {
65 let mut files = soc_files();
66 files.extend(ddr2_files());
67 files.push(("hart_cdc_fifo.v", include_str!("rtl/hart_cdc_fifo.v").to_string()));
68 files
69}
70
71pub fn bringup_files() -> Vec<(&'static str, String)> {
74 let mut files = board_files();
75 files.extend([
76 ("hart_uart_tx.v", include_str!("rtl/hart_uart_tx.v").to_string()),
77 ("hart_bringup_top.v", include_str!("rtl/hart_bringup_top.v").to_string()),
78 ("hart_bringup_top.xdc", include_str!("rtl/hart_bringup_top.xdc").to_string()),
79 ]);
80 files
81}
82
83pub fn loopback_files() -> Vec<(&'static str, String)> {
86 let xdc: String = include_str!("rtl/hart_bringup_top.xdc")
87 .lines()
88 .filter(|l| !(l.contains("{ qspi_") || l.contains("{ btn")))
89 .map(|l| format!("{l}\n"))
90 .collect();
91 vec![
92 ("hart_ddr2_phy.v", include_str!("rtl/hart_ddr2_phy.v").to_string()),
93 ("hart_uart_tx.v", include_str!("rtl/hart_uart_tx.v").to_string()),
94 ("hart_ddr2_loopback_top.v", include_str!("rtl/hart_ddr2_loopback_top.v").to_string()),
95 ("hart_ddr2_loopback_top.xdc", xdc),
96 ]
97}
98
99pub fn fingerprint(files: &[(&'static str, String)], rom_hex: &str) -> [u8; 16] {
102 let mut all = Vec::new();
103 for (name, text) in files {
104 all.extend_from_slice(name.as_bytes());
105 all.push(0);
106 all.extend_from_slice(text.as_bytes());
107 all.push(0);
108 }
109 all.extend_from_slice(rom_hex.as_bytes());
110 logicaffeine_base::hash::md5(&all)
111}
112
113pub fn fingerprint_words(f: [u8; 16]) -> (u64, u64) {
116 (u64::from_le_bytes(f[0..8].try_into().unwrap()), u64::from_le_bytes(f[8..16].try_into().unwrap()))
117}
118
119pub fn rom_hex(boot: &[u8]) -> Result<String, String> {
122 if boot.len() as u64 > soc::ROM_SIZE {
123 return Err(format!("the boot ROM is {} bytes; the ROM holds {}", boot.len(), soc::ROM_SIZE));
124 }
125 Ok((0..(soc::ROM_SIZE / 8) as usize)
126 .map(|i| {
127 let word = (0..8).rev().fold(0u64, |w, k| (w << 8) | *boot.get(8 * i + k).unwrap_or(&0) as u64);
128 format!("{word:016x}\n")
129 })
130 .collect())
131}