OpenCores
URL https://opencores.org/ocsvn/neorv32/neorv32/trunk

Subversion Repositories neorv32

Compare Revisions

  • This comparison shows the changes necessary to convert path
    /neorv32/trunk/rtl/core
    from Rev 22 to Rev 23
    Reverse comparison

Rev 22 → Rev 23

/neorv32_application_image.vhd
6,7 → 6,7
 
package neorv32_application_image is
 
type application_init_image_t is array (0 to 832) of std_ulogic_vector(31 downto 0);
type application_init_image_t is array (0 to 836) of std_ulogic_vector(31 downto 0);
constant application_init_image : application_init_image_t := (
00000000 => x"00000093",
00000001 => x"00000113",
17,100 → 17,100
00000006 => x"00000393",
00000007 => x"00000413",
00000008 => x"00000493",
00000009 => x"00000693",
00000010 => x"00000713",
00000011 => x"00000793",
00000012 => x"ff402583",
00000013 => x"ffc02603",
00000014 => x"00c58133",
00000015 => x"ffc10113",
00000016 => x"00010413",
00000017 => x"80000197",
00000018 => x"7bc18193",
00000019 => x"00000597",
00000020 => x"08058593",
00000021 => x"30559073",
00000022 => x"f8000593",
00000023 => x"0005a023",
00000024 => x"00458593",
00000025 => x"feb01ce3",
00000026 => x"80000597",
00000027 => x"f9858593",
00000028 => x"84018613",
00000029 => x"00c5d863",
00000030 => x"00058023",
00000031 => x"00158593",
00000032 => x"ff5ff06f",
00000033 => x"00001597",
00000034 => x"c7858593",
00000035 => x"80000617",
00000036 => x"f7460613",
00000037 => x"80000697",
00000038 => x"f6c68693",
00000039 => x"00d65c63",
00000040 => x"00058703",
00000041 => x"00e60023",
00000042 => x"00158593",
00000043 => x"00160613",
00000044 => x"fedff06f",
00000045 => x"00000513",
00000046 => x"00000593",
00000047 => x"05c000ef",
00000048 => x"30047073",
00000049 => x"10500073",
00000050 => x"0000006f",
00000051 => x"ff810113",
00000052 => x"00812023",
00000053 => x"00912223",
00000054 => x"34202473",
00000055 => x"02044663",
00000056 => x"34102473",
00000057 => x"00041483",
00000058 => x"0034f493",
00000059 => x"00240413",
00000060 => x"34141073",
00000061 => x"00300413",
00000062 => x"00941863",
00000063 => x"34102473",
00000064 => x"00240413",
00000065 => x"34141073",
00000066 => x"00012483",
00000067 => x"00412403",
00000068 => x"00810113",
00000069 => x"30200073",
00000070 => x"00005537",
00000071 => x"ff010113",
00000072 => x"00000613",
00000073 => x"00000593",
00000074 => x"b0050513",
00000075 => x"00112623",
00000076 => x"00812423",
00000077 => x"508000ef",
00000078 => x"7ec000ef",
00000079 => x"02050c63",
00000080 => x"3ac000ef",
00000081 => x"00001537",
00000082 => x"a3850513",
00000083 => x"58c000ef",
00000084 => x"00000513",
00000085 => x"7e0000ef",
00000086 => x"00000413",
00000087 => x"0ff47513",
00000088 => x"7d4000ef",
00000089 => x"0c800513",
00000090 => x"77c000ef",
00000091 => x"00140413",
00000092 => x"fedff06f",
00000093 => x"00001537",
00000094 => x"a1450513",
00000095 => x"55c000ef",
00000096 => x"00c12083",
00000097 => x"00812403",
00000098 => x"00000513",
00000099 => x"01010113",
00000100 => x"00008067",
00000101 => x"00000000",
00000102 => x"00000000",
00000009 => x"00000713",
00000010 => x"00000793",
00000011 => x"00002537",
00000012 => x"80050513",
00000013 => x"30051073",
00000014 => x"30401073",
00000015 => x"80002117",
00000016 => x"fc010113",
00000017 => x"ffc17113",
00000018 => x"00010413",
00000019 => x"80000197",
00000020 => x"7b418193",
00000021 => x"00000597",
00000022 => x"08058593",
00000023 => x"30559073",
00000024 => x"f8000593",
00000025 => x"0005a023",
00000026 => x"00458593",
00000027 => x"feb01ce3",
00000028 => x"80000597",
00000029 => x"f9058593",
00000030 => x"84018613",
00000031 => x"00c5d863",
00000032 => x"00058023",
00000033 => x"00158593",
00000034 => x"ff5ff06f",
00000035 => x"00001597",
00000036 => x"c8458593",
00000037 => x"80000617",
00000038 => x"f6c60613",
00000039 => x"80000697",
00000040 => x"f6468693",
00000041 => x"00d65c63",
00000042 => x"00058703",
00000043 => x"00e60023",
00000044 => x"00158593",
00000045 => x"00160613",
00000046 => x"fedff06f",
00000047 => x"00000513",
00000048 => x"00000593",
00000049 => x"05c000ef",
00000050 => x"30047073",
00000051 => x"10500073",
00000052 => x"0000006f",
00000053 => x"ff810113",
00000054 => x"00812023",
00000055 => x"00912223",
00000056 => x"34202473",
00000057 => x"02044663",
00000058 => x"34102473",
00000059 => x"00041483",
00000060 => x"0034f493",
00000061 => x"00240413",
00000062 => x"34141073",
00000063 => x"00300413",
00000064 => x"00941863",
00000065 => x"34102473",
00000066 => x"00240413",
00000067 => x"34141073",
00000068 => x"00012483",
00000069 => x"00412403",
00000070 => x"00810113",
00000071 => x"30200073",
00000072 => x"00005537",
00000073 => x"ff010113",
00000074 => x"00000613",
00000075 => x"00000593",
00000076 => x"b0050513",
00000077 => x"00112623",
00000078 => x"00812423",
00000079 => x"500000ef",
00000080 => x"7e4000ef",
00000081 => x"02050c63",
00000082 => x"3a4000ef",
00000083 => x"00001537",
00000084 => x"a3850513",
00000085 => x"584000ef",
00000086 => x"00000513",
00000087 => x"7d8000ef",
00000088 => x"00000413",
00000089 => x"0ff47513",
00000090 => x"7cc000ef",
00000091 => x"0c800513",
00000092 => x"774000ef",
00000093 => x"00140413",
00000094 => x"fedff06f",
00000095 => x"00001537",
00000096 => x"a1450513",
00000097 => x"554000ef",
00000098 => x"00c12083",
00000099 => x"00812403",
00000100 => x"00000513",
00000101 => x"01010113",
00000102 => x"00008067",
00000103 => x"00000000",
00000104 => x"fc010113",
00000105 => x"02112e23",
232,18 → 232,18
00000221 => x"00f77c63",
00000222 => x"00001537",
00000223 => x"00040593",
00000224 => x"c3c50513",
00000224 => x"c5050513",
00000225 => x"3ac000ef",
00000226 => x"0400006f",
00000227 => x"00001737",
00000228 => x"00279793",
00000229 => x"c6870713",
00000229 => x"c7c70713",
00000230 => x"00e787b3",
00000231 => x"0007a783",
00000232 => x"00078067",
00000233 => x"00001737",
00000234 => x"00241793",
00000235 => x"cac70713",
00000235 => x"cc070713",
00000236 => x"00e787b3",
00000237 => x"0007a783",
00000238 => x"00078067",
261,7 → 261,7
00000250 => x"00812403",
00000251 => x"00c12083",
00000252 => x"00001537",
00000253 => x"c4c50513",
00000253 => x"c6050513",
00000254 => x"01010113",
00000255 => x"3340006f",
00000256 => x"00001537",
301,13 → 301,13
00000290 => x"bec50513",
00000291 => x"f39ff06f",
00000292 => x"00001537",
00000293 => x"c0050513",
00000293 => x"c0450513",
00000294 => x"f2dff06f",
00000295 => x"00001537",
00000296 => x"c1450513",
00000296 => x"c1c50513",
00000297 => x"f21ff06f",
00000298 => x"00001537",
00000299 => x"c2850513",
00000299 => x"c3450513",
00000300 => x"f15ff06f",
00000301 => x"ffe58593",
00000302 => x"f2dff06f",
355,7 → 355,7
00000344 => x"00058523",
00000345 => x"00000993",
00000346 => x"00410913",
00000347 => x"cdca0a13",
00000347 => x"cf0a0a13",
00000348 => x"00a00593",
00000349 => x"00048513",
00000350 => x"438000ef",
495,7 → 495,7
00000484 => x"07300913",
00000485 => x"07500b13",
00000486 => x"07800b93",
00000487 => x"ce848493",
00000487 => x"cfc48493",
00000488 => x"00044c03",
00000489 => x"020c0463",
00000490 => x"134c1263",
775,70 → 775,75
00000764 => x"746e6920",
00000765 => x"75727265",
00000766 => x"30207470",
00000767 => x"00000000",
00000768 => x"74736146",
00000769 => x"746e6920",
00000770 => x"75727265",
00000771 => x"31207470",
00000772 => x"00000000",
00000773 => x"74736146",
00000774 => x"746e6920",
00000775 => x"75727265",
00000776 => x"32207470",
00000777 => x"00000000",
00000778 => x"74736146",
00000779 => x"746e6920",
00000780 => x"75727265",
00000781 => x"33207470",
00000782 => x"00000000",
00000783 => x"6e6b6e55",
00000784 => x"206e776f",
00000785 => x"25783028",
00000786 => x"00002978",
00000787 => x"30204020",
00000788 => x"2c782578",
00000789 => x"56544d20",
00000790 => x"303d4c41",
00000791 => x"20782578",
00000792 => x"54522f3c",
00000793 => x"00003e45",
00000794 => x"00000460",
00000795 => x"00000378",
00000796 => x"00000378",
00000797 => x"00000378",
00000798 => x"0000046c",
00000799 => x"00000378",
00000767 => x"44572820",
00000768 => x"00002954",
00000769 => x"74736146",
00000770 => x"746e6920",
00000771 => x"75727265",
00000772 => x"31207470",
00000773 => x"50472820",
00000774 => x"00294f49",
00000775 => x"74736146",
00000776 => x"746e6920",
00000777 => x"75727265",
00000778 => x"32207470",
00000779 => x"41552820",
00000780 => x"00295452",
00000781 => x"74736146",
00000782 => x"746e6920",
00000783 => x"75727265",
00000784 => x"33207470",
00000785 => x"50532820",
00000786 => x"57542f49",
00000787 => x"00002949",
00000788 => x"6e6b6e55",
00000789 => x"206e776f",
00000790 => x"25783028",
00000791 => x"00002978",
00000792 => x"30204020",
00000793 => x"2c782578",
00000794 => x"56544d20",
00000795 => x"303d4c41",
00000796 => x"20782578",
00000797 => x"54522f3c",
00000798 => x"00003e45",
00000799 => x"00000460",
00000800 => x"00000378",
00000801 => x"00000378",
00000802 => x"00000478",
00000803 => x"00000378",
00000802 => x"00000378",
00000803 => x"0000046c",
00000804 => x"00000378",
00000805 => x"00000378",
00000806 => x"00000378",
00000807 => x"00000484",
00000808 => x"00000490",
00000809 => x"0000049c",
00000810 => x"000004a8",
00000811 => x"000003bc",
00000812 => x"00000400",
00000813 => x"0000040c",
00000814 => x"00000418",
00000815 => x"00000424",
00000816 => x"00000430",
00000817 => x"0000043c",
00000818 => x"00000448",
00000819 => x"00000378",
00000820 => x"00000378",
00000821 => x"00000378",
00000822 => x"00000454",
00000823 => x"33323130",
00000824 => x"37363534",
00000825 => x"00003938",
00000826 => x"33323130",
00000827 => x"37363534",
00000828 => x"62613938",
00000829 => x"66656463",
00000830 => x"00000000",
00000807 => x"00000478",
00000808 => x"00000378",
00000809 => x"00000378",
00000810 => x"00000378",
00000811 => x"00000378",
00000812 => x"00000484",
00000813 => x"00000490",
00000814 => x"0000049c",
00000815 => x"000004a8",
00000816 => x"000003bc",
00000817 => x"00000400",
00000818 => x"0000040c",
00000819 => x"00000418",
00000820 => x"00000424",
00000821 => x"00000430",
00000822 => x"0000043c",
00000823 => x"00000448",
00000824 => x"00000378",
00000825 => x"00000378",
00000826 => x"00000378",
00000827 => x"00000454",
00000828 => x"33323130",
00000829 => x"37363534",
00000830 => x"00003938",
00000831 => x"33323130",
00000832 => x"37363534",
00000833 => x"62613938",
00000834 => x"66656463",
00000835 => x"00000000",
others => x"00000000"
);
 
/neorv32_boot_rom.vhd
41,6 → 41,10
use neorv32.neorv32_bootloader_image.all; -- this file is generated by the image generator
 
entity neorv32_boot_rom is
generic (
BOOTROM_BASE : std_ulogic_vector(31 downto 0) := x"FFFF0000"; -- boot ROM base address
BOOTROM_SIZE : natural := 4*1024 -- processor-internal boot ROM memory size in bytes
);
port (
clk_i : in std_ulogic; -- global clock line
rden_i : in std_ulogic; -- read enable
53,7 → 57,7
architecture neorv32_boot_rom_rtl of neorv32_boot_rom is
 
-- local types --
type boot_img_t is array (0 to boot_size_c/4-1) of std_ulogic_vector(31 downto 0);
type boot_img_t is array (0 to BOOTROM_SIZE/4-1) of std_ulogic_vector(31 downto 0);
 
-- init function --
-- impure function: returns NOT the same result every time it is evaluated with the same arguments since the source file might have changed
71,7 → 75,7
signal acc_en : std_ulogic;
signal rden : std_ulogic;
signal rdata : std_ulogic_vector(31 downto 0);
signal addr : std_ulogic_vector(index_size_f(boot_size_c/4)-1 downto 0);
signal addr : std_ulogic_vector(index_size_f(BOOTROM_SIZE/4)-1 downto 0);
 
-- bootloader image --
constant boot_img : boot_img_t := init_boot_rom(bootloader_init_image);
80,8 → 84,8
 
-- Access Control -------------------------------------------------------------------------
-- -------------------------------------------------------------------------------------------
acc_en <= '1' when (addr_i >= boot_base_c) and (addr_i < std_ulogic_vector(unsigned(boot_base_c) + boot_size_c)) else '0';
addr <= addr_i(index_size_f(boot_size_c/4)+1 downto 2); -- word aligned
acc_en <= '1' when (addr_i >= BOOTROM_BASE) and (addr_i < std_ulogic_vector(unsigned(BOOTROM_BASE) + BOOTROM_SIZE)) else '0';
addr <= addr_i(index_size_f(BOOTROM_SIZE/4)+1 downto 2); -- word aligned
 
 
-- Memory Access --------------------------------------------------------------------------
/neorv32_bootloader_image.vhd
6,7 → 6,7
 
package neorv32_bootloader_image is
 
type bootloader_init_image_t is array (0 to 1019) of std_ulogic_vector(31 downto 0);
type bootloader_init_image_t is array (0 to 1015) of std_ulogic_vector(31 downto 0);
constant bootloader_init_image : bootloader_init_image_t := (
00000000 => x"00000093",
00000001 => x"00000113",
17,237 → 17,237
00000006 => x"00000393",
00000007 => x"00000413",
00000008 => x"00000493",
00000009 => x"00000693",
00000010 => x"00000713",
00000011 => x"00000793",
00000012 => x"ff402583",
00000013 => x"ffc02603",
00000014 => x"00c58133",
00000015 => x"ffc10113",
00000016 => x"00010413",
00000017 => x"80010197",
00000018 => x"7bc18193",
00000019 => x"00000597",
00000020 => x"08058593",
00000021 => x"30559073",
00000022 => x"f8000593",
00000023 => x"0005a023",
00000024 => x"00458593",
00000025 => x"feb01ce3",
00000026 => x"80010597",
00000027 => x"f9858593",
00000028 => x"80418613",
00000029 => x"00c5d863",
00000030 => x"00058023",
00000031 => x"00158593",
00000032 => x"ff5ff06f",
00000033 => x"00001597",
00000034 => x"f6458593",
00000035 => x"80010617",
00000036 => x"f7460613",
00000037 => x"80010697",
00000038 => x"f6c68693",
00000039 => x"00d65c63",
00000040 => x"00058703",
00000041 => x"00e60023",
00000042 => x"00158593",
00000043 => x"00160613",
00000044 => x"fedff06f",
00000045 => x"00000513",
00000046 => x"00000593",
00000047 => x"05c000ef",
00000048 => x"30047073",
00000049 => x"10500073",
00000050 => x"0000006f",
00000051 => x"ff810113",
00000052 => x"00812023",
00000053 => x"00912223",
00000054 => x"34202473",
00000055 => x"02044663",
00000056 => x"34102473",
00000057 => x"00041483",
00000058 => x"0034f493",
00000059 => x"00240413",
00000060 => x"34141073",
00000061 => x"00300413",
00000062 => x"00941863",
00000063 => x"34102473",
00000064 => x"00240413",
00000065 => x"34141073",
00000066 => x"00012483",
00000067 => x"00412403",
00000068 => x"00810113",
00000069 => x"30200073",
00000070 => x"fd010113",
00000071 => x"02812423",
00000072 => x"fe002403",
00000073 => x"026267b7",
00000074 => x"02112623",
00000075 => x"02912223",
00000076 => x"03212023",
00000077 => x"01312e23",
00000078 => x"01412c23",
00000079 => x"01512a23",
00000080 => x"01612823",
00000081 => x"01712623",
00000082 => x"01812423",
00000083 => x"9ff78793",
00000084 => x"00000713",
00000085 => x"00000693",
00000086 => x"00000613",
00000087 => x"00000593",
00000088 => x"00200513",
00000089 => x"0087f463",
00000090 => x"00400513",
00000091 => x"399000ef",
00000092 => x"00005537",
00000093 => x"00000613",
00000094 => x"00000593",
00000095 => x"b0050513",
00000096 => x"281000ef",
00000097 => x"239000ef",
00000098 => x"00245793",
00000099 => x"00a78533",
00000100 => x"00f537b3",
00000101 => x"00b785b3",
00000102 => x"251000ef",
00000103 => x"ffff07b7",
00000104 => x"49478793",
00000105 => x"30579073",
00000106 => x"08000793",
00000107 => x"30479073",
00000108 => x"30046073",
00000109 => x"00100513",
00000110 => x"411000ef",
00000111 => x"ffff1537",
00000112 => x"800007b7",
00000113 => x"f0050513",
00000114 => x"0007a023",
00000115 => x"2e1000ef",
00000116 => x"135000ef",
00000117 => x"ffff1537",
00000118 => x"f3850513",
00000119 => x"2d1000ef",
00000120 => x"fe002503",
00000121 => x"240000ef",
00000122 => x"ffff1537",
00000123 => x"f4050513",
00000124 => x"2bd000ef",
00000125 => x"fe402503",
00000126 => x"22c000ef",
00000127 => x"ffff1537",
00000128 => x"f4c50513",
00000129 => x"2a9000ef",
00000130 => x"30102573",
00000131 => x"218000ef",
00000132 => x"ffff1537",
00000133 => x"f5450513",
00000134 => x"295000ef",
00000135 => x"fe802503",
00000136 => x"ffff14b7",
00000137 => x"00341413",
00000138 => x"1fc000ef",
00000139 => x"ffff1537",
00000140 => x"f5c50513",
00000141 => x"279000ef",
00000142 => x"ff802503",
00000143 => x"ffff1937",
00000144 => x"1e4000ef",
00000145 => x"f6448513",
00000146 => x"265000ef",
00000147 => x"ff002503",
00000148 => x"1d4000ef",
00000149 => x"ffff1537",
00000150 => x"f7050513",
00000151 => x"251000ef",
00000152 => x"ffc02503",
00000153 => x"1c0000ef",
00000154 => x"f6448513",
00000155 => x"241000ef",
00000156 => x"ff402503",
00000157 => x"1b0000ef",
00000158 => x"ffff1537",
00000159 => x"f7850513",
00000160 => x"22d000ef",
00000161 => x"139000ef",
00000162 => x"00a404b3",
00000163 => x"0084b433",
00000164 => x"00b40433",
00000165 => x"fa402783",
00000166 => x"0607d263",
00000167 => x"ffff1537",
00000168 => x"fa450513",
00000169 => x"209000ef",
00000170 => x"ffff1937",
00000171 => x"0d4000ef",
00000172 => x"ffff19b7",
00000173 => x"07200a13",
00000174 => x"06800a93",
00000175 => x"07500b13",
00000176 => x"07300b93",
00000177 => x"ffff14b7",
00000178 => x"ffff1c37",
00000179 => x"fb090513",
00000180 => x"1dd000ef",
00000181 => x"1c9000ef",
00000182 => x"00050413",
00000183 => x"1b1000ef",
00000184 => x"fa098513",
00000185 => x"1c9000ef",
00000186 => x"03441e63",
00000187 => x"30047073",
00000188 => x"ffff02b7",
00000189 => x"00028067",
00000190 => x"0000006f",
00000191 => x"0c1000ef",
00000192 => x"f885eae3",
00000193 => x"00b41463",
00000194 => x"f89566e3",
00000195 => x"00100513",
00000196 => x"430000ef",
00000197 => x"fa090513",
00000198 => x"195000ef",
00000199 => x"070000ef",
00000200 => x"f75ff06f",
00000201 => x"01541663",
00000202 => x"058000ef",
00000203 => x"fa1ff06f",
00000204 => x"00000513",
00000205 => x"01640e63",
00000206 => x"01741663",
00000207 => x"64c000ef",
00000208 => x"f8dff06f",
00000209 => x"06c00793",
00000210 => x"00f41863",
00000211 => x"00100513",
00000212 => x"3f0000ef",
00000213 => x"f79ff06f",
00000214 => x"06500793",
00000215 => x"00f41663",
00000216 => x"02c000ef",
00000217 => x"f69ff06f",
00000218 => x"03f00793",
00000219 => x"fb8c0513",
00000220 => x"00f40463",
00000221 => x"fcc48513",
00000222 => x"135000ef",
00000223 => x"f51ff06f",
00000224 => x"ffff1537",
00000225 => x"dd050513",
00000226 => x"1250006f",
00000227 => x"800007b7",
00000228 => x"0007a783",
00000229 => x"00079863",
00000230 => x"ffff1537",
00000231 => x"e3450513",
00000232 => x"10d0006f",
00000233 => x"ff010113",
00000234 => x"00112623",
00000235 => x"30047073",
00000236 => x"00000793",
00000237 => x"30479073",
00000009 => x"00000713",
00000010 => x"00000793",
00000011 => x"00002537",
00000012 => x"80050513",
00000013 => x"30051073",
00000014 => x"30401073",
00000015 => x"80012117",
00000016 => x"fc010113",
00000017 => x"ffc17113",
00000018 => x"00010413",
00000019 => x"80010197",
00000020 => x"7b418193",
00000021 => x"00000597",
00000022 => x"08058593",
00000023 => x"30559073",
00000024 => x"f8000593",
00000025 => x"0005a023",
00000026 => x"00458593",
00000027 => x"feb01ce3",
00000028 => x"80010597",
00000029 => x"f9058593",
00000030 => x"80418613",
00000031 => x"00c5d863",
00000032 => x"00058023",
00000033 => x"00158593",
00000034 => x"ff5ff06f",
00000035 => x"00001597",
00000036 => x"f5058593",
00000037 => x"80010617",
00000038 => x"f6c60613",
00000039 => x"80010697",
00000040 => x"f6468693",
00000041 => x"00d65c63",
00000042 => x"00058703",
00000043 => x"00e60023",
00000044 => x"00158593",
00000045 => x"00160613",
00000046 => x"fedff06f",
00000047 => x"00000513",
00000048 => x"00000593",
00000049 => x"05c000ef",
00000050 => x"30047073",
00000051 => x"10500073",
00000052 => x"0000006f",
00000053 => x"ff810113",
00000054 => x"00812023",
00000055 => x"00912223",
00000056 => x"34202473",
00000057 => x"02044663",
00000058 => x"34102473",
00000059 => x"00041483",
00000060 => x"0034f493",
00000061 => x"00240413",
00000062 => x"34141073",
00000063 => x"00300413",
00000064 => x"00941863",
00000065 => x"34102473",
00000066 => x"00240413",
00000067 => x"34141073",
00000068 => x"00012483",
00000069 => x"00412403",
00000070 => x"00810113",
00000071 => x"30200073",
00000072 => x"fd010113",
00000073 => x"02812423",
00000074 => x"fe002403",
00000075 => x"026267b7",
00000076 => x"02112623",
00000077 => x"02912223",
00000078 => x"03212023",
00000079 => x"01312e23",
00000080 => x"01412c23",
00000081 => x"01512a23",
00000082 => x"01612823",
00000083 => x"01712623",
00000084 => x"01812423",
00000085 => x"9ff78793",
00000086 => x"00000713",
00000087 => x"00000693",
00000088 => x"00000613",
00000089 => x"00000593",
00000090 => x"00200513",
00000091 => x"0087f463",
00000092 => x"00400513",
00000093 => x"391000ef",
00000094 => x"00005537",
00000095 => x"00000613",
00000096 => x"00000593",
00000097 => x"b0050513",
00000098 => x"279000ef",
00000099 => x"231000ef",
00000100 => x"00245793",
00000101 => x"00a78533",
00000102 => x"00f537b3",
00000103 => x"00b785b3",
00000104 => x"249000ef",
00000105 => x"ffff07b7",
00000106 => x"49478793",
00000107 => x"30579073",
00000108 => x"08000793",
00000109 => x"30479073",
00000110 => x"30046073",
00000111 => x"00100513",
00000112 => x"405000ef",
00000113 => x"ffff1537",
00000114 => x"800007b7",
00000115 => x"ef450513",
00000116 => x"0007a023",
00000117 => x"2d9000ef",
00000118 => x"12d000ef",
00000119 => x"ffff1537",
00000120 => x"f2c50513",
00000121 => x"2c9000ef",
00000122 => x"fe002503",
00000123 => x"238000ef",
00000124 => x"ffff1537",
00000125 => x"f3450513",
00000126 => x"2b5000ef",
00000127 => x"fe402503",
00000128 => x"224000ef",
00000129 => x"ffff1537",
00000130 => x"f4050513",
00000131 => x"2a1000ef",
00000132 => x"30102573",
00000133 => x"210000ef",
00000134 => x"ffff1537",
00000135 => x"f4850513",
00000136 => x"28d000ef",
00000137 => x"fe802503",
00000138 => x"ffff14b7",
00000139 => x"00341413",
00000140 => x"1f4000ef",
00000141 => x"ffff1537",
00000142 => x"f5050513",
00000143 => x"271000ef",
00000144 => x"ff802503",
00000145 => x"ffff1937",
00000146 => x"1dc000ef",
00000147 => x"f5848513",
00000148 => x"25d000ef",
00000149 => x"ff002503",
00000150 => x"1cc000ef",
00000151 => x"ffff1537",
00000152 => x"f6450513",
00000153 => x"249000ef",
00000154 => x"ffc02503",
00000155 => x"1b8000ef",
00000156 => x"f5848513",
00000157 => x"239000ef",
00000158 => x"ff402503",
00000159 => x"1a8000ef",
00000160 => x"ffff1537",
00000161 => x"f6c50513",
00000162 => x"225000ef",
00000163 => x"131000ef",
00000164 => x"00a404b3",
00000165 => x"0084b433",
00000166 => x"00b40433",
00000167 => x"fa402783",
00000168 => x"0607d263",
00000169 => x"ffff1537",
00000170 => x"f9850513",
00000171 => x"201000ef",
00000172 => x"ffff1937",
00000173 => x"0d4000ef",
00000174 => x"ffff19b7",
00000175 => x"07200a13",
00000176 => x"06800a93",
00000177 => x"07500b13",
00000178 => x"07300b93",
00000179 => x"ffff14b7",
00000180 => x"ffff1c37",
00000181 => x"fa490513",
00000182 => x"1d5000ef",
00000183 => x"1c1000ef",
00000184 => x"00050413",
00000185 => x"1a9000ef",
00000186 => x"f9498513",
00000187 => x"1c1000ef",
00000188 => x"03441e63",
00000189 => x"30047073",
00000190 => x"ffff02b7",
00000191 => x"00028067",
00000192 => x"0000006f",
00000193 => x"0b9000ef",
00000194 => x"f885eae3",
00000195 => x"00b41463",
00000196 => x"f89566e3",
00000197 => x"00100513",
00000198 => x"434000ef",
00000199 => x"f9490513",
00000200 => x"18d000ef",
00000201 => x"070000ef",
00000202 => x"f75ff06f",
00000203 => x"01541663",
00000204 => x"058000ef",
00000205 => x"fa1ff06f",
00000206 => x"00000513",
00000207 => x"01640e63",
00000208 => x"01741663",
00000209 => x"644000ef",
00000210 => x"f8dff06f",
00000211 => x"06c00793",
00000212 => x"00f41863",
00000213 => x"00100513",
00000214 => x"3f4000ef",
00000215 => x"f79ff06f",
00000216 => x"06500793",
00000217 => x"00f41663",
00000218 => x"02c000ef",
00000219 => x"f69ff06f",
00000220 => x"03f00793",
00000221 => x"facc0513",
00000222 => x"00f40463",
00000223 => x"fc048513",
00000224 => x"12d000ef",
00000225 => x"f51ff06f",
00000226 => x"ffff1537",
00000227 => x"dcc50513",
00000228 => x"11d0006f",
00000229 => x"800007b7",
00000230 => x"0007a783",
00000231 => x"00079863",
00000232 => x"ffff1537",
00000233 => x"e3050513",
00000234 => x"1050006f",
00000235 => x"ff010113",
00000236 => x"00112623",
00000237 => x"30047073",
00000238 => x"ffff1537",
00000239 => x"e5050513",
00000239 => x"e4c50513",
00000240 => x"0ed000ef",
00000241 => x"fa002783",
00000242 => x"fe07cee3",
262,7 → 262,7
00000251 => x"00812423",
00000252 => x"00050413",
00000253 => x"ffff1537",
00000254 => x"e6050513",
00000254 => x"e5c50513",
00000255 => x"00112623",
00000256 => x"0ad000ef",
00000257 => x"03040513",
270,7 → 270,7
00000259 => x"081000ef",
00000260 => x"30047073",
00000261 => x"00100513",
00000262 => x"1b1000ef",
00000262 => x"1ad000ef",
00000263 => x"10500073",
00000264 => x"0000006f",
00000265 => x"fe010113",
278,7 → 278,7
00000267 => x"00050913",
00000268 => x"ffff1537",
00000269 => x"00912a23",
00000270 => x"e8850513",
00000270 => x"e7c50513",
00000271 => x"ffff14b7",
00000272 => x"00812c23",
00000273 => x"01312623",
285,7 → 285,7
00000274 => x"00112e23",
00000275 => x"01c00413",
00000276 => x"05d000ef",
00000277 => x"fd848493",
00000277 => x"fcc48493",
00000278 => x"ffc00993",
00000279 => x"008957b3",
00000280 => x"00f7f793",
322,219 → 322,219
00000311 => x"34202473",
00000312 => x"800007b7",
00000313 => x"00778793",
00000314 => x"02f40a63",
00000315 => x"ffff1537",
00000316 => x"e7450513",
00000317 => x"7b8000ef",
00000318 => x"00040513",
00000319 => x"f29ff0ef",
00000320 => x"ffff1537",
00000321 => x"e8450513",
00000322 => x"7a4000ef",
00000323 => x"34102573",
00000324 => x"f15ff0ef",
00000325 => x"00500513",
00000326 => x"ed1ff0ef",
00000327 => x"00000513",
00000328 => x"089000ef",
00000329 => x"698000ef",
00000330 => x"fe002783",
00000331 => x"0027d793",
00000332 => x"00a78533",
00000333 => x"00f537b3",
00000334 => x"00b785b3",
00000335 => x"6ac000ef",
00000336 => x"03c12403",
00000337 => x"04c12083",
00000338 => x"04812283",
00000339 => x"04412303",
00000340 => x"04012383",
00000341 => x"03812503",
00000342 => x"03412583",
00000343 => x"03012603",
00000344 => x"02c12683",
00000345 => x"02812703",
00000346 => x"02412783",
00000347 => x"02012803",
00000348 => x"01c12883",
00000349 => x"01812e03",
00000350 => x"01412e83",
00000351 => x"01012f03",
00000352 => x"00c12f83",
00000353 => x"05010113",
00000354 => x"30200073",
00000355 => x"ff010113",
00000356 => x"00000513",
00000357 => x"00112623",
00000358 => x"00812423",
00000359 => x"7b4000ef",
00000360 => x"00500513",
00000361 => x"7f0000ef",
00000362 => x"00000513",
00000363 => x"7e8000ef",
00000364 => x"00050413",
00000314 => x"06f41a63",
00000315 => x"00000513",
00000316 => x"0b9000ef",
00000317 => x"6c8000ef",
00000318 => x"fe002783",
00000319 => x"0027d793",
00000320 => x"00a78533",
00000321 => x"00f537b3",
00000322 => x"00b785b3",
00000323 => x"6dc000ef",
00000324 => x"03c12403",
00000325 => x"04c12083",
00000326 => x"04812283",
00000327 => x"04412303",
00000328 => x"04012383",
00000329 => x"03812503",
00000330 => x"03412583",
00000331 => x"03012603",
00000332 => x"02c12683",
00000333 => x"02812703",
00000334 => x"02412783",
00000335 => x"02012803",
00000336 => x"01c12883",
00000337 => x"01812e03",
00000338 => x"01412e83",
00000339 => x"01012f03",
00000340 => x"00c12f83",
00000341 => x"05010113",
00000342 => x"30200073",
00000343 => x"00700793",
00000344 => x"00100513",
00000345 => x"02f40863",
00000346 => x"ffff1537",
00000347 => x"e6850513",
00000348 => x"73c000ef",
00000349 => x"00040513",
00000350 => x"eadff0ef",
00000351 => x"ffff1537",
00000352 => x"e7850513",
00000353 => x"728000ef",
00000354 => x"34102573",
00000355 => x"e99ff0ef",
00000356 => x"00500513",
00000357 => x"e55ff0ef",
00000358 => x"ff010113",
00000359 => x"00000513",
00000360 => x"00112623",
00000361 => x"00812423",
00000362 => x"7a8000ef",
00000363 => x"00500513",
00000364 => x"7e4000ef",
00000365 => x"00000513",
00000366 => x"7b8000ef",
00000367 => x"00c12083",
00000368 => x"0ff47513",
00000369 => x"00812403",
00000370 => x"01010113",
00000371 => x"00008067",
00000372 => x"ff010113",
00000373 => x"00000513",
00000374 => x"00112623",
00000375 => x"00812423",
00000376 => x"770000ef",
00000377 => x"09e00513",
00000378 => x"7ac000ef",
00000379 => x"00000513",
00000380 => x"7a4000ef",
00000381 => x"00050413",
00000366 => x"7dc000ef",
00000367 => x"00050413",
00000368 => x"00000513",
00000369 => x"7ac000ef",
00000370 => x"00c12083",
00000371 => x"0ff47513",
00000372 => x"00812403",
00000373 => x"01010113",
00000374 => x"00008067",
00000375 => x"ff010113",
00000376 => x"00000513",
00000377 => x"00112623",
00000378 => x"00812423",
00000379 => x"764000ef",
00000380 => x"09e00513",
00000381 => x"7a0000ef",
00000382 => x"00000513",
00000383 => x"774000ef",
00000384 => x"00c12083",
00000385 => x"0ff47513",
00000386 => x"00812403",
00000387 => x"01010113",
00000388 => x"00008067",
00000389 => x"ff010113",
00000390 => x"00000513",
00000391 => x"00112623",
00000392 => x"730000ef",
00000393 => x"00600513",
00000394 => x"76c000ef",
00000395 => x"00c12083",
00000396 => x"00000513",
00000397 => x"01010113",
00000398 => x"7380006f",
00000399 => x"ff010113",
00000400 => x"00812423",
00000401 => x"00050413",
00000402 => x"01055513",
00000403 => x"0ff57513",
00000404 => x"00112623",
00000405 => x"740000ef",
00000406 => x"00845513",
00000407 => x"0ff57513",
00000383 => x"798000ef",
00000384 => x"00050413",
00000385 => x"00000513",
00000386 => x"768000ef",
00000387 => x"00c12083",
00000388 => x"0ff47513",
00000389 => x"00812403",
00000390 => x"01010113",
00000391 => x"00008067",
00000392 => x"ff010113",
00000393 => x"00000513",
00000394 => x"00112623",
00000395 => x"724000ef",
00000396 => x"00600513",
00000397 => x"760000ef",
00000398 => x"00c12083",
00000399 => x"00000513",
00000400 => x"01010113",
00000401 => x"72c0006f",
00000402 => x"ff010113",
00000403 => x"00812423",
00000404 => x"00050413",
00000405 => x"01055513",
00000406 => x"0ff57513",
00000407 => x"00112623",
00000408 => x"734000ef",
00000409 => x"0ff47513",
00000410 => x"00812403",
00000411 => x"00c12083",
00000412 => x"01010113",
00000413 => x"7200006f",
00000414 => x"ff010113",
00000415 => x"00812423",
00000416 => x"00050413",
00000417 => x"00000513",
00000418 => x"00112623",
00000419 => x"6c4000ef",
00000420 => x"00300513",
00000421 => x"700000ef",
00000422 => x"00040513",
00000423 => x"fa1ff0ef",
00000424 => x"00000513",
00000425 => x"6f0000ef",
00000426 => x"00050413",
00000409 => x"00845513",
00000410 => x"0ff57513",
00000411 => x"728000ef",
00000412 => x"0ff47513",
00000413 => x"00812403",
00000414 => x"00c12083",
00000415 => x"01010113",
00000416 => x"7140006f",
00000417 => x"ff010113",
00000418 => x"00812423",
00000419 => x"00050413",
00000420 => x"00000513",
00000421 => x"00112623",
00000422 => x"6b8000ef",
00000423 => x"00300513",
00000424 => x"6f4000ef",
00000425 => x"00040513",
00000426 => x"fa1ff0ef",
00000427 => x"00000513",
00000428 => x"6c0000ef",
00000429 => x"00c12083",
00000430 => x"0ff47513",
00000431 => x"00812403",
00000432 => x"01010113",
00000433 => x"00008067",
00000434 => x"fd010113",
00000435 => x"02812423",
00000436 => x"02912223",
00000437 => x"03212023",
00000438 => x"01312e23",
00000439 => x"01412c23",
00000440 => x"02112623",
00000441 => x"00050913",
00000442 => x"00058993",
00000443 => x"00c10493",
00000444 => x"00000413",
00000445 => x"00400a13",
00000446 => x"02091e63",
00000447 => x"5a0000ef",
00000448 => x"00a481a3",
00000449 => x"00140413",
00000450 => x"fff48493",
00000451 => x"ff4416e3",
00000452 => x"02c12083",
00000453 => x"02812403",
00000454 => x"00c12503",
00000455 => x"02412483",
00000456 => x"02012903",
00000457 => x"01c12983",
00000458 => x"01812a03",
00000459 => x"03010113",
00000460 => x"00008067",
00000461 => x"00898533",
00000462 => x"f41ff0ef",
00000463 => x"fc5ff06f",
00000464 => x"fd010113",
00000465 => x"02812423",
00000466 => x"fe802403",
00000467 => x"02112623",
00000468 => x"02912223",
00000469 => x"03212023",
00000470 => x"01312e23",
00000471 => x"01412c23",
00000472 => x"01512a23",
00000473 => x"01612823",
00000474 => x"01712623",
00000475 => x"00847413",
00000476 => x"00040663",
00000477 => x"00400513",
00000478 => x"c71ff0ef",
00000479 => x"00050493",
00000480 => x"02051863",
00000481 => x"ffff1537",
00000482 => x"e8c50513",
00000483 => x"520000ef",
00000484 => x"008005b7",
00000485 => x"00048513",
00000486 => x"f31ff0ef",
00000487 => x"4788d7b7",
00000488 => x"afe78793",
00000489 => x"02f50463",
00000490 => x"00000513",
00000491 => x"fcdff06f",
00000492 => x"ffff1537",
00000493 => x"eac50513",
00000494 => x"4f4000ef",
00000495 => x"e15ff0ef",
00000496 => x"fc0518e3",
00000497 => x"00300513",
00000498 => x"fb1ff06f",
00000499 => x"00800a37",
00000500 => x"004a0593",
00000501 => x"00048513",
00000502 => x"ef1ff0ef",
00000503 => x"00050913",
00000504 => x"008a0593",
00000505 => x"00048513",
00000506 => x"ee1ff0ef",
00000507 => x"ff802783",
00000508 => x"00050a93",
00000509 => x"00100513",
00000510 => x"f927e0e3",
00000511 => x"ff002b83",
00000512 => x"ffc97b13",
00000513 => x"00000993",
00000514 => x"00ca0a13",
00000515 => x"014985b3",
00000516 => x"053b1863",
00000428 => x"6e4000ef",
00000429 => x"00050413",
00000430 => x"00000513",
00000431 => x"6b4000ef",
00000432 => x"00c12083",
00000433 => x"0ff47513",
00000434 => x"00812403",
00000435 => x"01010113",
00000436 => x"00008067",
00000437 => x"fd010113",
00000438 => x"02812423",
00000439 => x"02912223",
00000440 => x"03212023",
00000441 => x"01312e23",
00000442 => x"01412c23",
00000443 => x"02112623",
00000444 => x"00050913",
00000445 => x"00058993",
00000446 => x"00c10493",
00000447 => x"00000413",
00000448 => x"00400a13",
00000449 => x"02091e63",
00000450 => x"594000ef",
00000451 => x"00a481a3",
00000452 => x"00140413",
00000453 => x"fff48493",
00000454 => x"ff4416e3",
00000455 => x"02c12083",
00000456 => x"02812403",
00000457 => x"00c12503",
00000458 => x"02412483",
00000459 => x"02012903",
00000460 => x"01c12983",
00000461 => x"01812a03",
00000462 => x"03010113",
00000463 => x"00008067",
00000464 => x"00898533",
00000465 => x"f41ff0ef",
00000466 => x"fc5ff06f",
00000467 => x"fd010113",
00000468 => x"02812423",
00000469 => x"fe802403",
00000470 => x"02112623",
00000471 => x"02912223",
00000472 => x"03212023",
00000473 => x"01312e23",
00000474 => x"01412c23",
00000475 => x"01512a23",
00000476 => x"01612823",
00000477 => x"01712623",
00000478 => x"00847413",
00000479 => x"00040663",
00000480 => x"00400513",
00000481 => x"c65ff0ef",
00000482 => x"00050493",
00000483 => x"02051863",
00000484 => x"ffff1537",
00000485 => x"e8050513",
00000486 => x"514000ef",
00000487 => x"008005b7",
00000488 => x"00048513",
00000489 => x"f31ff0ef",
00000490 => x"4788d7b7",
00000491 => x"afe78793",
00000492 => x"02f50463",
00000493 => x"00000513",
00000494 => x"fcdff06f",
00000495 => x"ffff1537",
00000496 => x"ea050513",
00000497 => x"4e8000ef",
00000498 => x"e15ff0ef",
00000499 => x"fc0518e3",
00000500 => x"00300513",
00000501 => x"fb1ff06f",
00000502 => x"008009b7",
00000503 => x"00498593",
00000504 => x"00048513",
00000505 => x"ef1ff0ef",
00000506 => x"00050a13",
00000507 => x"00898593",
00000508 => x"00048513",
00000509 => x"ee1ff0ef",
00000510 => x"ff002b83",
00000511 => x"00050a93",
00000512 => x"ffca7b13",
00000513 => x"00000913",
00000514 => x"00c98993",
00000515 => x"013905b3",
00000516 => x"052b1863",
00000517 => x"01540433",
00000518 => x"00200513",
00000519 => x"f4041ee3",
00000519 => x"f60414e3",
00000520 => x"ffff1537",
00000521 => x"eb850513",
00000521 => x"eac50513",
00000522 => x"484000ef",
00000523 => x"02c12083",
00000524 => x"02812403",
00000525 => x"800007b7",
00000526 => x"0127a023",
00000526 => x"0147a023",
00000527 => x"02412483",
00000528 => x"02012903",
00000529 => x"01c12983",
545,11 → 545,11
00000534 => x"03010113",
00000535 => x"00008067",
00000536 => x"00048513",
00000537 => x"e65ff0ef",
00000538 => x"013b87b3",
00000537 => x"e71ff0ef",
00000538 => x"012b87b3",
00000539 => x"00a40433",
00000540 => x"00a7a023",
00000541 => x"00498993",
00000541 => x"00490913",
00000542 => x"f95ff06f",
00000543 => x"ff010113",
00000544 => x"00112623",
557,18 → 557,18
00000546 => x"00912223",
00000547 => x"00058413",
00000548 => x"00050493",
00000549 => x"d81ff0ef",
00000549 => x"d8dff0ef",
00000550 => x"00000513",
00000551 => x"4b4000ef",
00000552 => x"00200513",
00000553 => x"4f0000ef",
00000554 => x"00048513",
00000555 => x"d91ff0ef",
00000555 => x"d9dff0ef",
00000556 => x"00040513",
00000557 => x"4e0000ef",
00000558 => x"00000513",
00000559 => x"4b4000ef",
00000560 => x"ccdff0ef",
00000560 => x"cd9ff0ef",
00000561 => x"00157513",
00000562 => x"fe051ce3",
00000563 => x"00c12083",
602,16 → 602,16
00000591 => x"00112623",
00000592 => x"00812423",
00000593 => x"00050413",
00000594 => x"ccdff0ef",
00000594 => x"cd9ff0ef",
00000595 => x"00000513",
00000596 => x"400000ef",
00000597 => x"0d800513",
00000598 => x"43c000ef",
00000599 => x"00040513",
00000600 => x"cddff0ef",
00000600 => x"ce9ff0ef",
00000601 => x"00000513",
00000602 => x"408000ef",
00000603 => x"c21ff0ef",
00000603 => x"c2dff0ef",
00000604 => x"00157513",
00000605 => x"fe051ce3",
00000606 => x"00c12083",
630,7 → 630,7
00000619 => x"01512223",
00000620 => x"02041863",
00000621 => x"ffff1537",
00000622 => x"e3450513",
00000622 => x"e3050513",
00000623 => x"01812403",
00000624 => x"01c12083",
00000625 => x"01412483",
641,17 → 641,17
00000630 => x"02010113",
00000631 => x"2d00006f",
00000632 => x"ffff1537",
00000633 => x"ebc50513",
00000633 => x"eb050513",
00000634 => x"2c4000ef",
00000635 => x"00040513",
00000636 => x"a35ff0ef",
00000637 => x"ffff1537",
00000638 => x"ec850513",
00000638 => x"ebc50513",
00000639 => x"2b0000ef",
00000640 => x"00800537",
00000641 => x"a21ff0ef",
00000642 => x"ffff1537",
00000643 => x"ee450513",
00000643 => x"ed850513",
00000644 => x"29c000ef",
00000645 => x"288000ef",
00000646 => x"00050493",
658,12 → 658,12
00000647 => x"270000ef",
00000648 => x"07900793",
00000649 => x"0af49e63",
00000650 => x"ba9ff0ef",
00000650 => x"bb5ff0ef",
00000651 => x"00051663",
00000652 => x"00300513",
00000653 => x"9b5ff0ef",
00000654 => x"ffff1537",
00000655 => x"ef050513",
00000655 => x"ee450513",
00000656 => x"01045493",
00000657 => x"268000ef",
00000658 => x"00148493",
693,7 → 693,7
00000682 => x"412005b3",
00000683 => x"e35ff0ef",
00000684 => x"ffff1537",
00000685 => x"eb850513",
00000685 => x"eac50513",
00000686 => x"f05ff06f",
00000687 => x"00090513",
00000688 => x"e79ff0ef",
884,148 → 884,145
00000873 => x"00008067",
00000874 => x"f8400713",
00000875 => x"00072683",
00000876 => x"00f57793",
00000877 => x"00100513",
00000878 => x"00f51533",
00000879 => x"00d54533",
00000880 => x"00a72023",
00000881 => x"00008067",
00000882 => x"f8a02223",
00000883 => x"00008067",
00000884 => x"69617641",
00000885 => x"6c62616c",
00000886 => x"4d432065",
00000887 => x"0a3a7344",
00000888 => x"203a6820",
00000889 => x"706c6548",
00000890 => x"3a72200a",
00000891 => x"73655220",
00000892 => x"74726174",
00000893 => x"3a75200a",
00000894 => x"6c705520",
00000895 => x"0a64616f",
00000896 => x"203a7320",
00000897 => x"726f7453",
00000898 => x"6f742065",
00000899 => x"616c6620",
00000900 => x"200a6873",
00000901 => x"4c203a6c",
00000902 => x"2064616f",
00000903 => x"6d6f7266",
00000904 => x"616c6620",
00000905 => x"200a6873",
00000906 => x"45203a65",
00000907 => x"75636578",
00000908 => x"00006574",
00000909 => x"65206f4e",
00000910 => x"75636578",
00000911 => x"6c626174",
00000912 => x"76612065",
00000913 => x"616c6961",
00000914 => x"2e656c62",
00000915 => x"00000000",
00000916 => x"746f6f42",
00000917 => x"2e676e69",
00000918 => x"0a0a2e2e",
00000919 => x"00000000",
00000920 => x"6f420a07",
00000921 => x"6f6c746f",
00000922 => x"72656461",
00000923 => x"52524520",
00000924 => x"0000005f",
00000925 => x"58450a0a",
00000926 => x"54504543",
00000927 => x"204e4f49",
00000928 => x"00000028",
00000929 => x"20402029",
00000930 => x"00007830",
00000931 => x"69617741",
00000932 => x"676e6974",
00000933 => x"6f656e20",
00000934 => x"32337672",
00000935 => x"6578655f",
00000936 => x"6e69622e",
00000937 => x"202e2e2e",
00000938 => x"00000000",
00000939 => x"64616f4c",
00000940 => x"2e676e69",
00000941 => x"00202e2e",
00000942 => x"00004b4f",
00000943 => x"74697257",
00000944 => x"78302065",
00000945 => x"00000000",
00000946 => x"74796220",
00000947 => x"74207365",
00000948 => x"5053206f",
00000949 => x"6c662049",
00000950 => x"20687361",
00000951 => x"78302040",
00000876 => x"00100793",
00000877 => x"00a797b3",
00000878 => x"00d7c7b3",
00000879 => x"00f72023",
00000880 => x"00008067",
00000881 => x"f8a02223",
00000882 => x"00008067",
00000883 => x"69617641",
00000884 => x"6c62616c",
00000885 => x"4d432065",
00000886 => x"0a3a7344",
00000887 => x"203a6820",
00000888 => x"706c6548",
00000889 => x"3a72200a",
00000890 => x"73655220",
00000891 => x"74726174",
00000892 => x"3a75200a",
00000893 => x"6c705520",
00000894 => x"0a64616f",
00000895 => x"203a7320",
00000896 => x"726f7453",
00000897 => x"6f742065",
00000898 => x"616c6620",
00000899 => x"200a6873",
00000900 => x"4c203a6c",
00000901 => x"2064616f",
00000902 => x"6d6f7266",
00000903 => x"616c6620",
00000904 => x"200a6873",
00000905 => x"45203a65",
00000906 => x"75636578",
00000907 => x"00006574",
00000908 => x"65206f4e",
00000909 => x"75636578",
00000910 => x"6c626174",
00000911 => x"76612065",
00000912 => x"616c6961",
00000913 => x"2e656c62",
00000914 => x"00000000",
00000915 => x"746f6f42",
00000916 => x"2e676e69",
00000917 => x"0a0a2e2e",
00000918 => x"00000000",
00000919 => x"52450a07",
00000920 => x"5f524f52",
00000921 => x"00000000",
00000922 => x"58450a0a",
00000923 => x"54504543",
00000924 => x"204e4f49",
00000925 => x"00000028",
00000926 => x"20402029",
00000927 => x"00007830",
00000928 => x"69617741",
00000929 => x"676e6974",
00000930 => x"6f656e20",
00000931 => x"32337672",
00000932 => x"6578655f",
00000933 => x"6e69622e",
00000934 => x"202e2e2e",
00000935 => x"00000000",
00000936 => x"64616f4c",
00000937 => x"2e676e69",
00000938 => x"00202e2e",
00000939 => x"00004b4f",
00000940 => x"74697257",
00000941 => x"78302065",
00000942 => x"00000000",
00000943 => x"74796220",
00000944 => x"74207365",
00000945 => x"5053206f",
00000946 => x"6c662049",
00000947 => x"20687361",
00000948 => x"78302040",
00000949 => x"00000000",
00000950 => x"7928203f",
00000951 => x"20296e2f",
00000952 => x"00000000",
00000953 => x"7928203f",
00000954 => x"20296e2f",
00000955 => x"00000000",
00000956 => x"616c460a",
00000957 => x"6e696873",
00000958 => x"2e2e2e67",
00000959 => x"00000020",
00000960 => x"0a0a0a0a",
00000961 => x"4e203c3c",
00000962 => x"56524f45",
00000963 => x"42203233",
00000964 => x"6c746f6f",
00000965 => x"6564616f",
00000966 => x"3e3e2072",
00000967 => x"4c420a0a",
00000968 => x"203a5644",
00000969 => x"20677541",
00000970 => x"32203932",
00000971 => x"0a303230",
00000972 => x"3a565748",
00000973 => x"00002020",
00000974 => x"4b4c430a",
00000975 => x"0020203a",
00000976 => x"0a7a4820",
00000977 => x"52455355",
00000978 => x"0000203a",
00000979 => x"53494d0a",
00000980 => x"00203a41",
00000981 => x"4e4f430a",
00000982 => x"00203a46",
00000983 => x"454d490a",
00000984 => x"00203a4d",
00000985 => x"74796220",
00000986 => x"40207365",
00000987 => x"00000020",
00000988 => x"454d440a",
00000989 => x"00203a4d",
00000990 => x"75410a0a",
00000991 => x"6f626f74",
00000992 => x"6920746f",
00000993 => x"7338206e",
00000994 => x"7250202e",
00000995 => x"20737365",
00000996 => x"2079656b",
00000997 => x"61206f74",
00000998 => x"74726f62",
00000999 => x"00000a2e",
00001000 => x"0000000a",
00001001 => x"726f6241",
00001002 => x"2e646574",
00001003 => x"00000a0a",
00001004 => x"444d430a",
00001005 => x"00203e3a",
00001006 => x"53207962",
00001007 => x"68706574",
00001008 => x"4e206e61",
00001009 => x"69746c6f",
00001010 => x"0000676e",
00001011 => x"61766e49",
00001012 => x"2064696c",
00001013 => x"00444d43",
00001014 => x"33323130",
00001015 => x"37363534",
00001016 => x"42413938",
00001017 => x"46454443",
00000953 => x"616c460a",
00000954 => x"6e696873",
00000955 => x"2e2e2e67",
00000956 => x"00000020",
00000957 => x"0a0a0a0a",
00000958 => x"4e203c3c",
00000959 => x"56524f45",
00000960 => x"42203233",
00000961 => x"6c746f6f",
00000962 => x"6564616f",
00000963 => x"3e3e2072",
00000964 => x"4c420a0a",
00000965 => x"203a5644",
00000966 => x"20706553",
00000967 => x"32203631",
00000968 => x"0a303230",
00000969 => x"3a565748",
00000970 => x"00002020",
00000971 => x"4b4c430a",
00000972 => x"0020203a",
00000973 => x"0a7a4820",
00000974 => x"52455355",
00000975 => x"0000203a",
00000976 => x"53494d0a",
00000977 => x"00203a41",
00000978 => x"4e4f430a",
00000979 => x"00203a46",
00000980 => x"454d490a",
00000981 => x"00203a4d",
00000982 => x"74796220",
00000983 => x"40207365",
00000984 => x"00000020",
00000985 => x"454d440a",
00000986 => x"00203a4d",
00000987 => x"75410a0a",
00000988 => x"6f626f74",
00000989 => x"6920746f",
00000990 => x"7338206e",
00000991 => x"7250202e",
00000992 => x"20737365",
00000993 => x"2079656b",
00000994 => x"61206f74",
00000995 => x"74726f62",
00000996 => x"00000a2e",
00000997 => x"0000000a",
00000998 => x"726f6241",
00000999 => x"2e646574",
00001000 => x"00000a0a",
00001001 => x"444d430a",
00001002 => x"00203e3a",
00001003 => x"53207962",
00001004 => x"68706574",
00001005 => x"4e206e61",
00001006 => x"69746c6f",
00001007 => x"0000676e",
00001008 => x"61766e49",
00001009 => x"2064696c",
00001010 => x"00444d43",
00001011 => x"33323130",
00001012 => x"37363534",
00001013 => x"42413938",
00001014 => x"46454443",
others => x"00000000"
);
 
/neorv32_cfu.vhd
0,0 → 1,204
-- #################################################################################################
-- # << NEORV32 - Custom Function Unit (CFU) >> #
-- # ********************************************************************************************* #
-- # For tightly-coupled custom co-processors. Provides four memory mapped interface registers. #
-- # ********************************************************************************************* #
-- # BSD 3-Clause License #
-- # #
-- # Copyright (c) 2020, Stephan Nolting. All rights reserved. #
-- # #
-- # Redistribution and use in source and binary forms, with or without modification, are #
-- # permitted provided that the following conditions are met: #
-- # #
-- # 1. Redistributions of source code must retain the above copyright notice, this list of #
-- # conditions and the following disclaimer. #
-- # #
-- # 2. Redistributions in binary form must reproduce the above copyright notice, this list of #
-- # conditions and the following disclaimer in the documentation and/or other materials #
-- # provided with the distribution. #
-- # #
-- # 3. Neither the name of the copyright holder nor the names of its contributors may be used to #
-- # endorse or promote products derived from this software without specific prior written #
-- # permission. #
-- # #
-- # THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND ANY EXPRESS #
-- # OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF #
-- # MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE #
-- # COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, #
-- # EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE #
-- # GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED #
-- # AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING #
-- # NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED #
-- # OF THE POSSIBILITY OF SUCH DAMAGE. #
-- # ********************************************************************************************* #
-- # The NEORV32 Processor - https://github.com/stnolting/neorv32 (c) Stephan Nolting #
-- #################################################################################################
 
library ieee;
use ieee.std_logic_1164.all;
use ieee.numeric_std.all;
 
library neorv32;
use neorv32.neorv32_package.all;
 
entity neorv32_cfu is
port (
-- host access --
clk_i : in std_ulogic; -- global clock line
rstn_i : in std_ulogic; -- global reset line, low-active, use as async
addr_i : in std_ulogic_vector(31 downto 0); -- address
rden_i : in std_ulogic; -- read enable
wren_i : in std_ulogic; -- write enable
data_i : in std_ulogic_vector(31 downto 0); -- data in
data_o : out std_ulogic_vector(31 downto 0); -- data out
ack_o : out std_ulogic; -- transfer acknowledge
-- clock generator --
clkgen_en_o : out std_ulogic; -- enable clock generator
clkgen_i : in std_ulogic_vector(07 downto 0); -- "clock" inputs
-- interrupt --
irq_o : out std_ulogic
-- custom io --
-- ...
);
end neorv32_cfu;
 
architecture neorv32_cfu_rtl of neorv32_cfu is
 
-- IO space: module base address --
constant hi_abb_c : natural := index_size_f(io_size_c)-1; -- high address boundary bit
constant lo_abb_c : natural := index_size_f(cfu_size_c); -- low address boundary bit
 
-- access control --
signal acc_en : std_ulogic; -- module access enable
signal addr : std_ulogic_vector(31 downto 0); -- access address
signal wr_en : std_ulogic; -- word write enable
signal rd_en : std_ulogic; -- read enable
 
-- default CFU interface registers --
type cfu_regs_t is array (0 to 3) of std_ulogic_vector(31 downto 0);
signal cfu_reg_in : cfu_regs_t; -- interface registers for WRITE
signal cfu_reg_out : cfu_regs_t; -- interface registers for READ
 
begin
 
-- Access Control -------------------------------------------------------------------------
-- -------------------------------------------------------------------------------------------
-- These assignments are required to check if the CFU is accessed at all.
-- Do NOT modify this for your custom application (unless you really know what you are doing).
 
acc_en <= '1' when (addr_i(hi_abb_c downto lo_abb_c) = cfu_base_c(hi_abb_c downto lo_abb_c)) else '0';
addr <= cfu_base_c(31 downto lo_abb_c) & addr_i(lo_abb_c-1 downto 2) & "00"; -- word aligned
wr_en <= acc_en and wren_i;
rd_en <= acc_en and rden_i;
 
 
-- Clock System ---------------------------------------------------------------------------
-- -------------------------------------------------------------------------------------------
-- The top unit implements a clock generator providing 8 "derived clocks"
-- Actually, these signals must not be used as direct clock signals, but as clock enable signals.
 
-- The following clock divider rates are available:
-- clkgen_i(clk_div2_c) -> MAIN_CLK/2
-- clkgen_i(clk_div4_c) -> MAIN_CLK/4
-- clkgen_i(clk_div8_c) -> MAIN_CLK/8
-- clkgen_i(clk_div64_c) -> MAIN_CLK/64
-- clkgen_i(clk_div128_c) -> MAIN_CLK/128
-- clkgen_i(clk_div1024_c) -> MAIN_CLK/1024
-- clkgen_i(clk_div2048_c) -> MAIN_CLK/2048
-- clkgen_i(clk_div4096_c) -> MAIN_CLK/4096
 
-- For instance, if you want to drive a system at MAIN_CLK/8, you can use the following construct:
 
-- if (rstn_i = '0') then -- async and low-active reset
-- ...
-- elsif rising_edge(clk_i) then -- Always use the main clock for all clock processes!
-- if (clkgen_i(clk_div8_c) = '1') then -- the div8 "clock" is actually a clock enable
-- ...
-- end if;
-- end if;
 
-- The clkgen_i input clocks are available when at least one IO/peripheral device requires the clocks generated by the
-- clock generator. The CFU can enable the clock generator via the clkgen_en_o signal.
-- Make sure to deactivate clkgen_en_o if no clocks are required to reduce power consumption.
 
clkgen_en_o <= '0'; -- not used for this minimal example
 
 
-- Read/Write Access ----------------------------------------------------------------------
-- -------------------------------------------------------------------------------------------
-- Here we are reading/writing from/to the interface registers of the module. Please note that the peripheral/IO
-- modules of the NEORV32 can only be written in full word mode (32-bit). Any other write access (half-word or byte)
-- will trigger a store access fault exception.
--
-- All register of every unit are cleared during the processor boot sequence by the default crt0.S code.
-- Make cfu_reg0_addr_c the CFU's control register. This register is cleared first during booting.
-- If the control register is cleared, no actions should be taken when writing to other CFU registers.
--
-- The CFU provides 4 memory-mapped interface register. For instance, these could be used to provide
-- a <status register> for status information, a <data register< for reading/writing from/to a data FIFO, a <command register>
-- for issueing commands and a <control register> for global control of the unit.
--
rw_access: process(clk_i)
begin
if rising_edge(clk_i) then
-- transfer ack --
ack_o <= wr_en or rd_en;
 
-- write access --
if (wr_en = '1') then
if (addr = cfu_reg0_addr_c) then -- this should be the control register
cfu_reg_in(0) <= data_i; -- for example: control register
end if;
if (addr = cfu_reg1_addr_c) then
cfu_reg_in(1) <= data_i; -- for example: data in/out fifo
end if;
if (addr = cfu_reg2_addr_c) then
cfu_reg_in(2) <= data_i; -- for example: command fifo
end if;
if (addr = cfu_reg3_addr_c) then
cfu_reg_in(3) <= data_i; -- for example: status register
end if;
end if;
 
-- read access --
data_o <= (others => '0'); -- make sure the output is zero if there is no actual read access
if (rd_en = '1') then
if (addr = cfu_reg0_addr_c) then
data_o <= cfu_reg_out(0);
elsif (addr = cfu_reg1_addr_c) then
data_o <= cfu_reg_out(1);
elsif (addr = cfu_reg2_addr_c) then
data_o <= cfu_reg_out(2);
else -- addr = cfu_reg3_addr_c
data_o <= cfu_reg_out(3);
end if;
end if;
end if;
end process rw_access;
 
 
-- CFU Interrupt --------------------------------------------------------------------------
-- -------------------------------------------------------------------------------------------
-- The CFU provides a single interrupt request signal, which is forwarded to the CPU's fast interrupt channel 1.
-- This channel is shared with the GPIO unit - so both unit can trigger the same interrupt.
--
-- An interrupt request is generated when the irq_o signal is high for one cycle. If the signal is high for more than one cycle
-- more than one interrupt request might be generated.
--
-- There is no interrupt acknowledge signal. If required: The interrupt handler can write to a specific control reister bit within the
-- CFU to acknowledge an interrupt.
 
irq_o <= '0'; -- not used for this minimal example
 
 
-- CFU Core -------------------------------------------------------------------------------
-- -------------------------------------------------------------------------------------------
-- This is where the actual functionality can be implemented. In this example we are just doing some pointless operations.
 
cfu_reg_out(0) <= cfu_reg_in(0) and cfu_reg_in(1);
cfu_reg_out(1) <= cfu_reg_in(2) and cfu_reg_in(3);
cfu_reg_out(2) <= x"00000001";
cfu_reg_out(3) <= (others => '0');
 
 
end neorv32_cfu_rtl;
/neorv32_cpu.vhd
63,7 → 63,6
CPU_EXTENSION_RISCV_Zicsr : boolean := true; -- implement CSR system?
CPU_EXTENSION_RISCV_Zifencei : boolean := true; -- implement instruction stream sync.?
-- Extension Options --
CSR_COUNTERS_USE : boolean := true; -- implement RISC-V perf. counters ([m]instret[h], [m]cycle[h], time[h])?
FAST_MUL_EN : boolean := false; -- use DSPs for M extension's multiplier
-- Physical Memory Protection (PMP) --
PMP_USE : boolean := false; -- implement PMP?
149,46 → 148,25
 
-- Sanity Checks --------------------------------------------------------------------------
-- -------------------------------------------------------------------------------------------
sanity_check: process(clk_i)
begin
if rising_edge(clk_i) then
-- CSR system --
if (CPU_EXTENSION_RISCV_Zicsr = false) then
assert false report "NEORV32 CPU CONFIG WARNING! No exception/interrupt/machine features available when CPU_EXTENSION_RISCV_Zicsr = false." severity warning;
end if;
-- U-extension requires Zicsr extension --
if (CPU_EXTENSION_RISCV_Zicsr = false) and (CPU_EXTENSION_RISCV_U = true) then
assert false report "NEORV32 CPU CONFIG ERROR! User mode requires CPU_EXTENSION_RISCV_Zicsr extension." severity error;
end if;
-- PMP requires Zicsr extension --
if (CPU_EXTENSION_RISCV_Zicsr = false) and (PMP_USE = true) then
assert false report "NEORV32 CPU CONFIG ERROR! Physical memory protection (PMP) requires CPU_EXTENSION_RISCV_Zicsr extension." severity error;
end if;
-- performance counters require Zicsr extension --
if (CPU_EXTENSION_RISCV_Zicsr = false) and (CSR_COUNTERS_USE = true) then
assert false report "NEORV32 CPU CONFIG ERROR! Performance counter CSRs require CPU_EXTENSION_RISCV_Zicsr extension." severity error;
end if;
-- PMP regions --
if (PMP_NUM_REGIONS > pmp_max_r_c) and (PMP_USE = true) then
assert false report "NEORV32 CPU CONFIG ERROR! Number of PMP regions out of valid range." severity error;
end if;
-- PMP granulartiy --
if ((PMP_GRANULARITY < 1) or (PMP_GRANULARITY > 32)) and (PMP_USE = true) then
assert false report "NEORV32 CPU CONFIG ERROR! Invalid PMP granulartiy (0 < G < 33)." severity error;
end if;
-- Bus timeout --
if (BUS_TIMEOUT < 1) then
assert false report "NEORV32 CPU CONFIG ERROR! Invalid bus timeout - must be at least 1 cycle." severity error;
end if;
end if;
end process sanity_check;
-- CSR system --
assert not (CPU_EXTENSION_RISCV_Zicsr = false) report "NEORV32 CPU CONFIG WARNING! No exception/interrupt/machine features available when CPU_EXTENSION_RISCV_Zicsr = false." severity warning;
-- U-extension requires Zicsr extension --
assert not ((CPU_EXTENSION_RISCV_Zicsr = false) and (CPU_EXTENSION_RISCV_U = true)) report "NEORV32 CPU CONFIG ERROR! User mode requires CPU_EXTENSION_RISCV_Zicsr extension." severity error;
-- PMP requires Zicsr extension --
assert not ((CPU_EXTENSION_RISCV_Zicsr = false) and (PMP_USE = true)) report "NEORV32 CPU CONFIG ERROR! Physical memory protection (PMP) requires CPU_EXTENSION_RISCV_Zicsr extension." severity error;
-- PMP regions --
assert not ((PMP_NUM_REGIONS > pmp_max_r_c) and (PMP_USE = true)) report "NEORV32 CPU CONFIG ERROR! Number of PMP regions out of valid range." severity error;
-- PMP granulartiy --
assert not (((PMP_GRANULARITY < 1) or (PMP_GRANULARITY > 32)) and (PMP_USE = true)) report "NEORV32 CPU CONFIG ERROR! Invalid PMP granulartiy (0 < G < 33)." severity error;
-- Bus timeout --
assert not (BUS_TIMEOUT < 1) report "NEORV32 CPU CONFIG ERROR! Invalid bus timeout - must be at least 1 cycle." severity error;
 
 
-- Control Unit ---------------------------------------------------------------------------
-- -------------------------------------------------------------------------------------------
neorv32_cpu_control_inst: neorv32_cpu_control
generic map (
-- General --
CSR_COUNTERS_USE => CSR_COUNTERS_USE, -- implement RISC-V perf. counters ([m]instret[h], [m]cycle[h], time[h])?
HW_THREAD_ID => HW_THREAD_ID, -- hardware thread id
CPU_BOOT_ADDR => CPU_BOOT_ADDR, -- cpu boot address
-- RISC-V CPU Extensions --
/neorv32_cpu_alu.vhd
113,6 → 113,9
end record;
signal cp_ctrl : cp_ctrl_t;
 
-- bit manipulation --
signal bitm_res : std_ulogic_vector(31 downto 0);
 
begin
 
-- Operand Mux ----------------------------------------------------------------------------
163,6 → 166,19
add_o <= add_res; -- direct output
 
 
-- Bit Manipulation Unit ------------------------------------------------------------------
-- -------------------------------------------------------------------------------------------
 
-- ------------------ --
-- UNDER CONSTRUCTION --
-- ------------------ --
 
--bitm_minmax <= rs1_i when ((cmp_less xor ???) = '1') else rs2_i; -- min[u] / max[u]
 
-- result of bit manipulation operation --
bitm_res <= opa and (not opb); -- ANDN
 
 
-- Iterative Shifter Unit -----------------------------------------------------------------
-- -------------------------------------------------------------------------------------------
shifter_unit: process(rstn_i, clk_i)
177,7 → 193,7
shifter.sreg <= opa; -- shift operand
shifter.cnt <= opb(index_size_f(data_width_c)-1 downto 0); -- shift amount
elsif (shifter.run = '1') then -- running shift
-- coarse shift -> multiples of 4 --
-- coarse shift: multiples of 4 --
if (or_all_f(shifter.cnt(shifter.cnt'left downto 2)) = '1') then -- shift amount >= 4
shifter.cnt <= std_ulogic_vector(unsigned(shifter.cnt) - 4);
if (ctrl_i(ctrl_alu_shift_dir_c) = '0') then -- SLL: shift left logical
188,7 → 204,7
(shifter.sreg(shifter.sreg'left) and ctrl_i(ctrl_alu_shift_ar_c)) &
(shifter.sreg(shifter.sreg'left) and ctrl_i(ctrl_alu_shift_ar_c)) & shifter.sreg(shifter.sreg'left downto 4);
end if;
-- fine shift -> 0..3 --
-- fine shift: single shifts, 0..3 times --
else
shifter.cnt <= std_ulogic_vector(unsigned(shifter.cnt) - 1);
if (ctrl_i(ctrl_alu_shift_dir_c) = '0') then -- SLL: shift left logical
230,7 → 246,7
cp_ctrl.busy <= '0';
cp_ctrl.rb_ff0 <= '1';
end if;
else -- no co-processors implemented
else -- no co-processor(s) implemented
cp_ctrl.cmd_ff <= '0';
cp_ctrl.busy <= '0';
cp_ctrl.rb_ff0 <= '0';
241,8 → 257,8
 
-- is co-processor operation? --
cp_ctrl.start <= '1' when (ctrl_i(ctrl_cp_use_c) = '1') and (cp_ctrl.cmd_ff = '0') else '0';
cp0_start_o <= '1' when (cp_ctrl.start = '1') and (ctrl_i(ctrl_cp_id_msb_c downto ctrl_cp_id_lsb_c) = cp_sel_muldiv_c) else '0'; -- MULDIV CP
cp1_start_o <= '0'; -- not yet implemented
cp0_start_o <= '1' when (cp_ctrl.start = '1') and (ctrl_i(ctrl_cp_id_msb_c downto ctrl_cp_id_lsb_c) = cp_sel_muldiv_c) else '0'; -- MULDIV CP
cp1_start_o <= '0'; -- not yet implemented
 
-- co-processor operation running? --
cp_ctrl.halt <= cp_ctrl.busy or cp_ctrl.start;
250,12 → 266,12
 
-- ALU Function Select --------------------------------------------------------------------
-- -------------------------------------------------------------------------------------------
alu_function_mux: process(ctrl_i, opa, opb, add_res, sub_res, cmp_less, shifter)
alu_function_mux: process(ctrl_i, opa, opb, add_res, sub_res, cmp_less, shifter, bitm_res)
begin
case ctrl_i(ctrl_alu_cmd2_c downto ctrl_alu_cmd0_c) is
when alu_cmd_bitc_c => alu_res <= opa and (not opb); -- bit clear (for CSR modifications only)
when alu_cmd_bitm_c => alu_res <= bitm_res;
when alu_cmd_xor_c => alu_res <= opa xor opb;
when alu_cmd_or_c => alu_res <= opa or opb;
when alu_cmd_or_c => alu_res <= opa or opb;
when alu_cmd_and_c => alu_res <= opa and opb;
when alu_cmd_sub_c => alu_res <= sub_res;
when alu_cmd_add_c => alu_res <= add_res;
/neorv32_cpu_bus.vhd
324,7 → 324,7
i_arbiter.rd_req <= '0';
end if;
elsif (i_bus_ack_i = '1') then -- wait for normal termination
i_arbiter.rd_req <= '0';
i_arbiter.rd_req <= '0';
end if;
end if;
 
/neorv32_cpu_control.vhd
46,7 → 46,6
entity neorv32_cpu_control is
generic (
-- General --
CSR_COUNTERS_USE : boolean := true; -- implement RISC-V perf. counters ([m]instret[h], [m]cycle[h], time[h])?
HW_THREAD_ID : std_ulogic_vector(31 downto 0):= x"00000000"; -- hardware thread id
CPU_BOOT_ADDR : std_ulogic_vector(31 downto 0):= x"00000000"; -- cpu boot address
-- RISC-V CPU Extensions --
91,9 → 90,9
-- system time input from MTIME --
time_i : in std_ulogic_vector(63 downto 0); -- current system time
-- physical memory protection --
pmp_addr_o : out pmp_addr_if_t; -- addresses
pmp_ctrl_o : out pmp_ctrl_if_t; -- configs
priv_mode_o : out std_ulogic_vector(1 downto 0); -- current CPU privilege level
pmp_addr_o : out pmp_addr_if_t; -- addresses
pmp_ctrl_o : out pmp_ctrl_if_t; -- configs
priv_mode_o : out std_ulogic_vector(1 downto 0); -- current CPU privilege level
-- bus access exceptions --
mar_i : in std_ulogic_vector(data_width_c-1 downto 0); -- memory address register
ma_instr_i : in std_ulogic; -- misaligned instruction address
239,7 → 238,6
 
signal mcycle_msb : std_ulogic;
signal minstret_msb : std_ulogic;
signal systime : std_ulogic_vector(63 downto 0);
 
-- illegal instruction check --
signal illegal_instruction : std_ulogic;
255,30 → 253,9
-- Instruction Fetch
-- ****************************************************************************************************************************
 
-- Compressed Instructions Recoding -------------------------------------------------------
-- -------------------------------------------------------------------------------------------
neorv32_cpu_decompressor_inst_true:
if (CPU_EXTENSION_RISCV_C = true) generate
neorv32_cpu_decompressor_inst: neorv32_cpu_decompressor
port map (
-- instruction input --
ci_instr16_i => fetch_engine.ci_input, -- compressed instruction input
-- instruction output --
ci_illegal_o => ci_illegal, -- is an illegal compressed instruction
ci_instr32_o => ci_instr32 -- 32-bit decompressed instruction
);
end generate;
 
neorv32_cpu_decompressor_inst_false:
if (CPU_EXTENSION_RISCV_C = false) generate
ci_instr32 <= (others => '0');
ci_illegal <= '0';
end generate;
 
 
-- Fetch Engine FSM Sync ------------------------------------------------------------------
-- -------------------------------------------------------------------------------------------
-- for registers that require a specific reset state --
-- registers that require a specific reset state --
fetch_engine_fsm_sync_rst: process(rstn_i, clk_i)
begin
if (rstn_i = '0') then
293,7 → 270,7
end process fetch_engine_fsm_sync_rst;
 
 
-- for registers that DO NOT require a specific reset state --
-- registers that DO NOT require a specific reset state --
fetch_engine_fsm_sync: process(clk_i)
begin
if rising_edge(clk_i) then
404,6 → 381,27
end process fetch_engine_fsm_comb;
 
 
-- Compressed Instructions Recoding -------------------------------------------------------
-- -------------------------------------------------------------------------------------------
neorv32_cpu_decompressor_inst_true:
if (CPU_EXTENSION_RISCV_C = true) generate
neorv32_cpu_decompressor_inst: neorv32_cpu_decompressor
port map (
-- instruction input --
ci_instr16_i => fetch_engine.ci_input, -- compressed instruction input
-- instruction output --
ci_illegal_o => ci_illegal, -- is an illegal compressed instruction
ci_instr32_o => ci_instr32 -- 32-bit decompressed instruction
);
end generate;
 
neorv32_cpu_decompressor_inst_false:
if (CPU_EXTENSION_RISCV_C = false) generate
ci_instr32 <= (others => '0');
ci_illegal <= '0';
end generate;
 
 
-- ****************************************************************************************************************************
-- Instruction Prefetch Buffer
-- ****************************************************************************************************************************
527,7 → 525,7
execute_engine.last_pc <= CPU_BOOT_ADDR(data_width_c-1 downto 1) & '0';
execute_engine.state <= SYS_WAIT;
execute_engine.sleep <= '0';
execute_engine.if_rst <= '1'; -- IF is reset after system reset
execute_engine.if_rst <= '1'; -- instruction fetch is reset after system reset
elsif rising_edge(clk_i) then
execute_engine.pc <= execute_engine.pc_nxt(data_width_c-1 downto 1) & '0';
if (execute_engine.state = EXECUTE) then
622,11 → 620,11
else -- branches
ctrl_nxt(ctrl_alu_unsigned_c) <= execute_engine.i_reg(instr_funct3_lsb_c+1); -- unsigned branches (BLTU, BGEU)
end if;
ctrl_nxt(ctrl_bus_unsigned_c) <= execute_engine.i_reg(instr_funct3_msb_c); -- unsigned LOAD (LBU, LHU)
ctrl_nxt(ctrl_alu_shift_dir_c) <= execute_engine.i_reg(instr_funct3_msb_c); -- shift direction (left/right)
ctrl_nxt(ctrl_alu_shift_ar_c) <= execute_engine.i_reg(30); -- is arithmetic shift
ctrl_nxt(ctrl_bus_size_lsb_c) <= execute_engine.i_reg(instr_funct3_lsb_c+0); -- transfer size lsb (00=byte, 01=half-word)
ctrl_nxt(ctrl_bus_size_msb_c) <= execute_engine.i_reg(instr_funct3_lsb_c+1); -- transfer size msb (10=word, 11=?)
ctrl_nxt(ctrl_bus_unsigned_c) <= execute_engine.i_reg(instr_funct3_msb_c); -- unsigned LOAD (LBU, LHU)
ctrl_nxt(ctrl_alu_shift_dir_c) <= execute_engine.i_reg(instr_funct3_msb_c); -- shift direction (left/right)
ctrl_nxt(ctrl_alu_shift_ar_c) <= execute_engine.i_reg(30); -- is arithmetic shift
ctrl_nxt(ctrl_bus_size_lsb_c) <= execute_engine.i_reg(instr_funct3_lsb_c+0); -- transfer size lsb (00=byte, 01=half-word)
ctrl_nxt(ctrl_bus_size_msb_c) <= execute_engine.i_reg(instr_funct3_lsb_c+1); -- transfer size msb (10=word, 11=?)
ctrl_nxt(ctrl_cp_cmd2_c downto ctrl_cp_cmd0_c) <= execute_engine.i_reg(instr_funct3_msb_c downto instr_funct3_lsb_c); -- CP operation
ctrl_nxt(ctrl_cp_id_msb_c downto ctrl_cp_id_lsb_c) <= cp_sel_muldiv_c; -- only CP0 (MULDIV) implemented yet
 
712,7 → 710,7
ctrl_nxt(ctrl_rf_in_mux_msb_c downto ctrl_rf_in_mux_lsb_c) <= "00"; -- RF input = ALU result
-- multi cycle alu operation? --
if (alu_operation_v = alu_cmd_shift_c) or -- shift operation?
((CPU_EXTENSION_RISCV_M = true) and (execute_engine.i_reg(instr_opcode_msb_c downto instr_opcode_lsb_c) = opcode_alu_c) and
((CPU_EXTENSION_RISCV_M = true) and (execute_engine.i_reg(instr_opcode_lsb_c+5) = opcode_alu_c(5)) and
(execute_engine.i_reg(instr_funct7_lsb_c) = '1')) then -- MULDIV?
execute_engine.state_nxt <= ALU_WAIT;
else
720,7 → 718,7
execute_engine.state_nxt <= DISPATCH;
end if;
-- cp access? --
if (CPU_EXTENSION_RISCV_M = true) and (execute_engine.i_reg(instr_opcode_msb_c downto instr_opcode_lsb_c) = opcode_alu_c) and
if (CPU_EXTENSION_RISCV_M = true) and (execute_engine.i_reg(instr_opcode_lsb_c+5) = opcode_alu_c(5)) and
(execute_engine.i_reg(instr_funct7_lsb_c) = '1') then -- MULDIV?
ctrl_nxt(ctrl_cp_use_c) <= '1'; -- use CP
end if;
728,7 → 726,7
when opcode_lui_c | opcode_auipc_c => -- load upper immediate (add to PC)
-- ------------------------------------------------------------
ctrl_nxt(ctrl_rf_clear_rs1_c) <= '1'; -- force RS1 = r0 (only relevant for LUI)
if (execute_engine.i_reg(instr_opcode_msb_c downto instr_opcode_lsb_c) = opcode_auipc_c) then -- AUIPC
if (execute_engine.i_reg(instr_opcode_lsb_c+5) = opcode_auipc_c(5)) then -- AUIPC
ctrl_nxt(ctrl_alu_opa_mux_lsb_c) <= '1'; -- use PC as ALU.OPA
else -- LUI
ctrl_nxt(ctrl_alu_opa_mux_lsb_c) <= '0'; -- use RS1 as ALU.OPA
758,7 → 756,7
when opcode_jal_c | opcode_jalr_c => -- jump and link (with register)
-- ------------------------------------------------------------
-- compute target address --
if (execute_engine.i_reg(instr_opcode_msb_c downto instr_opcode_lsb_c) = opcode_jal_c) then -- JAL
if (execute_engine.i_reg(instr_opcode_lsb_c+3) = opcode_jal_c(3)) then -- JAL
ctrl_nxt(ctrl_alu_opa_mux_lsb_c) <= '1'; -- use PC as ALU.OPA
else -- JALR
ctrl_nxt(ctrl_alu_opa_mux_lsb_c) <= '0'; -- use RS1 as ALU.OPA
773,13 → 771,13
 
when opcode_fence_c => -- fence operations
-- ------------------------------------------------------------
if (execute_engine.i_reg(instr_funct3_msb_c downto instr_funct3_lsb_c) = funct3_fencei_c) and (CPU_EXTENSION_RISCV_Zifencei = true) then -- FENCE.I
if (execute_engine.i_reg(instr_funct3_lsb_c) = funct3_fencei_c(0)) and (CPU_EXTENSION_RISCV_Zifencei = true) then -- FENCE.I
fetch_engine.reset <= '1';
execute_engine.if_rst_nxt <= '1'; -- this is a non-linear PC modification
execute_engine.pc_nxt <= execute_engine.next_pc; -- "refetch" next instruction (only relevant for fence.i)
ctrl_nxt(ctrl_bus_fencei_c) <= '1';
end if;
if (execute_engine.i_reg(instr_funct3_msb_c downto instr_funct3_lsb_c) = funct3_fence_c) then -- FENCE
if (execute_engine.i_reg(instr_funct3_lsb_c) = funct3_fence_c(0)) then -- FENCE
ctrl_nxt(ctrl_bus_fence_c) <= '1';
end if;
execute_engine.state_nxt <= SYS_WAIT;
820,7 → 818,8
ctrl_nxt(ctrl_alu_opa_mux_lsb_c) <= '0'; -- default
ctrl_nxt(ctrl_alu_opb_mux_msb_c) <= '0'; -- default
ctrl_nxt(ctrl_alu_opb_mux_lsb_c) <= '0'; -- default
ctrl_nxt(ctrl_alu_cmd2_c downto ctrl_alu_cmd0_c) <= alu_cmd_or_c; -- default ALU operation = OR
ctrl_nxt(ctrl_alu_cmd2_c downto ctrl_alu_cmd0_c) <= alu_cmd_or_c; -- default ALU operation = OR
-- ctrl_nxt(ctrl_alu_bmop2_c downto ctrl_alu_bmop0_c) <= alu_bm_andn_c; -- bit manipulation operation = ANDN
case execute_engine.i_reg(instr_funct3_msb_c downto instr_funct3_lsb_c) is
-- register operations --
when funct3_csrrw_c => -- CSRRW
837,7 → 836,7
when funct3_csrrc_c => -- CSRRC
ctrl_nxt(ctrl_alu_opa_mux_msb_c) <= '1'; -- OPA = csr
ctrl_nxt(ctrl_alu_opb_mux_msb_c) <= '1'; -- OPB = rs1
ctrl_nxt(ctrl_alu_cmd2_c downto ctrl_alu_cmd0_c) <= alu_cmd_bitc_c; -- actual ALU operation = bit clear
ctrl_nxt(ctrl_alu_cmd2_c downto ctrl_alu_cmd0_c) <= alu_cmd_bitm_c; -- actual ALU operation = bit manipulation (ANDN)
csr.we_nxt <= (not rs1_is_r0_v) and csr_acc_valid; -- write CSR if rs1 is not zero_reg and if valid access
-- immediate operations --
when funct3_csrrwi_c => -- CSRRWI
854,7 → 853,7
when funct3_csrrci_c => -- CSRRCI
ctrl_nxt(ctrl_alu_opa_mux_msb_c) <= '1'; -- OPA = csr
ctrl_nxt(ctrl_alu_opb_mux_lsb_c) <= '1'; -- OPB = immediate
ctrl_nxt(ctrl_alu_cmd2_c downto ctrl_alu_cmd0_c) <= alu_cmd_bitc_c; -- actual ALU operation = bit clear
ctrl_nxt(ctrl_alu_cmd2_c downto ctrl_alu_cmd0_c) <= alu_cmd_bitm_c; -- actual ALU operation = bit manipulation (ANDN)
csr.we_nxt <= (not rs1_is_r0_v) and csr_acc_valid; -- write CSR if UIMM5 is not zero (bits from rs1 filed) and if valid access
when others => -- undefined
NULL;
910,7 → 909,7
if (ma_load_i = '1') or (be_load_i = '1') or (ma_store_i = '1') or (be_store_i = '1') then -- abort if exception
execute_engine.state_nxt <= SYS_WAIT;
elsif (bus_d_wait_i = '0') then -- wait here for bus to finish transaction
if (execute_engine.i_reg(instr_opcode_msb_c downto instr_opcode_lsb_c) = opcode_load_c) then -- LOAD?
if (execute_engine.i_reg(instr_opcode_msb_c-1) = '0') then -- LOAD
ctrl_nxt(ctrl_rf_wb_en_c) <= '1'; -- valid RF write-back
end if;
execute_engine.state_nxt <= DISPATCH;
941,7 → 940,6
end if;
 
-- check CSR access --
csr_acc_valid <= '0'; -- default
case execute_engine.i_reg(instr_funct12_msb_c downto instr_funct12_lsb_c) is
when x"300" => csr_acc_valid <= is_m_mode_v; -- mstatus
when x"301" => csr_acc_valid <= is_m_mode_v; -- misa
953,29 → 951,29
when x"343" => csr_acc_valid <= is_m_mode_v; -- mtval
when x"344" => csr_acc_valid <= is_m_mode_v; -- mip
--
when x"3a0" => csr_acc_valid <= bool_to_ulogic_f(PMP_USE) and bool_to_ulogic_f(boolean(PMP_NUM_REGIONS >= 1)) and is_m_mode_v; -- pmpacfg0
when x"3a1" => csr_acc_valid <= bool_to_ulogic_f(PMP_USE) and bool_to_ulogic_f(boolean(PMP_NUM_REGIONS >= 5)) and is_m_mode_v; -- pmpacfg1
when x"3a0" => csr_acc_valid <= bool_to_ulogic_f(PMP_USE) and bool_to_ulogic_f(boolean(PMP_NUM_REGIONS >= 1)) and is_m_mode_v; -- pmpacfg0
when x"3a1" => csr_acc_valid <= bool_to_ulogic_f(PMP_USE) and bool_to_ulogic_f(boolean(PMP_NUM_REGIONS >= 5)) and is_m_mode_v; -- pmpacfg1
--
when x"3b0" => csr_acc_valid <= bool_to_ulogic_f(PMP_USE) and bool_to_ulogic_f(boolean(PMP_NUM_REGIONS >= 1)) and is_m_mode_v; -- pmpaddr0
when x"3b1" => csr_acc_valid <= bool_to_ulogic_f(PMP_USE) and bool_to_ulogic_f(boolean(PMP_NUM_REGIONS >= 2)) and is_m_mode_v; -- pmpaddr1
when x"3b2" => csr_acc_valid <= bool_to_ulogic_f(PMP_USE) and bool_to_ulogic_f(boolean(PMP_NUM_REGIONS >= 3)) and is_m_mode_v; -- pmpaddr2
when x"3b3" => csr_acc_valid <= bool_to_ulogic_f(PMP_USE) and bool_to_ulogic_f(boolean(PMP_NUM_REGIONS >= 4)) and is_m_mode_v; -- pmpaddr3
when x"3b4" => csr_acc_valid <= bool_to_ulogic_f(PMP_USE) and bool_to_ulogic_f(boolean(PMP_NUM_REGIONS >= 5)) and is_m_mode_v; -- pmpaddr4
when x"3b5" => csr_acc_valid <= bool_to_ulogic_f(PMP_USE) and bool_to_ulogic_f(boolean(PMP_NUM_REGIONS >= 6)) and is_m_mode_v; -- pmpaddr5
when x"3b6" => csr_acc_valid <= bool_to_ulogic_f(PMP_USE) and bool_to_ulogic_f(boolean(PMP_NUM_REGIONS >= 7)) and is_m_mode_v; -- pmpaddr6
when x"3b7" => csr_acc_valid <= bool_to_ulogic_f(PMP_USE) and bool_to_ulogic_f(boolean(PMP_NUM_REGIONS >= 8)) and is_m_mode_v; -- pmpaddr7
when x"3b0" => csr_acc_valid <= bool_to_ulogic_f(PMP_USE) and bool_to_ulogic_f(boolean(PMP_NUM_REGIONS >= 1)) and is_m_mode_v; -- pmpaddr0
when x"3b1" => csr_acc_valid <= bool_to_ulogic_f(PMP_USE) and bool_to_ulogic_f(boolean(PMP_NUM_REGIONS >= 2)) and is_m_mode_v; -- pmpaddr1
when x"3b2" => csr_acc_valid <= bool_to_ulogic_f(PMP_USE) and bool_to_ulogic_f(boolean(PMP_NUM_REGIONS >= 3)) and is_m_mode_v; -- pmpaddr2
when x"3b3" => csr_acc_valid <= bool_to_ulogic_f(PMP_USE) and bool_to_ulogic_f(boolean(PMP_NUM_REGIONS >= 4)) and is_m_mode_v; -- pmpaddr3
when x"3b4" => csr_acc_valid <= bool_to_ulogic_f(PMP_USE) and bool_to_ulogic_f(boolean(PMP_NUM_REGIONS >= 5)) and is_m_mode_v; -- pmpaddr4
when x"3b5" => csr_acc_valid <= bool_to_ulogic_f(PMP_USE) and bool_to_ulogic_f(boolean(PMP_NUM_REGIONS >= 6)) and is_m_mode_v; -- pmpaddr5
when x"3b6" => csr_acc_valid <= bool_to_ulogic_f(PMP_USE) and bool_to_ulogic_f(boolean(PMP_NUM_REGIONS >= 7)) and is_m_mode_v; -- pmpaddr6
when x"3b7" => csr_acc_valid <= bool_to_ulogic_f(PMP_USE) and bool_to_ulogic_f(boolean(PMP_NUM_REGIONS >= 8)) and is_m_mode_v; -- pmpaddr7
--
when x"c00" => csr_acc_valid <= bool_to_ulogic_f(CSR_COUNTERS_USE); -- cycle
when x"c01" => csr_acc_valid <= bool_to_ulogic_f(CSR_COUNTERS_USE); -- time
when x"c02" => csr_acc_valid <= bool_to_ulogic_f(CSR_COUNTERS_USE); -- instret
when x"c80" => csr_acc_valid <= bool_to_ulogic_f(CSR_COUNTERS_USE); -- cycleh
when x"c81" => csr_acc_valid <= bool_to_ulogic_f(CSR_COUNTERS_USE); -- timeh
when x"c82" => csr_acc_valid <= bool_to_ulogic_f(CSR_COUNTERS_USE); -- instreth
when x"c00" => csr_acc_valid <= '1'; -- cycle
when x"c01" => csr_acc_valid <= '1'; -- time
when x"c02" => csr_acc_valid <= '1'; -- instret
when x"c80" => csr_acc_valid <= '1'; -- cycleh
when x"c81" => csr_acc_valid <= '1'; -- timeh
when x"c82" => csr_acc_valid <= '1'; -- instreth
--
when x"b00" => csr_acc_valid <= bool_to_ulogic_f(CSR_COUNTERS_USE) and is_m_mode_v; -- mcycle
when x"b02" => csr_acc_valid <= bool_to_ulogic_f(CSR_COUNTERS_USE) and is_m_mode_v; -- minstret
when x"b80" => csr_acc_valid <= bool_to_ulogic_f(CSR_COUNTERS_USE) and is_m_mode_v; -- mcycleh
when x"b82" => csr_acc_valid <= bool_to_ulogic_f(CSR_COUNTERS_USE) and is_m_mode_v; -- minstreth
when x"b00" => csr_acc_valid <= is_m_mode_v; -- mcycle
when x"b02" => csr_acc_valid <= is_m_mode_v; -- minstret
when x"b80" => csr_acc_valid <= is_m_mode_v; -- mcycleh
when x"b82" => csr_acc_valid <= is_m_mode_v; -- minstreth
--
when x"f11" => csr_acc_valid <= is_m_mode_v; -- mvendorid
when x"f12" => csr_acc_valid <= is_m_mode_v; -- marchid
984,7 → 982,7
--
when x"fc0" => csr_acc_valid <= is_m_mode_v; -- mzext (custom CSR)
--
when others => csr_acc_valid <= '0'; -- undefined
when others => csr_acc_valid <= '0'; -- undefined, invalid access
end case;
end process invalid_csr_access_check;
 
1000,13 → 998,6
illegal_instruction <= '0';
illegal_register <= '0';
 
-- check if using reg >= 16 for E-CPUs --
--if (CPU_EXTENSION_RISCV_E = true) then
-- illegal_register <= ????? FIXME
--else
-- illegal_register <= '0';
--end if;
 
-- check instructions --
case execute_engine.i_reg(instr_opcode_msb_c downto instr_opcode_lsb_c) is
 
1013,6 → 1004,10
-- OPCODE check sufficient: LUI, UIPC, JAL --
when opcode_lui_c | opcode_auipc_c | opcode_jal_c =>
illegal_instruction <= '0';
-- illegal E-CPU register? --
if (CPU_EXTENSION_RISCV_E = true) and (execute_engine.i_reg(instr_rd_msb_c) = '1') then
illegal_register <= '1';
end if;
 
when opcode_alui_c => -- check ALUI funct7
if ((execute_engine.i_reg(instr_funct3_msb_c downto instr_funct3_lsb_c) = funct3_sll_c) and
1024,6 → 1019,10
else
illegal_instruction <= '0';
end if;
-- illegal E-CPU register? --
if (CPU_EXTENSION_RISCV_E = true) and ((execute_engine.i_reg(instr_rs1_msb_c) = '1') or (execute_engine.i_reg(instr_rd_msb_c) = '1')) then
illegal_register <= '1';
end if;
when opcode_load_c => -- check LOAD funct3
if (execute_engine.i_reg(instr_funct3_msb_c downto instr_funct3_lsb_c) = funct3_lb_c) or
1035,6 → 1034,10
else
illegal_instruction <= '1';
end if;
-- illegal E-CPU register? --
if (CPU_EXTENSION_RISCV_E = true) and ((execute_engine.i_reg(instr_rs1_msb_c) = '1') or (execute_engine.i_reg(instr_rd_msb_c) = '1')) then
illegal_register <= '1';
end if;
when opcode_store_c => -- check STORE funct3
if (execute_engine.i_reg(instr_funct3_msb_c downto instr_funct3_lsb_c) = funct3_sb_c) or
1044,6 → 1047,10
else
illegal_instruction <= '1';
end if;
-- illegal E-CPU register? --
if (CPU_EXTENSION_RISCV_E = true) and ((execute_engine.i_reg(instr_rs2_msb_c) = '1') or (execute_engine.i_reg(instr_rs1_msb_c) = '1')) then
illegal_register <= '1';
end if;
 
when opcode_branch_c => -- check BRANCH funct3
if (execute_engine.i_reg(instr_funct3_msb_c downto instr_funct3_lsb_c) = funct3_beq_c) or
1056,6 → 1063,10
else
illegal_instruction <= '1';
end if;
-- illegal E-CPU register? --
if (CPU_EXTENSION_RISCV_E = true) and ((execute_engine.i_reg(instr_rs2_msb_c) = '1') or (execute_engine.i_reg(instr_rs1_msb_c) = '1')) then
illegal_register <= '1';
end if;
 
when opcode_jalr_c => -- check JALR funct3
if (execute_engine.i_reg(instr_funct3_msb_c downto instr_funct3_lsb_c) = "000") then
1063,6 → 1074,10
else
illegal_instruction <= '1';
end if;
-- illegal E-CPU register? --
if (CPU_EXTENSION_RISCV_E = true) and ((execute_engine.i_reg(instr_rs1_msb_c) = '1') or (execute_engine.i_reg(instr_rd_msb_c) = '1')) then
illegal_register <= '1';
end if;
 
when opcode_alu_c => -- check ALU funct3 & funct7
if (execute_engine.i_reg(instr_funct7_msb_c downto instr_funct7_lsb_c) = "0000001") then -- MULDIV
1077,6 → 1092,11
else
illegal_instruction <= '0';
end if;
-- illegal E-CPU register? --
if (CPU_EXTENSION_RISCV_E = true) and
((execute_engine.i_reg(instr_rs2_msb_c) = '1') or (execute_engine.i_reg(instr_rs1_msb_c) = '1') or (execute_engine.i_reg(instr_rd_msb_c) = '1')) then
illegal_register <= '1';
end if;
 
when opcode_fence_c => -- fence instructions --
if (execute_engine.i_reg(instr_funct3_msb_c downto instr_funct3_lsb_c) = funct3_fencei_c) and (CPU_EXTENSION_RISCV_Zifencei = true) then -- FENCE.I
1101,6 → 1121,14
else
illegal_instruction <= '1';
end if;
-- illegal E-CPU register? --
if (CPU_EXTENSION_RISCV_E = true) then
if (execute_engine.i_reg(instr_funct3_msb_c) = '0') then -- reg-reg CSR
illegal_register <= execute_engine.i_reg(instr_rs1_msb_c) or execute_engine.i_reg(instr_rd_msb_c);
else -- reg-imm CSR
illegal_register <= execute_engine.i_reg(instr_rd_msb_c);
end if;
end if;
 
-- ecall, ebreak, mret, wfi --
elsif (execute_engine.i_reg(instr_rd_msb_c downto instr_rd_lsb_c) = "00000") and
1181,6 → 1209,7
trap_ctrl.exc_ack <= '1'; -- clear execption
trap_ctrl.irq_ack <= trap_ctrl.irq_ack_nxt; -- capture and clear with interrupt ACK mask
trap_ctrl.env_start <= '1'; -- now execute engine can start trap handler
-- assert false report "NEORV32.CPU TRAP: mcause=" & integer'image(to_integer(unsigned(trap_ctrl.cause_nxt))) severity note; -- for debugging
end if;
else -- trap waiting to get started
if (trap_ctrl.env_start_ack = '1') then -- start of trap handler acknowledged by execution engine
1641,22 → 1670,22
when x"c00" | x"b00" => -- R/(W): cycle/mcycle: Cycle counter LOW
csr_rdata_o <= csr.mcycle(31 downto 0);
when x"c01" => -- R/-: time: System time LOW (from MTIME unit)
csr_rdata_o <= systime(31 downto 0);
csr_rdata_o <= time_i(31 downto 0);
when x"c02" | x"b02" => -- R/(W): instret/minstret: Instructions-retired counter LOW
csr_rdata_o <= csr.minstret(31 downto 0);
when x"c80" | x"b80" => -- R/(W): cycleh/mcycleh: Cycle counter HIGH
csr_rdata_o <= x"000" & csr.mcycleh(19 downto 0); -- only the lowest 20 bit!
when x"c81" => -- R/-: timeh: System time HIGH (from MTIME unit)
csr_rdata_o <= systime(63 downto 32);
csr_rdata_o <= time_i(63 downto 32);
when x"c82" | x"b82" => -- R/(W): instreth/minstreth: Instructions-retired counter HIGH
csr_rdata_o <= x"000" & csr.minstreth(19 downto 0); -- only the lowest 20 bit!
 
-- machine information registers --
when x"f11" => -- R/-: mvendorid
csr_rdata_o <= (others => '0'); -- not available for NEORV32
csr_rdata_o <= (others => '0'); -- not assigned
when x"f12" => -- R/-: marchid
csr_rdata_o <= (others => '0'); -- not available for NEORV32
when x"f13" => -- R/-: mimpid - implementation ID / NEORV32: version
csr_rdata_o <= (others => '0'); -- not assigned
when x"f13" => -- R/-: mimpid - implementation ID / NEORV32 version
csr_rdata_o <= hw_version_c;
when x"f14" => -- R/-: mhartid - hardware thread ID
csr_rdata_o <= HW_THREAD_ID;
1665,7 → 1694,6
when x"fc0" => -- R/-: mzext
csr_rdata_o(0) <= bool_to_ulogic_f(CPU_EXTENSION_RISCV_Zicsr); -- Zicsr CPU extension
csr_rdata_o(1) <= bool_to_ulogic_f(CPU_EXTENSION_RISCV_Zifencei); -- Zifencei CPU extension
csr_rdata_o(2) <= bool_to_ulogic_f(CSR_COUNTERS_USE); -- std (performance) counters enabled
 
-- undefined/unavailable --
when others =>
1678,9 → 1706,6
end if;
end process csr_read_access;
 
-- time[h] CSR --
systime <= time_i when (CSR_COUNTERS_USE = true) else (others => '0');
 
-- CPU's current privilege level --
priv_mode_o <= csr.privilege;
 
1710,47 → 1735,37
mcycle_msb <= '0';
minstret_msb <= '0';
elsif rising_edge(clk_i) then
if (CSR_COUNTERS_USE = true) then
 
-- mcycle (cycle) --
mcycle_msb <= csr.mcycle(csr.mcycle'left);
if (csr.we = '1') and (execute_engine.i_reg(31 downto 20) = x"b00") then -- write access
csr.mcycle(31 downto 0) <= csr_wdata_i;
csr.mcycle(32) <= '0';
elsif (execute_engine.sleep = '0') then -- automatic update
csr.mcycle <= std_ulogic_vector(unsigned(csr.mcycle) + 1);
end if;
-- mcycle (cycle) --
mcycle_msb <= csr.mcycle(csr.mcycle'left);
if (csr.we = '1') and (execute_engine.i_reg(31 downto 20) = x"b00") then -- write access
csr.mcycle(31 downto 0) <= csr_wdata_i;
csr.mcycle(32) <= '0';
elsif (execute_engine.sleep = '0') then -- automatic update (if CPU is not in sleep mode)
csr.mcycle <= std_ulogic_vector(unsigned(csr.mcycle) + 1);
end if;
 
-- mcycleh (cycleh) --
if (csr.we = '1') and (execute_engine.i_reg(31 downto 20) = x"b80") then -- write access
csr.mcycleh <= csr_wdata_i(19 downto 0);
elsif ((mcycle_msb xor csr.mcycle(csr.mcycle'left)) = '1') then -- automatic update
csr.mcycleh <= std_ulogic_vector(unsigned(csr.mcycleh) + 1);
end if;
-- mcycleh (cycleh) --
if (csr.we = '1') and (execute_engine.i_reg(31 downto 20) = x"b80") then -- write access
csr.mcycleh <= csr_wdata_i(csr.mcycleh'left downto 0);
elsif ((mcycle_msb xor csr.mcycle(csr.mcycle'left)) = '1') then -- automatic update
csr.mcycleh <= std_ulogic_vector(unsigned(csr.mcycleh) + 1);
end if;
 
-- minstret (instret) --
minstret_msb <= csr.minstret(csr.minstret'left);
if (csr.we = '1') and (execute_engine.i_reg(31 downto 20) = x"b02") then -- write access
csr.minstret(31 downto 0) <= csr_wdata_i;
csr.minstret(32) <= '0';
elsif (execute_engine.state_prev /= EXECUTE) and (execute_engine.state = EXECUTE) then -- automatic update
csr.minstret <= std_ulogic_vector(unsigned(csr.minstret) + 1);
end if;
-- minstret (instret) --
minstret_msb <= csr.minstret(csr.minstret'left);
if (csr.we = '1') and (execute_engine.i_reg(31 downto 20) = x"b02") then -- write access
csr.minstret(31 downto 0) <= csr_wdata_i;
csr.minstret(32) <= '0';
elsif (execute_engine.state_prev /= EXECUTE) and (execute_engine.state = EXECUTE) then -- automatic update
csr.minstret <= std_ulogic_vector(unsigned(csr.minstret) + 1);
end if;
 
-- minstreth (instreth) --
if (csr.we = '1') and (execute_engine.i_reg(31 downto 20) = x"b82") then -- write access
csr.minstreth <= csr_wdata_i(19 downto 0);
elsif ((minstret_msb xor csr.minstret(csr.minstret'left)) = '1') then -- automatic update
csr.minstreth <= std_ulogic_vector(unsigned(csr.minstreth) + 1);
end if;
 
else -- if not implemented
csr.mcycle <= (others => '0');
csr.minstret <= (others => '0');
csr.mcycleh <= (others => '0');
csr.minstreth <= (others => '0');
mcycle_msb <= '0';
minstret_msb <= '0';
-- minstreth (instreth) --
if (csr.we = '1') and (execute_engine.i_reg(31 downto 20) = x"b82") then -- write access
csr.minstreth <= csr_wdata_i(csr.minstreth'left downto 0);
elsif ((minstret_msb xor csr.minstret(csr.minstret'left)) = '1') then -- automatic update
csr.minstreth <= std_ulogic_vector(unsigned(csr.minstreth) + 1);
end if;
end if;
end process csr_counters;
/neorv32_gpio.vhd
70,8 → 70,9
signal addr : std_ulogic_vector(31 downto 0); -- access address
 
-- accessible regs --
signal din : std_ulogic_vector(31 downto 0); -- r/w
signal dout : std_ulogic_vector(31 downto 0); -- r/w
signal din : std_ulogic_vector(31 downto 0); -- r/-
signal dout : std_ulogic_vector(31 downto 0); -- r/w
signal irq_en : std_ulogic_vector(31 downto 0); -- -/w, uses the same address as data_in
 
-- misc --
signal in_buf : std_ulogic_vector(31 downto 0);
92,8 → 93,10
ack_o <= acc_en and (rden_i or wren_i);
-- write access --
if ((acc_en and wren_i) = '1') then
if (addr = gpio_out_addr_c) then
dout <= data_i;
if (addr = gpio_in_addr_c) then
irq_en <= data_i; -- pin change IRQ enable
else -- gpio_out_addr_c
dout <= data_i; -- data output port
end if;
end if;
-- read access --
100,9 → 103,9
data_o <= (others => '0');
if ((acc_en and rden_i) = '1') then
if (addr = gpio_in_addr_c) then
data_o <= din;
data_o <= din; -- data input port
else -- gpio_out_addr_c
data_o <= dout;
data_o <= dout; -- data output port
end if;
end if;
end if;
121,7 → 124,7
in_buf <= gpio_i;
din <= in_buf;
-- IRQ --
irq_o <= or_all_f(in_buf xor din); -- any transition triggers an interrupt
irq_o <= or_all_f((in_buf xor din) and irq_en); -- any enabled pin transition triggers an interrupt
end if;
end process irq_detector;
 
/neorv32_package.vhd
38,11 → 38,11
 
package neorv32_package is
 
-- Architecture Constants -----------------------------------------------------------------
-- Architecture Constants/Configuration ---------------------------------------------------
-- -------------------------------------------------------------------------------------------
constant data_width_c : natural := 32; -- data width - FIXED!
constant hw_version_c : std_ulogic_vector(31 downto 0) := x"01040000"; -- no touchy!
constant pmp_max_r_c : natural := 8; -- max PMP regions
constant hw_version_c : std_ulogic_vector(31 downto 0) := x"01040300"; -- no touchy!
constant pmp_max_r_c : natural := 8; -- max PMP regions - FIXED!
constant ipb_entries_c : natural := 2; -- entries in instruction prefetch buffer, must be a power of 2, default=2
 
-- Helper Functions -----------------------------------------------------------------------
62,16 → 62,26
type pmp_ctrl_if_t is array (0 to pmp_max_r_c-1) of std_ulogic_vector(7 downto 0);
type pmp_addr_if_t is array (0 to pmp_max_r_c-1) of std_ulogic_vector(33 downto 0);
 
-- Processor-internal Address Space Layout ------------------------------------------------
-- General Address Space Layout -----------------------------------------------------------
-- -------------------------------------------------------------------------------------------
-- Instruction Memory & Data Memory --
-- => configured via top's generics
constant ispace_base_c : std_ulogic_vector(data_width_c-1 downto 0) := x"00000000"; -- instruction memory space base address
constant dspace_base_c : std_ulogic_vector(data_width_c-1 downto 0) := x"80000000"; -- data memory space base address
 
-- Bootloader ROM --
constant boot_base_c : std_ulogic_vector(data_width_c-1 downto 0) := x"FFFF0000"; -- bootloader base address, fixed!
constant boot_size_c : natural := 4*1024; -- bytes
constant boot_max_size_c : natural := 32*1024; -- bytes, fixed!
-- Processor-Internal Address Space Layout ------------------------------------------------
-- -------------------------------------------------------------------------------------------
-- Internal Instruction Memory (IMEM) --
constant imem_base_c : std_ulogic_vector(data_width_c-1 downto 0) := ispace_base_c; -- internal instruction memory base address
--> size is configured via top's generic
 
-- Internal Data Memory (DMEM) --
constant dmem_base_c : std_ulogic_vector(data_width_c-1 downto 0) := dspace_base_c; -- internal data memory base address
--> size is configured via top's generic
 
-- Internal Bootloader ROM --
constant boot_rom_base_c : std_ulogic_vector(data_width_c-1 downto 0) := x"FFFF0000"; -- bootloader base address, fixed!
constant boot_rom_size_c : natural := 4*1024; -- bytes
constant boot_rom_max_size_c : natural := 32*1024; -- bytes, fixed!
 
-- IO: Peripheral Devices ("IO") Area --
-- Control register(s) (including the device-enable) should be located at the base address of each device
constant io_base_c : std_ulogic_vector(data_width_c-1 downto 0) := x"FFFFFF80";
79,65 → 89,72
 
-- General Purpose Input/Output Unit (GPIO) --
constant gpio_base_c : std_ulogic_vector(data_width_c-1 downto 0) := x"FFFFFF80"; -- base address, fixed!
constant gpio_size_c : natural := 2*4; -- bytes, fixed!
constant gpio_in_addr_c : std_ulogic_vector(31 downto 0) := std_ulogic_vector(unsigned(gpio_base_c) + x"00000000");
constant gpio_out_addr_c : std_ulogic_vector(31 downto 0) := std_ulogic_vector(unsigned(gpio_base_c) + x"00000004");
constant gpio_size_c : natural := 2*4; -- bytes
constant gpio_in_addr_c : std_ulogic_vector(data_width_c-1 downto 0) := x"FFFFFF80";
constant gpio_out_addr_c : std_ulogic_vector(data_width_c-1 downto 0) := x"FFFFFF84";
 
-- Dummy Device (with SIMULATION output) (DEVNULL) --
constant devnull_base_c : std_ulogic_vector(data_width_c-1 downto 0) := x"FFFFFF88"; -- base address, fixed!
constant devnull_size_c : natural := 1*4; -- bytes, fixed!
constant devnull_data_addr_c : std_ulogic_vector(31 downto 0) := std_ulogic_vector(unsigned(devnull_base_c) + x"00000000");
constant devnull_size_c : natural := 1*4; -- bytes
constant devnull_data_addr_c : std_ulogic_vector(data_width_c-1 downto 0) := x"FFFFFF88";
 
-- Watch Dog Timer (WDT) --
constant wdt_base_c : std_ulogic_vector(data_width_c-1 downto 0) := x"FFFFFF8C"; -- base address, fixed!
constant wdt_size_c : natural := 1*4; -- bytes, fixed!
constant wdt_ctrl_addr_c : std_ulogic_vector(31 downto 0) := std_ulogic_vector(unsigned(wdt_base_c) + x"00000000");
constant wdt_size_c : natural := 1*4; -- bytes
constant wdt_ctrl_addr_c : std_ulogic_vector(data_width_c-1 downto 0) := x"FFFFFF8C";
 
-- Machine System Timer (MTIME) --
constant mtime_base_c : std_ulogic_vector(data_width_c-1 downto 0) := x"FFFFFF90"; -- base address, fixed!
constant mtime_size_c : natural := 4*4; -- bytes, fixed!
constant mtime_time_lo_addr_c : std_ulogic_vector(31 downto 0) := std_ulogic_vector(unsigned(mtime_base_c) + x"00000000");
constant mtime_time_hi_addr_c : std_ulogic_vector(31 downto 0) := std_ulogic_vector(unsigned(mtime_base_c) + x"00000004");
constant mtime_cmp_lo_addr_c : std_ulogic_vector(31 downto 0) := std_ulogic_vector(unsigned(mtime_base_c) + x"00000008");
constant mtime_cmp_hi_addr_c : std_ulogic_vector(31 downto 0) := std_ulogic_vector(unsigned(mtime_base_c) + x"0000000C");
constant mtime_size_c : natural := 4*4; -- bytes
constant mtime_time_lo_addr_c : std_ulogic_vector(data_width_c-1 downto 0) := x"FFFFFF90";
constant mtime_time_hi_addr_c : std_ulogic_vector(data_width_c-1 downto 0) := x"FFFFFF94";
constant mtime_cmp_lo_addr_c : std_ulogic_vector(data_width_c-1 downto 0) := x"FFFFFF98";
constant mtime_cmp_hi_addr_c : std_ulogic_vector(data_width_c-1 downto 0) := x"FFFFFF9C";
 
-- Universal Asynchronous Receiver/Transmitter (UART) --
constant uart_base_c : std_ulogic_vector(data_width_c-1 downto 0) := x"FFFFFFA0"; -- base address, fixed!
constant uart_size_c : natural := 2*4; -- bytes, fixed!
constant uart_ctrl_addr_c : std_ulogic_vector(31 downto 0) := std_ulogic_vector(unsigned(uart_base_c) + x"00000000");
constant uart_rtx_addr_c : std_ulogic_vector(31 downto 0) := std_ulogic_vector(unsigned(uart_base_c) + x"00000004");
constant uart_size_c : natural := 2*4; -- bytes
constant uart_ctrl_addr_c : std_ulogic_vector(data_width_c-1 downto 0) := x"FFFFFFA0";
constant uart_rtx_addr_c : std_ulogic_vector(data_width_c-1 downto 0) := x"FFFFFFA4";
 
-- Serial Peripheral Interface (SPI) --
constant spi_base_c : std_ulogic_vector(data_width_c-1 downto 0) := x"FFFFFFA8"; -- base address, fixed!
constant spi_size_c : natural := 2*4; -- bytes, fixed!
constant spi_ctrl_addr_c : std_ulogic_vector(31 downto 0) := std_ulogic_vector(unsigned(spi_base_c) + x"00000000");
constant spi_rtx_addr_c : std_ulogic_vector(31 downto 0) := std_ulogic_vector(unsigned(spi_base_c) + x"00000004");
constant spi_size_c : natural := 2*4; -- bytes
constant spi_ctrl_addr_c : std_ulogic_vector(data_width_c-1 downto 0) := x"FFFFFFA8";
constant spi_rtx_addr_c : std_ulogic_vector(data_width_c-1 downto 0) := x"FFFFFFAC";
 
-- Two Wire Interface (TWI) --
constant twi_base_c : std_ulogic_vector(data_width_c-1 downto 0) := x"FFFFFFB0"; -- base address, fixed!
constant twi_size_c : natural := 2*4; -- bytes, fixed!
constant twi_ctrl_addr_c : std_ulogic_vector(31 downto 0) := std_ulogic_vector(unsigned(twi_base_c) + x"00000000");
constant twi_rtx_addr_c : std_ulogic_vector(31 downto 0) := std_ulogic_vector(unsigned(twi_base_c) + x"00000004");
constant twi_size_c : natural := 2*4; -- bytes
constant twi_ctrl_addr_c : std_ulogic_vector(data_width_c-1 downto 0) := x"FFFFFFB0";
constant twi_rtx_addr_c : std_ulogic_vector(data_width_c-1 downto 0) := x"FFFFFFB4";
 
-- Pulse-Width Modulation Controller (PWM) --
constant pwm_base_c : std_ulogic_vector(data_width_c-1 downto 0) := x"FFFFFFB8"; -- base address, fixed!
constant pwm_size_c : natural := 2*4; -- bytes, fixed!
constant pwm_ctrl_addr_c : std_ulogic_vector(31 downto 0) := std_ulogic_vector(unsigned(pwm_base_c) + x"00000000");
constant pwm_duty_addr_c : std_ulogic_vector(31 downto 0) := std_ulogic_vector(unsigned(pwm_base_c) + x"00000004");
constant pwm_size_c : natural := 2*4; -- bytes
constant pwm_ctrl_addr_c : std_ulogic_vector(data_width_c-1 downto 0) := x"FFFFFFB8";
constant pwm_duty_addr_c : std_ulogic_vector(data_width_c-1 downto 0) := x"FFFFFFBC";
 
-- True Random Number generator (TRNG) --
-- True Random Number Generator (TRNG) --
constant trng_base_c : std_ulogic_vector(data_width_c-1 downto 0) := x"FFFFFFC0"; -- base address, fixed!
constant trng_size_c : natural := 2*4; -- bytes, fixed!
constant trng_ctrl_addr_c : std_ulogic_vector(31 downto 0) := std_ulogic_vector(unsigned(trng_base_c) + x"00000000");
constant trng_data_addr_c : std_ulogic_vector(31 downto 0) := std_ulogic_vector(unsigned(trng_base_c) + x"00000004");
constant trng_size_c : natural := 1*4; -- bytes
constant trng_ctrl_addr_c : std_ulogic_vector(data_width_c-1 downto 0) := x"FFFFFFC0";
 
-- RESERVED --
--constant ???_base_c : std_ulogic_vector(data_width_c-1 downto 0) := x"FFFFFFC8"; -- base address, fixed!
--constant ???_size_c : natural := 6*4; -- bytes, fixed!
--constant ???_base_c : std_ulogic_vector(data_width_c-1 downto 0) := x"FFFFFFC4"; -- base address, fixed!
--constant ???_size_c : natural := 3*4; -- bytes
 
-- System Information Memory (with SIMULATION output) (SYSINFO) --
-- Custom Functions Unit (CFU) --
constant cfu_base_c : std_ulogic_vector(data_width_c-1 downto 0) := x"FFFFFFD0"; -- base address, fixed!
constant cfu_size_c : natural := 4*4; -- bytes
constant cfu_reg0_addr_c : std_ulogic_vector(data_width_c-1 downto 0) := x"FFFFFFD0";
constant cfu_reg1_addr_c : std_ulogic_vector(data_width_c-1 downto 0) := x"FFFFFFD4";
constant cfu_reg2_addr_c : std_ulogic_vector(data_width_c-1 downto 0) := x"FFFFFFD8";
constant cfu_reg3_addr_c : std_ulogic_vector(data_width_c-1 downto 0) := x"FFFFFFDC";
 
-- System Information Memory (SYSINFO) --
constant sysinfo_base_c : std_ulogic_vector(data_width_c-1 downto 0) := x"FFFFFFE0"; -- base address, fixed!
constant sysinfo_size_c : natural := 8*4; -- bytes, fixed!
constant sysinfo_size_c : natural := 8*4; -- bytes
 
-- Main Control Bus -----------------------------------------------------------------------
-- -------------------------------------------------------------------------------------------
315,7 → 332,7
constant alu_cmd_xor_c : std_ulogic_vector(2 downto 0) := "100"; -- r <= A xor B
constant alu_cmd_or_c : std_ulogic_vector(2 downto 0) := "101"; -- r <= A or B
constant alu_cmd_and_c : std_ulogic_vector(2 downto 0) := "110"; -- r <= A and B
constant alu_cmd_bitc_c : std_ulogic_vector(2 downto 0) := "111"; -- r <= A and (not B)
constant alu_cmd_bitm_c : std_ulogic_vector(2 downto 0) := "111"; -- r <= bit manipulation
 
-- Trap ID Codes --------------------------------------------------------------------------
-- -------------------------------------------------------------------------------------------
396,24 → 413,19
CPU_EXTENSION_RISCV_Zicsr : boolean := true; -- implement CSR system?
CPU_EXTENSION_RISCV_Zifencei : boolean := true; -- implement instruction stream sync.?
-- Extension Options --
CSR_COUNTERS_USE : boolean := true; -- implement RISC-V perf. counters ([m]instret[h], [m]cycle[h], time[h])?
FAST_MUL_EN : boolean := false; -- use DSPs for M extension's multiplier
-- Physical Memory Protection (PMP) --
PMP_USE : boolean := false; -- implement PMP?
PMP_NUM_REGIONS : natural := 4; -- number of regions (max 8)
PMP_GRANULARITY : natural := 14; -- minimal region granularity (1=8B, 2=16B, 3=32B, ...) default is 64k
-- Memory configuration: Instruction memory --
MEM_ISPACE_BASE : std_ulogic_vector(31 downto 0) := x"00000000"; -- base address of instruction memory space
MEM_ISPACE_SIZE : natural := 16*1024; -- total size of instruction memory space in byte
-- Internal Instruction memory --
MEM_INT_IMEM_USE : boolean := true; -- implement processor-internal instruction memory
MEM_INT_IMEM_SIZE : natural := 16*1024; -- size of processor-internal instruction memory in bytes
MEM_INT_IMEM_ROM : boolean := false; -- implement processor-internal instruction memory as ROM
-- Memory configuration: Data memory --
MEM_DSPACE_BASE : std_ulogic_vector(31 downto 0) := x"80000000"; -- base address of data memory space
MEM_DSPACE_SIZE : natural := 8*1024; -- total size of data memory space in byte
-- Internal Data memory --
MEM_INT_DMEM_USE : boolean := true; -- implement processor-internal data memory
MEM_INT_DMEM_SIZE : natural := 8*1024; -- size of processor-internal data memory in bytes
-- Memory configuration: External memory interface --
-- External memory interface --
MEM_EXT_USE : boolean := false; -- implement external memory bus interface?
MEM_EXT_REG_STAGES : natural := 2; -- number of interface register stages (0,1,2)
MEM_EXT_TIMEOUT : natural := 15; -- cycles after which a valid bus access will timeout (>=1)
426,7 → 438,8
IO_PWM_USE : boolean := true; -- implement pulse-width modulation unit (PWM)?
IO_WDT_USE : boolean := true; -- implement watch dog timer (WDT)?
IO_TRNG_USE : boolean := false; -- implement true random number generator (TRNG)?
IO_DEVNULL_USE : boolean := true -- implement dummy device (DEVNULL)?
IO_DEVNULL_USE : boolean := true; -- implement dummy device (DEVNULL)?
IO_CFU_USE : boolean := false -- implement custom functions unit (CFU)?
);
port (
-- Global control --
482,7 → 495,6
CPU_EXTENSION_RISCV_Zicsr : boolean := true; -- implement CSR system?
CPU_EXTENSION_RISCV_Zifencei : boolean := true; -- implement instruction stream sync.?
-- Extension Options --
CSR_COUNTERS_USE : boolean := true; -- implement RISC-V perf. counters ([m]instret[h], [m]cycle[h], time[h])?
FAST_MUL_EN : boolean := false; -- use DSPs for M extension's multiplier
-- Physical Memory Protection (PMP) --
PMP_USE : boolean := false; -- implement PMP?
533,7 → 545,6
component neorv32_cpu_control
generic (
-- General --
CSR_COUNTERS_USE : boolean := true; -- implement RISC-V perf. counters ([m]instret[h], [m]cycle[h], time[h])?
HW_THREAD_ID : std_ulogic_vector(31 downto 0):= x"00000000"; -- hardware thread id
CPU_BOOT_ADDR : std_ulogic_vector(31 downto 0):= x"00000000"; -- cpu boot address
-- RISC-V CPU Extensions --
830,6 → 841,10
-- Component: Processor-internal bootloader ROM (BOOTROM) ---------------------------------
-- -------------------------------------------------------------------------------------------
component neorv32_boot_rom
generic (
BOOTROM_BASE : std_ulogic_vector(31 downto 0) := x"FFFF0000"; -- boot ROM base address
BOOTROM_SIZE : natural := 4*1024 -- processor-internal boot ROM memory size in bytes
);
port (
clk_i : in std_ulogic; -- global clock line
rden_i : in std_ulogic; -- read enable
1012,14 → 1027,10
component neorv32_wishbone
generic (
INTERFACE_REG_STAGES : natural := 2; -- number of interface register stages (0,1,2)
-- Memory configuration: Instruction memory --
MEM_ISPACE_BASE : std_ulogic_vector(31 downto 0) := x"00000000"; -- base address of instruction memory space
MEM_ISPACE_SIZE : natural := 8*1024; -- total size of instruction memory space in byte
-- Internal instruction memory --
MEM_INT_IMEM_USE : boolean := true; -- implement processor-internal instruction memory
MEM_INT_IMEM_SIZE : natural := 8*1024; -- size of processor-internal instruction memory in bytes
-- Memory configuration: Data memory --
MEM_DSPACE_BASE : std_ulogic_vector(31 downto 0) := x"80000000"; -- base address of data memory space
MEM_DSPACE_SIZE : natural := 4*1024; -- total size of data memory space in byte
-- Internal data memory --
MEM_INT_DMEM_USE : boolean := true; -- implement processor-internal data memory
MEM_INT_DMEM_SIZE : natural := 4*1024 -- size of processor-internal data memory in bytes
);
1050,8 → 1061,8
);
end component;
 
---- Component: Dummy Device with SIM Output (DEVNULL) -------------------------------------
---- -------------------------------------------------------------------------------------------
-- Component: Dummy Device with SIM Output (DEVNULL) --------------------------------------
-- -------------------------------------------------------------------------------------------
component neorv32_devnull
port (
-- host access --
1065,8 → 1076,31
);
end component;
 
---- Component: System Configuration Information Memory (SYSINFO) ---------------------------
---- -------------------------------------------------------------------------------------------
-- Component: Custom Functions Unit (CFU) -------------------------------------------------
-- -------------------------------------------------------------------------------------------
component neorv32_cfu
port (
-- host access --
clk_i : in std_ulogic; -- global clock line
rstn_i : in std_ulogic; -- global reset line, low-active, use as async
addr_i : in std_ulogic_vector(31 downto 0); -- address
rden_i : in std_ulogic; -- read enable
wren_i : in std_ulogic; -- write enable
data_i : in std_ulogic_vector(31 downto 0); -- data in
data_o : out std_ulogic_vector(31 downto 0); -- data out
ack_o : out std_ulogic; -- transfer acknowledge
-- clock generator --
clkgen_en_o : out std_ulogic; -- enable clock generator
clkgen_i : in std_ulogic_vector(07 downto 0); -- "clock" inputs
-- interrupt --
irq_o : out std_ulogic
-- custom io --
-- ...
);
end component;
 
-- Component: System Configuration Information Memory (SYSINFO) ---------------------------
-- -------------------------------------------------------------------------------------------
component neorv32_sysinfo
generic (
-- General --
1073,18 → 1107,14
CLOCK_FREQUENCY : natural := 0; -- clock frequency of clk_i in Hz
BOOTLOADER_USE : boolean := true; -- implement processor-internal bootloader?
USER_CODE : std_ulogic_vector(31 downto 0) := x"00000000"; -- custom user code
-- Memory configuration: Instruction memory --
MEM_ISPACE_BASE : std_ulogic_vector(31 downto 0) := x"00000000"; -- base address of instruction memory space
MEM_ISPACE_SIZE : natural := 8*1024; -- total size of instruction memory space in byte
-- Internal Instruction memory --
MEM_INT_IMEM_USE : boolean := true; -- implement processor-internal instruction memory
MEM_INT_IMEM_SIZE : natural := 8*1024; -- size of processor-internal instruction memory in bytes
MEM_INT_IMEM_ROM : boolean := false; -- implement processor-internal instruction memory as ROM
-- Memory configuration: Data memory --
MEM_DSPACE_BASE : std_ulogic_vector(31 downto 0) := x"80000000"; -- base address of data memory space
MEM_DSPACE_SIZE : natural := 4*1024; -- total size of data memory space in byte
-- Internal Data memory --
MEM_INT_DMEM_USE : boolean := true; -- implement processor-internal data memory
MEM_INT_DMEM_SIZE : natural := 4*1024; -- size of processor-internal data memory in bytes
-- Memory configuration: External memory interface --
-- External memory interface --
MEM_EXT_USE : boolean := false; -- implement external memory bus interface?
-- Processor peripherals --
IO_GPIO_USE : boolean := true; -- implement general purpose input/output port unit (GPIO)?
1095,7 → 1125,8
IO_PWM_USE : boolean := true; -- implement pulse-width modulation unit (PWM)?
IO_WDT_USE : boolean := true; -- implement watch dog timer (WDT)?
IO_TRNG_USE : boolean := true; -- implement true random number generator (TRNG)?
IO_DEVNULL_USE : boolean := true -- implement dummy device (DEVNULL)?
IO_DEVNULL_USE : boolean := true; -- implement dummy device (DEVNULL)?
IO_CFU_USE : boolean := true -- implement custom functions unit (CFU)?
);
port (
-- host access --
/neorv32_pwm.vhd
90,9 → 90,8
-- prescaler clock generator --
signal prsc_tick : std_ulogic;
 
-- pwm counter --
-- pwm core counter --
signal pwm_cnt : std_ulogic_vector(7 downto 0);
signal pwm_out : std_ulogic_vector(3 downto 0);
 
begin
 
157,19 → 156,13
-- channels --
for i in 0 to num_pwm_channels_c-1 loop
if (unsigned(pwm_cnt) >= unsigned(pwm_ch(i))) or (enable = '0') then
pwm_out(i) <= '0';
pwm_o(i) <= '0';
else
pwm_out(i) <= '1';
pwm_o(i) <= '1';
end if;
end loop; -- i, pwm channel
end if;
end process pwm_core;
 
-- output --
pwm_o(0) <= pwm_out(0);
pwm_o(1) <= pwm_out(1);
pwm_o(2) <= pwm_out(2);
pwm_o(3) <= pwm_out(3);
 
 
end neorv32_pwm_rtl;
/neorv32_sysinfo.vhd
48,18 → 48,14
CLOCK_FREQUENCY : natural := 0; -- clock frequency of clk_i in Hz
BOOTLOADER_USE : boolean := true; -- implement processor-internal bootloader?
USER_CODE : std_ulogic_vector(31 downto 0) := x"00000000"; -- custom user code
-- Memory configuration: Instruction memory --
MEM_ISPACE_BASE : std_ulogic_vector(31 downto 0) := x"00000000"; -- base address of instruction memory space
MEM_ISPACE_SIZE : natural := 8*1024; -- total size of instruction memory space in byte
-- Internal Instruction memory --
MEM_INT_IMEM_USE : boolean := true; -- implement processor-internal instruction memory
MEM_INT_IMEM_SIZE : natural := 8*1024; -- size of processor-internal instruction memory in bytes
MEM_INT_IMEM_ROM : boolean := false; -- implement processor-internal instruction memory as ROM
-- Memory configuration: Data memory --
MEM_DSPACE_BASE : std_ulogic_vector(31 downto 0) := x"80000000"; -- base address of data memory space
MEM_DSPACE_SIZE : natural := 4*1024; -- total size of data memory space in byte
-- Internal Data memory --
MEM_INT_DMEM_USE : boolean := true; -- implement processor-internal data memory
MEM_INT_DMEM_SIZE : natural := 4*1024; -- size of processor-internal data memory in bytes
-- Memory configuration: External memory interface --
-- External memory interface --
MEM_EXT_USE : boolean := false; -- implement external memory bus interface?
-- Processor peripherals --
IO_GPIO_USE : boolean := true; -- implement general purpose input/output port unit (GPIO)?
70,7 → 66,8
IO_PWM_USE : boolean := true; -- implement pulse-width modulation unit (PWM)?
IO_WDT_USE : boolean := true; -- implement watch dog timer (WDT)?
IO_TRNG_USE : boolean := true; -- implement true random number generator (TRNG)?
IO_DEVNULL_USE : boolean := true -- implement dummy device (DEVNULL)?
IO_DEVNULL_USE : boolean := true; -- implement dummy device (DEVNULL)?
IO_CFU_USE : boolean := true -- implement custom functions unit (CFU)?
);
port (
-- host access --
114,44 → 111,46
-- SYSINFO(0): Processor (primary) clock frequency --
sysinfo_mem(0) <= std_ulogic_vector(to_unsigned(CLOCK_FREQUENCY, 32));
 
-- SYSINFO(1): Custom user code --
-- SYSINFO(1): Custom user code/ID --
sysinfo_mem(1) <= USER_CODE;
 
-- SYSINFO(2): Implemented processor devices/features --
-- Memory
sysinfo_mem(2)(00) <= bool_to_ulogic_f(BOOTLOADER_USE); -- implement processor-internal bootloader?
sysinfo_mem(2)(01) <= bool_to_ulogic_f(MEM_EXT_USE); -- implement external memory bus interface?
sysinfo_mem(2)(02) <= bool_to_ulogic_f(MEM_INT_IMEM_USE); -- implement processor-internal instruction memory?
sysinfo_mem(2)(03) <= bool_to_ulogic_f(MEM_INT_IMEM_ROM); -- implement processor-internal instruction memory as ROM?
sysinfo_mem(2)(04) <= bool_to_ulogic_f(MEM_INT_DMEM_USE); -- implement processor-internal data memory?
-- Memory --
sysinfo_mem(2)(00) <= bool_to_ulogic_f(BOOTLOADER_USE); -- processor-internal bootloader implemented?
sysinfo_mem(2)(01) <= bool_to_ulogic_f(MEM_EXT_USE); -- external memory bus interface implemented?
sysinfo_mem(2)(02) <= bool_to_ulogic_f(MEM_INT_IMEM_USE); -- processor-internal instruction memory implemented?
sysinfo_mem(2)(03) <= bool_to_ulogic_f(MEM_INT_IMEM_ROM); -- processor-internal instruction memory implemented as ROM?
sysinfo_mem(2)(04) <= bool_to_ulogic_f(MEM_INT_DMEM_USE); -- processor-internal data memory implemented?
--
sysinfo_mem(2)(15 downto 05) <= (others => '0'); -- reserved
-- IO
sysinfo_mem(2)(16) <= bool_to_ulogic_f(IO_GPIO_USE); -- implement general purpose input/output port unit (GPIO)?
sysinfo_mem(2)(17) <= bool_to_ulogic_f(IO_MTIME_USE); -- implement machine system timer (MTIME)?
sysinfo_mem(2)(18) <= bool_to_ulogic_f(IO_UART_USE); -- implement universal asynchronous receiver/transmitter (UART)?
sysinfo_mem(2)(19) <= bool_to_ulogic_f(IO_SPI_USE); -- implement serial peripheral interface (SPI)?
sysinfo_mem(2)(20) <= bool_to_ulogic_f(IO_TWI_USE); -- implement two-wire interface (TWI)?
sysinfo_mem(2)(21) <= bool_to_ulogic_f(IO_PWM_USE); -- implement pulse-width modulation unit (PWM)?
sysinfo_mem(2)(22) <= bool_to_ulogic_f(IO_WDT_USE); -- implement watch dog timer (WDT)?
sysinfo_mem(2)(23) <= '0';
sysinfo_mem(2)(24) <= bool_to_ulogic_f(IO_TRNG_USE); -- implement true random number generator (TRNG)?
sysinfo_mem(2)(25) <= bool_to_ulogic_f(IO_DEVNULL_USE); -- implement dummy device (DEVNULL)?
-- IO --
sysinfo_mem(2)(16) <= bool_to_ulogic_f(IO_GPIO_USE); -- general purpose input/output port unit (GPIO) implemented?
sysinfo_mem(2)(17) <= bool_to_ulogic_f(IO_MTIME_USE); -- machine system timer (MTIME) implemented?
sysinfo_mem(2)(18) <= bool_to_ulogic_f(IO_UART_USE); -- universal asynchronous receiver/transmitter (UART) implemented?
sysinfo_mem(2)(19) <= bool_to_ulogic_f(IO_SPI_USE); -- serial peripheral interface (SPI) implemented?
sysinfo_mem(2)(20) <= bool_to_ulogic_f(IO_TWI_USE); -- two-wire interface (TWI) implemented?
sysinfo_mem(2)(21) <= bool_to_ulogic_f(IO_PWM_USE); -- pulse-width modulation unit (PWM) implemented?
sysinfo_mem(2)(22) <= bool_to_ulogic_f(IO_WDT_USE); -- watch dog timer (WDT) implemented?
sysinfo_mem(2)(23) <= bool_to_ulogic_f(IO_CFU_USE); -- custom functions unit (CFU) implemented?
sysinfo_mem(2)(24) <= bool_to_ulogic_f(IO_TRNG_USE); -- true random number generator (TRNG) implemented?
sysinfo_mem(2)(25) <= bool_to_ulogic_f(IO_DEVNULL_USE); -- dummy device (DEVNULL) implemented?
--
sysinfo_mem(2)(31 downto 26) <= (others => '0'); -- reserved
 
-- SYSINFO(3): reserved --
sysinfo_mem(3) <= (others => '0'); -- reserved - maybe for technology-specific configuration options?
sysinfo_mem(3) <= (others => '0'); -- reserved
 
-- SYSINFO(4): Base address of instruction memory space --
sysinfo_mem(4) <= MEM_ISPACE_BASE;
sysinfo_mem(4) <= ispace_base_c; -- defined in neorv32_package.vhd file
 
-- SYSINFO(5): Base address of data memory space --
sysinfo_mem(5) <= MEM_DSPACE_BASE;
sysinfo_mem(5) <= dspace_base_c; -- defined in neorv32_package.vhd file
 
-- SYSINFO(6): Total size of instruction memory space in bytes --
sysinfo_mem(6) <= std_ulogic_vector(to_unsigned(MEM_ISPACE_SIZE, 32));
-- SYSINFO(6): Size of IMEM in bytes --
sysinfo_mem(6) <= std_ulogic_vector(to_unsigned(MEM_INT_IMEM_SIZE, 32)) when (MEM_INT_IMEM_USE = true) else (others => '0');
 
-- SYSINFO(7): Total size of data memory space in bytes --
sysinfo_mem(7) <= std_ulogic_vector(to_unsigned(MEM_DSPACE_SIZE, 32));
-- SYSINFO(7): Size of DMEM in bytes --
sysinfo_mem(7) <= std_ulogic_vector(to_unsigned(MEM_INT_DMEM_SIZE, 32)) when (MEM_INT_DMEM_USE = true) else (others => '0');
 
 
-- Read Access ----------------------------------------------------------------------------
159,11 → 158,10
read_access: process(clk_i)
begin
if rising_edge(clk_i) then
ack_o <= rden;
ack_o <= rden;
data_o <= (others => '0');
if (rden = '1') then
data_o <= sysinfo_mem(to_integer(unsigned(info_addr)));
else
data_o <= (others => '0');
end if;
end if;
end process read_access;
/neorv32_top.vhd
5,7 → 5,7
-- # and define all the configuration generics according to your needs. Alternatively, you can use #
-- # one of the alternative top entities provided in the "rtl/top_templates" folder. #
-- # #
-- # Check the processor's documentary for more information: docs/NEORV32.pdf #
-- # Check the processor's data sheet for more information: docs/NEORV32.pdf #
-- # ********************************************************************************************* #
-- # BSD 3-Clause License #
-- # #
59,24 → 59,19
CPU_EXTENSION_RISCV_Zicsr : boolean := true; -- implement CSR system?
CPU_EXTENSION_RISCV_Zifencei : boolean := true; -- implement instruction stream sync.?
-- Extension Options --
CSR_COUNTERS_USE : boolean := true; -- implement RISC-V perf. counters ([m]instret[h], [m]cycle[h], time[h])?
FAST_MUL_EN : boolean := false; -- use DSPs for M extension's multiplier
FAST_MUL_EN : boolean := false; -- use DSPs for M extension's multiplier
-- Physical Memory Protection (PMP) --
PMP_USE : boolean := false; -- implement PMP?
PMP_NUM_REGIONS : natural := 4; -- number of regions (max 8)
PMP_GRANULARITY : natural := 14; -- minimal region granularity (1=8B, 2=16B, 3=32B, ...) default is 64k
-- Memory configuration: Instruction memory --
MEM_ISPACE_BASE : std_ulogic_vector(31 downto 0) := x"00000000"; -- base address of instruction memory space
MEM_ISPACE_SIZE : natural := 16*1024; -- total size of instruction memory space in byte
PMP_USE : boolean := false; -- implement PMP?
PMP_NUM_REGIONS : natural := 4; -- number of regions (max 8)
PMP_GRANULARITY : natural := 14; -- minimal region granularity (1=8B, 2=16B, 3=32B, ...) default is 64k
-- Internal Instruction memory --
MEM_INT_IMEM_USE : boolean := true; -- implement processor-internal instruction memory
MEM_INT_IMEM_SIZE : natural := 16*1024; -- size of processor-internal instruction memory in bytes
MEM_INT_IMEM_ROM : boolean := false; -- implement processor-internal instruction memory as ROM
-- Memory configuration: Data memory --
MEM_DSPACE_BASE : std_ulogic_vector(31 downto 0) := x"80000000"; -- base address of data memory space
MEM_DSPACE_SIZE : natural := 8*1024; -- total size of data memory space in byte
-- Internal Data memory --
MEM_INT_DMEM_USE : boolean := true; -- implement processor-internal data memory
MEM_INT_DMEM_SIZE : natural := 8*1024; -- size of processor-internal data memory in bytes
-- Memory configuration: External memory interface --
-- External memory interface --
MEM_EXT_USE : boolean := false; -- implement external memory bus interface?
MEM_EXT_REG_STAGES : natural := 2; -- number of interface register stages (0,1,2)
MEM_EXT_TIMEOUT : natural := 15; -- cycles after which a valid bus access will timeout
89,7 → 84,8
IO_PWM_USE : boolean := true; -- implement pulse-width modulation unit (PWM)?
IO_WDT_USE : boolean := true; -- implement watch dog timer (WDT)?
IO_TRNG_USE : boolean := false; -- implement true random number generator (TRNG)?
IO_DEVNULL_USE : boolean := true -- implement dummy device (DEVNULL)?
IO_DEVNULL_USE : boolean := true; -- implement dummy device (DEVNULL)?
IO_CFU_USE : boolean := false -- implement custom functions unit (CFU)?
);
port (
-- Global control --
133,7 → 129,7
architecture neorv32_top_rtl of neorv32_top is
 
-- CPU boot address --
constant boot_addr_c : std_ulogic_vector(31 downto 0) := cond_sel_stdulogicvector_f(BOOTLOADER_USE, boot_base_c, MEM_ISPACE_BASE);
constant cpu_boot_addr_c : std_ulogic_vector(31 downto 0) := cond_sel_stdulogicvector_f(BOOTLOADER_USE, boot_rom_base_c, ispace_base_c);
 
-- reset generator --
signal rstn_i_sync0 : std_ulogic;
153,6 → 149,7
signal spi_cg_en : std_ulogic;
signal twi_cg_en : std_ulogic;
signal pwm_cg_en : std_ulogic;
signal cfu_cg_en : std_ulogic;
 
-- bus interface --
type bus_interface_t is record
202,6 → 199,8
signal trng_ack : std_ulogic;
signal devnull_rdata : std_ulogic_vector(data_width_c-1 downto 0);
signal devnull_ack : std_ulogic;
signal cfu_rdata : std_ulogic_vector(data_width_c-1 downto 0);
signal cfu_ack : std_ulogic;
signal sysinfo_rdata : std_ulogic_vector(data_width_c-1 downto 0);
signal sysinfo_ack : std_ulogic;
 
213,6 → 212,7
signal uart_irq : std_ulogic;
signal spi_irq : std_ulogic;
signal twi_irq : std_ulogic;
signal cfu_irq : std_ulogic;
 
-- misc --
signal mtime_time : std_ulogic_vector(63 downto 0); -- current system time from MTIME
221,60 → 221,23
 
-- Sanity Checks --------------------------------------------------------------------------
-- -------------------------------------------------------------------------------------------
sanity_check: process(clk_i)
begin
if rising_edge(clk_i) then
-- internal bootloader memory --
if (BOOTLOADER_USE = true) and (boot_size_c > boot_max_size_c) then
assert false report "NEORV32 PROCESSOR CONFIG ERROR! Boot ROM size out of range." severity error;
end if;
if (BOOTLOADER_USE = true) and (MEM_INT_IMEM_ROM = true) then
assert false report "NEORV32 PROCESSOR CONFIG WARNING! IMEM is configured as read-only. Bootloader will not be able to load new executables." severity warning;
end if;
-- internal bootloader ROM --
assert not ((BOOTLOADER_USE = true) and (boot_rom_size_c > boot_rom_max_size_c)) report "NEORV32 PROCESSOR CONFIG ERROR! Boot ROM size out of range." severity error;
assert not ((BOOTLOADER_USE = true) and (MEM_INT_IMEM_ROM = true)) report "NEORV32 PROCESSOR CONFIG WARNING! IMEM is configured as read-only. Bootloader will not be able to load new executables." severity warning;
-- memory system - data/instruction fetch --
assert not ((MEM_EXT_USE = false) and (MEM_INT_DMEM_USE = false)) report "NEORV32 PROCESSOR CONFIG ERROR! Core cannot fetch data without external memory interface and internal data memory." severity error;
assert not ((MEM_EXT_USE = false) and (MEM_INT_IMEM_USE = false) and (BOOTLOADER_USE = false)) report "NEORV32 PROCESSOR CONFIG ERROR! Core cannot fetch instructions without external memory interface, internal data memory and bootloader." severity error;
-- memory system --
assert not (imem_base_c(1 downto 0) /= "00") report "NEORV32 PROCESSOR CONFIG ERROR! Instruction memory space base address must be 4-byte-aligned." severity error;
assert not (dmem_base_c(1 downto 0) /= "00") report "NEORV32 PROCESSOR CONFIG ERROR! Data memory space base address must be 4-byte-aligned." severity error;
assert not (MEM_EXT_TIMEOUT < 1) report "NEORV32 PROCESSOR CONFIG ERROR! Invalid bus timeout. Processor-internal components have 1 cycle latency." severity error;
-- clock --
assert not (CLOCK_FREQUENCY = 0) report "NEORV32 PROCESSOR CONFIG ERROR! Core clock frequency (CLOCK_FREQUENCY) not specified." severity error;
-- memory layout notifier --
assert not (imem_base_c /= x"00000000") report "NEORV32 PROCESSOR CONFIG WARNING! Non-default base address for instruction address space. Make sure this is sync with the software framework." severity warning;
assert not (dmem_base_c /= x"80000000") report "NEORV32 PROCESSOR CONFIG WARNING! Non-default base address for data address space. Make sure this is sync with the software framework." severity warning;
 
-- memory system - data/instruction fetch --
if (MEM_EXT_USE = false) then
if (MEM_INT_DMEM_USE = false) then
assert false report "NEORV32 PROCESSOR CONFIG ERROR! Core cannot fetch data without external memory interface and internal data memory." severity error;
end if;
if (MEM_INT_IMEM_USE = false) and (BOOTLOADER_USE = false) then
assert false report "NEORV32 PROCESSOR CONFIG ERROR! Core cannot fetch instructions without external memory interface, internal data memory and bootloader." severity error;
end if;
end if;
 
-- memory system --
if (MEM_ISPACE_BASE(1 downto 0) /= "00") then
assert false report "NEORV32 PROCESSOR CONFIG ERROR! Instruction memory space base address must be 4-byte-aligned." severity error;
end if;
if (MEM_DSPACE_BASE(1 downto 0) /= "00") then
assert false report "NEORV32 PROCESSOR CONFIG ERROR! Data memory space base address must be 4-byte-aligned." severity error;
end if;
if (MEM_INT_IMEM_USE = true) and (MEM_INT_IMEM_SIZE > MEM_ISPACE_SIZE) then
assert false report "NEORV32 PROCESSOR CONFIG ERROR! Internal instruction memory (IMEM) cannot be greater than total instruction address space." severity error;
end if;
if (MEM_INT_DMEM_USE = true) and (MEM_INT_DMEM_SIZE > MEM_DSPACE_SIZE) then
assert false report "NEORV32 PROCESSOR CONFIG ERROR! Internal data memory (DMEM) cannot be greater than total data address space." severity error;
end if;
if (MEM_EXT_TIMEOUT < 1) then
assert false report "NEORV32 PROCESSOR CONFIG ERROR! Invalid bus timeout. Processor-internal components have 1 cycle delay." severity error;
end if;
 
-- clock --
if (CLOCK_FREQUENCY = 0) then
assert false report "NEORV32 PROCESSOR CONFIG ERROR! Core clock frequency (CLOCK_FREQUENCY) not specified." severity error;
end if;
 
-- memory layout notifier --
if (MEM_ISPACE_BASE /= x"00000000") then
assert false report "NEORV32 PROCESSOR CONFIG WARNING! Non-default base address for instruction address space. Make sure this is sync with the software framwork." severity warning;
end if;
if (MEM_DSPACE_BASE /= x"80000000") then
assert false report "NEORV32 PROCESSOR CONFIG WARNING! Non-default base address for data address space. Make sure this is sync with the software framwork." severity warning;
end if;
end if;
end process sanity_check;
 
 
-- Reset Generator ------------------------------------------------------------------------
-- -------------------------------------------------------------------------------------------
reset_generator_sync: process(clk_i)
290,7 → 253,7
-- keep internal reset active for at least 4 clock cycles
reset_generator: process(rstn_i_sync1, rstn_i_sync2, clk_i)
begin
if ((rstn_i_sync1 or rstn_i_sync2) = '0') then -- signal stable somehow?
if ((rstn_i_sync1 and rstn_i_sync2) = '0') then -- signal stable?
rstn_gen <= (others => '0');
elsif rising_edge(clk_i) then
rstn_gen <= rstn_gen(rstn_gen'left-1 downto 0) & '1';
298,7 → 261,7
end process reset_generator;
 
ext_rstn <= rstn_gen(rstn_gen'left); -- the beautified external reset signal
sys_rstn <= ext_rstn and wdt_rstn; -- system reset - can also be triggered by watchdog
sys_rstn <= ext_rstn and wdt_rstn; -- system reset - can also be triggered by watchdog
 
 
-- Clock Generator ------------------------------------------------------------------------
309,23 → 272,28
clk_div <= (others => '0');
clk_div_ff <= (others => '0');
elsif rising_edge(clk_i) then
-- anybody wanting some fresh clocks? --
if ((wdt_cg_en or uart_cg_en or spi_cg_en or twi_cg_en or pwm_cg_en) = '1') then
clk_div <= std_ulogic_vector(unsigned(clk_div) + 1);
clk_div_ff <= clk_div;
-- fresh clocks anyone? --
if ((wdt_cg_en or uart_cg_en or spi_cg_en or twi_cg_en or pwm_cg_en or cfu_cg_en) = '1') then
clk_div <= std_ulogic_vector(unsigned(clk_div) + 1);
end if;
clk_div_ff <= clk_div;
end if;
end process clock_generator;
 
-- clock enable select: rising edge detectors --
clk_gen(clk_div2_c) <= clk_div(0) and (not clk_div_ff(0)); -- CLK/2
clk_gen(clk_div4_c) <= clk_div(1) and (not clk_div_ff(1)); -- CLK/4
clk_gen(clk_div8_c) <= clk_div(2) and (not clk_div_ff(2)); -- CLK/8
clk_gen(clk_div64_c) <= clk_div(5) and (not clk_div_ff(5)); -- CLK/64
clk_gen(clk_div128_c) <= clk_div(6) and (not clk_div_ff(6)); -- CLK/128
clk_gen(clk_div1024_c) <= clk_div(9) and (not clk_div_ff(9)); -- CLK/1024
clk_gen(clk_div2048_c) <= clk_div(10) and (not clk_div_ff(10)); -- CLK/2048
clk_gen(clk_div4096_c) <= clk_div(11) and (not clk_div_ff(11)); -- CLK/4096
-- clock enables: rising edge detectors --
clock_generator_edge: process(clk_i)
begin
if rising_edge(clk_i) then
clk_gen(clk_div2_c) <= clk_div(0) and (not clk_div_ff(0)); -- CLK/2
clk_gen(clk_div4_c) <= clk_div(1) and (not clk_div_ff(1)); -- CLK/4
clk_gen(clk_div8_c) <= clk_div(2) and (not clk_div_ff(2)); -- CLK/8
clk_gen(clk_div64_c) <= clk_div(5) and (not clk_div_ff(5)); -- CLK/64
clk_gen(clk_div128_c) <= clk_div(6) and (not clk_div_ff(6)); -- CLK/128
clk_gen(clk_div1024_c) <= clk_div(9) and (not clk_div_ff(9)); -- CLK/1024
clk_gen(clk_div2048_c) <= clk_div(10) and (not clk_div_ff(10)); -- CLK/2048
clk_gen(clk_div4096_c) <= clk_div(11) and (not clk_div_ff(11)); -- CLK/4096
end if;
end process clock_generator_edge;
 
 
-- CPU ------------------------------------------------------------------------------------
334,7 → 302,7
generic map (
-- General --
HW_THREAD_ID => (others => '0'), -- hardware thread id
CPU_BOOT_ADDR => boot_addr_c, -- cpu boot address
CPU_BOOT_ADDR => cpu_boot_addr_c, -- cpu boot address
-- RISC-V CPU Extensions --
CPU_EXTENSION_RISCV_C => CPU_EXTENSION_RISCV_C, -- implement compressed extension?
CPU_EXTENSION_RISCV_E => CPU_EXTENSION_RISCV_E, -- implement embedded RF extension?
343,7 → 311,6
CPU_EXTENSION_RISCV_Zicsr => CPU_EXTENSION_RISCV_Zicsr, -- implement CSR system?
CPU_EXTENSION_RISCV_Zifencei => CPU_EXTENSION_RISCV_Zifencei, -- implement instruction stream sync.?
-- Extension Options --
CSR_COUNTERS_USE => CSR_COUNTERS_USE, -- implement RISC-V perf. counters ([m]instret[h], [m]cycle[h], time[h])?
FAST_MUL_EN => FAST_MUL_EN, -- use DSPs for M extension's multiplier
-- Physical Memory Protection (PMP) --
PMP_USE => PMP_USE, -- implement PMP?
394,7 → 361,7
 
-- fast interrupts --
fast_irq(0) <= wdt_irq; -- highest priority
fast_irq(1) <= gpio_irq;
fast_irq(1) <= gpio_irq or cfu_irq; -- can be triggered by GPIO pin-change or CFU
fast_irq(2) <= uart_irq;
fast_irq(3) <= spi_irq or twi_irq; -- lowest priority, can be triggered by SPI or TWI
 
444,11 → 411,11
 
-- processor bus: CPU data input --
p_bus.rdata <= (imem_rdata or dmem_rdata or bootrom_rdata) or wishbone_rdata or (gpio_rdata or mtime_rdata or uart_rdata or
spi_rdata or twi_rdata or pwm_rdata or wdt_rdata or trng_rdata or devnull_rdata or sysinfo_rdata);
spi_rdata or twi_rdata or pwm_rdata or wdt_rdata or trng_rdata or devnull_rdata or cfu_rdata or sysinfo_rdata);
 
-- processor bus: CPU data ACK input --
p_bus.ack <= (imem_ack or dmem_ack or bootrom_ack) or wishbone_ack or (gpio_ack or mtime_ack or uart_ack or
spi_ack or twi_ack or pwm_ack or wdt_ack or trng_ack or devnull_ack or sysinfo_ack);
spi_ack or twi_ack or pwm_ack or wdt_ack or trng_ack or devnull_ack or cfu_ack or sysinfo_ack);
 
-- processor bus: CPU data bus error input --
p_bus.err <= wishbone_err;
460,7 → 427,7
if (MEM_INT_IMEM_USE = true) generate
neorv32_int_imem_inst: neorv32_imem
generic map (
IMEM_BASE => MEM_ISPACE_BASE, -- memory base address
IMEM_BASE => imem_base_c, -- memory base address
IMEM_SIZE => MEM_INT_IMEM_SIZE, -- processor-internal instruction memory size in bytes
IMEM_AS_ROM => MEM_INT_IMEM_ROM, -- implement IMEM as read-only memory?
BOOTLOADER_USE => BOOTLOADER_USE -- implement and use bootloader?
491,7 → 458,7
if (MEM_INT_DMEM_USE = true) generate
neorv32_int_dmem_inst: neorv32_dmem
generic map (
DMEM_BASE => MEM_DSPACE_BASE, -- memory base address
DMEM_BASE => dmem_base_c, -- memory base address
DMEM_SIZE => MEM_INT_DMEM_SIZE -- processor-internal data memory size in bytes
)
port map (
518,6 → 485,10
neorv32_boot_rom_inst_true:
if (BOOTLOADER_USE = true) generate
neorv32_boot_rom_inst: neorv32_boot_rom
generic map (
BOOTROM_BASE => boot_rom_base_c, -- boot ROM base address
BOOTROM_SIZE => boot_rom_size_c -- processor-internal boot TOM memory size in bytes
)
port map (
clk_i => clk_i, -- global clock line
rden_i => p_bus.re, -- read enable
541,14 → 512,10
neorv32_wishbone_inst: neorv32_wishbone
generic map (
INTERFACE_REG_STAGES => MEM_EXT_REG_STAGES, -- number of interface register stages (0,1,2)
-- Memory configuration: Instruction memory --
MEM_ISPACE_BASE => MEM_ISPACE_BASE, -- base address of instruction memory space
MEM_ISPACE_SIZE => MEM_ISPACE_SIZE, -- total size of instruction memory space in byte
-- Internal instruction memory --
MEM_INT_IMEM_USE => MEM_INT_IMEM_USE, -- implement processor-internal instruction memory
MEM_INT_IMEM_SIZE => MEM_INT_IMEM_SIZE, -- size of processor-internal instruction memory in bytes
-- Memory configuration: Data memory --
MEM_DSPACE_BASE => MEM_DSPACE_BASE, -- base address of data memory space
MEM_DSPACE_SIZE => MEM_DSPACE_SIZE, -- total size of data memory space in byte
-- Internal data memory --
MEM_INT_DMEM_USE => MEM_INT_DMEM_USE, -- implement processor-internal data memory
MEM_INT_DMEM_SIZE => MEM_INT_DMEM_SIZE -- size of processor-internal data memory in bytes
)
887,6 → 854,40
end generate;
 
 
-- Custom Functions Unit (CFU) ------------------------------------------------------------
-- -------------------------------------------------------------------------------------------
neorv32_cfu_inst_true:
if (IO_CFU_USE = true) generate
neorv32_cfu_inst: neorv32_cfu
port map (
-- host access --
clk_i => clk_i, -- global clock line
rstn_i => sys_rstn, -- global reset line, low-active, use as async
addr_i => p_bus.addr, -- address
rden_i => io_rden, -- read enable
wren_i => io_wren, -- write enable
data_i => p_bus.wdata, -- data in
data_o => cfu_rdata, -- data out
ack_o => cfu_ack, -- transfer acknowledge
-- clock generator --
clkgen_en_o => cfu_cg_en, -- enable clock generator
clkgen_i => clk_gen, -- "clock" inputs
-- interrupt --
irq_o => cfu_irq
-- custom io --
-- ...
);
end generate;
 
neorv32_cfu_inst_false:
if (IO_CFU_USE = false) generate
cfu_rdata <= (others => '0');
cfu_ack <= '0';
cfu_cg_en <= '0';
cfu_irq <= '0';
end generate;
 
 
-- System Configuration Information Memory (SYSINFO) --------------------------------------
-- -------------------------------------------------------------------------------------------
neorv32_sysinfo_inst: neorv32_sysinfo
895,18 → 896,14
CLOCK_FREQUENCY => CLOCK_FREQUENCY, -- clock frequency of clk_i in Hz
BOOTLOADER_USE => BOOTLOADER_USE, -- implement processor-internal bootloader?
USER_CODE => USER_CODE, -- custom user code
-- Memory configuration: Instruction memory --
MEM_ISPACE_BASE => MEM_ISPACE_BASE, -- base address of instruction memory space
MEM_ISPACE_SIZE => MEM_ISPACE_SIZE, -- total size of instruction memory space in byte
-- internal Instruction memory --
MEM_INT_IMEM_USE => MEM_INT_IMEM_USE, -- implement processor-internal instruction memory
MEM_INT_IMEM_SIZE => MEM_INT_IMEM_SIZE, -- size of processor-internal instruction memory in bytes
MEM_INT_IMEM_ROM => MEM_INT_IMEM_ROM, -- implement processor-internal instruction memory as ROM
-- Memory configuration: Data memory --
MEM_DSPACE_BASE => MEM_DSPACE_BASE, -- base address of data memory space
MEM_DSPACE_SIZE => MEM_DSPACE_SIZE, -- total size of data memory space in byte
-- Internal Data memory --
MEM_INT_DMEM_USE => MEM_INT_DMEM_USE, -- implement processor-internal data memory
MEM_INT_DMEM_SIZE => MEM_INT_DMEM_SIZE, -- size of processor-internal data memory in bytes
-- Memory configuration: External memory interface --
-- External memory interface --
MEM_EXT_USE => MEM_EXT_USE, -- implement external memory bus interface?
-- Processor peripherals --
IO_GPIO_USE => IO_GPIO_USE, -- implement general purpose input/output port unit (GPIO)?
917,7 → 914,8
IO_PWM_USE => IO_PWM_USE, -- implement pulse-width modulation unit (PWM)?
IO_WDT_USE => IO_WDT_USE, -- implement watch dog timer (WDT)?
IO_TRNG_USE => IO_TRNG_USE, -- implement true random number generator (TRNG)?
IO_DEVNULL_USE => IO_DEVNULL_USE -- implement dummy device (DEVNULL)?
IO_DEVNULL_USE => IO_DEVNULL_USE, -- implement dummy device (DEVNULL)?
IO_CFU_USE => IO_CFU_USE -- implement custom functions unit (CFU)?
)
port map (
-- host access --
/neorv32_trng.vhd
1,21 → 1,11
-- #################################################################################################
-- # << NEORV32 - True Random Number Generator (TRNG) >> #
-- # ********************************************************************************************* #
-- # This unit implements a true random number generator which uses an inverter chain as entropy #
-- # source. The inverter chain is constructed as GARO (Galois Ring Oscillator) TRNG. The single #
-- # inverters are connected via simple latches that are used to enbale/disable the TRNG. Also, #
-- # these latches are used as additional delay element. By using unique enable signals for each #
-- # latch, the synthesis tool cannot "optimize" one of the inverters out of the design. Further- #
-- # more, the latches prevent the synthesis tool from detecting combinatorial loops. #
-- # The output of the GARO is de-biased by a simple von Neuman random extractor and is further #
-- # post-processed by a 16-bit LFSR for improved whitening. #
-- # This unit implements a true random number generator which uses several GARO chain as entropy #
-- # source. The outputs of all chains are XORed and de-biased using a John von Neumann randomness #
-- # extractor. The de-biased signal is further processed by a simple LFSR for improved whitening. #
-- # #
-- # Sources: #
-- # - GARO: "Experimental Assessment of FIRO- and GARO-based Noise Sources for Digital TRNG #
-- # Designs on FPGAs" by Martin Schramm, Reiner Dojen and Michael Heigly, 2017 #
-- # - Latches for platform independence: "Extended Abstract: The Butterfly PUF Protecting IP #
-- # on every FPGA" by Sandeep S. Kumar, Jorge Guajardo, Roel Maesyz, Geert-Jan Schrijen and #
-- # Pim Tuyls, Philips Research Europe, 2008 #
-- # - Von Neumann De-Biasing: "Iterating Von Neumann's Post-Processing under Hardware #
-- # Constraints" by Vladimir Rozic, Bohan Yang, Wim Dehaene and Ingrid Verbauwhede, 2016 #
-- # ********************************************************************************************* #
73,24 → 63,45
architecture neorv32_trng_rtl of neorv32_trng is
 
-- advanced configuration --------------------------------------------------------------------------------
constant num_inv_c : natural := 16; -- length of GARO inverter chain (default=16, max=16)
constant lfsr_taps_c : std_ulogic_vector(15 downto 0) := "1101000000001000"; -- Fibonacci LFSR feedback taps
constant num_inv_c : natural := 15; -- length of GARO inverter chain (default=15, has to be odd)
constant num_garos_c : natural := 2; -- number of GARO elements (default=2)
constant lfsr_taps_c : std_ulogic_vector(7 downto 0) := "10111000"; -- Fibonacci post-processing LFSR feedback taps
constant lfsr_en_c : boolean := true; -- use LFSR-based post-processing
type tap_mask_t is array (0 to num_garos_c-1) of std_ulogic_vector(num_inv_c-2 downto 0);
constant tap_mask : tap_mask_t := ( -- GARO tap masks, sum of set bits has to be even
"11110000000000",
"00000011000000"
);
-- -------------------------------------------------------------------------------------------------------
 
-- control register bits --
constant ctrl_taps_lsb_c : natural := 0; -- -/w: TAP 0 enable
constant ctrl_taps_msb_c : natural := 15; -- -/w: TAP 15 enable
constant ctrl_en_c : natural := 31; -- r/w: TRNG enable
constant ctrl_data_lsb_c : natural := 0; -- r/-: Random data bit LSB
constant ctrl_data_msb_c : natural := 7; -- r/-: Random data bit MSB
constant ctrl_data_valid_c : natural := 15; -- r/-: Output data valid
constant ctrl_err_zero_c : natural := 16; -- r/-: stuck at 0 error
constant ctrl_err_one_c : natural := 17; -- r/-: stuck at 1 error
constant ctrl_en_c : natural := 31; -- r/w: TRNG enable
 
-- data register bits --
constant ctrl_data_lsb_c : natural := 0; -- r/-: Random data bit 0
constant ctrl_data_msb_c : natural := 15; -- r/-: Random data bit 15
constant ctrl_rnd_valid_c : natural := 31; -- r/-: Output byte valid
 
-- IO space: module base address --
constant hi_abb_c : natural := index_size_f(io_size_c)-1; -- high address boundary bit
constant lo_abb_c : natural := index_size_f(trng_size_c); -- low address boundary bit
 
-- Component: GARO Element --
component neorv32_trng_garo_element
generic (
NUM_INV : natural := 16 -- number of inverters in chain
);
port (
clk_i : in std_ulogic;
enable_i : in std_ulogic;
enable_o : out std_ulogic;
mask_i : in std_ulogic_vector(NUM_INV-2 downto 0);
data_o : out std_ulogic;
error0_o : out std_ulogic;
error1_o : out std_ulogic
);
end component;
 
-- access control --
signal acc_en : std_ulogic; -- module access enable
signal addr : std_ulogic_vector(31 downto 0); -- access address
97,23 → 108,33
signal wren : std_ulogic; -- full word write enable
signal rden : std_ulogic; -- read enable
 
-- random number generator --
signal rnd_inv : std_ulogic_vector(num_inv_c-1 downto 0); -- inverter chain
signal rnd_enable_sreg : std_ulogic_vector(num_inv_c-1 downto 0); -- enable shift register
signal rnd_enable : std_ulogic;
signal tap_config : std_ulogic_vector(15 downto 0);
signal rnd_sync : std_ulogic_vector(02 downto 0); -- metastability filter & de-biasing
signal ready_ff : std_ulogic; -- new random data available
signal rnd_sreg : std_ulogic_vector(15 downto 0); -- sample shift reg
signal rnd_cnt : std_ulogic_vector(04 downto 0);
signal new_sample : std_ulogic; -- new output byte ready
signal rnd_data : std_ulogic_vector(15 downto 0); -- random data register (read-only)
-- garo array --
signal garo_en_in : std_ulogic_vector(num_garos_c-1 downto 0);
signal garo_en_out : std_ulogic_vector(num_garos_c-1 downto 0);
signal garo_data : std_ulogic_vector(num_garos_c-1 downto 0);
signal garo_err_zero : std_ulogic_vector(num_garos_c-1 downto 0);
signal garo_err_one : std_ulogic_vector(num_garos_c-1 downto 0);
signal garo_res : std_ulogic;
signal garo_err0 : std_ulogic;
signal garo_err1 : std_ulogic;
 
-- Randomness extractor (von Neumann De-Biasing) --
signal db_state : std_ulogic;
signal db_enable : std_ulogic; -- valid data from de-biasing
signal db_data : std_ulogic; -- actual data from de-biasing
-- de-biasing --
signal db_data : std_ulogic_vector(2 downto 0);
signal db_state : std_ulogic; -- process de-biasing every second cycle
signal rnd_valid : std_ulogic;
signal rnd_data : std_ulogic;
 
-- processing core --
signal rnd_enable : std_ulogic;
signal rnd_cnt : std_ulogic_vector(3 downto 0);
signal rnd_sreg : std_ulogic_vector(7 downto 0);
signal rnd_output : std_ulogic_vector(7 downto 0);
signal rnd_ready : std_ulogic;
 
-- health check --
signal rnd_error_zero : std_ulogic; -- stuck at zero
signal rnd_error_one : std_ulogic; -- stuck at one
 
begin
 
-- Access Control -------------------------------------------------------------------------
132,119 → 153,320
ack_o <= acc_en and (rden_i or wren_i);
-- write access --
if (wren = '1') then
if (addr = trng_ctrl_addr_c) then
tap_config <= data_i(tap_config'left downto 0);
rnd_enable <= data_i(ctrl_en_c);
end if;
rnd_enable <= data_i(ctrl_en_c);
end if;
-- read access --
data_o <= (others => '0');
if (rden = '1') then
if (addr = trng_ctrl_addr_c) then
data_o(ctrl_taps_msb_c downto ctrl_taps_lsb_c) <= tap_config;
data_o(ctrl_en_c) <= rnd_enable;
else -- trng_data_addr_c
data_o(ctrl_data_msb_c downto ctrl_data_lsb_c) <= rnd_data;
data_o(ctrl_rnd_valid_c) <= ready_ff;
end if;
data_o(ctrl_data_msb_c downto ctrl_data_lsb_c) <= rnd_output;
data_o(ctrl_data_valid_c) <= rnd_ready;
data_o(ctrl_err_zero_c) <= rnd_error_zero;
data_o(ctrl_err_one_c) <= rnd_error_one;
data_o(ctrl_en_c) <= rnd_enable;
end if;
end if;
end process rw_access;
 
 
-- True Random Generator ------------------------------------------------------------------
-- Entropy Source -------------------------------------------------------------------------
-- -------------------------------------------------------------------------------------------
entropy_source: process(rnd_enable_sreg, rnd_enable, rnd_inv, tap_config)
neorv32_trng_garo_element_inst:
for i in 0 to num_garos_c-1 generate
neorv32_trng_garo_element_inst_i: neorv32_trng_garo_element
generic map (
NUM_INV => num_inv_c -- number of inverters in chain
)
port map (
clk_i => clk_i,
enable_i => garo_en_in(i),
enable_o => garo_en_out(i),
mask_i => tap_mask(i),
data_o => garo_data(i),
error0_o => garo_err_zero(i),
error1_o => garo_err_one(i)
);
end generate;
 
-- GARO element connection --
garo_intercon: process(rnd_enable, garo_en_out, garo_data, garo_err_zero, garo_err_one)
variable data_v : std_ulogic;
variable err0_v : std_ulogic;
variable err1_v : std_ulogic;
begin
for i in 0 to num_inv_c-1 loop
if (rnd_enable = '0') then -- start with a defined state (latch reset)
rnd_inv(i) <= '0';
-- uniquely enable latches to prevent synthesis from removing chain elements
elsif (rnd_enable_sreg(i) = '1') then -- latch enable
-- here we have the inverter chain --
if (i = num_inv_c-1) then -- left most inverter?
if (tap_config(i) = '1') then
rnd_inv(i) <= not rnd_inv(0); -- direct input of right most inverter (= output signal)
else
rnd_inv(i) <= '0';
end if;
else
if (tap_config(i) = '1') then
rnd_inv(i) <= not (rnd_inv(i+1) xor rnd_inv(0)); -- use final output as feedback
else
rnd_inv(i) <= not rnd_inv(i+1); -- normal chain: use previous inverter's output as input
end if;
end if;
-- enable chain --
for i in 0 to num_garos_c-1 loop
if (i = 0) then
garo_en_in(i) <= rnd_enable;
else
garo_en_in(i) <= garo_en_out(i-1);
end if;
end loop; -- i
end process entropy_source;
-- data & status --
data_v := garo_data(0);
err0_v := garo_err_zero(0);
err1_v := garo_err_one(0);
for i in 1 to num_garos_c-1 loop
data_v := data_v xor garo_data(i);
err0_v := err0_v or garo_err_zero(i);
err1_v := err1_v or garo_err_one(i);
end loop; -- i
garo_res <= data_v;
garo_err0 <= err0_v;
garo_err1 <= err1_v;
end process garo_intercon;
 
-- unique enable signals for each inverter latch --
inv_enable: process(clk_i)
 
-- De-Biasing -----------------------------------------------------------------------------
-- -------------------------------------------------------------------------------------------
jvn_debiasing_sync: process(clk_i)
begin
if rising_edge(clk_i) then
-- using individual enable signals for each inverter - derived from a shift register - to prevent the synthesis tool
-- from removing all but one inverter (since they implement "logical identical functions")
-- this also allows to make the trng platform independent
rnd_enable_sreg <= rnd_enable_sreg(num_inv_c-2 downto 0) & rnd_enable; -- activate right most inverter first
db_data <= db_data(db_data'left-1 downto 0) & garo_res;
db_state <= (not db_state) and rnd_enable; -- just toggle when enabled -> process in every second cycle
end if;
end process inv_enable;
end process jvn_debiasing_sync;
 
 
-- John von Neumann De-Biasing --
jvn_debiasing: process(db_state, db_data)
variable tmp_v : std_ulogic_vector(2 downto 0);
begin
-- check groups of two non-overlapping bits from the input stream
tmp_v := db_state & db_data(db_data'left downto db_data'left-1);
case tmp_v is
when "101" => rnd_valid <= '1'; rnd_data <= '1'; -- rising edge -> '1'
when "110" => rnd_valid <= '1'; rnd_data <= '0'; -- falling edge -> '0'
when others => rnd_valid <= '0'; rnd_data <= '-'; -- invalid
end case;
end process jvn_debiasing;
 
 
-- Processing Core ------------------------------------------------------------------------
-- -------------------------------------------------------------------------------------------
processing_core: process(clk_i)
begin
if rising_edge(clk_i) then
-- synchronize output of GARO --
rnd_sync <= rnd_sync(1 downto 0) & rnd_inv(0); -- no more metastability
 
-- von Neumann De-Biasing state --
db_state <= (not db_state) and rnd_enable; -- just toggle -> process in every second cycle
 
-- sample random data & post-processing --
-- sample random data and apply post-processing --
if (rnd_enable = '0') then
rnd_cnt <= (others => '0');
rnd_sreg <= (others => '0');
elsif (db_enable = '1') then -- valid de-biased output?
if (rnd_cnt = "10000") then
elsif (rnd_valid = '1') and (garo_en_out(garo_en_out'left) = '1') then -- valid random sample and GAROs ready?
if (rnd_cnt = "1000") then
rnd_cnt <= (others => '0');
else
rnd_cnt <= std_ulogic_vector(unsigned(rnd_cnt) + 1);
end if;
rnd_sreg <= rnd_sreg(rnd_sreg'left-1 downto 0) & (xnor_all_f(rnd_sreg and lfsr_taps_c) xor db_data); -- LFSR post-processing
-- rnd_sreg <= rnd_sreg(rnd_sreg'left-1 downto 0) & db_data; -- LFSR post-processing
if (lfsr_en_c = true) then -- LFSR post-processing
rnd_sreg <= rnd_sreg(rnd_sreg'left-1 downto 0) & (xnor_all_f(rnd_sreg and lfsr_taps_c) xnor rnd_data);
else -- NO post-processing
rnd_sreg <= rnd_sreg(rnd_sreg'left-1 downto 0) & rnd_data;
end if;
end if;
 
-- data output register --
if (new_sample = '1') then
rnd_data <= rnd_sreg;
if (rnd_cnt = "1000") then
rnd_output <= rnd_sreg;
end if;
 
-- health check error --
if (rnd_enable = '0') then
rnd_error_zero <= '0';
rnd_error_one <= '0';
else
rnd_error_zero <= rnd_error_zero or garo_err0;
rnd_error_one <= rnd_error_one or garo_err1;
end if;
 
-- data ready flag --
if (rnd_enable = '0') or (rden = '1') then -- clear when deactivated or on data read
ready_ff <= '0';
elsif (new_sample = '1') then
ready_ff <= '1';
if (rnd_cnt = "1000") then -- new sample ready?
rnd_ready <= '1';
elsif (rnd_enable = '0') or (rden = '1') then -- clear when deactivated or on data read
rnd_ready <= '0';
end if;
end if;
end process processing_core;
 
-- John von Neumann De-Biasing --
debiasing: process(db_state, rnd_sync)
variable tmp_v : std_ulogic_vector(2 downto 0);
 
end neorv32_trng_rtl;
 
 
-- ############################################################################################################################
-- ############################################################################################################################
 
 
-- #################################################################################################
-- # << NEORV32 - True Random Number Generator (TRNG) - GARO Chain-Based Entropy Source >> #
-- # ********************************************************************************************* #
-- # An inverter chain (ring oscillator) is used as entropy source. The inverter chain is #
-- # constructed as GARO (Galois Ring Oscillator) TRNG, which is an "asynchronous" LFSR. The #
-- # single inverters are connected via latches that are used to enbale/disable the TRNG. Also, #
-- # these latches are used as additional delay element. By using unique enable signals for each #
-- # latch, the synthesis tool cannot "optimize" (=remove) any of the inverters out of the design. #
-- # Furthermore, the latches prevent the synthesis tool from detecting combinatorial loops. #
-- # #
-- # Sources: #
-- # - GARO: "Experimental Assessment of FIRO- and GARO-based Noise Sources for Digital TRNG #
-- # Designs on FPGAs" by Martin Schramm, Reiner Dojen and Michael Heigly, 2017 #
-- # - Latches for platform independence: "Extended Abstract: The Butterfly PUF Protecting IP #
-- # on every FPGA" by Sandeep S. Kumar, Jorge Guajardo, Roel Maesyz, Geert-Jan Schrijen and #
-- # Pim Tuyls, Philips Research Europe, 2008 #
-- # ********************************************************************************************* #
-- # BSD 3-Clause License #
-- # #
-- # Copyright (c) 2020, Stephan Nolting. All rights reserved. #
-- # #
-- # Redistribution and use in source and binary forms, with or without modification, are #
-- # permitted provided that the following conditions are met: #
-- # #
-- # 1. Redistributions of source code must retain the above copyright notice, this list of #
-- # conditions and the following disclaimer. #
-- # #
-- # 2. Redistributions in binary form must reproduce the above copyright notice, this list of #
-- # conditions and the following disclaimer in the documentation and/or other materials #
-- # provided with the distribution. #
-- # #
-- # 3. Neither the name of the copyright holder nor the names of its contributors may be used to #
-- # endorse or promote products derived from this software without specific prior written #
-- # permission. #
-- # #
-- # THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND ANY EXPRESS #
-- # OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF #
-- # MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE #
-- # COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, #
-- # EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE #
-- # GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED #
-- # AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING #
-- # NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED #
-- # OF THE POSSIBILITY OF SUCH DAMAGE. #
-- # ********************************************************************************************* #
-- # The NEORV32 Processor - https://github.com/stnolting/neorv32 (c) Stephan Nolting #
-- #################################################################################################
 
library ieee;
use ieee.std_logic_1164.all;
use ieee.numeric_std.all;
 
library neorv32;
use neorv32.neorv32_package.all;
 
entity neorv32_trng_garo_element is
generic (
NUM_INV : natural := 15 -- number of inverters in chain
);
port (
clk_i : in std_ulogic;
enable_i : in std_ulogic;
enable_o : out std_ulogic;
mask_i : in std_ulogic_vector(NUM_INV-2 downto 0);
data_o : out std_ulogic;
error0_o : out std_ulogic;
error1_o : out std_ulogic
);
end neorv32_trng_garo_element;
 
architecture neorv32_trng_garo_element_rtl of neorv32_trng_garo_element is
 
-- debugging --
constant is_sim_c : boolean := false;
 
signal inv_chain : std_ulogic_vector(NUM_INV-1 downto 0); -- oscillator chain
signal enable_sreg : std_ulogic_vector(NUM_INV-1 downto 0); -- enable shift register
signal sync_ff : std_ulogic_vector(2 downto 0); -- synchronizer
 
signal cnt_zero, cnt_one : std_ulogic_vector(5 downto 0); -- stuck-at-0/1 counters
 
begin
 
-- Sanity Check ---------------------------------------------------------------------------
-- -------------------------------------------------------------------------------------------
assert ((NUM_INV mod 2) /= 0) report "NEORV32 TRNG.GARO_element: NUM_INV has to be odd." severity error;
 
 
-- Entropy Source -------------------------------------------------------------------------
-- -------------------------------------------------------------------------------------------
garo_chain: process(clk_i, enable_i, enable_sreg, mask_i, inv_chain)
begin
-- check groups of two non-overlapping bits from the input stream
tmp_v := db_state & rnd_sync(2 downto 1);
case tmp_v is
when "101" => db_enable <= '1'; db_data <= '1'; -- rising edge -> '1'
when "110" => db_enable <= '1'; db_data <= '0'; -- falling edge -> '0'
when others => db_enable <= '0'; db_data <= '0'; -- invalid
end case;
end process debiasing;
if (is_sim_c = false) then
for i in 0 to NUM_INV-1 loop -- inverters in chain
if (enable_i = '0') then -- start with a defined state (latch reset)
inv_chain(i) <= '0';
-- Using individual enable signals for each inverter - derived from a shift register - to prevent the synthesis tool
-- from removing all but one inverter (since they implement "logical identical functions").
-- This also allows to make the TRNG platform independent.
elsif (enable_sreg(i) = '1') then
-- here we have the inverter chain --
if (i = NUM_INV-1) then -- left-most inverter?
inv_chain(i) <= not inv_chain(0); -- direct input of right most inverter (= output signal)
else
-- if tap switch is ON: use final output XORed with previous inverter's output
-- if tap switch is OFF: just use previous inverter's output
inv_chain(i) <= not (inv_chain(i+1) xor (inv_chain(0) and mask_i(i)));
end if;
end if;
end loop; -- i
else -- simulate as simple LFSR
if rising_edge(clk_i) then
if (enable_i = '0') then
inv_chain <= (others => '0');
else
inv_chain(NUM_INV-1 downto 0) <= inv_chain(inv_chain'left-1 downto 0) & xnor_all_f(inv_chain(NUM_INV-2 downto 0) and mask_i);
end if;
end if;
end if;
end process garo_chain;
 
-- new valid byte available? --
new_sample <= '1' when (rnd_cnt = "10000") and (rnd_enable = '1') and (db_enable = '1') else '0';
 
-- Control --------------------------------------------------------------------------------
-- -------------------------------------------------------------------------------------------
ctrl_unit: process(clk_i)
begin
if rising_edge(clk_i) then
enable_sreg <= enable_sreg(enable_sreg'left-1 downto 0) & enable_i; -- activate right-most inverter first
sync_ff <= sync_ff(sync_ff'left-1 downto 0) & inv_chain(0); -- synchronize to prevent metastability
end if;
end process ctrl_unit;
 
end neorv32_trng_rtl;
-- output for "enable chain" --
enable_o <= enable_sreg(enable_sreg'left);
 
-- rnd output --
data_o <= sync_ff(sync_ff'left);
 
 
-- Health Check ---------------------------------------------------------------------------
-- -------------------------------------------------------------------------------------------
health_check: process(clk_i)
begin
if rising_edge(clk_i) then
if (enable_sreg(enable_sreg'left) = '0') then
cnt_zero <= (others => '0');
cnt_one <= (others => '0');
else
-- stuck-at-zero --
if (and_all_f(cnt_zero) = '0') then -- max not reached yet
error0_o <= '0';
if (sync_ff(sync_ff'left) = '0') then
cnt_zero <= std_ulogic_vector(unsigned(cnt_zero) + 1);
else
cnt_zero <= (others => '0');
end if;
else
error0_o <= '1';
end if;
-- stuck-at-one --
if (and_all_f(cnt_one) = '0') then -- max not reached yet
error1_o <= '0';
if (sync_ff(sync_ff'left) = '1') then
cnt_one <= std_ulogic_vector(unsigned(cnt_one) + 1);
else
cnt_one <= (others => '0');
end if;
else
error1_o <= '1';
end if;
end if;
end if;
end process health_check;
 
 
end neorv32_trng_garo_element_rtl;
/neorv32_uart.vhd
152,27 → 152,8
data_o <= (others => '0');
if (rd_en = '1') then
if (addr = uart_ctrl_addr_c) then
data_o(ctrl_uart_baud00_c) <= ctrl(ctrl_uart_baud00_c);
data_o(ctrl_uart_baud01_c) <= ctrl(ctrl_uart_baud01_c);
data_o(ctrl_uart_baud02_c) <= ctrl(ctrl_uart_baud02_c);
data_o(ctrl_uart_baud03_c) <= ctrl(ctrl_uart_baud03_c);
data_o(ctrl_uart_baud04_c) <= ctrl(ctrl_uart_baud04_c);
data_o(ctrl_uart_baud05_c) <= ctrl(ctrl_uart_baud05_c);
data_o(ctrl_uart_baud06_c) <= ctrl(ctrl_uart_baud06_c);
data_o(ctrl_uart_baud07_c) <= ctrl(ctrl_uart_baud07_c);
--
data_o(ctrl_uart_baud08_c) <= ctrl(ctrl_uart_baud08_c);
data_o(ctrl_uart_baud09_c) <= ctrl(ctrl_uart_baud09_c);
data_o(ctrl_uart_baud10_c) <= ctrl(ctrl_uart_baud10_c);
data_o(ctrl_uart_baud11_c) <= ctrl(ctrl_uart_baud11_c);
--
data_o(ctrl_uart_prsc0_c) <= ctrl(ctrl_uart_prsc0_c);
data_o(ctrl_uart_prsc1_c) <= ctrl(ctrl_uart_prsc1_c);
data_o(ctrl_uart_prsc2_c) <= ctrl(ctrl_uart_prsc2_c);
data_o <= ctrl; -- default
data_o(ctrl_uart_rxovr_c) <= uart_rx_avail(0) and uart_rx_avail(1);
data_o(ctrl_uart_en_c) <= ctrl(ctrl_uart_en_c);
data_o(ctrl_uart_rx_irq_c) <= ctrl(ctrl_uart_rx_irq_c);
data_o(ctrl_uart_tx_irq_c) <= ctrl(ctrl_uart_tx_irq_c);
data_o(ctrl_uart_tx_busy_c) <= uart_tx_busy;
else -- uart_rtx_addr_c
data_o(data_rx_avail_c) <= uart_rx_avail(0);
/neorv32_wishbone.vhd
4,9 → 4,9
-- # The interface is either unregistered (INTERFACE_REG_STAGES = 0), only outgoing signals are #
-- # registered (INTERFACE_REG_STAGES = 1) or incoming and outgoing signals are registered #
-- # (INTERFACE_REG_STAGES = 2). #
-- # #
-- # - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - #
-- # All bus accesses from the CPU, which do not target the internal IO region, the internal boot- #
-- # loader or the internal instruction & data memories (if implemented), are delegated via this #
-- # loader or the internal instruction or data memories (if implemented), are delegated via this #
-- # Wishbone gateway to the external bus interface. #
-- # ********************************************************************************************* #
-- # BSD 3-Clause License #
50,14 → 50,10
entity neorv32_wishbone is
generic (
INTERFACE_REG_STAGES : natural := 2; -- number of interface register stages (0,1,2)
-- Memory configuration: Instruction memory --
MEM_ISPACE_BASE : std_ulogic_vector(31 downto 0) := x"00000000"; -- base address of instruction memory space
MEM_ISPACE_SIZE : natural := 8*1024; -- total size of instruction memory space in byte
-- Internal instruction memory --
MEM_INT_IMEM_USE : boolean := true; -- implement processor-internal instruction memory
MEM_INT_IMEM_SIZE : natural := 8*1024; -- size of processor-internal instruction memory in bytes
-- Memory configuration: Data memory --
MEM_DSPACE_BASE : std_ulogic_vector(31 downto 0) := x"80000000"; -- base address of data memory space
MEM_DSPACE_SIZE : natural := 4*1024; -- total size of data memory space in byte
-- Internal data memory --
MEM_INT_DMEM_USE : boolean := true; -- implement processor-internal data memory
MEM_INT_DMEM_SIZE : natural := 4*1024 -- size of processor-internal data memory in bytes
);
93,8 → 89,10
-- access control --
signal int_imem_acc, int_imem_acc_real : std_ulogic;
signal int_dmem_acc, int_dmem_acc_real : std_ulogic;
signal int_boot_acc, int_io_acc : std_ulogic;
signal int_boot_acc : std_ulogic;
signal wb_access : std_ulogic;
signal wb_access_ff, wb_access_ff_ff : std_ulogic;
signal rb_en : std_ulogic;
 
-- bus arbiter --
signal wb_stb_ff0 : std_ulogic;
103,32 → 101,29
signal wb_ack_ff : std_ulogic;
signal wb_err_ff : std_ulogic;
 
-- data read-back --
signal wb_rdata : std_ulogic_vector(31 downto 0);
 
begin
 
-- Sanity Check ---------------------------------------------------------------------------
-- -------------------------------------------------------------------------------------------
sanity_check: process(clk_i)
begin
if rising_edge(clk_i) then
if (INTERFACE_REG_STAGES > 2) then
assert false report "NEORV32 CONFIG ERROR! Number of external memory interface buffer stages must be 0, 1 or 2." severity error;
end if;
end if;
end process sanity_check;
assert (INTERFACE_REG_STAGES <= 2) report "NEORV32 CONFIG ERROR! Number of external memory interface buffer stages must be 0, 1 or 2." severity error;
assert (INTERFACE_REG_STAGES /= 0) report "NEORV32 CONFIG WARNING! External memory interface without register stages is still experimental for peripherals with more than 1 cycle latency." severity warning;
 
 
-- Access Control -------------------------------------------------------------------------
-- -------------------------------------------------------------------------------------------
-- access to internal IMEM or DMEM? --
int_imem_acc <= '1' when (addr_i >= MEM_ISPACE_BASE) and (addr_i < std_ulogic_vector(unsigned(MEM_ISPACE_BASE) + MEM_INT_IMEM_SIZE)) else '0';
int_dmem_acc <= '1' when (addr_i >= MEM_DSPACE_BASE) and (addr_i < std_ulogic_vector(unsigned(MEM_DSPACE_BASE) + MEM_INT_DMEM_SIZE)) else '0';
int_imem_acc <= '1' when (addr_i >= imem_base_c) and (addr_i < std_ulogic_vector(unsigned(imem_base_c) + MEM_INT_IMEM_SIZE)) else '0';
int_dmem_acc <= '1' when (addr_i >= dmem_base_c) and (addr_i < std_ulogic_vector(unsigned(dmem_base_c) + MEM_INT_DMEM_SIZE)) else '0';
int_imem_acc_real <= int_imem_acc when (MEM_INT_IMEM_USE = true) else '0';
int_dmem_acc_real <= int_dmem_acc when (MEM_INT_DMEM_USE = true) else '0';
int_boot_acc <= '1' when (addr_i >= boot_base_c) else '0';
int_io_acc <= '1' when (addr_i >= io_base_c) else '0';
int_boot_acc <= '1' when (addr_i >= boot_rom_base_c) else '0'; -- this also covers access to the IO space
--int_io_acc <= '1' when (addr_i >= io_base_c) else '0';
 
-- actual external bus access? --
wb_access <= (not int_imem_acc_real) and (not int_dmem_acc_real) and (not int_boot_acc) and (not int_io_acc) and (wren_i or rden_i);
wb_access <= (not int_imem_acc_real) and (not int_dmem_acc_real) and (not int_boot_acc) and (wren_i or rden_i);
 
 
-- Bus Arbiter -----------------------------------------------------------------------------
136,17 → 131,19
bus_arbiter: process(rstn_i, clk_i)
begin
if (rstn_i = '0') then
wb_cyc_ff <= '0';
wb_stb_ff1 <= '0';
wb_stb_ff0 <= '0';
wb_ack_ff <= '0';
wb_err_ff <= '0';
wb_cyc_ff <= '0';
wb_stb_ff1 <= '0';
wb_stb_ff0 <= '0';
wb_ack_ff <= '0';
wb_err_ff <= '0';
wb_access_ff <= '0';
wb_access_ff_ff <= '0';
elsif rising_edge(clk_i) then
-- bus cycle --
if (INTERFACE_REG_STAGES = 0) then
wb_cyc_ff <= '0'; -- unused
else
wb_cyc_ff <= (wb_cyc_ff or wb_access) and ((not wb_ack_i) or (not wb_err_i)) and (not cancel_i);
wb_cyc_ff <= (wb_cyc_ff or wb_access) and (not wb_ack_i) and (not wb_err_i) and (not cancel_i);
end if;
-- bus strobe --
wb_stb_ff1 <= wb_stb_ff0;
155,6 → 152,13
wb_ack_ff <= wb_ack_i;
-- bus err --
wb_err_ff <= wb_err_i;
-- access still active? --
wb_access_ff_ff <= wb_access_ff;
if (wb_access = '1') then
wb_access_ff <= '1';
elsif ((wb_ack_i or wb_err_i or cancel_i) = '1') then
wb_access_ff <= '0';
end if;
end if;
end process bus_arbiter;
 
170,12 → 174,16
-- cpu err --
err_o <= wb_err_ff when (INTERFACE_REG_STAGES = 2) else wb_err_i;
 
-- cpu read-data --
rb_en <= wb_access_ff_ff when (INTERFACE_REG_STAGES = 2) else wb_access_ff;
data_o <= wb_rdata when (rb_en = '1') else (others => '0');
 
 
-- Bus Buffer -----------------------------------------------------------------------------
-- -------------------------------------------------------------------------------------------
interface_reg_level_zero:
if (INTERFACE_REG_STAGES = 0) generate -- 0 register levels: direct connection
data_o <= wb_dat_i;
wb_rdata <= wb_dat_i;
wb_adr_o <= addr_i;
wb_dat_o <= data_i;
wb_sel_o <= ben_i;
195,7 → 203,7
end if;
end if;
end process buffer_stages_one;
data_o <= wb_dat_i;
wb_rdata <= wb_dat_i;
end generate;
 
interface_reg_level_two:
208,8 → 216,10
wb_dat_o <= data_i;
wb_sel_o <= ben_i;
wb_we_o <= wren_i;
data_o <= wb_dat_i;
end if;
if (wb_ack_i = '1') then
wb_rdata <= wb_dat_i;
end if;
end if;
end process buffer_stages_two;
end generate;

powered by: WebSVN 2.1.0

© copyright 1999-2024 OpenCores.org, equivalent to Oliscience, all rights reserved. OpenCores®, registered trademark.