Compare commits
| Author | SHA1 | Date | |
|---|---|---|---|
|
|
aacb0c448b | ||
|
|
ba2264ed97 | ||
|
|
3072e46951 | ||
|
|
19fe5c9005 | ||
|
|
d9f9c66962 | ||
|
|
ec8a4254a9 | ||
|
|
8ee78f468d | ||
|
|
00234a1efd | ||
|
|
a3d54edf64 | ||
|
|
9ea208eaf0 | ||
|
|
6ab6c0632c | ||
|
|
6da937fe58 | ||
|
|
1d72b92b46 | ||
|
|
2d45364d7e | ||
|
|
b56a35171a | ||
|
|
194eacd637 | ||
|
|
8aa77da2b1 | ||
|
|
034f28a4f6 | ||
|
|
9cdec8e722 | ||
|
|
efa1c33c13 | ||
|
|
ecb22dfeee | ||
|
|
5ecfef0595 | ||
|
|
0b8624c6ac | ||
|
|
3709ffcefe | ||
|
|
8b49c6197c | ||
|
|
c8306cafc4 | ||
|
|
4a5178da93 | ||
|
|
5d7fed1259 | ||
|
|
116defca80 | ||
|
|
ddeccf3a34 | ||
|
|
65404dbba8 | ||
|
|
6130b4c260 | ||
|
|
08f122c910 | ||
|
|
97453f606e | ||
|
|
fe950520b4 | ||
|
|
a07b596168 | ||
|
|
d8083946f3 | ||
|
|
44b4412d53 | ||
|
|
55ef215f63 | ||
|
|
774fe348b5 | ||
|
|
584ac47a8a | ||
|
|
8159135dfd | ||
|
|
6ac97e7bf3 | ||
|
|
51ea254c82 | ||
|
|
eafadbfa05 | ||
|
|
a6cf47015c | ||
|
|
730714620d | ||
|
|
73dcae8d35 | ||
|
|
abb030f663 | ||
|
|
749c8a6144 | ||
|
|
9a1a5579bf | ||
|
|
47c0a1b682 | ||
|
|
5b743dea38 | ||
|
|
38b70b722c | ||
|
|
a6b19c1621 | ||
|
|
45d8f099ca | ||
|
|
15d9de633c | ||
|
|
b288e8ee43 | ||
|
|
4b25be2021 | ||
|
|
8549615cd0 | ||
|
|
822059724f | ||
|
|
c104a7b916 | ||
|
|
3a8641003e | ||
|
|
2424f52409 | ||
|
|
237fc3d163 | ||
|
|
21f33a1768 | ||
|
|
f706de00bb | ||
|
|
f3d4b8bdb3 | ||
|
|
48da5e410e | ||
|
|
e7b85e0138 | ||
|
|
c5027772aa | ||
|
|
63b60eee52 | ||
|
|
830f840b83 | ||
|
|
3d02793488 | ||
|
|
27d59cb442 | ||
|
|
1e0fc89d3a | ||
|
|
2316880678 | ||
|
|
e2da4a5108 | ||
|
|
331590cc36 | ||
|
|
874ed6f824 | ||
|
|
bea098d743 | ||
|
|
1fe9a2c398 | ||
|
|
6449f3fa78 | ||
|
|
1884f3158c | ||
|
|
9794a67ba6 | ||
|
|
6f74cd1662 | ||
|
|
f046307aa9 | ||
|
|
0edf614e5e | ||
|
|
eabf73aa4f | ||
|
|
3de1c312bb | ||
|
|
1c17d74ae1 | ||
|
|
134119db33 | ||
|
|
f6ce6d39e7 | ||
|
|
fc342f5734 | ||
|
|
52a8946996 | ||
|
|
22149e3dfd | ||
|
|
b9bdef1e30 | ||
|
|
efa56c97f2 | ||
|
|
a2a17fd24a | ||
|
|
66984e5b25 | ||
|
|
b5e1d45b20 | ||
|
|
4c309f1eef | ||
|
|
20dc046c75 | ||
|
|
d97c9dd6ec | ||
|
|
cd867dad7d | ||
|
|
2e57a02355 | ||
|
|
ef6b247b01 | ||
|
|
68429fd3b0 | ||
|
|
917ceced01 | ||
|
|
69a654f218 | ||
|
|
83d260fc0d | ||
|
|
79de05d54c | ||
|
|
be038f16ba | ||
|
|
4452820f09 | ||
|
|
133df33e35 | ||
|
|
47d5b9ac7f | ||
|
|
1be58489b0 | ||
|
|
cf72d81cd3 | ||
|
|
0b1cd9b7b1 | ||
|
|
f3ee78329b | ||
|
|
842553943a | ||
|
|
a00c0c1a0d | ||
|
|
30340bd6cf | ||
|
|
4372265ee2 | ||
|
|
e19528b20f | ||
|
|
893e93530d | ||
|
|
2fb198d941 | ||
|
|
b8890b0132 | ||
|
|
d3c322ca48 | ||
|
|
a3c4ba6e82 | ||
|
|
1c5db27de0 | ||
|
|
f34847adb1 | ||
|
|
b5b15b90e2 | ||
|
|
d3e486b6d5 | ||
|
|
ae50048039 | ||
|
|
a94fb20d4f | ||
|
|
5b9f651efe | ||
|
|
68ba887854 | ||
|
|
6983e7ebec | ||
|
|
2e1850c19b | ||
|
|
599380bd10 | ||
|
|
eb22574d20 | ||
|
|
1cbfc94fde | ||
|
|
4dc562bfe5 | ||
|
|
e89e61291a | ||
|
|
ad0284bd10 | ||
|
|
962cffac1d | ||
|
|
7892b38128 | ||
|
|
2761d5926b | ||
|
|
5a3f3d4cbe | ||
|
|
241658d3ba | ||
|
|
8054aedcb5 | ||
|
|
dbff927a63 | ||
|
|
52e9decf78 | ||
|
|
2dfce691ce | ||
|
|
c97b7cdf39 | ||
|
|
7225dcfa87 | ||
|
|
1a0e8f08f5 | ||
|
|
b201db2193 | ||
|
|
5140d7a6fa | ||
|
|
9cb7ef5930 | ||
|
|
4bf6b28c71 | ||
|
|
e2c40b91a1 | ||
|
|
8d6a5af6c8 | ||
|
|
4f99ce0c87 | ||
|
|
81c8bf1897 | ||
|
|
e465dc860b | ||
|
|
180dad1fe3 | ||
|
|
c1d14214ac | ||
|
|
4f19324605 | ||
|
|
ae421c7a15 | ||
|
|
b44d2ba1f9 | ||
|
|
a332b172b3 | ||
|
|
cd8b53c3f3 | ||
|
|
8282389078 | ||
|
|
2a5dd91588 | ||
|
|
09d21bef97 | ||
|
|
ac89acfbeb | ||
|
|
58f704112c | ||
|
|
5f24a7e1dc | ||
|
|
f643864e54 | ||
|
|
bd19ea587b | ||
|
|
538c115367 | ||
|
|
ea356d50e3 | ||
|
|
2c9f747259 | ||
|
|
15ba5e691f | ||
|
|
6b4a578ccc | ||
|
|
c3b72ca3a9 | ||
|
|
32d5cf7674 | ||
|
|
7cad6e874d | ||
|
|
a7387810b9 | ||
|
|
c5394b8b22 | ||
|
|
548c2b4e94 | ||
|
|
92a1179fee | ||
|
|
0f52e03f7b | ||
|
|
62e35386a5 | ||
|
|
15651ad162 | ||
|
|
cae7d9eb39 | ||
|
|
6ce723794d | ||
|
|
8018a94936 | ||
|
|
08466372b2 | ||
|
|
2667c79d70 | ||
|
|
4ade970e3f | ||
|
|
6afb5d9c2e | ||
|
|
ea7e05ba30 | ||
|
|
c3c42386d8 | ||
|
|
e874bfa228 | ||
|
|
3057cdd154 | ||
|
|
2e7765311c | ||
|
|
d06519bd49 | ||
|
|
1c1eae6e8e | ||
|
|
e32cecbfe4 | ||
|
|
200cc27da2 | ||
|
|
b656379683 | ||
|
|
7d818d0db4 | ||
|
|
2987754b98 | ||
|
|
1597bc6240 | ||
|
|
44ef835b7a | ||
|
|
905094be8b | ||
|
|
3def04d376 | ||
|
|
e159dd917b | ||
|
|
1861ea2a60 | ||
|
|
99c1ef6686 | ||
|
|
95596c23ff | ||
|
|
4baea1c92c | ||
|
|
e333f6ca2a | ||
|
|
295d996216 | ||
|
|
6ff7294c1e | ||
|
|
fed261182c | ||
|
|
9bff7ff2ae | ||
|
|
0e825a1df5 | ||
|
|
5226b0bb0a | ||
|
|
a1afb1e9c5 | ||
|
|
5ce761ead5 | ||
|
|
4f6b9e2082 | ||
|
|
397eb46e02 | ||
|
|
d74ba76649 | ||
|
|
2895aa265a | ||
|
|
b9f89bb7f2 | ||
|
|
2e6aed7e91 | ||
|
|
8476888778 | ||
|
|
856f335db3 | ||
|
|
ec84f598aa | ||
|
|
9e43596a76 | ||
|
|
eebb15e773 | ||
|
|
4282eb6221 | ||
|
|
f2ea795156 | ||
|
|
3e6b68932f | ||
|
|
1c754e35ab | ||
|
|
1cce8b6526 | ||
|
|
0ee9f8f3fa | ||
|
|
94b90d1fef | ||
|
|
30cfa326f2 | ||
|
|
cc122dd696 | ||
|
|
f0636b8805 | ||
|
|
917db4cc8b | ||
|
|
f3d47b0bb9 | ||
|
|
5ed37017b5 | ||
|
|
b3da8c3d7b | ||
|
|
c605a19368 | ||
|
|
70a8763f3b | ||
|
|
e0504e7320 | ||
|
|
aacedf75a9 | ||
|
|
f2faffb88f | ||
|
|
4d5f821e7a | ||
|
|
538a55d1a2 | ||
|
|
0b7f09d0d9 | ||
|
|
342de5f159 | ||
|
|
2c59e2959f | ||
|
|
3970467a7d | ||
|
|
464eb37a7d | ||
|
|
2151b77ef3 | ||
|
|
a691c0b7fa | ||
|
|
c0985f0f53 | ||
|
|
5aff9e1b93 | ||
|
|
c3507638c1 | ||
|
|
4a79ecce80 | ||
|
|
68b045848e | ||
|
|
f681936a59 | ||
|
|
cfe818b87b | ||
|
|
9d43d91da8 | ||
|
|
8867efa451 | ||
|
|
25e3d4f36f | ||
|
|
3db7aa0fb4 | ||
|
|
523e216793 | ||
|
|
bd4b69206f | ||
|
|
61e740cc1d | ||
|
|
592c158275 | ||
|
|
791e97a873 | ||
|
|
0b5b8ceed7 | ||
|
|
31bd88a707 | ||
|
|
739921d7a9 | ||
|
|
cfb87bf755 | ||
|
|
73f7a85646 | ||
|
|
03780653b8 | ||
|
|
0dcb62d6ff | ||
|
|
8534d570e0 | ||
|
|
60bb979bb7 | ||
|
|
5681bf5693 | ||
|
|
1a26f8176a | ||
|
|
9ef46952e2 | ||
|
|
06bb5f8f0d | ||
|
|
987f426a57 | ||
|
|
6c03c853f6 | ||
|
|
d63cdf3cb1 | ||
|
|
4c482f1cda | ||
|
|
9f7547c68e | ||
|
|
dd6bd675f1 | ||
|
|
c882f1d469 | ||
|
|
9163ced247 | ||
|
|
0c8a1c2ec5 | ||
|
|
f053756416 | ||
|
|
70645de004 | ||
|
|
e91134a95f | ||
|
|
d9030dc07c | ||
|
|
1417d6f5cd | ||
|
|
ef9b538769 | ||
|
|
6a1d8f729f | ||
|
|
bcefe4639e | ||
|
|
cf548fd893 | ||
|
|
89723cf6d0 | ||
|
|
308d0d8f4a | ||
|
|
5483606f74 | ||
|
|
4e2cb68237 | ||
|
|
8d0bb58b5d | ||
|
|
bce7ba16b7 | ||
|
|
7649b3fff0 | ||
|
|
16e7312df1 | ||
|
|
dd42e17b18 | ||
|
|
748bd9e52a | ||
|
|
c403b3b22d | ||
|
|
9c45912627 | ||
|
|
170a65237b | ||
|
|
937e129a55 | ||
|
|
d059cf8109 | ||
|
|
ffa4eb81ca | ||
|
|
04e1b6fcbf | ||
|
|
8106295641 | ||
|
|
5f40d70789 | ||
|
|
83a9b4c417 | ||
|
|
a98a8bb0ba | ||
|
|
590734078c | ||
|
|
0ed5461442 | ||
|
|
c46a1caaf5 | ||
|
|
9c12bc9640 | ||
|
|
90a889a5f8 | ||
|
|
245c01ad45 | ||
|
|
9832fbfac9 | ||
|
|
650e5db110 | ||
|
|
58257266ad | ||
|
|
c10463c961 | ||
|
|
e4dc3e69a1 | ||
|
|
9a756d4ca8 | ||
|
|
f05c6bb829 | ||
|
|
fe60d9d7a4 | ||
|
|
9675773b2a | ||
|
|
1738a6c0b6 | ||
|
|
bc4c015150 | ||
|
|
d28b2225a7 | ||
|
|
fcdbc0e601 | ||
|
|
690c6c24f6 | ||
|
|
ba703d81df | ||
|
|
0ed3e397f2 | ||
|
|
eb818a15bb | ||
|
|
a165d37bb7 | ||
|
|
c574f7f0fd | ||
|
|
a10614df0a | ||
|
|
5f1b2738de | ||
|
|
d7ed0a9fb0 | ||
|
|
655cfb7f0d | ||
|
|
55a702d6bd | ||
|
|
e8ddaf8d98 | ||
|
|
377b8c0993 | ||
|
|
8c652af1a7 | ||
|
|
18641b8411 | ||
|
|
dc63b8df76 | ||
|
|
7c7fc19162 | ||
|
|
c11d040f68 | ||
|
|
4cd2e0fd19 | ||
|
|
61d5c40cd2 | ||
|
|
75f8ddd340 | ||
|
|
8136d54172 | ||
|
|
50e4d2d32a | ||
|
|
c45b123bdb | ||
|
|
4fe3a1c636 | ||
|
|
d9ba866ed0 | ||
|
|
f7e19d3d44 | ||
|
|
fb625665d2 | ||
|
|
ef5da14068 | ||
|
|
f3c6c4c644 | ||
|
|
64cb0bb426 | ||
|
|
4735454c40 | ||
|
|
0e4e1b0fba | ||
|
|
d9961e9efb | ||
|
|
be85922612 | ||
|
|
1e9bed13e5 | ||
|
|
28bd8e959d | ||
|
|
860e2984fd | ||
|
|
13df4bbf12 | ||
|
|
9a7ffd09ac | ||
|
|
21e3023bfb | ||
|
|
2903f5b7f1 | ||
|
|
6e65134b53 | ||
|
|
4bb7087b60 | ||
|
|
de9ad2d469 | ||
|
|
988b2ed138 | ||
|
|
50af9fe70d | ||
|
|
bf78b1beef | ||
|
|
fbee2fe578 | ||
|
|
080e286b1c | ||
|
|
32e4a933b9 | ||
|
|
15645ec096 | ||
|
|
776094e4b2 | ||
|
|
8e6affa627 | ||
|
|
27b1d6a426 | ||
|
|
bb5f153651 | ||
|
|
a2e01a7966 | ||
|
|
b4392a5c7a | ||
|
|
5091040c1d | ||
|
|
755b318e7a | ||
|
|
a41b5f572a | ||
|
|
ba2d02d4e6 | ||
|
|
a14c98c05f | ||
|
|
529658b710 | ||
|
|
11129059e7 | ||
|
|
1f03bb3d41 | ||
|
|
b0a0e4ae6c | ||
|
|
c10be79075 | ||
|
|
6b38a0acba | ||
|
|
84255df928 | ||
|
|
9954268b22 | ||
|
|
6597bccd01 | ||
|
|
a6c7859e22 | ||
|
|
1c7fd9022e | ||
|
|
5120448104 | ||
|
|
8e41790680 | ||
|
|
08317c7744 | ||
|
|
9918af8a12 | ||
|
|
8102a16c3c | ||
|
|
ed47f478f8 | ||
|
|
7cdfa6929d | ||
|
|
16b4f2b138 | ||
|
|
7ccefbab86 | ||
|
|
5abe0f9234 | ||
|
|
29eb6a05c3 | ||
|
|
2c95fae0ab | ||
|
|
545379c99d | ||
|
|
533a0bd328 | ||
|
|
b81ce94c39 | ||
|
|
48c7618752 | ||
|
|
5c63d629a7 | ||
|
|
36e8cd1e00 | ||
|
|
c90b63d476 | ||
|
|
41593cbc54 | ||
|
|
0bba7d2e10 | ||
|
|
a5f0a35f80 | ||
|
|
5bd0c6ea4a | ||
|
|
1929d9374e | ||
|
|
c9900e509a | ||
|
|
029bf8eb22 | ||
|
|
8060efb864 | ||
|
|
3f62f79d12 | ||
|
|
fdc3664187 | ||
|
|
69697d7222 | ||
|
|
419ccc4edf | ||
|
|
b67911c65d | ||
|
|
e9e132b3e6 | ||
|
|
32cbb4fc13 | ||
|
|
9e404bfb06 | ||
|
|
0ea7ced5e3 | ||
|
|
de0a8c6e17 | ||
|
|
f59e4dd7d1 | ||
|
|
85bf744892 | ||
|
|
891e764a23 | ||
|
|
20b3bfb41b | ||
|
|
8a8adce98e | ||
|
|
051b4182f1 | ||
|
|
3685973be8 | ||
|
|
b656e2890b | ||
|
|
f50a47246a | ||
|
|
c104c6e67d | ||
|
|
c96015bbad | ||
|
|
fe372f0efa | ||
|
|
61b2095bf8 | ||
|
|
329c639c1a | ||
|
|
f8962066f0 | ||
|
|
1c499c6b34 | ||
|
|
225e0d5eeb | ||
|
|
f960a13953 | ||
|
|
c8da959dbb | ||
|
|
78db345b82 | ||
|
|
fda12e53c3 | ||
|
|
40d96126e7 | ||
|
|
959217a81c | ||
|
|
91347dd60e | ||
|
|
3be3800dc7 | ||
|
|
0bc9ef0b00 | ||
|
|
5694dddd9f | ||
|
|
b47d55d61f | ||
|
|
14489d80e9 | ||
|
|
de6bd8f29c | ||
|
|
b6309838f1 | ||
|
|
25a276d19b | ||
|
|
f1e2601c27 | ||
|
|
c17d99dc2b | ||
|
|
b3684f6403 | ||
|
|
1afb05d18a | ||
|
|
db98ad86d2 | ||
|
|
1493e3e779 | ||
|
|
3015a0c6de | ||
|
|
beca7f7ec8 | ||
|
|
7e82a94595 | ||
|
|
86866b26a7 | ||
|
|
098b5982b2 | ||
|
|
2a0d20f4b2 | ||
|
|
b117df0bc9 | ||
|
|
316b998f86 | ||
|
|
e873c4ef07 | ||
|
|
dd38d30198 | ||
|
|
3ecd76f185 | ||
|
|
f2ebee9703 | ||
|
|
6eb25882ba | ||
|
|
de0e513eb0 | ||
|
|
496be499fb | ||
|
|
a2c574150f | ||
|
|
48f5a19d30 | ||
|
|
bbf7601a09 | ||
|
|
38291789bf | ||
|
|
7756d5c412 | ||
|
|
3080c176c2 | ||
|
|
01e9796a47 | ||
|
|
45af6006a1 | ||
|
|
c69bccf68b | ||
|
|
40be1e7cd8 | ||
|
|
4ab330986f |
Binary file not shown.
@@ -12,8 +12,8 @@ vcom -explicit -93 "../src/core/dpath_ctrl.vhd"
|
|||||||
vcom -explicit -93 "../src/core/int_ctrl.vhd"
|
vcom -explicit -93 "../src/core/int_ctrl.vhd"
|
||||||
vcom -explicit -93 "../src/core/alu.vhd"
|
vcom -explicit -93 "../src/core/alu.vhd"
|
||||||
vcom -explicit -93 "../src/core/cpu.vhd"
|
vcom -explicit -93 "../src/core/cpu.vhd"
|
||||||
vcom -explicit -93 "../src/test_irom.vhdl"
|
vcom -explicit -93 "../src/itest_irom.vhdl"
|
||||||
vcom -explicit -93 "../src/core/tb_cpu.vhd"
|
vcom -explicit -93 "../src/tb_cpu_itest.vhd"
|
||||||
vsim -t 1ps -lib work tb_cpu
|
vsim -t 1ps -lib work tb_cpu
|
||||||
do {tb_cpu.wdo}
|
do {tb_cpu.wdo}
|
||||||
view wave
|
view wave
|
||||||
|
|||||||
@@ -12,7 +12,7 @@ vcom -explicit -93 "../src/core/alu.vhd"
|
|||||||
vcom -explicit -93 "../src/core/cpu.vhd"
|
vcom -explicit -93 "../src/core/cpu.vhd"
|
||||||
vcom -explicit -93 "../src/cpu_embedded.vhd"
|
vcom -explicit -93 "../src/cpu_embedded.vhd"
|
||||||
vcom -explicit -93 "../src/tb_cpu_embedded.vhd"
|
vcom -explicit -93 "../src/tb_cpu_embedded.vhd"
|
||||||
vcom -explicit -93 "../src/test_irom.vhdl"
|
vcom -explicit -93 "../src/itest_irom.vhdl"
|
||||||
vsim -t 1ps -lib work tb_cpu_embedded
|
vsim -t 1ps -lib work tb_cpu_embedded
|
||||||
do {tb_cpu_embedded.wdo}
|
do {tb_cpu_embedded.wdo}
|
||||||
view wave
|
view wave
|
||||||
|
|||||||
@@ -42,7 +42,7 @@ end chipreg;
|
|||||||
|
|
||||||
architecture Behavioral of chipreg is
|
architecture Behavioral of chipreg is
|
||||||
|
|
||||||
signal reg_page_sel : page_sel_t;
|
signal reg_bank_sel : bank_sel_t;
|
||||||
signal reg_int_ctrl : int_ctrl_in_t;
|
signal reg_int_ctrl : int_ctrl_in_t;
|
||||||
signal reg_stk_high : unsigned(IMEM_ADDR_WIDTH-DMEM_ADDR_WIDTH-1 downto 0);
|
signal reg_stk_high : unsigned(IMEM_ADDR_WIDTH-DMEM_ADDR_WIDTH-1 downto 0);
|
||||||
signal reg_cmem_high : unsigned(IMEM_ADDR_WIDTH-DMEM_ADDR_WIDTH-1 downto 0);
|
signal reg_cmem_high : unsigned(IMEM_ADDR_WIDTH-DMEM_ADDR_WIDTH-1 downto 0);
|
||||||
@@ -53,7 +53,7 @@ proc_assign_ctrl_lines:
|
|||||||
process (clk)
|
process (clk)
|
||||||
begin
|
begin
|
||||||
if rising_edge(clk) then
|
if rising_edge(clk) then
|
||||||
ctrl_out.page_sel <= reg_page_sel;
|
ctrl_out.bank_sel <= reg_bank_sel;
|
||||||
ctrl_out.int_ctrl <= reg_int_ctrl;
|
ctrl_out.int_ctrl <= reg_int_ctrl;
|
||||||
ctrl_out.stk_high <= reg_stk_high;
|
ctrl_out.stk_high <= reg_stk_high;
|
||||||
ctrl_out.cmem_high <= reg_cmem_high;
|
ctrl_out.cmem_high <= reg_cmem_high;
|
||||||
@@ -66,21 +66,15 @@ proc_reg_write:
|
|||||||
if rst = '1' then
|
if rst = '1' then
|
||||||
reg_stk_high <= (others => '0');
|
reg_stk_high <= (others => '0');
|
||||||
reg_cmem_high <= (others => '0');
|
reg_cmem_high <= (others => '0');
|
||||||
reg_page_sel <= (others => '0');
|
reg_bank_sel <= (others => '0');
|
||||||
reg_int_ctrl.enable <= '0';
|
reg_int_ctrl.enable <= '0';
|
||||||
reg_int_ctrl.polarity <= '1';
|
|
||||||
reg_int_ctrl.edge_sens <= '1';
|
|
||||||
elsif rising_edge(clk) then
|
elsif rising_edge(clk) then
|
||||||
reg_int_ctrl.request <= '0';
|
|
||||||
if we = '1' then
|
if we = '1' then
|
||||||
case addr is
|
case addr is
|
||||||
when X"01" =>
|
when X"01" =>
|
||||||
reg_page_sel(page_sel_t'range) <= din(page_sel_t'range);
|
reg_bank_sel(bank_sel_t'range) <= din(bank_sel_t'range);
|
||||||
when X"03" =>
|
when X"03" =>
|
||||||
reg_int_ctrl.enable <= din(0);
|
reg_int_ctrl.enable <= din(0);
|
||||||
reg_int_ctrl.polarity <= din(1);
|
|
||||||
reg_int_ctrl.edge_sens <= din(2);
|
|
||||||
reg_int_ctrl.request <= din(7);
|
|
||||||
when X"04" =>
|
when X"04" =>
|
||||||
reg_cmem_high <= din(IMEM_ADDR_WIDTH-DMEM_ADDR_WIDTH-1 downto 0);
|
reg_cmem_high <= din(IMEM_ADDR_WIDTH-DMEM_ADDR_WIDTH-1 downto 0);
|
||||||
when X"05" =>
|
when X"05" =>
|
||||||
@@ -99,11 +93,11 @@ proc_reg_read:
|
|||||||
when X"00" => -- Revison
|
when X"00" => -- Revison
|
||||||
dout <= to_unsigned(REVISION, dmem_data_t'length);
|
dout <= to_unsigned(REVISION, dmem_data_t'length);
|
||||||
when X"01" => -- Control 0
|
when X"01" => -- Control 0
|
||||||
dout <= (7 downto page_sel_t'length => '0') & reg_page_sel;
|
dout <= (7 downto bank_sel_t'length => '0') & reg_bank_sel;
|
||||||
when X"02" => -- CPU status
|
when X"02" => -- CPU status
|
||||||
dout <= "000000" & ctrl_in.alu.carry & ctrl_in.alu.zero;
|
dout <= "000000" & ctrl_in.alu.carry & ctrl_in.alu.zero;
|
||||||
when X"03" => -- Interrupt control
|
when X"03" => -- Interrupt control
|
||||||
dout <= "00000" & reg_int_ctrl.edge_sens & reg_int_ctrl.polarity & reg_int_ctrl.enable;
|
dout <= "0000000" & reg_int_ctrl.enable;
|
||||||
when X"04" => -- Upper stack bits out
|
when X"04" => -- Upper stack bits out
|
||||||
dout <= "0000" & reg_cmem_high;
|
dout <= "0000" & reg_cmem_high;
|
||||||
when X"05" => -- Upper cmem bits out
|
when X"05" => -- Upper cmem bits out
|
||||||
|
|||||||
@@ -39,7 +39,6 @@ entity cpu is
|
|||||||
ce : in STD_LOGIC;
|
ce : in STD_LOGIC;
|
||||||
int_in : in STD_LOGIC;
|
int_in : in STD_LOGIC;
|
||||||
int_ack : out STD_LOGIC;
|
int_ack : out STD_LOGIC;
|
||||||
xmem_wait : in STD_LOGIC;
|
|
||||||
xmem_we : out STD_LOGIC;
|
xmem_we : out STD_LOGIC;
|
||||||
xmem_re : out STD_LOGIC;
|
xmem_re : out STD_LOGIC;
|
||||||
instr_din : in unsigned (IMEM_DATA_WIDTH-1 downto 0);
|
instr_din : in unsigned (IMEM_DATA_WIDTH-1 downto 0);
|
||||||
@@ -215,13 +214,12 @@ begin
|
|||||||
pc_inc <= cpu_active and ctrl.lines.pc_inc;
|
pc_inc <= cpu_active and ctrl.lines.pc_inc;
|
||||||
stk_addr <= '0' & stk_ptr;
|
stk_addr <= '0' & stk_ptr;
|
||||||
cpu_status.alu <= alu_status;
|
cpu_status.alu <= alu_status;
|
||||||
cpu_status.xmem_wait <= xmem_wait;
|
|
||||||
creg_ctrl_in.alu <= alu_status;
|
creg_ctrl_in.alu <= alu_status;
|
||||||
|
|
||||||
xmem_dout <= mem_data;
|
xmem_dout <= mem_data;
|
||||||
xmem_addr <= mem_addr;
|
xmem_addr <= mem_addr;
|
||||||
cmem_din <= creg_ctrl_out.cmem_high & mem_data;
|
cmem_din <= creg_ctrl_out.cmem_high & mem_data;
|
||||||
cmem_addr <= '1' & creg_ctrl_out.page_sel & mem_addr(MIN(cmem_addr'length-creg_ctrl_out.page_sel'length-1, mem_addr'length)-1 downto 0);
|
cmem_addr <= '1' & creg_ctrl_out.bank_sel & mem_addr(MIN(cmem_addr'length-creg_ctrl_out.bank_sel'length-1, mem_addr'length)-1 downto 0);
|
||||||
|
|
||||||
--------------------------------------------------------------------
|
--------------------------------------------------------------------
|
||||||
mem_ctrl_lines:
|
mem_ctrl_lines:
|
||||||
@@ -368,7 +366,7 @@ mem_data_mux:
|
|||||||
end process;
|
end process;
|
||||||
|
|
||||||
mem_addr_mux:
|
mem_addr_mux:
|
||||||
process(ctrl.lines.daddr_src_sel, reg_a_dout, reg_b_dout, const_data, creg_ctrl_out.page_sel)
|
process(ctrl.lines.daddr_src_sel, reg_a_dout, reg_b_dout, const_data, creg_ctrl_out.bank_sel)
|
||||||
begin
|
begin
|
||||||
case ctrl.lines.daddr_src_sel is
|
case ctrl.lines.daddr_src_sel is
|
||||||
when reg_a =>
|
when reg_a =>
|
||||||
|
|||||||
@@ -34,9 +34,6 @@ package cpu_pkg is
|
|||||||
-- Chipram depth (valid values 9..floor(log2(BlockRamBytes)))
|
-- Chipram depth (valid values 9..floor(log2(BlockRamBytes)))
|
||||||
constant CHIPRAM_SIZE_BITS : integer := 10;
|
constant CHIPRAM_SIZE_BITS : integer := 10;
|
||||||
|
|
||||||
-- Chipregister file depth
|
|
||||||
constant CHIPREG_SIZE_BITS : integer := 8;
|
|
||||||
|
|
||||||
-- Number of registers (16 registers fixed)
|
-- Number of registers (16 registers fixed)
|
||||||
constant REG_SIZE_BITS : integer := 4;
|
constant REG_SIZE_BITS : integer := 4;
|
||||||
|
|
||||||
@@ -52,7 +49,7 @@ package cpu_pkg is
|
|||||||
constant IMEM_DATA_WIDTH : integer := INST_OPCODE_WIDTH + DMEM_DATA_WIDTH + REG_SIZE_BITS;
|
constant IMEM_DATA_WIDTH : integer := INST_OPCODE_WIDTH + DMEM_DATA_WIDTH + REG_SIZE_BITS;
|
||||||
|
|
||||||
-- Microcode ROM
|
-- Microcode ROM
|
||||||
constant MUCODE_ADDR_WIDTH : integer := 10;
|
constant MUCODE_ADDR_WIDTH : integer := 9;
|
||||||
|
|
||||||
-- Stack depth (uses lower half of CHIPRAM)
|
-- Stack depth (uses lower half of CHIPRAM)
|
||||||
constant STACK_SIZE_BITS : integer := CHIPRAM_SIZE_BITS-1;
|
constant STACK_SIZE_BITS : integer := CHIPRAM_SIZE_BITS-1;
|
||||||
@@ -75,7 +72,7 @@ package cpu_pkg is
|
|||||||
subtype reg_ptr_t is unsigned (3 downto 0);
|
subtype reg_ptr_t is unsigned (3 downto 0);
|
||||||
type dmem_array_t is array (natural range <>) of dmem_data_t;
|
type dmem_array_t is array (natural range <>) of dmem_data_t;
|
||||||
type instr_addr_array is array (integer range <>) of inst_addr_t;
|
type instr_addr_array is array (integer range <>) of inst_addr_t;
|
||||||
subtype page_sel_t is unsigned (CHIPRAM_SIZE_BITS-DMEM_DATA_WIDTH-2 downto 0);
|
subtype bank_sel_t is unsigned (CHIPRAM_SIZE_BITS-DMEM_DATA_WIDTH-2 downto 0);
|
||||||
|
|
||||||
type alu_op_t is
|
type alu_op_t is
|
||||||
(
|
(
|
||||||
@@ -103,7 +100,6 @@ package cpu_pkg is
|
|||||||
|
|
||||||
type cpu_status_t is record
|
type cpu_status_t is record
|
||||||
alu : alu_status_t;
|
alu : alu_status_t;
|
||||||
xmem_wait : STD_LOGIC;
|
|
||||||
end record;
|
end record;
|
||||||
|
|
||||||
type ctrl_lines_t is record
|
type ctrl_lines_t is record
|
||||||
@@ -136,13 +132,10 @@ package cpu_pkg is
|
|||||||
|
|
||||||
type int_ctrl_in_t is record
|
type int_ctrl_in_t is record
|
||||||
enable : std_logic;
|
enable : std_logic;
|
||||||
polarity : std_logic;
|
|
||||||
edge_sens : std_logic;
|
|
||||||
request : std_logic;
|
|
||||||
end record;
|
end record;
|
||||||
|
|
||||||
type creg_ctrl_out_t is record
|
type creg_ctrl_out_t is record
|
||||||
page_sel : page_sel_t;
|
bank_sel : bank_sel_t;
|
||||||
int_ctrl : int_ctrl_in_t;
|
int_ctrl : int_ctrl_in_t;
|
||||||
stk_high : unsigned(IMEM_ADDR_WIDTH-DMEM_ADDR_WIDTH-1 downto 0);
|
stk_high : unsigned(IMEM_ADDR_WIDTH-DMEM_ADDR_WIDTH-1 downto 0);
|
||||||
cmem_high : unsigned(IMEM_ADDR_WIDTH-DMEM_ADDR_WIDTH-1 downto 0);
|
cmem_high : unsigned(IMEM_ADDR_WIDTH-DMEM_ADDR_WIDTH-1 downto 0);
|
||||||
@@ -337,12 +330,11 @@ package body cpu_pkg is
|
|||||||
|
|
||||||
function idecoder(instr_name : instr_name_t; iphase : iphase_t; status : cpu_status_t) return ctrl_lines_t is
|
function idecoder(instr_name : instr_name_t; iphase : iphase_t; status : cpu_status_t) return ctrl_lines_t is
|
||||||
variable result : ctrl_lines_t;
|
variable result : ctrl_lines_t;
|
||||||
variable ze, cy, xmem_wait : STD_LOGIC;
|
variable ze, cy : STD_LOGIC;
|
||||||
|
|
||||||
begin
|
begin
|
||||||
ze := status.alu.zero;
|
ze := status.alu.zero;
|
||||||
cy := status.alu.carry;
|
cy := status.alu.carry;
|
||||||
xmem_wait := status.xmem_wait;
|
|
||||||
|
|
||||||
result := ctrl_lines_default;
|
result := ctrl_lines_default;
|
||||||
if iphase = 0 then
|
if iphase = 0 then
|
||||||
@@ -438,10 +430,6 @@ package body cpu_pkg is
|
|||||||
if iphase = 0 then
|
if iphase = 0 then
|
||||||
result.mem_write := '1';
|
result.mem_write := '1';
|
||||||
end if;
|
end if;
|
||||||
if xmem_wait = '1' then
|
|
||||||
result.mem_write := '1';
|
|
||||||
result.pc_inc := '0';
|
|
||||||
end if;
|
|
||||||
when "MOVX|Ri|K " => -- [R(a)] <= kk
|
when "MOVX|Ri|K " => -- [R(a)] <= kk
|
||||||
result.mem_access := xmem_access;
|
result.mem_access := xmem_access;
|
||||||
result.daddr_src_sel := reg_a;
|
result.daddr_src_sel := reg_a;
|
||||||
@@ -449,10 +437,6 @@ package body cpu_pkg is
|
|||||||
if iphase = 0 then
|
if iphase = 0 then
|
||||||
result.mem_write := '1';
|
result.mem_write := '1';
|
||||||
end if;
|
end if;
|
||||||
if xmem_wait = '1' then
|
|
||||||
result.mem_write := '1';
|
|
||||||
result.pc_inc := '0';
|
|
||||||
end if;
|
|
||||||
when "XOUT|Ri|K " => -- [R(a)] <= kk
|
when "XOUT|Ri|K " => -- [R(a)] <= kk
|
||||||
result.mem_access := xio_access;
|
result.mem_access := xio_access;
|
||||||
result.daddr_src_sel := reg_a;
|
result.daddr_src_sel := reg_a;
|
||||||
@@ -460,55 +444,33 @@ package body cpu_pkg is
|
|||||||
if iphase = 0 then
|
if iphase = 0 then
|
||||||
result.mem_write := '1';
|
result.mem_write := '1';
|
||||||
end if;
|
end if;
|
||||||
if xmem_wait = '1' then
|
|
||||||
result.pc_inc := '0';
|
|
||||||
result.mem_write := '1';
|
|
||||||
end if;
|
|
||||||
when "MOVX|R|Ri " => -- R(a) <= [R(b)]
|
when "MOVX|R|Ri " => -- R(a) <= [R(b)]
|
||||||
result.mem_access := xmem_access;
|
result.mem_access := xmem_access;
|
||||||
result.reg_src_sel := xmem_src;
|
result.reg_src_sel := xmem_src;
|
||||||
result.daddr_src_sel := reg_b;
|
result.daddr_src_sel := reg_b;
|
||||||
if iphase = 0 then
|
if iphase = 0 then
|
||||||
result.mem_read := '1';
|
result.mem_read := '1';
|
||||||
end if;
|
elsif iphase = 1 then
|
||||||
if xmem_wait = '0' then
|
|
||||||
if iphase = 1 then
|
|
||||||
result.reg_we := '1';
|
result.reg_we := '1';
|
||||||
end if;
|
end if;
|
||||||
else
|
|
||||||
result.pc_inc := '0';
|
|
||||||
result.mem_read := '1';
|
|
||||||
end if;
|
|
||||||
when "MOVX|R|Ki " => -- R(a) <= [#addr]
|
when "MOVX|R|Ki " => -- R(a) <= [#addr]
|
||||||
result.mem_access := xmem_access;
|
result.mem_access := xmem_access;
|
||||||
result.reg_src_sel := xmem_src;
|
result.reg_src_sel := xmem_src;
|
||||||
result.daddr_src_sel := const;
|
result.daddr_src_sel := const;
|
||||||
if iphase = 0 then
|
if iphase = 0 then
|
||||||
result.mem_read := '1';
|
result.mem_read := '1';
|
||||||
end if;
|
elsif iphase = 1 then
|
||||||
if xmem_wait = '0' then
|
|
||||||
if iphase = 1 then
|
|
||||||
result.reg_we := '1';
|
result.reg_we := '1';
|
||||||
end if;
|
end if;
|
||||||
else
|
|
||||||
result.pc_inc := '0';
|
|
||||||
result.mem_read := '1';
|
|
||||||
end if;
|
|
||||||
when "XIN|R|Ki " => -- R(a) <= [#addr]
|
when "XIN|R|Ki " => -- R(a) <= [#addr]
|
||||||
result.mem_access := xio_access;
|
result.mem_access := xio_access;
|
||||||
result.reg_src_sel := xmem_src;
|
result.reg_src_sel := xmem_src;
|
||||||
result.daddr_src_sel := const;
|
result.daddr_src_sel := const;
|
||||||
if iphase = 0 then
|
if iphase = 0 then
|
||||||
result.mem_read := '1';
|
result.mem_read := '1';
|
||||||
end if;
|
elsif iphase = 1 then
|
||||||
if xmem_wait = '0' then
|
|
||||||
if iphase = 1 then
|
|
||||||
result.reg_we := '1';
|
result.reg_we := '1';
|
||||||
end if;
|
end if;
|
||||||
else
|
|
||||||
result.pc_inc := '0';
|
|
||||||
result.mem_read := '1';
|
|
||||||
end if;
|
|
||||||
when "MOVX|Ki|R " => -- [#addr] <= R(a)
|
when "MOVX|Ki|R " => -- [#addr] <= R(a)
|
||||||
result.mem_access := xmem_access;
|
result.mem_access := xmem_access;
|
||||||
result.daddr_src_sel := const;
|
result.daddr_src_sel := const;
|
||||||
@@ -516,10 +478,6 @@ package body cpu_pkg is
|
|||||||
if iphase = 0 then
|
if iphase = 0 then
|
||||||
result.mem_write := '1';
|
result.mem_write := '1';
|
||||||
end if;
|
end if;
|
||||||
if xmem_wait = '1' then
|
|
||||||
result.pc_inc := '0';
|
|
||||||
result.mem_write := '1';
|
|
||||||
end if;
|
|
||||||
when "XOUT|Ki|R " => -- [#addr] <= R(a)
|
when "XOUT|Ki|R " => -- [#addr] <= R(a)
|
||||||
result.mem_access := xio_access;
|
result.mem_access := xio_access;
|
||||||
result.daddr_src_sel := const;
|
result.daddr_src_sel := const;
|
||||||
@@ -527,10 +485,6 @@ package body cpu_pkg is
|
|||||||
if iphase = 0 then
|
if iphase = 0 then
|
||||||
result.mem_write := '1';
|
result.mem_write := '1';
|
||||||
end if;
|
end if;
|
||||||
if xmem_wait = '1' then
|
|
||||||
result.pc_inc := '0';
|
|
||||||
result.mem_write := '1';
|
|
||||||
end if;
|
|
||||||
when "ADD|R|R " => -- R(a) <= R(a) + R(b)
|
when "ADD|R|R " => -- R(a) <= R(a) + R(b)
|
||||||
result.alu_opsel := op1_add_op2;
|
result.alu_opsel := op1_add_op2;
|
||||||
result.alu_op1_src_sel := reg_a;
|
result.alu_op1_src_sel := reg_a;
|
||||||
@@ -858,8 +812,6 @@ package body cpu_pkg is
|
|||||||
status.alu.zero := addr(pos);
|
status.alu.zero := addr(pos);
|
||||||
pos := pos + 1;
|
pos := pos + 1;
|
||||||
status.alu.carry := addr(pos);
|
status.alu.carry := addr(pos);
|
||||||
pos := pos + 1;
|
|
||||||
status.xmem_wait := addr(pos);
|
|
||||||
|
|
||||||
result(i) := idecoder(opcode, iphase, status);
|
result(i) := idecoder(opcode, iphase, status);
|
||||||
end loop;
|
end loop;
|
||||||
@@ -870,7 +822,7 @@ package body cpu_pkg is
|
|||||||
function get_muromaddr (opcode : opcode_t; iphase : iphase_t; status : cpu_status_t) return unsigned is
|
function get_muromaddr (opcode : opcode_t; iphase : iphase_t; status : cpu_status_t) return unsigned is
|
||||||
variable addr : unsigned(MUCODE_ADDR_WIDTH-1 downto 0);
|
variable addr : unsigned(MUCODE_ADDR_WIDTH-1 downto 0);
|
||||||
begin
|
begin
|
||||||
addr := status.xmem_wait & status.alu.carry & status.alu.zero & to_unsigned(iphase, 1) & opcode;
|
addr := status.alu.carry & status.alu.zero & to_unsigned(iphase, 1) & opcode;
|
||||||
return addr;
|
return addr;
|
||||||
|
|
||||||
end get_muromaddr;
|
end get_muromaddr;
|
||||||
|
|||||||
@@ -48,13 +48,11 @@ end int_ctrl;
|
|||||||
architecture Behavioral of int_ctrl is
|
architecture Behavioral of int_ctrl is
|
||||||
|
|
||||||
type int_state_t is (int_idle, int_inject, int_active, int_release);
|
type int_state_t is (int_idle, int_inject, int_active, int_release);
|
||||||
type pin_state_t is (pin_s0, pin_s1, pin_s2);
|
|
||||||
|
|
||||||
signal int_state, int_state_next : int_state_t;
|
signal int_state, int_state_next : int_state_t;
|
||||||
signal pin_state, pin_state_next : pin_state_t;
|
|
||||||
signal pc_load, int_ack, stk_push, stk_pop : STD_LOGIC;
|
signal pc_load, int_ack, stk_push, stk_pop : STD_LOGIC;
|
||||||
signal int_request : std_logic;
|
signal int_request : std_logic;
|
||||||
signal int_sampled : std_logic;
|
|
||||||
|
|
||||||
begin
|
begin
|
||||||
|
|
||||||
@@ -74,7 +72,6 @@ irg_ctrl_fsm:
|
|||||||
pc_load <= '0';
|
pc_load <= '0';
|
||||||
stk_push <= '0';
|
stk_push <= '0';
|
||||||
stk_pop <= '0';
|
stk_pop <= '0';
|
||||||
|
|
||||||
case int_state is
|
case int_state is
|
||||||
|
|
||||||
when int_idle =>
|
when int_idle =>
|
||||||
@@ -121,46 +118,10 @@ pin_sample:
|
|||||||
process (clk)
|
process (clk)
|
||||||
begin
|
begin
|
||||||
if rising_edge(clk) then
|
if rising_edge(clk) then
|
||||||
int_sampled <= int_in xor (not ctrl_in.polarity);
|
int_request <= '0';
|
||||||
end if;
|
if ctrl_in.enable = '1' then
|
||||||
end process;
|
int_request <= int_in;
|
||||||
|
end if;
|
||||||
-----------------------------------------------------------------------
|
|
||||||
pin_fsm:
|
|
||||||
process (pin_state, int_sampled, int_ack, ctrl_in)
|
|
||||||
begin
|
|
||||||
int_request <= '0';
|
|
||||||
pin_state_next <= pin_state;
|
|
||||||
case pin_state is
|
|
||||||
when pin_s0 =>
|
|
||||||
if int_sampled = '1' or ctrl_in.request = '1' then
|
|
||||||
if ctrl_in.enable = '1' then
|
|
||||||
pin_state_next <= pin_s1;
|
|
||||||
end if;
|
|
||||||
end if;
|
|
||||||
when pin_s1 =>
|
|
||||||
int_request <= '1';
|
|
||||||
if int_ack = '1' then
|
|
||||||
pin_state_next <= pin_s2;
|
|
||||||
end if;
|
|
||||||
when pin_s2 =>
|
|
||||||
if ctrl_in.edge_sens = '0' then
|
|
||||||
pin_state_next <= pin_s0;
|
|
||||||
elsif int_sampled = '0' then
|
|
||||||
pin_state_next <= pin_s0;
|
|
||||||
end if;
|
|
||||||
when others =>
|
|
||||||
pin_state_next <= pin_s0;
|
|
||||||
end case;
|
|
||||||
end process;
|
|
||||||
|
|
||||||
pin_states:
|
|
||||||
process (rst, clk, pin_state_next)
|
|
||||||
begin
|
|
||||||
if rst = '1' then
|
|
||||||
pin_state <= pin_s0;
|
|
||||||
elsif rising_edge(clk) then
|
|
||||||
pin_state <= pin_state_next;
|
|
||||||
end if;
|
end if;
|
||||||
end process;
|
end process;
|
||||||
|
|
||||||
|
|||||||
@@ -34,7 +34,6 @@ entity cpu_embedded is
|
|||||||
ce : in STD_LOGIC;
|
ce : in STD_LOGIC;
|
||||||
int_in : in STD_LOGIC;
|
int_in : in STD_LOGIC;
|
||||||
int_ack : out STD_LOGIC;
|
int_ack : out STD_LOGIC;
|
||||||
xmem_wait : in STD_LOGIC;
|
|
||||||
xmem_we : out STD_LOGIC;
|
xmem_we : out STD_LOGIC;
|
||||||
xmem_re : out STD_LOGIC;
|
xmem_re : out STD_LOGIC;
|
||||||
xmem_din : in unsigned (DMEM_DATA_WIDTH-1 downto 0);
|
xmem_din : in unsigned (DMEM_DATA_WIDTH-1 downto 0);
|
||||||
@@ -56,7 +55,6 @@ architecture rtl of cpu_embedded is
|
|||||||
ce : in STD_LOGIC;
|
ce : in STD_LOGIC;
|
||||||
int_in : in STD_LOGIC;
|
int_in : in STD_LOGIC;
|
||||||
int_ack : out STD_LOGIC;
|
int_ack : out STD_LOGIC;
|
||||||
xmem_wait : in STD_LOGIC;
|
|
||||||
xmem_we : out STD_LOGIC;
|
xmem_we : out STD_LOGIC;
|
||||||
xmem_re : out STD_LOGIC;
|
xmem_re : out STD_LOGIC;
|
||||||
instr_din : in unsigned (IMEM_DATA_WIDTH-1 downto 0);
|
instr_din : in unsigned (IMEM_DATA_WIDTH-1 downto 0);
|
||||||
@@ -87,7 +85,6 @@ inst_cpu: cpu
|
|||||||
ce => ce,
|
ce => ce,
|
||||||
int_in => int_in,
|
int_in => int_in,
|
||||||
int_ack => int_ack,
|
int_ack => int_ack,
|
||||||
xmem_wait => xmem_wait,
|
|
||||||
xmem_we => xmem_we,
|
xmem_we => xmem_we,
|
||||||
xmem_re => xmem_re,
|
xmem_re => xmem_re,
|
||||||
instr_din => irom_data,
|
instr_din => irom_data,
|
||||||
|
|||||||
@@ -26,25 +26,22 @@ use IEEE.STD_LOGIC_1164.ALL;
|
|||||||
USE ieee.numeric_std.ALL;
|
USE ieee.numeric_std.ALL;
|
||||||
|
|
||||||
library work;
|
library work;
|
||||||
use work.types_pkg.all;
|
use work.cpu_pkg.all;
|
||||||
|
|
||||||
-- JASM_ROM_INSERT_HERE
|
-- JASM_ROM_INSERT_HERE
|
||||||
ENTITY irom IS
|
ENTITY irom IS
|
||||||
Generic
|
Port
|
||||||
(
|
(
|
||||||
depth : integer := 4
|
|
||||||
);
|
|
||||||
Port (
|
|
||||||
clk : in STD_LOGIC;
|
clk : in STD_LOGIC;
|
||||||
ce : in STD_LOGIC;
|
ce : in STD_LOGIC;
|
||||||
addr : in addr_t;
|
addr : in inst_addr_t;
|
||||||
dout : out word_t
|
dout : out inst_t
|
||||||
);
|
);
|
||||||
END irom;
|
END irom;
|
||||||
|
|
||||||
ARCHITECTURE itest OF irom IS
|
ARCHITECTURE itest OF irom IS
|
||||||
|
|
||||||
type imem_rom_t is array (0 to depth-1) of word_t;
|
type imem_rom_t is array (0 to 1023) of inst_t;
|
||||||
|
|
||||||
-- Assembled from itest.jsm
|
-- Assembled from itest.jsm
|
||||||
constant imem_rom : imem_rom_t :=
|
constant imem_rom : imem_rom_t :=
|
||||||
|
|||||||
@@ -41,7 +41,6 @@ ARCHITECTURE behavior OF tb_cpu_embedded IS
|
|||||||
ce : in STD_LOGIC;
|
ce : in STD_LOGIC;
|
||||||
int_in : in STD_LOGIC;
|
int_in : in STD_LOGIC;
|
||||||
int_ack : out STD_LOGIC;
|
int_ack : out STD_LOGIC;
|
||||||
xmem_wait : in STD_LOGIC;
|
|
||||||
xmem_we : out STD_LOGIC;
|
xmem_we : out STD_LOGIC;
|
||||||
xmem_re : out STD_LOGIC;
|
xmem_re : out STD_LOGIC;
|
||||||
xmem_din : in unsigned (DMEM_DATA_WIDTH-1 downto 0);
|
xmem_din : in unsigned (DMEM_DATA_WIDTH-1 downto 0);
|
||||||
@@ -58,7 +57,6 @@ ARCHITECTURE behavior OF tb_cpu_embedded IS
|
|||||||
signal ce : std_logic := '0';
|
signal ce : std_logic := '0';
|
||||||
signal int_in : std_logic := '0';
|
signal int_in : std_logic := '0';
|
||||||
signal int_ack : std_logic;
|
signal int_ack : std_logic;
|
||||||
signal xmem_wait : std_logic := '0';
|
|
||||||
signal xmem_din : dmem_data_t := (others => '-');
|
signal xmem_din : dmem_data_t := (others => '-');
|
||||||
signal xmem_dout : dmem_data_t;
|
signal xmem_dout : dmem_data_t;
|
||||||
signal xmem_addr : dmem_addr_t;
|
signal xmem_addr : dmem_addr_t;
|
||||||
@@ -77,7 +75,6 @@ uut: cpu_embedded
|
|||||||
ce => ce,
|
ce => ce,
|
||||||
int_in => int_in,
|
int_in => int_in,
|
||||||
int_ack => int_ack,
|
int_ack => int_ack,
|
||||||
xmem_wait => xmem_wait,
|
|
||||||
xmem_we => xmem_we,
|
xmem_we => xmem_we,
|
||||||
xmem_re => xmem_re,
|
xmem_re => xmem_re,
|
||||||
xmem_din => xmem_din,
|
xmem_din => xmem_din,
|
||||||
|
|||||||
@@ -47,7 +47,6 @@ ARCHITECTURE behavior OF tb_cpu IS
|
|||||||
ce : in STD_LOGIC;
|
ce : in STD_LOGIC;
|
||||||
int_in : in STD_LOGIC;
|
int_in : in STD_LOGIC;
|
||||||
int_ack : out STD_LOGIC;
|
int_ack : out STD_LOGIC;
|
||||||
xmem_wait : in STD_LOGIC;
|
|
||||||
xmem_we : out STD_LOGIC;
|
xmem_we : out STD_LOGIC;
|
||||||
xmem_re : out STD_LOGIC;
|
xmem_re : out STD_LOGIC;
|
||||||
instr_din : in unsigned (IMEM_DATA_WIDTH-1 downto 0);
|
instr_din : in unsigned (IMEM_DATA_WIDTH-1 downto 0);
|
||||||
@@ -77,7 +76,6 @@ ARCHITECTURE behavior OF tb_cpu IS
|
|||||||
signal ce : std_logic := '0';
|
signal ce : std_logic := '0';
|
||||||
signal int_in : std_logic := '0';
|
signal int_in : std_logic := '0';
|
||||||
signal int_ack : std_logic;
|
signal int_ack : std_logic;
|
||||||
signal xmem_wait : std_logic := '1';
|
|
||||||
signal irom_data : unsigned (IMEM_DATA_WIDTH-1 downto 0) := (others => '-');
|
signal irom_data : unsigned (IMEM_DATA_WIDTH-1 downto 0) := (others => '-');
|
||||||
signal irom_addr : unsigned (IMEM_ADDR_WIDTH-1 downto 0);
|
signal irom_addr : unsigned (IMEM_ADDR_WIDTH-1 downto 0);
|
||||||
signal xmem_din : dmem_data_t := (others => '-');
|
signal xmem_din : dmem_data_t := (others => '-');
|
||||||
@@ -112,7 +110,6 @@ uut: cpu
|
|||||||
ce => ce,
|
ce => ce,
|
||||||
int_in => int_in,
|
int_in => int_in,
|
||||||
int_ack => int_ack,
|
int_ack => int_ack,
|
||||||
xmem_wait => xmem_wait,
|
|
||||||
xmem_we => xmem_we,
|
xmem_we => xmem_we,
|
||||||
xmem_re => xmem_re,
|
xmem_re => xmem_re,
|
||||||
instr_din => irom_data,
|
instr_din => irom_data,
|
||||||
@@ -137,21 +134,6 @@ CLK_GEN: process
|
|||||||
clk <= not clk;
|
clk <= not clk;
|
||||||
end process;
|
end process;
|
||||||
|
|
||||||
XWAIT_GEN:process(rst, clk)
|
|
||||||
variable cnt : unsigned(3 downto 0);
|
|
||||||
begin
|
|
||||||
if (rst = '1') then
|
|
||||||
cnt := (others => '1');
|
|
||||||
elsif rising_edge(clk) then
|
|
||||||
if cnt /= "0000" then
|
|
||||||
cnt := cnt - 1;
|
|
||||||
else
|
|
||||||
cnt := (others => '1');
|
|
||||||
xmem_wait <= not xmem_wait;
|
|
||||||
end if;
|
|
||||||
end if;
|
|
||||||
end process;
|
|
||||||
|
|
||||||
STIMULUS: process
|
STIMULUS: process
|
||||||
file RESULT: text open write_mode is "../tools/opc.list";
|
file RESULT: text open write_mode is "../tools/opc.list";
|
||||||
variable L: line;
|
variable L: line;
|
||||||
|
|||||||
@@ -1,6 +0,0 @@
|
|||||||
vlib simprim
|
|
||||||
|
|
||||||
vcom -93 -work simprim F:/Xilinx9/vhdl/src/simprims/simprim_Vcomponents_mti.vhd
|
|
||||||
vcom -93 -work simprim F:/Xilinx9/vhdl/src/simprims/simprim_Vpackage_mti.vhd
|
|
||||||
vcom -93 -work simprim F:/Xilinx9/vhdl/src/simprims/simprim_SMODEL_mti.vhd
|
|
||||||
vcom -93 -work simprim F:/Xilinx9/vhdl/src/simprims/simprim_VITAL_mti.vhd
|
|
||||||
@@ -1,6 +0,0 @@
|
|||||||
vlib unisim
|
|
||||||
|
|
||||||
vcom -93 -work unisim F:/Xilinx9/vhdl/src/unisims/unisim_vpkg.vhd
|
|
||||||
vcom -93 -work unisim F:/Xilinx9/vhdl/src/unisims/unisim_vcomp.vhd
|
|
||||||
vcom -93 -work unisim F:/Xilinx9/vhdl/src/unisims/unisim_smodel.vhd
|
|
||||||
vcom -93 -work unisim F:/Xilinx9/vhdl/src/unisims/unisim_vital.vhd
|
|
||||||
@@ -1,13 +0,0 @@
|
|||||||
## NOTE: Do not edit this file.
|
|
||||||
##
|
|
||||||
vlib work
|
|
||||||
vcom -explicit -93 "../src/core/mips_types.vhd"
|
|
||||||
vcom -explicit -93 "../src/core/mips_instr.vhd"
|
|
||||||
vcom -explicit -93 "../src/tb_eval_muldiv.vhd"
|
|
||||||
vsim -t 1ps -lib work tb_eval_muldiv
|
|
||||||
do {tb_eval_muldiv.wdo}
|
|
||||||
view wave
|
|
||||||
|
|
||||||
view structure
|
|
||||||
view signals
|
|
||||||
run 2400ns
|
|
||||||
@@ -1,27 +0,0 @@
|
|||||||
onerror {resume}
|
|
||||||
quietly WaveActivateNextPane {} 0
|
|
||||||
add wave -noupdate -format Logic /tb_eval_muldiv/clk
|
|
||||||
add wave -noupdate -format Literal -radix hexadecimal /tb_eval_muldiv/op1_in
|
|
||||||
add wave -noupdate -format Literal -radix hexadecimal /tb_eval_muldiv/op2_in
|
|
||||||
add wave -noupdate -format Literal -radix hexadecimal /tb_eval_muldiv/pp0
|
|
||||||
add wave -noupdate -format Literal -radix hexadecimal /tb_eval_muldiv/pp1
|
|
||||||
add wave -noupdate -format Literal -radix hexadecimal /tb_eval_muldiv/pp2
|
|
||||||
add wave -noupdate -format Literal -radix hexadecimal /tb_eval_muldiv/pp3
|
|
||||||
add wave -noupdate -format Literal -radix hexadecimal /tb_eval_muldiv/result
|
|
||||||
add wave -noupdate -format Literal -radix hexadecimal /tb_eval_muldiv/result_reg
|
|
||||||
TreeUpdate [SetDefaultTree]
|
|
||||||
WaveRestoreCursors {{Cursor 1} {693234 ps} 0} {{Cursor 2} {290409 ps} 0}
|
|
||||||
configure wave -namecolwidth 149
|
|
||||||
configure wave -valuecolwidth 171
|
|
||||||
configure wave -justifyvalue left
|
|
||||||
configure wave -signalnamewidth 1
|
|
||||||
configure wave -snapdistance 10
|
|
||||||
configure wave -datasetprefix 0
|
|
||||||
configure wave -rowmargin 4
|
|
||||||
configure wave -childrowmargin 2
|
|
||||||
configure wave -gridoffset 0
|
|
||||||
configure wave -gridperiod 100
|
|
||||||
configure wave -griddelta 40
|
|
||||||
configure wave -timeline 1
|
|
||||||
update
|
|
||||||
WaveRestoreZoom {0 ps} {2520 ns}
|
|
||||||
@@ -1,22 +0,0 @@
|
|||||||
## NOTE: Do not edit this file.
|
|
||||||
##
|
|
||||||
vlib work
|
|
||||||
vcom -explicit -93 "../src/core/mips_types.vhd"
|
|
||||||
vcom -explicit -93 "../src/core/mips_instr.vhd"
|
|
||||||
vcom -explicit -93 "../src/core/mips_idecode_rom.vhd"
|
|
||||||
vcom -explicit -93 "../src/core/mips_reg.vhd"
|
|
||||||
vcom -explicit -93 "../src/core/mips_shifter.vhd"
|
|
||||||
vcom -explicit -93 "../src/core/mips_alu.vhd"
|
|
||||||
vcom -explicit -93 "../src/core/mips_bcu.vhd"
|
|
||||||
vcom -explicit -93 "../src/core/mips_pipeline.vhd"
|
|
||||||
vcom -explicit -93 "../src/core/mips_top.vhd"
|
|
||||||
vcom -explicit -93 "../src/ram.vhd"
|
|
||||||
vcom -explicit -93 "../asm/fibonacci.vhd"
|
|
||||||
vcom -explicit -93 "../src/mips_embedded.vhd"
|
|
||||||
vcom -explicit -93 "../src/tb_mips_embedded.vhd"
|
|
||||||
vsim -t 1ps -lib work tb_mips_embedded
|
|
||||||
do {tb_mips_embedded.wdo}
|
|
||||||
view wave
|
|
||||||
view structure
|
|
||||||
view signals
|
|
||||||
run 20us
|
|
||||||
@@ -1,41 +0,0 @@
|
|||||||
onerror {resume}
|
|
||||||
quietly WaveActivateNextPane {} 0
|
|
||||||
add wave -noupdate -format Logic /tb_mips_embedded/rst
|
|
||||||
add wave -noupdate -format Logic /tb_mips_embedded/clk
|
|
||||||
add wave -noupdate -format Logic /tb_mips_embedded/uut/inst_mips_top/inst_pipeline/exception
|
|
||||||
add wave -noupdate -format Literal -radix hexadecimal -expand /tb_mips_embedded/uut/inst_mips_top/inst_pipeline/pc
|
|
||||||
add wave -noupdate -format Literal -radix hexadecimal /tb_mips_embedded/dout
|
|
||||||
add wave -noupdate -format Literal -radix hexadecimal /tb_mips_embedded/uut/inst_ram/sram
|
|
||||||
add wave -noupdate -format Literal -radix hexadecimal /tb_mips_embedded/uut/dmem_addr
|
|
||||||
add wave -noupdate -format Literal -radix hexadecimal /tb_mips_embedded/uut/dmem_din
|
|
||||||
add wave -noupdate -format Literal -radix hexadecimal /tb_mips_embedded/uut/dmem_dout
|
|
||||||
add wave -noupdate -format Logic -radix hexadecimal /tb_mips_embedded/uut/dmem_re
|
|
||||||
add wave -noupdate -format Logic -radix hexadecimal /tb_mips_embedded/uut/dmem_we
|
|
||||||
add wave -noupdate -format Literal -radix hexadecimal /tb_mips_embedded/uut/imem_addr
|
|
||||||
add wave -noupdate -format Literal -radix hexadecimal /tb_mips_embedded/uut/imem_din
|
|
||||||
add wave -noupdate -format Logic /tb_mips_embedded/clk
|
|
||||||
add wave -noupdate -format Literal -radix hexadecimal /tb_mips_embedded/uut/inst_mips_top/inst_pipeline/id_stage
|
|
||||||
add wave -noupdate -format Logic /tb_mips_embedded/clk
|
|
||||||
add wave -noupdate -format Literal -radix hexadecimal -expand /tb_mips_embedded/uut/inst_mips_top/inst_pipeline/ex_stage
|
|
||||||
add wave -noupdate -format Logic /tb_mips_embedded/clk
|
|
||||||
add wave -noupdate -format Literal -radix hexadecimal -expand /tb_mips_embedded/uut/inst_mips_top/inst_pipeline/mem_stage
|
|
||||||
add wave -noupdate -format Logic /tb_mips_embedded/clk
|
|
||||||
add wave -noupdate -format Literal -radix hexadecimal -expand /tb_mips_embedded/uut/inst_mips_top/inst_pipeline/wb_stage
|
|
||||||
add wave -noupdate -format Logic /tb_mips_embedded/clk
|
|
||||||
add wave -noupdate -format Literal /tb_mips_embedded/uut/inst_mips_top/inst_pipeline/hdu
|
|
||||||
TreeUpdate [SetDefaultTree]
|
|
||||||
WaveRestoreCursors {{Cursor 1} {624000 ps} 0}
|
|
||||||
configure wave -namecolwidth 150
|
|
||||||
configure wave -valuecolwidth 100
|
|
||||||
configure wave -justifyvalue left
|
|
||||||
configure wave -signalnamewidth 1
|
|
||||||
configure wave -snapdistance 10
|
|
||||||
configure wave -datasetprefix 0
|
|
||||||
configure wave -rowmargin 4
|
|
||||||
configure wave -childrowmargin 2
|
|
||||||
configure wave -gridoffset 0
|
|
||||||
configure wave -gridperiod 100
|
|
||||||
configure wave -griddelta 40
|
|
||||||
configure wave -timeline 1
|
|
||||||
update
|
|
||||||
WaveRestoreZoom {0 ps} {2520 ns}
|
|
||||||
@@ -1,31 +0,0 @@
|
|||||||
## NOTE: Do not edit this file.
|
|
||||||
##
|
|
||||||
vlib work
|
|
||||||
vcom -explicit -93 "../src/core/mips_types.vhd"
|
|
||||||
vcom -explicit -93 "../src/core/mips_instr.vhd"
|
|
||||||
vcom -explicit -93 "../src/core/mips_idecode_rom.vhd"
|
|
||||||
vcom -explicit -93 "../src/core/mips_reg.vhd"
|
|
||||||
vcom -explicit -93 "../src/core/mips_shifter.vhd"
|
|
||||||
vcom -explicit -93 "../src/core/mips_alu.vhd"
|
|
||||||
vcom -explicit -93 "../src/core/mips_bcu.vhd"
|
|
||||||
vcom -explicit -93 "../src/core/mips_pipeline.vhd"
|
|
||||||
vcom -explicit -93 "../src/core/mips_muldiv.vhd"
|
|
||||||
vcom -explicit -93 "../src/core/mips_cop.vhd"
|
|
||||||
vcom -explicit -93 "../src/core/mips_bui.vhd"
|
|
||||||
vcom -explicit -93 "../src/core/mips_top.vhd"
|
|
||||||
vcom -explicit -93 "../src/core/dcache.vhd"
|
|
||||||
vcom -explicit -93 "../asm/testbench.ROM.vhd"
|
|
||||||
vcom -explicit -93 "../src/mips_embedded.vhd"
|
|
||||||
vcom -explicit -93 "../src/mips_embedded_syn.vhd"
|
|
||||||
vcom -explicit -93 "../../../uart/bbfifo_16x8.vhd"
|
|
||||||
vcom -explicit -93 "../../../uart/kcuart_rx.vhd"
|
|
||||||
vcom -explicit -93 "../../../uart/kcuart_tx.vhd"
|
|
||||||
vcom -explicit -93 "../../../uart/uart_rx.vhd"
|
|
||||||
vcom -explicit -93 "../../../uart/uart_tx.vhd"
|
|
||||||
vcom -explicit -93 "../src/tb_mips_embedded_syn.vhd"
|
|
||||||
vsim -t 1ps -lib work tb_mips_embedded_syn
|
|
||||||
do {tb_mips_embedded_syn.wdo}
|
|
||||||
view wave
|
|
||||||
view structure
|
|
||||||
view signals
|
|
||||||
run 100us
|
|
||||||
@@ -1,13 +0,0 @@
|
|||||||
## NOTE: Do not edit this file.
|
|
||||||
##
|
|
||||||
vlib work
|
|
||||||
|
|
||||||
vcom -explicit -93 "../syn/ise9/netgen/par/mips_embedded_syn_timesim.vhd"
|
|
||||||
vcom -explicit -93 "../src/tb_mips_embedded_syn.vhd"
|
|
||||||
vsim -t 1ps -sdfmax "/uut=../syn/ise9/netgen/par/mips_embedded_syn_timesim.sdf" -lib work tb_mips_embedded_syn
|
|
||||||
do {tb_mips_embedded_syn.wdo}
|
|
||||||
view wave
|
|
||||||
#add wave *
|
|
||||||
view structure
|
|
||||||
view signals
|
|
||||||
run 2400ns
|
|
||||||
@@ -1,112 +0,0 @@
|
|||||||
onerror {resume}
|
|
||||||
quietly WaveActivateNextPane {} 0
|
|
||||||
add wave -noupdate -format Logic /tb_mips_embedded_syn/uut/sys_rx
|
|
||||||
add wave -noupdate -format Logic /tb_mips_embedded_syn/uut/sys_tx
|
|
||||||
add wave -noupdate -format Logic /tb_mips_embedded_syn/sys_rst_n_in
|
|
||||||
add wave -noupdate -format Logic /tb_mips_embedded_syn/sys_clk_in
|
|
||||||
add wave -noupdate -format Literal /tb_mips_embedded_syn/sys_led
|
|
||||||
add wave -noupdate -format Literal /tb_mips_embedded_syn/sys_dip
|
|
||||||
add wave -noupdate -format Literal /tb_mips_embedded_syn/sys_btn
|
|
||||||
add wave -noupdate -format Literal /tb_mips_embedded_syn/sys_error
|
|
||||||
add wave -noupdate -format Logic /tb_mips_embedded_syn/uut/inst_mips_embedded/inst_mips_top/inst_pipeline/cpu_rst
|
|
||||||
add wave -noupdate -format Logic /tb_mips_embedded_syn/uut/inst_mips_embedded/inst_mips_top/inst_pipeline/cpu_run
|
|
||||||
add wave -noupdate -format Literal -radix hexadecimal /tb_mips_embedded_syn/uut/inst_mips_embedded/reg_uart_rx
|
|
||||||
add wave -noupdate -format Literal -radix hexadecimal /tb_mips_embedded_syn/uut/inst_mips_embedded/reg_uart_tx
|
|
||||||
add wave -noupdate -format Literal -radix hexadecimal /tb_mips_embedded_syn/uut/inst_mips_embedded/reg_uart_ctrl
|
|
||||||
add wave -noupdate -format Literal -radix hexadecimal /tb_mips_embedded_syn/uut/inst_mips_embedded/reg_uart_baud
|
|
||||||
add wave -noupdate -format Literal -radix hexadecimal /tb_mips_embedded_syn/uut/inst_mips_embedded/uart_status_port
|
|
||||||
add wave -noupdate -format Literal -radix decimal /tb_mips_embedded_syn/uut/inst_mips_embedded/cnt_usec
|
|
||||||
add wave -noupdate -format Logic /tb_mips_embedded_syn/uut/inst_mips_embedded/cnt_usec_en
|
|
||||||
add wave -noupdate -format Literal -radix hexadecimal /tb_mips_embedded_syn/uut/inst_mips_embedded/cnt_sec
|
|
||||||
add wave -noupdate -format Logic /tb_mips_embedded_syn/uut/inst_mips_embedded/inst_mips_top/mem_rdy
|
|
||||||
add wave -noupdate -format Logic /tb_mips_embedded_syn/uut/inst_mips_embedded/inst_mips_top/mem_en
|
|
||||||
add wave -noupdate -format Logic /tb_mips_embedded_syn/uut/inst_mips_embedded/inst_mips_top/mem_re
|
|
||||||
add wave -noupdate -format Literal /tb_mips_embedded_syn/uut/inst_mips_embedded/inst_mips_top/mem_we
|
|
||||||
add wave -noupdate -format Literal -radix hexadecimal /tb_mips_embedded_syn/uut/inst_mips_embedded/inst_mips_top/mem_addr
|
|
||||||
add wave -noupdate -format Literal -radix hexadecimal /tb_mips_embedded_syn/uut/inst_mips_embedded/inst_mips_top/mem_din
|
|
||||||
add wave -noupdate -format Literal -radix hexadecimal /tb_mips_embedded_syn/uut/inst_mips_embedded/inst_mips_top/mem_dout
|
|
||||||
add wave -noupdate -format Literal /tb_mips_embedded_syn/uut/inst_mips_embedded/inst_mips_top/inst_bui/s
|
|
||||||
add wave -noupdate -divider DMEM
|
|
||||||
add wave -noupdate -format Logic /tb_mips_embedded_syn/uut/inst_mips_embedded/inst_mips_top/inst_pipeline/clk
|
|
||||||
add wave -noupdate -format Literal -radix hexadecimal /tb_mips_embedded_syn/uut/inst_mips_embedded/inst_mips_top/dmem_addr
|
|
||||||
add wave -noupdate -format Literal -radix hexadecimal /tb_mips_embedded_syn/uut/inst_mips_embedded/inst_mips_top/dmem_din
|
|
||||||
add wave -noupdate -format Literal -radix hexadecimal /tb_mips_embedded_syn/uut/inst_mips_embedded/inst_mips_top/dmem_dout
|
|
||||||
add wave -noupdate -format Logic /tb_mips_embedded_syn/uut/inst_mips_embedded/inst_mips_top/dmem_en
|
|
||||||
add wave -noupdate -format Literal /tb_mips_embedded_syn/uut/inst_mips_embedded/inst_mips_top/dmem_we
|
|
||||||
add wave -noupdate -divider IMEM
|
|
||||||
add wave -noupdate -format Logic /tb_mips_embedded_syn/uut/inst_mips_embedded/inst_mips_top/inst_pipeline/clk
|
|
||||||
add wave -noupdate -format Literal -radix hexadecimal /tb_mips_embedded_syn/uut/inst_mips_embedded/inst_mips_top/inst_pipeline/imem_addr
|
|
||||||
add wave -noupdate -format Literal -radix hexadecimal /tb_mips_embedded_syn/uut/inst_mips_embedded/inst_mips_top/imem_din
|
|
||||||
add wave -noupdate -format Logic /tb_mips_embedded_syn/uut/inst_mips_embedded/inst_mips_top/imem_en
|
|
||||||
add wave -noupdate -format Logic /tb_mips_embedded_syn/uut/inst_mips_embedded/inst_mips_top/inst_pipeline/pc_run
|
|
||||||
add wave -noupdate -divider PC
|
|
||||||
add wave -noupdate -format Logic /tb_mips_embedded_syn/uut/inst_mips_embedded/inst_mips_top/inst_pipeline/clk
|
|
||||||
add wave -noupdate -format Literal -radix hexadecimal /tb_mips_embedded_syn/uut/inst_mips_embedded/inst_mips_top/inst_pipeline/pc
|
|
||||||
add wave -noupdate -format Literal /tb_mips_embedded_syn/uut/inst_mips_embedded/inst_mips_top/inst_pipeline/hdu
|
|
||||||
add wave -noupdate -divider Stages
|
|
||||||
add wave -noupdate -format Logic /tb_mips_embedded_syn/uut/inst_mips_embedded/inst_mips_top/inst_pipeline/clk
|
|
||||||
add wave -noupdate -format Logic /tb_mips_embedded_syn/uut/inst_mips_embedded/inst_mips_top/inst_pipeline/clk
|
|
||||||
add wave -noupdate -format Logic /tb_mips_embedded_syn/uut/inst_mips_embedded/inst_mips_top/inst_pipeline/clk
|
|
||||||
add wave -noupdate -format Logic /tb_mips_embedded_syn/uut/halt
|
|
||||||
add wave -noupdate -format Literal /tb_mips_embedded_syn/uut/inst_mips_embedded/inst_mips_top/inst_pipeline/inst_reg_dual_a/reg_mem
|
|
||||||
add wave -noupdate -divider Cop
|
|
||||||
add wave -noupdate -format Logic /tb_mips_embedded_syn/uut/inst_mips_embedded/inst_mips_top/inst_pipeline/inst_cop/ir_valid
|
|
||||||
add wave -noupdate -format Literal -radix hexadecimal /tb_mips_embedded_syn/uut/inst_mips_embedded/inst_mips_top/inst_pipeline/inst_cop/cop_pipe_id
|
|
||||||
add wave -noupdate -format Literal -radix hexadecimal /tb_mips_embedded_syn/uut/inst_mips_embedded/inst_mips_top/inst_pipeline/inst_cop/cop_pipe_ex
|
|
||||||
add wave -noupdate -format Logic /tb_mips_embedded_syn/uut/inst_mips_embedded/inst_mips_top/inst_pipeline/inst_cop/cop_ex_en
|
|
||||||
add wave -noupdate -format Literal -radix hexadecimal /tb_mips_embedded_syn/uut/inst_mips_embedded/inst_mips_top/inst_pipeline/inst_cop/ctrl_in
|
|
||||||
add wave -noupdate -format Literal -radix hexadecimal -expand /tb_mips_embedded_syn/uut/inst_mips_embedded/inst_mips_top/inst_pipeline/inst_cop/ctrl_out
|
|
||||||
add wave -noupdate -format Logic /tb_mips_embedded_syn/uut/inst_mips_embedded/inst_mips_top/inst_pipeline/inst_cop/exc_entered
|
|
||||||
add wave -noupdate -format Literal -radix hexadecimal /tb_mips_embedded_syn/uut/inst_mips_embedded/inst_mips_top/inst_pipeline/inst_cop/din
|
|
||||||
add wave -noupdate -format Literal -radix hexadecimal /tb_mips_embedded_syn/uut/inst_mips_embedded/inst_mips_top/inst_pipeline/inst_cop/dout
|
|
||||||
add wave -noupdate -format Literal -radix hexadecimal /tb_mips_embedded_syn/uut/inst_mips_embedded/inst_mips_top/inst_pipeline/inst_cop/epc
|
|
||||||
add wave -noupdate -format Literal -radix hexadecimal /tb_mips_embedded_syn/uut/inst_mips_embedded/inst_mips_top/inst_pipeline/inst_cop/cause
|
|
||||||
add wave -noupdate -format Logic /tb_mips_embedded_syn/uut/inst_mips_embedded/inst_mips_top/inst_pipeline/inst_cop/test_reg_we
|
|
||||||
add wave -noupdate -format Literal -radix hexadecimal /tb_mips_embedded_syn/uut/inst_mips_embedded/inst_mips_top/inst_pipeline/inst_cop/test_reg
|
|
||||||
add wave -noupdate -format Logic /tb_mips_embedded_syn/uut/inst_mips_embedded/inst_mips_top/inst_pipeline/inst_cop/stat_reg_we
|
|
||||||
add wave -noupdate -format Literal -radix hexadecimal /tb_mips_embedded_syn/uut/inst_mips_embedded/inst_mips_top/inst_pipeline/inst_cop/status
|
|
||||||
add wave -noupdate -format Literal /tb_mips_embedded_syn/uut/inst_mips_embedded/inst_mips_top/inst_pipeline/events
|
|
||||||
add wave -noupdate -format Literal /tb_mips_embedded_syn/uut/inst_mips_embedded/inst_mips_top/inst_pipeline/inst_cop/eflags
|
|
||||||
add wave -noupdate -format Literal -radix hexadecimal /tb_mips_embedded_syn/uut/inst_mips_embedded/inst_mips_top/inst_pipeline/inst_cop/badvaddr
|
|
||||||
add wave -noupdate -format Logic /tb_mips_embedded_syn/uut/inst_mips_embedded/inst_mips_top/inst_pipeline/inst_cop/rst
|
|
||||||
add wave -noupdate -format Logic /tb_mips_embedded_syn/uut/inst_mips_embedded/inst_mips_top/inst_pipeline/inst_cop/exception
|
|
||||||
add wave -noupdate -format Logic /tb_mips_embedded_syn/uut/inst_mips_embedded/inst_mips_top/inst_pipeline/inst_cop/status_save
|
|
||||||
add wave -noupdate -format Logic /tb_mips_embedded_syn/uut/inst_mips_embedded/inst_mips_top/inst_pipeline/inst_cop/status_rest
|
|
||||||
add wave -noupdate -format Logic /tb_mips_embedded_syn/uut/inst_mips_embedded/inst_mips_top/inst_pipeline/inst_cop/exc_strobe
|
|
||||||
add wave -noupdate -format Literal /tb_mips_embedded_syn/uut/inst_mips_embedded/inst_mips_top/inst_pipeline/inst_cop/ip
|
|
||||||
add wave -noupdate -divider Stages
|
|
||||||
add wave -noupdate -format Literal -radix hexadecimal /tb_mips_embedded_syn/uut/inst_mips_embedded/inst_mips_top/inst_pipeline/id_stage
|
|
||||||
add wave -noupdate -format Logic /tb_mips_embedded_syn/uut/inst_mips_embedded/inst_mips_top/inst_pipeline/clk
|
|
||||||
add wave -noupdate -format Literal -radix hexadecimal /tb_mips_embedded_syn/uut/inst_mips_embedded/inst_mips_top/inst_pipeline/dmem_addr
|
|
||||||
add wave -noupdate -format Literal -radix hexadecimal /tb_mips_embedded_syn/uut/inst_mips_embedded/inst_mips_top/inst_pipeline/dmem_din
|
|
||||||
add wave -noupdate -format Literal -radix hexadecimal /tb_mips_embedded_syn/uut/inst_mips_embedded/inst_mips_top/inst_pipeline/dmem_dout
|
|
||||||
add wave -noupdate -format Literal -radix hexadecimal -expand /tb_mips_embedded_syn/uut/inst_mips_embedded/inst_mips_top/inst_pipeline/ex_stage
|
|
||||||
add wave -noupdate -format Logic /tb_mips_embedded_syn/uut/inst_mips_embedded/inst_mips_top/inst_pipeline/clk
|
|
||||||
add wave -noupdate -format Literal -radix hexadecimal -expand /tb_mips_embedded_syn/uut/inst_mips_embedded/inst_mips_top/inst_pipeline/mem_stage
|
|
||||||
add wave -noupdate -format Logic /tb_mips_embedded_syn/uut/inst_mips_embedded/inst_mips_top/inst_pipeline/clk
|
|
||||||
add wave -noupdate -format Literal -radix hexadecimal -expand /tb_mips_embedded_syn/uut/inst_mips_embedded/inst_mips_top/inst_pipeline/wb_stage
|
|
||||||
add wave -noupdate -divider Muldiv
|
|
||||||
add wave -noupdate -format Logic /tb_mips_embedded_syn/uut/inst_mips_embedded/inst_mips_top/inst_pipeline/inst_muldiv/clk
|
|
||||||
add wave -noupdate -format Literal -radix hexadecimal /tb_mips_embedded_syn/uut/inst_mips_embedded/inst_mips_top/inst_pipeline/inst_muldiv/dout
|
|
||||||
add wave -noupdate -format Literal -radix hexadecimal /tb_mips_embedded_syn/uut/inst_mips_embedded/inst_mips_top/inst_pipeline/inst_muldiv/result
|
|
||||||
add wave -noupdate -format Logic /tb_mips_embedded_syn/uut/inst_mips_embedded/inst_mips_top/inst_pipeline/inst_muldiv/start
|
|
||||||
add wave -noupdate -format Logic /tb_mips_embedded_syn/uut/inst_mips_embedded/inst_mips_top/inst_pipeline/inst_muldiv/busy
|
|
||||||
add wave -noupdate -format Logic /tb_mips_embedded_syn/uut/inst_mips_embedded/inst_mips_top/inst_pipeline/inst_muldiv/hilo_sel
|
|
||||||
add wave -noupdate -format Literal -radix hexadecimal /tb_mips_embedded_syn/uut/inst_mips_embedded/inst_mips_top/inst_pipeline/inst_muldiv/din_hi
|
|
||||||
add wave -noupdate -format Literal -radix hexadecimal /tb_mips_embedded_syn/uut/inst_mips_embedded/inst_mips_top/inst_pipeline/inst_muldiv/din_lo
|
|
||||||
TreeUpdate [SetDefaultTree]
|
|
||||||
WaveRestoreCursors {{Cursor 1} {1121030000 ps} 0} {{Cursor 2} {1436367 ps} 0} {{Cursor 3} {1122030000 ps} 0}
|
|
||||||
configure wave -namecolwidth 179
|
|
||||||
configure wave -valuecolwidth 89
|
|
||||||
configure wave -justifyvalue left
|
|
||||||
configure wave -signalnamewidth 1
|
|
||||||
configure wave -snapdistance 10
|
|
||||||
configure wave -datasetprefix 0
|
|
||||||
configure wave -rowmargin 4
|
|
||||||
configure wave -childrowmargin 2
|
|
||||||
configure wave -gridoffset 0
|
|
||||||
configure wave -gridperiod 100
|
|
||||||
configure wave -griddelta 40
|
|
||||||
configure wave -timeline 1
|
|
||||||
update
|
|
||||||
WaveRestoreZoom {1351336 ps} {1583596 ps}
|
|
||||||
@@ -1,15 +0,0 @@
|
|||||||
## NOTE: Do not edit this file.
|
|
||||||
##
|
|
||||||
vlib work
|
|
||||||
vcom -explicit -93 "../../../PCK_FIO-1.16/PCK_FIO.vhd"
|
|
||||||
vcom -explicit -93 "../src/core/mips_types.vhd"
|
|
||||||
vcom -explicit -93 "../src/core/mips_instr.vhd"
|
|
||||||
vcom -explicit -93 "../src/core/mips_muldiv.vhd"
|
|
||||||
vcom -explicit -93 "../src/tb_mips_muldiv.vhd"
|
|
||||||
vsim -t 1ps -lib work tb_mips_muldiv
|
|
||||||
do {tb_mips_muldiv.wdo}
|
|
||||||
view wave
|
|
||||||
|
|
||||||
view structure
|
|
||||||
view signals
|
|
||||||
run 5000us
|
|
||||||
@@ -1,19 +0,0 @@
|
|||||||
## NOTE: Do not edit this file.
|
|
||||||
## Auto generated by Project Navigator for Post-Translate Simulation
|
|
||||||
##
|
|
||||||
vlib work
|
|
||||||
## Compile Post-Translate Model
|
|
||||||
vcom -explicit -93 "../syn/eval_muldiv/netgen/translate/muldiv_translate.vhd"
|
|
||||||
vcom -explicit -93 "../../../PCK_FIO-1.16/PCK_FIO.vhd"
|
|
||||||
vcom -explicit -93 "../src/core/mips_types.vhd"
|
|
||||||
vcom -explicit -93 "../src/core/mips_instr.vhd"
|
|
||||||
vcom -explicit -93 "../src/tb_mips_muldiv.vhd"
|
|
||||||
|
|
||||||
vsim -t 1ps -lib work tb_mips_muldiv
|
|
||||||
#do {tb_mips_muldiv.udo}
|
|
||||||
view wave
|
|
||||||
add wave *
|
|
||||||
view structure
|
|
||||||
view signals
|
|
||||||
run 1000ns
|
|
||||||
## End
|
|
||||||
@@ -1,19 +0,0 @@
|
|||||||
## NOTE: Do not edit this file.
|
|
||||||
## Auto generated by Project Navigator for Post-Translate Simulation
|
|
||||||
##
|
|
||||||
vlib work
|
|
||||||
## Compile Post-Translate Model
|
|
||||||
vcom -explicit -93 "../syn/eval_muldiv/netgen/synthesis/muldiv_synthesis.vhd"
|
|
||||||
vcom -explicit -93 "../../../PCK_FIO-1.16/PCK_FIO.vhd"
|
|
||||||
vcom -explicit -93 "../src/core/mips_types.vhd"
|
|
||||||
vcom -explicit -93 "../src/core/mips_instr.vhd"
|
|
||||||
vcom -explicit -93 "../src/tb_mips_muldiv.vhd"
|
|
||||||
|
|
||||||
vsim -t 1ps -lib work tb_mips_muldiv
|
|
||||||
do {tb_mips_muldiv.wdo}
|
|
||||||
view wave
|
|
||||||
#add wave *
|
|
||||||
view structure
|
|
||||||
view signals
|
|
||||||
run 1000ns
|
|
||||||
## End
|
|
||||||
@@ -1,79 +0,0 @@
|
|||||||
onerror {resume}
|
|
||||||
quietly WaveActivateNextPane {} 0
|
|
||||||
add wave -noupdate -format Logic /tb_mips_muldiv/rst
|
|
||||||
add wave -noupdate -format Logic /tb_mips_muldiv/clk
|
|
||||||
add wave -noupdate -format Logic /tb_mips_muldiv/mul_divn
|
|
||||||
add wave -noupdate -format Logic /tb_mips_muldiv/start
|
|
||||||
add wave -noupdate -format Logic /tb_mips_muldiv/busy
|
|
||||||
add wave -noupdate -format Logic /tb_mips_muldiv/s_un
|
|
||||||
add wave -noupdate -format Literal -radix hexadecimal /tb_mips_muldiv/uut/din_hi
|
|
||||||
add wave -noupdate -format Literal -radix hexadecimal /tb_mips_muldiv/uut/din_lo
|
|
||||||
add wave -noupdate -format Logic /tb_mips_muldiv/hilo_sel
|
|
||||||
add wave -noupdate -format Logic /tb_mips_muldiv/hilo_we
|
|
||||||
add wave -noupdate -format Literal -radix hexadecimal /tb_mips_muldiv/dout
|
|
||||||
add wave -noupdate -format Literal -radix hexadecimal /tb_mips_muldiv/result
|
|
||||||
add wave -noupdate -format Literal -radix hexadecimal /tb_mips_muldiv/uut/result
|
|
||||||
add wave -noupdate -format Literal -radix hexadecimal /tb_mips_muldiv/ref_result
|
|
||||||
add wave -noupdate -format Literal -radix hexadecimal /tb_mips_muldiv/ref_hi
|
|
||||||
add wave -noupdate -format Literal -radix hexadecimal /tb_mips_muldiv/ref_lo
|
|
||||||
add wave -noupdate -format Logic /tb_mips_muldiv/uut/pre_sum_vld
|
|
||||||
add wave -noupdate -format Logic /tb_mips_muldiv/uut/mul_en
|
|
||||||
add wave -noupdate -format Logic /tb_mips_muldiv/uut/sum_en
|
|
||||||
add wave -noupdate -divider FSM
|
|
||||||
add wave -noupdate -format Literal /tb_mips_muldiv/uut/cycle_cnt
|
|
||||||
add wave -noupdate -format Logic /tb_mips_muldiv/uut/cycle_cnt_load
|
|
||||||
add wave -noupdate -format Literal /tb_mips_muldiv/uut/cycle_cnt_preset
|
|
||||||
add wave -noupdate -format Literal /tb_mips_muldiv/uut/s
|
|
||||||
add wave -noupdate -format Literal /tb_mips_muldiv/uut/sn
|
|
||||||
add wave -noupdate -divider {Multiplier internals}
|
|
||||||
add wave -noupdate -format Literal -radix hexadecimal -expand /tb_mips_muldiv/uut/pprod
|
|
||||||
add wave -noupdate -format Literal /tb_mips_muldiv/uut/ppadd_cyi
|
|
||||||
add wave -noupdate -format Literal /tb_mips_muldiv/uut/ppadd_cyo
|
|
||||||
add wave -noupdate -format Literal -radix hexadecimal /tb_mips_muldiv/uut/ppadd_op1
|
|
||||||
add wave -noupdate -format Literal -radix hexadecimal /tb_mips_muldiv/uut/ppadd_op2
|
|
||||||
add wave -noupdate -format Literal -radix hexadecimal /tb_mips_muldiv/uut/ppadd_res
|
|
||||||
add wave -noupdate -format Literal -radix hexadecimal /tb_mips_muldiv/uut/pp_op2
|
|
||||||
add wave -noupdate -format Literal -radix hexadecimal /tb_mips_muldiv/uut/pp_op2_r
|
|
||||||
add wave -noupdate -format Literal -radix hexadecimal /tb_mips_muldiv/uut/add_op1
|
|
||||||
add wave -noupdate -format Literal -radix hexadecimal /tb_mips_muldiv/uut/add_op2
|
|
||||||
add wave -noupdate -format Literal -radix hexadecimal /tb_mips_muldiv/uut/add_res
|
|
||||||
add wave -noupdate -format Literal -radix hexadecimal /tb_mips_muldiv/uut/pp_reg
|
|
||||||
add wave -noupdate -divider {Divider internals}
|
|
||||||
add wave -noupdate -format Logic /tb_mips_muldiv/busy
|
|
||||||
add wave -noupdate -format Logic /tb_mips_muldiv/s_un
|
|
||||||
add wave -noupdate -format Logic /tb_mips_muldiv/uut/div_start
|
|
||||||
add wave -noupdate -format Literal -radix hexadecimal /tb_mips_muldiv/uut/din_hi
|
|
||||||
add wave -noupdate -format Literal -radix hexadecimal /tb_mips_muldiv/uut/din_lo
|
|
||||||
add wave -noupdate -format Literal -radix hexadecimal /tb_mips_muldiv/uut/result
|
|
||||||
add wave -noupdate -format Logic /tb_mips_muldiv/uut/div_add_cyi
|
|
||||||
add wave -noupdate -format Literal -radix hexadecimal /tb_mips_muldiv/uut/div_add_op1
|
|
||||||
add wave -noupdate -format Literal -radix hexadecimal /tb_mips_muldiv/uut/div_add_op2
|
|
||||||
add wave -noupdate -format Literal -radix hexadecimal /tb_mips_muldiv/uut/div_add_res
|
|
||||||
add wave -noupdate -format Literal -radix hexadecimal /tb_mips_muldiv/uut/div_m
|
|
||||||
add wave -noupdate -format Literal -radix hexadecimal /tb_mips_muldiv/uut/div_m_n
|
|
||||||
add wave -noupdate -format Literal -radix hexadecimal /tb_mips_muldiv/uut/div_a
|
|
||||||
add wave -noupdate -format Literal -radix hexadecimal /tb_mips_muldiv/uut/div_q
|
|
||||||
add wave -noupdate -format Logic /tb_mips_muldiv/uut/div_qbit
|
|
||||||
add wave -noupdate -format Logic /tb_mips_muldiv/uut/div_en
|
|
||||||
add wave -noupdate -divider FSM
|
|
||||||
add wave -noupdate -format Literal /tb_mips_muldiv/uut/cycle_cnt
|
|
||||||
add wave -noupdate -format Logic /tb_mips_muldiv/uut/cycle_cnt_load
|
|
||||||
add wave -noupdate -format Literal /tb_mips_muldiv/uut/cycle_cnt_preset
|
|
||||||
add wave -noupdate -format Literal /tb_mips_muldiv/uut/s
|
|
||||||
add wave -noupdate -format Literal /tb_mips_muldiv/uut/sn
|
|
||||||
TreeUpdate [SetDefaultTree]
|
|
||||||
WaveRestoreCursors {{Cursor 1} {4999822285 ps} 0} {{Cursor 2} {1278050000 ps} 0}
|
|
||||||
configure wave -namecolwidth 149
|
|
||||||
configure wave -valuecolwidth 171
|
|
||||||
configure wave -justifyvalue left
|
|
||||||
configure wave -signalnamewidth 1
|
|
||||||
configure wave -snapdistance 10
|
|
||||||
configure wave -datasetprefix 0
|
|
||||||
configure wave -rowmargin 4
|
|
||||||
configure wave -childrowmargin 2
|
|
||||||
configure wave -gridoffset 0
|
|
||||||
configure wave -gridperiod 100
|
|
||||||
configure wave -griddelta 40
|
|
||||||
configure wave -timeline 1
|
|
||||||
update
|
|
||||||
WaveRestoreZoom {0 ps} {5250 us}
|
|
||||||
@@ -1,22 +0,0 @@
|
|||||||
## NOTE: Do not edit this file.
|
|
||||||
##
|
|
||||||
vlib work
|
|
||||||
vcom -explicit -93 "../../../PCK_FIO-1.16/PCK_FIO.vhd"
|
|
||||||
vcom -explicit -93 "../src/core/mips_types.vhd"
|
|
||||||
vcom -explicit -93 "../src/core/mips_instr.vhd"
|
|
||||||
vcom -explicit -93 "../src/core/mips_idecode_rom.vhd"
|
|
||||||
vcom -explicit -93 "../src/core/mips_reg.vhd"
|
|
||||||
vcom -explicit -93 "../src/core/mips_shifter.vhd"
|
|
||||||
vcom -explicit -93 "../src/core/mips_alu.vhd"
|
|
||||||
vcom -explicit -93 "../src/core/mips_bcu.vhd"
|
|
||||||
vcom -explicit -93 "../src/core/mips_pipeline.vhd"
|
|
||||||
vcom -explicit -93 "../src/core/mips_top.vhd"
|
|
||||||
vcom -explicit -93 "../asm/fibonacci.vhd"
|
|
||||||
vcom -explicit -93 "../src/ram.vhd"
|
|
||||||
vcom -explicit -93 "../src/tb_mips_top.vhd"
|
|
||||||
vsim -t 1ps -lib work tb_mips_top
|
|
||||||
do {tb_mips_top.wdo}
|
|
||||||
view wave
|
|
||||||
view structure
|
|
||||||
view signals
|
|
||||||
run 40000ns
|
|
||||||
@@ -1,18 +0,0 @@
|
|||||||
## NOTE: Do not edit this file.
|
|
||||||
##
|
|
||||||
vlib work
|
|
||||||
## Compile Post-Map Model
|
|
||||||
vcom -explicit -93 "../syn/ise9/netgen/map/mips_top_map.vhd"
|
|
||||||
vsim -t 1ps -sdfmax "/mips_top=../syn/ise9/netgen/map/mips_top_map.sdf" -lib work mips_top
|
|
||||||
vcom -explicit -93 "../../../PCK_FIO-1.16/PCK_FIO.vhd"
|
|
||||||
vcom -explicit -93 "../src/core/mips_types.vhd"
|
|
||||||
vcom -explicit -93 "../src/core/mips_instr.vhd"
|
|
||||||
vcom -explicit -93 "../src/irom_hello.vhd"
|
|
||||||
vcom -explicit -93 "../src/tb_mips_top.vhd"
|
|
||||||
vsim -t 1ps -lib work tb_mips_top
|
|
||||||
do {tb_mips_top.mwdo}
|
|
||||||
view wave
|
|
||||||
#add wave *
|
|
||||||
view structure
|
|
||||||
view signals
|
|
||||||
run 2400ns
|
|
||||||
@@ -1,31 +0,0 @@
|
|||||||
onerror {resume}
|
|
||||||
quietly WaveActivateNextPane {} 0
|
|
||||||
add wave -noupdate -format Logic /tb_mips_top/rst
|
|
||||||
add wave -noupdate -format Logic /tb_mips_top/clk
|
|
||||||
add wave -noupdate -format Logic /tb_mips_top/ce
|
|
||||||
add wave -noupdate -format Literal -radix hexadecimal /tb_mips_top/irom_data
|
|
||||||
add wave -noupdate -format Literal -radix hexadecimal /tb_mips_top/irom_addr
|
|
||||||
add wave -noupdate -format Literal -radix hexadecimal /tb_mips_top/dmem_din
|
|
||||||
add wave -noupdate -format Literal -radix hexadecimal /tb_mips_top/dmem_dout
|
|
||||||
add wave -noupdate -format Literal -radix hexadecimal /tb_mips_top/dmem_addr
|
|
||||||
add wave -noupdate -format Logic /tb_mips_top/dmem_we
|
|
||||||
add wave -noupdate -format Logic /tb_mips_top/dmem_re
|
|
||||||
add wave -noupdate -format Literal -radix hexadecimal /tb_mips_top/sram
|
|
||||||
add wave -noupdate -format Literal /tb_mips_top/uut/inst_pipeline_ex_stage_alu_op2
|
|
||||||
add wave -noupdate -format Literal /tb_mips_top/uut/inst_pipeline_ex_stage_alu_result
|
|
||||||
TreeUpdate [SetDefaultTree]
|
|
||||||
WaveRestoreCursors {{Cursor 1} {77481 ps} 0}
|
|
||||||
configure wave -namecolwidth 150
|
|
||||||
configure wave -valuecolwidth 100
|
|
||||||
configure wave -justifyvalue left
|
|
||||||
configure wave -signalnamewidth 1
|
|
||||||
configure wave -snapdistance 10
|
|
||||||
configure wave -datasetprefix 0
|
|
||||||
configure wave -rowmargin 4
|
|
||||||
configure wave -childrowmargin 2
|
|
||||||
configure wave -gridoffset 0
|
|
||||||
configure wave -gridperiod 100
|
|
||||||
configure wave -griddelta 40
|
|
||||||
configure wave -timeline 1
|
|
||||||
update
|
|
||||||
WaveRestoreZoom {0 ps} {729730 ps}
|
|
||||||
@@ -1,16 +0,0 @@
|
|||||||
## NOTE: Do not edit this file.
|
|
||||||
##
|
|
||||||
vlib work
|
|
||||||
vcom -explicit -93 "../syn/ise9/netgen/synthesis/mips_top_synthesis.vhd"
|
|
||||||
vcom -explicit -93 "../../../PCK_FIO-1.16/PCK_FIO.vhd"
|
|
||||||
vcom -explicit -93 "../src/core/mips_types.vhd"
|
|
||||||
vcom -explicit -93 "../src/core/mips_instr.vhd"
|
|
||||||
vcom -explicit -93 "../src/irom_hello.vhd"
|
|
||||||
vcom -explicit -93 "../src/tb_mips_top.vhd"
|
|
||||||
vsim -t 1ps -lib work tb_mips_top
|
|
||||||
#do {tb_mips_top.wdo}
|
|
||||||
view wave
|
|
||||||
add wave *
|
|
||||||
view structure
|
|
||||||
view signals
|
|
||||||
run 2400ns
|
|
||||||
@@ -1,51 +0,0 @@
|
|||||||
onerror {resume}
|
|
||||||
quietly WaveActivateNextPane {} 0
|
|
||||||
add wave -noupdate -format Logic /tb_mips_top/rst
|
|
||||||
add wave -noupdate -format Logic /tb_mips_top/clk
|
|
||||||
add wave -noupdate -format Logic /tb_mips_top/cpu_halt
|
|
||||||
add wave -noupdate -format Literal -radix hexadecimal /tb_mips_top/irom_data
|
|
||||||
add wave -noupdate -format Literal -radix hexadecimal /tb_mips_top/irom_addr
|
|
||||||
add wave -noupdate -format Literal -radix hexadecimal /tb_mips_top/dmem_addr
|
|
||||||
add wave -noupdate -format Literal -radix hexadecimal /tb_mips_top/dmem_din
|
|
||||||
add wave -noupdate -format Literal -radix hexadecimal /tb_mips_top/dmem_dout
|
|
||||||
add wave -noupdate -format Logic /tb_mips_top/dmem_re
|
|
||||||
add wave -noupdate -format Logic /tb_mips_top/dmem_we
|
|
||||||
add wave -noupdate -format Literal -radix hexadecimal /tb_mips_top/inst_ram/sram
|
|
||||||
add wave -noupdate -divider ALU
|
|
||||||
add wave -noupdate -format Literal /tb_mips_top/uut/inst_pipeline/hdu
|
|
||||||
add wave -noupdate -format Logic /tb_mips_top/clk
|
|
||||||
add wave -noupdate -divider PC
|
|
||||||
add wave -noupdate -format Literal -radix hexadecimal /tb_mips_top/uut/inst_pipeline/pc
|
|
||||||
add wave -noupdate -format Logic /tb_mips_top/uut/inst_pipeline/exception
|
|
||||||
add wave -noupdate -format Logic /tb_mips_top/clk
|
|
||||||
add wave -noupdate -format Logic /tb_mips_top/uut/inst_pipeline/stall
|
|
||||||
add wave -noupdate -divider PC
|
|
||||||
add wave -noupdate -format Logic /tb_mips_top/clk
|
|
||||||
add wave -noupdate -format Literal -radix hexadecimal /tb_mips_top/uut/inst_pipeline/if_stage
|
|
||||||
add wave -noupdate -format Logic /tb_mips_top/clk
|
|
||||||
add wave -noupdate -format Literal -radix hexadecimal -expand /tb_mips_top/uut/inst_pipeline/id_stage
|
|
||||||
add wave -noupdate -format Logic /tb_mips_top/clk
|
|
||||||
add wave -noupdate -format Literal -radix hexadecimal /tb_mips_top/dmem_din
|
|
||||||
add wave -noupdate -format Literal -radix hexadecimal -expand /tb_mips_top/uut/inst_pipeline/ex_stage
|
|
||||||
add wave -noupdate -format Logic /tb_mips_top/clk
|
|
||||||
add wave -noupdate -format Literal -radix hexadecimal -expand /tb_mips_top/uut/inst_pipeline/mem_stage
|
|
||||||
add wave -noupdate -format Logic /tb_mips_top/clk
|
|
||||||
add wave -noupdate -format Literal -radix hexadecimal /tb_mips_top/dmem_din
|
|
||||||
add wave -noupdate -format Literal -radix hexadecimal -expand /tb_mips_top/uut/inst_pipeline/wb_stage
|
|
||||||
add wave -noupdate -format Logic /tb_mips_top/clk
|
|
||||||
TreeUpdate [SetDefaultTree]
|
|
||||||
WaveRestoreCursors {{Cursor 1} {0 ps} 0}
|
|
||||||
configure wave -namecolwidth 188
|
|
||||||
configure wave -valuecolwidth 100
|
|
||||||
configure wave -justifyvalue left
|
|
||||||
configure wave -signalnamewidth 1
|
|
||||||
configure wave -snapdistance 10
|
|
||||||
configure wave -datasetprefix 0
|
|
||||||
configure wave -rowmargin 4
|
|
||||||
configure wave -childrowmargin 2
|
|
||||||
configure wave -gridoffset 0
|
|
||||||
configure wave -gridperiod 100
|
|
||||||
configure wave -griddelta 40
|
|
||||||
configure wave -timeline 1
|
|
||||||
update
|
|
||||||
WaveRestoreZoom {0 ps} {42 us}
|
|
||||||
@@ -1,17 +0,0 @@
|
|||||||
## NOTE: Do not edit this file.
|
|
||||||
##
|
|
||||||
vlib work
|
|
||||||
## Compile Post-Map Model
|
|
||||||
vcom -explicit -93 "../syn/ise9/netgen/map/mips_top_syn_map.vhd"
|
|
||||||
vsim -t 1ps -sdfmax "/mips_top_syn=../syn/ise9/netgen/map/mips_top_syn_map.sdf" -lib work mips_top_syn
|
|
||||||
vcom -explicit -93 "../src/core/mips_types.vhd"
|
|
||||||
vcom -explicit -93 "../src/core/mips_instr.vhd"
|
|
||||||
vcom -explicit -93 "../src/irom_hello.vhd"
|
|
||||||
vcom -explicit -93 "../src/tb_mips_top_syn.vhd"
|
|
||||||
vsim -t 1ps -lib work tb_mips_top_syn
|
|
||||||
do {tb_mips_top_syn.wdo}
|
|
||||||
view wave
|
|
||||||
#add wave *
|
|
||||||
view structure
|
|
||||||
view signals
|
|
||||||
run 2400ns
|
|
||||||
@@ -1,17 +0,0 @@
|
|||||||
## NOTE: Do not edit this file.
|
|
||||||
##
|
|
||||||
vlib work
|
|
||||||
## Compile Post-Map Model
|
|
||||||
vcom -explicit -93 "../syn/ise9/netgen/par/mips_top_syn_timesim.vhd"
|
|
||||||
vsim -t 1ps -sdfmax "/mips_top_syn=../syn/ise9/netgen/par/mips_top_syn_timesim.sdf" -lib work mips_top_syn
|
|
||||||
vcom -explicit -93 "../src/core/mips_types.vhd"
|
|
||||||
vcom -explicit -93 "../src/core/mips_instr.vhd"
|
|
||||||
vcom -explicit -93 "../src/irom_hello.vhd"
|
|
||||||
vcom -explicit -93 "../src/tb_mips_top_syn.vhd"
|
|
||||||
vsim -t 1ps -lib work tb_mips_top_syn
|
|
||||||
do {tb_mips_top_syn.wdo}
|
|
||||||
view wave
|
|
||||||
#add wave *
|
|
||||||
view structure
|
|
||||||
view signals
|
|
||||||
run 2400ns
|
|
||||||
@@ -1,31 +0,0 @@
|
|||||||
onerror {resume}
|
|
||||||
quietly WaveActivateNextPane {} 0
|
|
||||||
add wave -noupdate -format Logic /tb_mips_top_syn/rst
|
|
||||||
add wave -noupdate -format Logic /tb_mips_top_syn/clk
|
|
||||||
add wave -noupdate -format Logic /tb_mips_top_syn/ce
|
|
||||||
add wave -noupdate -format Literal -radix hexadecimal /tb_mips_top_syn/irom_data
|
|
||||||
add wave -noupdate -format Literal -radix hexadecimal /tb_mips_top_syn/irom_addr
|
|
||||||
add wave -noupdate -format Literal -radix hexadecimal /tb_mips_top_syn/dmem_din
|
|
||||||
add wave -noupdate -format Literal -radix hexadecimal /tb_mips_top_syn/dmem_dout
|
|
||||||
add wave -noupdate -format Literal -radix hexadecimal /tb_mips_top_syn/dmem_addr
|
|
||||||
add wave -noupdate -format Logic /tb_mips_top_syn/dmem_we
|
|
||||||
add wave -noupdate -format Logic /tb_mips_top_syn/dmem_re
|
|
||||||
add wave -noupdate -format Literal -radix hexadecimal /tb_mips_top_syn/uut/inst_mips_top_inst_pipeline_id_stage_boff
|
|
||||||
add wave -noupdate -format Literal -radix hexadecimal /tb_mips_top_syn/uut/inst_mips_top_inst_pipeline_stage_ex_inst_alu_sum_res
|
|
||||||
add wave -noupdate -format Literal -radix hexadecimal -expand /tb_mips_top_syn/sram
|
|
||||||
TreeUpdate [SetDefaultTree]
|
|
||||||
WaveRestoreCursors {{Cursor 1} {118199 ps} 0}
|
|
||||||
configure wave -namecolwidth 188
|
|
||||||
configure wave -valuecolwidth 100
|
|
||||||
configure wave -justifyvalue left
|
|
||||||
configure wave -signalnamewidth 1
|
|
||||||
configure wave -snapdistance 10
|
|
||||||
configure wave -datasetprefix 0
|
|
||||||
configure wave -rowmargin 4
|
|
||||||
configure wave -childrowmargin 2
|
|
||||||
configure wave -gridoffset 0
|
|
||||||
configure wave -gridperiod 100
|
|
||||||
configure wave -griddelta 40
|
|
||||||
configure wave -timeline 1
|
|
||||||
update
|
|
||||||
WaveRestoreZoom {0 ps} {2520 ns}
|
|
||||||
@@ -1,430 +0,0 @@
|
|||||||
LIBRARY IEEE;
|
|
||||||
USE IEEE.STD_LOGIC_1164.ALL;
|
|
||||||
USE IEEE.NUMERIC_STD.ALL;
|
|
||||||
use IEEE.MATH_REAL.ALL;
|
|
||||||
|
|
||||||
library work;
|
|
||||||
use work.mips_types.all;
|
|
||||||
|
|
||||||
ENTITY dcache IS
|
|
||||||
Generic
|
|
||||||
(
|
|
||||||
cache_size : natural := 2048; -- words
|
|
||||||
line_size : natural := 8 -- words
|
|
||||||
);
|
|
||||||
Port
|
|
||||||
(
|
|
||||||
clk : in STD_LOGIC;
|
|
||||||
rst : in STD_LOGIC;
|
|
||||||
en : in STD_LOGIC;
|
|
||||||
cpu_en : in STD_LOGIC;
|
|
||||||
cpu_r_wn : in STD_LOGIC;
|
|
||||||
cpu_we : in unsigned(3 downto 0);
|
|
||||||
cpu_addr : in word_t;
|
|
||||||
cpu_din : in word_t;
|
|
||||||
cpu_dout : out word_t;
|
|
||||||
cpu_busy : out STD_LOGIC;
|
|
||||||
mem_req : out STD_LOGIC;
|
|
||||||
mem_gnt : in STD_LOGIC;
|
|
||||||
mem_en : out STD_LOGIC;
|
|
||||||
mem_addr : out word_t;
|
|
||||||
mem_din : in word_t;
|
|
||||||
mem_valid : in STD_LOGIC;
|
|
||||||
mem_rdy : in STD_LOGIC
|
|
||||||
);
|
|
||||||
END dcache;
|
|
||||||
|
|
||||||
ARCHITECTURE behavior OF dcache IS
|
|
||||||
|
|
||||||
COMPONENT dpram_1w1r
|
|
||||||
GENERIC
|
|
||||||
(
|
|
||||||
addr_width : integer := 3;
|
|
||||||
data_width : integer := 8
|
|
||||||
);
|
|
||||||
PORT (
|
|
||||||
clka : in STD_LOGIC;
|
|
||||||
clkb : in STD_LOGIC;
|
|
||||||
en_a : in STD_LOGIC;
|
|
||||||
en_b : in STD_LOGIC;
|
|
||||||
we_a : in STD_LOGIC;
|
|
||||||
addr_a : in unsigned (addr_width-1 downto 0);
|
|
||||||
addr_b : in unsigned (addr_width-1 downto 0);
|
|
||||||
din_a : in unsigned (data_width-1 downto 0);
|
|
||||||
dout_b : out unsigned (data_width-1 downto 0)
|
|
||||||
);
|
|
||||||
END COMPONENT;
|
|
||||||
|
|
||||||
COMPONENT dpram_2w2r is
|
|
||||||
GENERIC
|
|
||||||
(
|
|
||||||
addr_width : integer := 3;
|
|
||||||
data_width : integer := 8
|
|
||||||
);
|
|
||||||
PORT
|
|
||||||
(
|
|
||||||
clk_a : in STD_LOGIC;
|
|
||||||
clk_b : in STD_LOGIC;
|
|
||||||
en_a : in STD_LOGIC;
|
|
||||||
en_b : in STD_LOGIC;
|
|
||||||
we_a : in STD_LOGIC;
|
|
||||||
we_b : in STD_LOGIC;
|
|
||||||
addr_a : in unsigned (addr_width-1 downto 0);
|
|
||||||
addr_b : in unsigned (addr_width-1 downto 0);
|
|
||||||
din_a : in unsigned (data_width-1 downto 0);
|
|
||||||
din_b : in unsigned (data_width-1 downto 0);
|
|
||||||
dout_a : out unsigned (data_width-1 downto 0);
|
|
||||||
dout_b : out unsigned (data_width-1 downto 0)
|
|
||||||
);
|
|
||||||
END COMPONENT;
|
|
||||||
|
|
||||||
function lg2(x : natural) return natural is
|
|
||||||
begin
|
|
||||||
return natural(ceil(log2(real(x))));
|
|
||||||
end lg2;
|
|
||||||
|
|
||||||
function po2(x : natural) return natural is
|
|
||||||
begin
|
|
||||||
|
|
||||||
return 2**lg2(x);
|
|
||||||
end po2;
|
|
||||||
|
|
||||||
constant word_index_width : natural := lg2(line_size);
|
|
||||||
constant cache_index_width : natural := lg2(cache_size) - word_index_width;
|
|
||||||
constant tag_width : natural := 32 - word_index_width - cache_index_width - 2;
|
|
||||||
constant tag_parity_width : natural := 3;
|
|
||||||
constant tram_data_width : natural := 2 + tag_parity_width + tag_width;
|
|
||||||
constant tram_addr_width : natural := cache_index_width;
|
|
||||||
|
|
||||||
subtype tram_data_t is unsigned (tram_data_width-1 downto 0);
|
|
||||||
|
|
||||||
type dcache_entry_t is record
|
|
||||||
valid : std_logic;
|
|
||||||
dirty : std_logic;
|
|
||||||
tv_p : unsigned(tag_parity_width-1 downto 0);
|
|
||||||
tag : unsigned(tag_width-1 downto 0);
|
|
||||||
end record;
|
|
||||||
|
|
||||||
alias cpu_word_index is cpu_addr(word_index_width+1 downto 2);
|
|
||||||
alias cpu_cache_index is cpu_addr(cache_index_width+word_index_width+1 downto word_index_width+2);
|
|
||||||
alias cpu_tag is cpu_addr(tag_width+cache_index_width+word_index_width+1 downto cache_index_width+word_index_width+2);
|
|
||||||
|
|
||||||
function to_dcache_entry(x : tram_data_t) return dcache_entry_t is
|
|
||||||
variable result : dcache_entry_t;
|
|
||||||
begin
|
|
||||||
result.valid := x(0);
|
|
||||||
result.dirty := x(1);
|
|
||||||
result.tv_p := x(4 downto 2);
|
|
||||||
result.tag := x(tag_width+4 downto 5);
|
|
||||||
|
|
||||||
return result;
|
|
||||||
end to_dcache_entry;
|
|
||||||
|
|
||||||
function to_tram_data(x : dcache_entry_t) return tram_data_t is
|
|
||||||
variable result : tram_data_t;
|
|
||||||
begin
|
|
||||||
result(0) := x.valid;
|
|
||||||
result(1) := x.dirty;
|
|
||||||
result(4 downto 2) := x.tv_p;
|
|
||||||
result(tag_width+4 downto 5) := x.tag;
|
|
||||||
|
|
||||||
return result;
|
|
||||||
end to_tram_data;
|
|
||||||
|
|
||||||
type cache_state_t is (init, ready, flush, mem_request, mem_access, mem_wait, mem_data, upd_cache, rd_cache, wr_cache);
|
|
||||||
signal s, sn : cache_state_t;
|
|
||||||
|
|
||||||
signal cache_busy : std_logic;
|
|
||||||
signal cache_read_miss : std_logic;
|
|
||||||
signal cache_write_miss : std_logic;
|
|
||||||
signal tag_match : std_logic;
|
|
||||||
signal word_index_reg : unsigned(word_index_width-1 downto 0);
|
|
||||||
signal cache_index_reg : unsigned(cache_index_width-1 downto 0);
|
|
||||||
signal tag_index_reg : unsigned(tag_width-1 downto 0);
|
|
||||||
|
|
||||||
signal cache_entry_in : dcache_entry_t;
|
|
||||||
signal cache_entry_out : dcache_entry_t;
|
|
||||||
signal cpu_dram_addr : unsigned(lg2(cache_size)-1 downto 0);
|
|
||||||
signal cpu_dram_dout : word_t;
|
|
||||||
signal cpu_dram_din : word_t;
|
|
||||||
signal cpu_data_reg : word_t;
|
|
||||||
signal cpu_we_reg : unsigned(3 downto 0);
|
|
||||||
signal ctrl_force_we : unsigned(3 downto 0);
|
|
||||||
signal cpu_was_write : std_logic;
|
|
||||||
signal ctrl_dram_addr : unsigned(lg2(cache_size)-1 downto 0);
|
|
||||||
signal ctrl_dram_din : word_t;
|
|
||||||
signal ctrl_dram_we : unsigned(3 downto 0);
|
|
||||||
signal cpu_dram_we : unsigned(3 downto 0);
|
|
||||||
signal dram_en : std_logic;
|
|
||||||
signal cpu_was_en : std_logic;
|
|
||||||
|
|
||||||
signal tram_addr_rd : unsigned(cache_index_width-1 downto 0);
|
|
||||||
signal tram_dout : tram_data_t;
|
|
||||||
signal tram_addr_wr : unsigned(cache_index_width-1 downto 0);
|
|
||||||
signal tram_din : tram_data_t;
|
|
||||||
signal tram_re : std_logic;
|
|
||||||
signal tram_we : std_logic;
|
|
||||||
|
|
||||||
signal ram_index_count : natural range 0 to 2**word_index_width-1;
|
|
||||||
signal ram_index_count_rst : std_logic;
|
|
||||||
signal cache_index_count : natural range 0 to 2**cache_index_width-1;
|
|
||||||
signal cache_index_count_en : std_logic;
|
|
||||||
signal mem_index_count : natural range 0 to 2**word_index_width-1;
|
|
||||||
signal mem_index_count_en : std_logic;
|
|
||||||
signal mem_index_count_rst : std_logic;
|
|
||||||
signal cpu_reg_en : std_logic;
|
|
||||||
signal was_miss : std_logic;
|
|
||||||
signal data_write : std_logic;
|
|
||||||
signal cpu_we2 : std_logic;
|
|
||||||
|
|
||||||
begin
|
|
||||||
|
|
||||||
|
|
||||||
cpu_index_reg:
|
|
||||||
process(clk)
|
|
||||||
begin
|
|
||||||
if rising_edge(clk) then
|
|
||||||
if rst = '1' then
|
|
||||||
cache_index_reg <= (others => '0');
|
|
||||||
tag_index_reg <= (others => '0');
|
|
||||||
cpu_was_write <= '0';
|
|
||||||
elsif cpu_reg_en = '1' and en = '1' then
|
|
||||||
word_index_reg <= cpu_word_index;
|
|
||||||
cache_index_reg <= cpu_cache_index;
|
|
||||||
tag_index_reg <= cpu_tag;
|
|
||||||
cpu_data_reg <= cpu_din;
|
|
||||||
cpu_we_reg <= cpu_we;
|
|
||||||
cpu_was_write <= not cpu_r_wn;
|
|
||||||
end if;
|
|
||||||
end if;
|
|
||||||
end process;
|
|
||||||
|
|
||||||
cpu_was_wr_reg:
|
|
||||||
process(clk)
|
|
||||||
begin
|
|
||||||
if rising_edge(clk) then
|
|
||||||
cpu_was_en <= '0';
|
|
||||||
cpu_we2 <= '0';
|
|
||||||
if cpu_en = '1' and en = '1' then
|
|
||||||
cpu_we2 <= not cpu_r_wn;
|
|
||||||
cpu_was_en <= '1';
|
|
||||||
cpu_dram_din <= cpu_din;
|
|
||||||
end if;
|
|
||||||
end if;
|
|
||||||
end process;
|
|
||||||
|
|
||||||
inst_tag_ram : dpram_1w1r
|
|
||||||
GENERIC MAP (
|
|
||||||
addr_width => tram_addr_width,
|
|
||||||
data_width => tram_data_width
|
|
||||||
)
|
|
||||||
PORT MAP (
|
|
||||||
clka => clk,
|
|
||||||
clkb => clk,
|
|
||||||
en_a => '1',
|
|
||||||
en_b => tram_re,
|
|
||||||
we_a => tram_we,
|
|
||||||
addr_a => tram_addr_wr,
|
|
||||||
addr_b => tram_addr_rd,
|
|
||||||
din_a => tram_din,
|
|
||||||
dout_b => tram_dout
|
|
||||||
);
|
|
||||||
|
|
||||||
gen_data_ram:
|
|
||||||
for i in 0 to 3 generate
|
|
||||||
begin
|
|
||||||
|
|
||||||
inst_data_ram : dpram_2w2r
|
|
||||||
GENERIC MAP (
|
|
||||||
addr_width => lg2(cache_size),
|
|
||||||
data_width => word_t'length/4
|
|
||||||
)
|
|
||||||
PORT MAP (
|
|
||||||
clk_a => clk,
|
|
||||||
clk_b => clk,
|
|
||||||
en_a => '1',
|
|
||||||
en_b => dram_en,
|
|
||||||
we_a => ctrl_dram_we(i),
|
|
||||||
we_b => cpu_dram_we(i),
|
|
||||||
addr_a => ctrl_dram_addr,
|
|
||||||
addr_b => cpu_dram_addr,
|
|
||||||
din_a => ctrl_dram_din(8*(i+1)-1 downto 8*i),
|
|
||||||
din_b => cpu_dram_din(8*(i+1)-1 downto 8*i),
|
|
||||||
dout_a => open,
|
|
||||||
dout_b => cpu_dram_dout(8*(i+1)-1 downto 8*i)
|
|
||||||
);
|
|
||||||
end generate;
|
|
||||||
|
|
||||||
cache_state_next:
|
|
||||||
process(clk)
|
|
||||||
begin
|
|
||||||
if rising_edge(clk) then
|
|
||||||
if rst = '1' then
|
|
||||||
s <= init;
|
|
||||||
else
|
|
||||||
s <= sn;
|
|
||||||
end if;
|
|
||||||
end if;
|
|
||||||
end process;
|
|
||||||
|
|
||||||
cpu_busy <= cache_busy;
|
|
||||||
cpu_dout <= cpu_dram_dout;
|
|
||||||
|
|
||||||
tag_match <= '1' when tag_index_reg = cache_entry_out.tag else '0';
|
|
||||||
cache_read_miss <= not (tag_match and cache_entry_out.valid) and not cpu_was_write;
|
|
||||||
cache_write_miss <= not (tag_match and cache_entry_out.valid and cpu_was_write);
|
|
||||||
tram_din <= to_tram_data(cache_entry_in);
|
|
||||||
tram_addr_rd <= cpu_cache_index when was_miss = '0' else cache_index_reg;
|
|
||||||
cache_entry_out <= to_dcache_entry(tram_dout);
|
|
||||||
cpu_dram_addr <= (cpu_cache_index & cpu_word_index) when (was_miss = '0' and cpu_we2 = '0') else (cache_index_reg & word_index_reg);
|
|
||||||
mem_addr <= tag_index_reg & cache_index_reg & to_unsigned(mem_index_count, word_index_width) & "00";
|
|
||||||
ctrl_dram_addr <= cache_index_reg & to_unsigned(ram_index_count, word_index_width);
|
|
||||||
ctrl_dram_din <= mem_din;
|
|
||||||
ctrl_dram_we <= (3 downto 0 => (data_write and mem_valid)) or ctrl_force_we;
|
|
||||||
cpu_dram_we <= cpu_we_reg when (cpu_we2 = '1' and cache_write_miss = '0') else (others => '0');
|
|
||||||
|
|
||||||
cache_state:
|
|
||||||
process(s, cache_read_miss, cache_index_count, ram_index_count, mem_index_count, cache_index_reg, mem_valid, tag_index_reg, cpu_en, cpu_r_wn, mem_gnt, mem_rdy, cpu_was_en, cpu_was_write, cpu_we_reg)
|
|
||||||
begin
|
|
||||||
cpu_reg_en <= '0';
|
|
||||||
cache_busy <= '1';
|
|
||||||
tram_we <= '0';
|
|
||||||
cache_index_count_en <= '0';
|
|
||||||
ram_index_count_rst <= '0';
|
|
||||||
mem_index_count_en <= '0';
|
|
||||||
mem_index_count_rst <= '0';
|
|
||||||
mem_req <= '0';
|
|
||||||
mem_en <= '0';
|
|
||||||
dram_en <= '0';
|
|
||||||
tram_re <= '0';
|
|
||||||
was_miss <= '0';
|
|
||||||
data_write <= '0';
|
|
||||||
tram_addr_wr <= to_unsigned(cache_index_count, cache_index_width);
|
|
||||||
cache_entry_in.tv_p <= (others => '0');
|
|
||||||
cache_entry_in.tag <= tag_index_reg;
|
|
||||||
cache_entry_in.valid <= '0';
|
|
||||||
cache_entry_in.dirty <= '0';
|
|
||||||
ctrl_force_we <= (others => '0');
|
|
||||||
sn <= s;
|
|
||||||
|
|
||||||
case s is
|
|
||||||
when init =>
|
|
||||||
sn <= flush;
|
|
||||||
when ready =>
|
|
||||||
cache_busy <= '0';
|
|
||||||
cpu_reg_en <= '1';
|
|
||||||
dram_en <= cpu_en or cpu_was_en;
|
|
||||||
tram_re <= cpu_en;
|
|
||||||
if cpu_was_en = '1' then
|
|
||||||
if cache_read_miss = '1' then
|
|
||||||
sn <= mem_request;
|
|
||||||
cpu_reg_en <= '0';
|
|
||||||
cache_busy <= '1';
|
|
||||||
end if;
|
|
||||||
end if;
|
|
||||||
when flush =>
|
|
||||||
cache_index_count_en <= '1';
|
|
||||||
tram_addr_wr <= to_unsigned(cache_index_count, cache_index_width);
|
|
||||||
tram_we <= '1';
|
|
||||||
cache_entry_in.valid <= '0';
|
|
||||||
cache_entry_in.tag <= (others => '0');
|
|
||||||
if cache_index_count = 0 then
|
|
||||||
sn <= ready;
|
|
||||||
if cpu_en = '1' then
|
|
||||||
cpu_reg_en <= '1';
|
|
||||||
dram_en <= '1';
|
|
||||||
tram_re <= '1';
|
|
||||||
end if;
|
|
||||||
end if;
|
|
||||||
when mem_request =>
|
|
||||||
ram_index_count_rst <= '1';
|
|
||||||
mem_index_count_rst <= '1';
|
|
||||||
mem_req <= '1';
|
|
||||||
if mem_gnt = '1' then
|
|
||||||
sn <= mem_access;
|
|
||||||
end if;
|
|
||||||
when mem_access =>
|
|
||||||
data_write <= '1';
|
|
||||||
mem_req <= '1';
|
|
||||||
if mem_rdy = '1' then
|
|
||||||
mem_index_count_en <= '1';
|
|
||||||
mem_en <= '1';
|
|
||||||
if mem_index_count = 2**word_index_width-1 then
|
|
||||||
sn <= mem_data;
|
|
||||||
end if;
|
|
||||||
end if;
|
|
||||||
when mem_data =>
|
|
||||||
mem_req <= '1';
|
|
||||||
data_write <= '1';
|
|
||||||
if ram_index_count = 2**word_index_width-1 then
|
|
||||||
if mem_valid = '1' then
|
|
||||||
sn <= upd_cache;
|
|
||||||
end if;
|
|
||||||
end if;
|
|
||||||
when upd_cache =>
|
|
||||||
mem_req <= '1';
|
|
||||||
tram_addr_wr <= cache_index_reg;
|
|
||||||
tram_we <= '1';
|
|
||||||
cache_entry_in.valid <= '1';
|
|
||||||
if cpu_was_write = '1' then
|
|
||||||
sn <= wr_cache;
|
|
||||||
else
|
|
||||||
sn <= rd_cache;
|
|
||||||
end if;
|
|
||||||
|
|
||||||
when rd_cache =>
|
|
||||||
tram_re <= '1';
|
|
||||||
dram_en <= '1';
|
|
||||||
was_miss <= '1';
|
|
||||||
sn <= ready;
|
|
||||||
|
|
||||||
when wr_cache =>
|
|
||||||
tram_re <= '1';
|
|
||||||
ctrl_force_we <= cpu_we_reg;
|
|
||||||
sn <= ready;
|
|
||||||
when others =>
|
|
||||||
sn <= ready;
|
|
||||||
end case;
|
|
||||||
end process;
|
|
||||||
|
|
||||||
cache_index_counter:
|
|
||||||
process(clk)
|
|
||||||
begin
|
|
||||||
if rising_edge(clk) then
|
|
||||||
if cache_index_count_en = '0' then
|
|
||||||
cache_index_count <= 2**cache_index_width-1;
|
|
||||||
elsif cache_index_count /= 0 then
|
|
||||||
cache_index_count <= cache_index_count - 1;
|
|
||||||
end if;
|
|
||||||
end if;
|
|
||||||
end process;
|
|
||||||
|
|
||||||
ram_index_counter:
|
|
||||||
process(clk)
|
|
||||||
begin
|
|
||||||
if rising_edge(clk) then
|
|
||||||
if ram_index_count_rst = '1' then
|
|
||||||
ram_index_count <= 0;
|
|
||||||
elsif data_write = '1' and mem_valid = '1' then
|
|
||||||
if ram_index_count /= 2**word_index_width-1 then
|
|
||||||
ram_index_count <= ram_index_count + 1;
|
|
||||||
end if;
|
|
||||||
end if;
|
|
||||||
end if;
|
|
||||||
end process;
|
|
||||||
|
|
||||||
mem_index_counter:
|
|
||||||
process(clk)
|
|
||||||
begin
|
|
||||||
if rising_edge(clk) then
|
|
||||||
if mem_index_count_rst = '1' then
|
|
||||||
mem_index_count <= 0;
|
|
||||||
elsif mem_index_count_en = '1' then
|
|
||||||
if mem_index_count /= 2**word_index_width-1 then
|
|
||||||
mem_index_count <= mem_index_count + 1;
|
|
||||||
end if;
|
|
||||||
end if;
|
|
||||||
end if;
|
|
||||||
end process;
|
|
||||||
|
|
||||||
end behavior;
|
|
||||||
@@ -1,356 +0,0 @@
|
|||||||
LIBRARY IEEE;
|
|
||||||
USE IEEE.STD_LOGIC_1164.ALL;
|
|
||||||
USE IEEE.NUMERIC_STD.ALL;
|
|
||||||
use IEEE.MATH_REAL.ALL;
|
|
||||||
|
|
||||||
library work;
|
|
||||||
use work.mips_types.all;
|
|
||||||
|
|
||||||
ENTITY icache IS
|
|
||||||
Generic
|
|
||||||
(
|
|
||||||
cache_size : natural := 2048; -- words
|
|
||||||
line_size : natural := 8 -- words
|
|
||||||
);
|
|
||||||
Port
|
|
||||||
(
|
|
||||||
clk : in STD_LOGIC;
|
|
||||||
rst : in STD_LOGIC;
|
|
||||||
en : in STD_LOGIC;
|
|
||||||
cpu_en : in STD_LOGIC;
|
|
||||||
cpu_addr : in word_t;
|
|
||||||
cpu_dout : out word_t;
|
|
||||||
cpu_busy : out STD_LOGIC;
|
|
||||||
mem_req : out STD_LOGIC;
|
|
||||||
mem_gnt : in STD_LOGIC;
|
|
||||||
mem_en : out STD_LOGIC;
|
|
||||||
mem_addr : out word_t;
|
|
||||||
mem_din : in word_t;
|
|
||||||
mem_valid : in STD_LOGIC;
|
|
||||||
mem_rdy : in STD_LOGIC
|
|
||||||
);
|
|
||||||
END icache;
|
|
||||||
|
|
||||||
ARCHITECTURE behavior OF icache IS
|
|
||||||
|
|
||||||
COMPONENT dpram_1w1r
|
|
||||||
GENERIC
|
|
||||||
(
|
|
||||||
addr_width : integer := 3;
|
|
||||||
data_width : integer := 8
|
|
||||||
);
|
|
||||||
PORT (
|
|
||||||
clka : in STD_LOGIC;
|
|
||||||
clkb : in STD_LOGIC;
|
|
||||||
en_a : in STD_LOGIC;
|
|
||||||
en_b : in STD_LOGIC;
|
|
||||||
we_a : in STD_LOGIC;
|
|
||||||
addr_a : in unsigned (addr_width-1 downto 0);
|
|
||||||
addr_b : in unsigned (addr_width-1 downto 0);
|
|
||||||
din_a : in unsigned (data_width-1 downto 0);
|
|
||||||
dout_b : out unsigned (data_width-1 downto 0)
|
|
||||||
);
|
|
||||||
END COMPONENT;
|
|
||||||
|
|
||||||
function lg2(x : natural) return natural is
|
|
||||||
begin
|
|
||||||
return natural(ceil(log2(real(x))));
|
|
||||||
end lg2;
|
|
||||||
|
|
||||||
function po2(x : natural) return natural is
|
|
||||||
begin
|
|
||||||
|
|
||||||
return 2**lg2(x);
|
|
||||||
end po2;
|
|
||||||
|
|
||||||
constant word_index_width : natural := lg2(line_size);
|
|
||||||
constant cache_index_width : natural := lg2(cache_size) - word_index_width;
|
|
||||||
constant tag_width : natural := 32 - word_index_width - cache_index_width - 2;
|
|
||||||
constant tag_parity_width : natural := 3;
|
|
||||||
constant tag_ram_data_width : natural := 1 + tag_parity_width + tag_width;
|
|
||||||
constant tag_ram_addr_width : natural := cache_index_width;
|
|
||||||
|
|
||||||
subtype tag_ram_data_t is unsigned (tag_ram_data_width-1 downto 0);
|
|
||||||
|
|
||||||
type icache_entry_t is record
|
|
||||||
valid : std_logic;
|
|
||||||
tv_p : unsigned(tag_parity_width-1 downto 0);
|
|
||||||
tag : unsigned(tag_width-1 downto 0);
|
|
||||||
end record;
|
|
||||||
|
|
||||||
alias cpu_word_index is cpu_addr(word_index_width+1 downto 2);
|
|
||||||
alias cpu_cache_index is cpu_addr(cache_index_width+word_index_width+1 downto word_index_width+2);
|
|
||||||
alias cpu_tag is cpu_addr(tag_width+cache_index_width+word_index_width+1 downto cache_index_width+word_index_width+2);
|
|
||||||
|
|
||||||
function to_icache_entry(x : tag_ram_data_t) return icache_entry_t is
|
|
||||||
variable result : icache_entry_t;
|
|
||||||
begin
|
|
||||||
result.valid := x(0);
|
|
||||||
result.tv_p := x(3 downto 1);
|
|
||||||
result.tag := x(tag_width+3 downto 4);
|
|
||||||
|
|
||||||
return result;
|
|
||||||
end to_icache_entry;
|
|
||||||
|
|
||||||
function to_tag_ram_data(x : icache_entry_t) return tag_ram_data_t is
|
|
||||||
variable result : tag_ram_data_t;
|
|
||||||
begin
|
|
||||||
result(0) := x.valid;
|
|
||||||
result(3 downto 1) := x.tv_p;
|
|
||||||
result(tag_width+3 downto 4) := x.tag;
|
|
||||||
|
|
||||||
return result;
|
|
||||||
end to_tag_ram_data;
|
|
||||||
|
|
||||||
type cache_state_t is (init, ready, flush, mem_request, mem_access, mem_wait, mem_data, upd_cache, rd_cache);
|
|
||||||
signal s, sn : cache_state_t;
|
|
||||||
|
|
||||||
signal cache_busy : std_logic;
|
|
||||||
signal cache_miss : std_logic;
|
|
||||||
signal tag_match : std_logic;
|
|
||||||
signal word_index_reg : unsigned(word_index_width-1 downto 0);
|
|
||||||
signal cache_index_reg : unsigned(cache_index_width-1 downto 0);
|
|
||||||
signal tag_index_reg : unsigned(tag_width-1 downto 0);
|
|
||||||
|
|
||||||
signal cache_entry_in : icache_entry_t;
|
|
||||||
signal cache_entry_out : icache_entry_t;
|
|
||||||
signal data_ram_addr_rd : unsigned(lg2(cache_size)-1 downto 0);
|
|
||||||
signal data_ram_data_rd : word_t;
|
|
||||||
signal data_ram_addr_wr : unsigned(lg2(cache_size)-1 downto 0);
|
|
||||||
signal data_ram_data_wr : word_t;
|
|
||||||
signal data_ram_we : std_logic;
|
|
||||||
signal data_ram_re : std_logic;
|
|
||||||
|
|
||||||
signal tag_ram_addr_rd : unsigned(cache_index_width-1 downto 0);
|
|
||||||
signal tag_ram_data_rd : tag_ram_data_t;
|
|
||||||
signal tag_ram_addr_wr : unsigned(cache_index_width-1 downto 0);
|
|
||||||
signal tag_ram_data_wr : tag_ram_data_t;
|
|
||||||
signal tag_ram_re : std_logic;
|
|
||||||
signal tag_ram_we : std_logic;
|
|
||||||
|
|
||||||
signal ram_index_count : natural range 0 to 2**word_index_width-1;
|
|
||||||
signal ram_index_count_rst : std_logic;
|
|
||||||
signal cache_index_count : natural range 0 to 2**cache_index_width-1;
|
|
||||||
signal cache_index_count_en : std_logic;
|
|
||||||
signal mem_index_count : natural range 0 to 2**word_index_width-1;
|
|
||||||
signal mem_index_count_en : std_logic;
|
|
||||||
signal mem_index_count_rst : std_logic;
|
|
||||||
signal cpu_reg_en : std_logic;
|
|
||||||
signal was_miss : std_logic;
|
|
||||||
signal data_write : std_logic;
|
|
||||||
|
|
||||||
begin
|
|
||||||
|
|
||||||
|
|
||||||
cpu_index_reg:
|
|
||||||
process(clk)
|
|
||||||
begin
|
|
||||||
if rising_edge(clk) then
|
|
||||||
if rst = '1' then
|
|
||||||
cache_index_reg <= (others => '0');
|
|
||||||
tag_index_reg <= (others => '0');
|
|
||||||
elsif cpu_reg_en = '1' then
|
|
||||||
word_index_reg <= cpu_word_index;
|
|
||||||
cache_index_reg <= cpu_cache_index;
|
|
||||||
tag_index_reg <= cpu_tag;
|
|
||||||
end if;
|
|
||||||
end if;
|
|
||||||
end process;
|
|
||||||
|
|
||||||
inst_tag_ram : dpram_1w1r
|
|
||||||
GENERIC MAP (
|
|
||||||
addr_width => tag_ram_addr_width,
|
|
||||||
data_width => tag_ram_data_width
|
|
||||||
)
|
|
||||||
PORT MAP (
|
|
||||||
clka => clk,
|
|
||||||
clkb => clk,
|
|
||||||
en_a => '1',
|
|
||||||
en_b => tag_ram_re,
|
|
||||||
we_a => tag_ram_we,
|
|
||||||
addr_a => tag_ram_addr_wr,
|
|
||||||
addr_b => tag_ram_addr_rd,
|
|
||||||
din_a => tag_ram_data_wr,
|
|
||||||
dout_b => tag_ram_data_rd
|
|
||||||
);
|
|
||||||
|
|
||||||
inst_data_ram : dpram_1w1r
|
|
||||||
GENERIC MAP (
|
|
||||||
addr_width => lg2(cache_size),
|
|
||||||
data_width => word_t'length
|
|
||||||
)
|
|
||||||
PORT MAP (
|
|
||||||
clka => clk,
|
|
||||||
clkb => clk,
|
|
||||||
en_a => '1',
|
|
||||||
en_b => data_ram_re,
|
|
||||||
we_a => data_ram_we,
|
|
||||||
addr_a => data_ram_addr_wr,
|
|
||||||
addr_b => data_ram_addr_rd,
|
|
||||||
din_a => data_ram_data_wr,
|
|
||||||
dout_b => data_ram_data_rd
|
|
||||||
);
|
|
||||||
|
|
||||||
|
|
||||||
cache_state_next:
|
|
||||||
process(clk)
|
|
||||||
begin
|
|
||||||
if rising_edge(clk) then
|
|
||||||
if rst = '1' then
|
|
||||||
s <= init;
|
|
||||||
else
|
|
||||||
s <= sn;
|
|
||||||
end if;
|
|
||||||
end if;
|
|
||||||
end process;
|
|
||||||
|
|
||||||
cpu_busy <= cache_busy;
|
|
||||||
cpu_dout <= data_ram_data_rd;
|
|
||||||
|
|
||||||
tag_match <= '1' when tag_index_reg = cache_entry_out.tag else '0';
|
|
||||||
cache_miss <= not (tag_match and cache_entry_out.valid);
|
|
||||||
tag_ram_data_wr <= to_tag_ram_data(cache_entry_in);
|
|
||||||
tag_ram_addr_rd <= cpu_cache_index when was_miss = '0' else cache_index_reg;
|
|
||||||
cache_entry_out <= to_icache_entry(tag_ram_data_rd);
|
|
||||||
data_ram_addr_rd <= (cpu_cache_index & cpu_word_index) when was_miss = '0' else (cache_index_reg & word_index_reg);
|
|
||||||
mem_addr <= tag_index_reg & cache_index_reg & to_unsigned(mem_index_count, word_index_width) & "00";
|
|
||||||
data_ram_addr_wr <= cache_index_reg & to_unsigned(ram_index_count, word_index_width);
|
|
||||||
data_ram_data_wr <= mem_din;
|
|
||||||
data_ram_we <= data_write and mem_valid;
|
|
||||||
|
|
||||||
cache_state:
|
|
||||||
process(s, cache_miss, cache_index_count, ram_index_count, mem_index_count, cache_index_reg, mem_valid, tag_index_reg, cpu_en, mem_gnt, mem_rdy, en)
|
|
||||||
begin
|
|
||||||
cpu_reg_en <= '0';
|
|
||||||
cache_busy <= '1';
|
|
||||||
tag_ram_we <= '0';
|
|
||||||
cache_index_count_en <= '0';
|
|
||||||
ram_index_count_rst <= '0';
|
|
||||||
mem_index_count_en <= '0';
|
|
||||||
mem_index_count_rst <= '0';
|
|
||||||
mem_req <= '0';
|
|
||||||
mem_en <= '0';
|
|
||||||
data_ram_re <= '0';
|
|
||||||
tag_ram_re <= '0';
|
|
||||||
was_miss <= '0';
|
|
||||||
data_write <= '0';
|
|
||||||
tag_ram_addr_wr <= to_unsigned(cache_index_count, cache_index_width);
|
|
||||||
cache_entry_in.tv_p <= (others => '0');
|
|
||||||
cache_entry_in.tag <= tag_index_reg;
|
|
||||||
cache_entry_in.valid <= '0';
|
|
||||||
sn <= s;
|
|
||||||
|
|
||||||
case s is
|
|
||||||
when init =>
|
|
||||||
sn <= flush;
|
|
||||||
when ready =>
|
|
||||||
if en = '1' then
|
|
||||||
cache_busy <= '0';
|
|
||||||
if cache_miss = '1' then
|
|
||||||
sn <= mem_request;
|
|
||||||
cpu_reg_en <= '0';
|
|
||||||
cache_busy <= '1';
|
|
||||||
elsif cpu_en = '1' then
|
|
||||||
cpu_reg_en <= '1';
|
|
||||||
data_ram_re <= '1';
|
|
||||||
tag_ram_re <= '1';
|
|
||||||
end if;
|
|
||||||
end if;
|
|
||||||
when flush =>
|
|
||||||
cache_index_count_en <= '1';
|
|
||||||
tag_ram_addr_wr <= to_unsigned(cache_index_count, cache_index_width);
|
|
||||||
tag_ram_we <= '1';
|
|
||||||
cache_entry_in.valid <= '0';
|
|
||||||
cache_entry_in.tag <= (others => '0');
|
|
||||||
if cache_index_count = 0 then
|
|
||||||
sn <= ready;
|
|
||||||
if cpu_en = '1' then
|
|
||||||
cpu_reg_en <= '1';
|
|
||||||
data_ram_re <= '1';
|
|
||||||
tag_ram_re <= '1';
|
|
||||||
end if;
|
|
||||||
end if;
|
|
||||||
when mem_request =>
|
|
||||||
ram_index_count_rst <= '1';
|
|
||||||
mem_index_count_rst <= '1';
|
|
||||||
mem_req <= '1';
|
|
||||||
if mem_gnt = '1' then
|
|
||||||
sn <= mem_access;
|
|
||||||
end if;
|
|
||||||
when mem_access =>
|
|
||||||
data_write <= '1';
|
|
||||||
mem_req <= '1';
|
|
||||||
if mem_rdy = '1' then
|
|
||||||
mem_index_count_en <= '1';
|
|
||||||
mem_en <= '1';
|
|
||||||
if mem_index_count = 2**word_index_width-1 then
|
|
||||||
sn <= mem_data;
|
|
||||||
end if;
|
|
||||||
end if;
|
|
||||||
when mem_data =>
|
|
||||||
mem_req <= '1';
|
|
||||||
data_write <= '1';
|
|
||||||
if ram_index_count = 2**word_index_width-1 then
|
|
||||||
if mem_valid = '1' then
|
|
||||||
sn <= upd_cache;
|
|
||||||
end if;
|
|
||||||
end if;
|
|
||||||
when upd_cache =>
|
|
||||||
mem_req <= '1';
|
|
||||||
tag_ram_addr_wr <= cache_index_reg;
|
|
||||||
tag_ram_we <= '1';
|
|
||||||
cache_entry_in.valid <= '1';
|
|
||||||
sn <= rd_cache;
|
|
||||||
|
|
||||||
when rd_cache =>
|
|
||||||
-- mem_req <= '1';
|
|
||||||
tag_ram_re <= '1';
|
|
||||||
data_ram_re <= '1';
|
|
||||||
was_miss <= '1';
|
|
||||||
sn <= ready;
|
|
||||||
when others =>
|
|
||||||
sn <= ready;
|
|
||||||
end case;
|
|
||||||
end process;
|
|
||||||
|
|
||||||
cache_index_counter:
|
|
||||||
process(clk)
|
|
||||||
begin
|
|
||||||
if rising_edge(clk) then
|
|
||||||
if cache_index_count_en = '0' then
|
|
||||||
cache_index_count <= 2**cache_index_width-1;
|
|
||||||
elsif cache_index_count /= 0 then
|
|
||||||
cache_index_count <= cache_index_count - 1;
|
|
||||||
end if;
|
|
||||||
end if;
|
|
||||||
end process;
|
|
||||||
|
|
||||||
ram_index_counter:
|
|
||||||
process(clk)
|
|
||||||
begin
|
|
||||||
if rising_edge(clk) then
|
|
||||||
if ram_index_count_rst = '1' then
|
|
||||||
ram_index_count <= 0;
|
|
||||||
elsif data_write = '1' and mem_valid = '1' then
|
|
||||||
if ram_index_count /= 2**word_index_width-1 then
|
|
||||||
ram_index_count <= ram_index_count + 1;
|
|
||||||
end if;
|
|
||||||
end if;
|
|
||||||
end if;
|
|
||||||
end process;
|
|
||||||
|
|
||||||
mem_index_counter:
|
|
||||||
process(clk)
|
|
||||||
begin
|
|
||||||
if rising_edge(clk) then
|
|
||||||
if mem_index_count_rst = '1' then
|
|
||||||
mem_index_count <= 0;
|
|
||||||
elsif mem_index_count_en = '1' then
|
|
||||||
if mem_index_count /= 2**word_index_width-1 then
|
|
||||||
mem_index_count <= mem_index_count + 1;
|
|
||||||
end if;
|
|
||||||
end if;
|
|
||||||
end if;
|
|
||||||
end process;
|
|
||||||
|
|
||||||
end behavior;
|
|
||||||
@@ -1,184 +0,0 @@
|
|||||||
--------------------------------------------------------------------------
|
|
||||||
-- Project: JIPS, a portable 32-bit RISC CPU written in VHDL
|
|
||||||
-- This file: The arithmetic logic unit
|
|
||||||
--
|
|
||||||
-- Copyright (C) 2008 J. Ahrensfeld
|
|
||||||
--
|
|
||||||
-- This program is free software: you can redistribute it and/or modify
|
|
||||||
-- it under the terms of the GNU General Public License as published by
|
|
||||||
-- the Free Software Foundation, either version 3 of the License, or
|
|
||||||
-- (at your option) any later version.
|
|
||||||
--
|
|
||||||
-- This program is distributed in the hope that it will be useful,
|
|
||||||
-- but WITHOUT ANY WARRANTY; without even the implied warranty of
|
|
||||||
-- MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
|
||||||
-- GNU General Public License for more details.
|
|
||||||
--
|
|
||||||
-- You should have received a copy of the GNU General Public License
|
|
||||||
-- along with this program. If not, see <http://www.gnu.org/licenses/>.
|
|
||||||
--
|
|
||||||
-- For questions and ideas, please contact the author at jens@jayfield.org
|
|
||||||
--
|
|
||||||
--------------------------------------------------------------------------
|
|
||||||
|
|
||||||
library IEEE;
|
|
||||||
use IEEE.STD_LOGIC_1164.ALL;
|
|
||||||
use IEEE.numeric_std.ALL;
|
|
||||||
|
|
||||||
use work.mips_types.all;
|
|
||||||
|
|
||||||
entity alu is
|
|
||||||
Generic
|
|
||||||
(
|
|
||||||
data_width : integer := 8
|
|
||||||
);
|
|
||||||
Port
|
|
||||||
(
|
|
||||||
op1_in : in unsigned (data_width-1 downto 0);
|
|
||||||
op2_in : in unsigned (data_width-1 downto 0);
|
|
||||||
op2_shifted : in unsigned (data_width-1 downto 0);
|
|
||||||
ctrl : in alu_ctrl_t;
|
|
||||||
result : out unsigned (data_width-1 downto 0);
|
|
||||||
flags : out alu_flags_t
|
|
||||||
);
|
|
||||||
end alu;
|
|
||||||
|
|
||||||
architecture Behavioral of alu is
|
|
||||||
|
|
||||||
signal sum_res : unsigned (data_width-1 downto 0);
|
|
||||||
signal and_res : unsigned (data_width-1 downto 0);
|
|
||||||
signal xor_res : unsigned (data_width-1 downto 0);
|
|
||||||
signal nor_res : unsigned (data_width-1 downto 0);
|
|
||||||
signal or_res : unsigned (data_width-1 downto 0);
|
|
||||||
signal eq, sa, sb, sr, c, z : STD_LOGIC;
|
|
||||||
signal lts, ltu : STD_LOGIC;
|
|
||||||
|
|
||||||
--------------------------------------------------------------------------
|
|
||||||
begin
|
|
||||||
|
|
||||||
eq <= '1' when op1_in = op2_in else '0' after 3 ns;
|
|
||||||
sa <= op1_in(op1_in'left);
|
|
||||||
sb <= op2_in(op2_in'left);
|
|
||||||
sr <= sum_res(sum_res'left);
|
|
||||||
z <= '1' when op1_in = (data_width-1 downto 0 => '0') else '0' after 2 ns;
|
|
||||||
|
|
||||||
flags.uvf <= (not ctrl.add) and ((sa and (not sb) and (not sr)) or ((not sa) and sb and sr));
|
|
||||||
flags.ovf <= ctrl.add and ((sa and sb and (not sr)) or ((not sa) and (not sb) and sr));
|
|
||||||
-- lts <= (not eq) and (((not c) and sa and sb) or (((not sr) and sa) or (sa and (not sb)) or (sr and (not sb))));
|
|
||||||
lts <= not eq and ((not c and sa) or (not sb and sa) or (not sb and sr));
|
|
||||||
|
|
||||||
ltu <= (not eq) and (not c);
|
|
||||||
flags.lts <= lts;
|
|
||||||
flags.ltu <= ltu;
|
|
||||||
flags.c <= c;
|
|
||||||
|
|
||||||
--------------------------------------------------------------------------
|
|
||||||
proc_op_and:
|
|
||||||
process(op1_in, op2_in)
|
|
||||||
variable x1, x2 : unsigned (data_width-1 downto 0);
|
|
||||||
begin
|
|
||||||
x1 := op1_in;
|
|
||||||
x2 := op2_in;
|
|
||||||
|
|
||||||
and_res <= (x1 and x2) after 1 ns;
|
|
||||||
|
|
||||||
end process;
|
|
||||||
|
|
||||||
--------------------------------------------------------------------------
|
|
||||||
proc_proc_xor:
|
|
||||||
process(op1_in, op2_in)
|
|
||||||
variable x1, x2 : unsigned (data_width-1 downto 0);
|
|
||||||
begin
|
|
||||||
x1 := op1_in;
|
|
||||||
x2 := op2_in;
|
|
||||||
|
|
||||||
xor_res <= (x1 xor x2) after 2 ns;
|
|
||||||
|
|
||||||
end process;
|
|
||||||
|
|
||||||
--------------------------------------------------------------------------
|
|
||||||
proc_proc_nor:
|
|
||||||
process(op1_in, op2_in)
|
|
||||||
variable x1, x2 : unsigned (data_width-1 downto 0);
|
|
||||||
begin
|
|
||||||
x1 := op1_in;
|
|
||||||
x2 := op2_in;
|
|
||||||
|
|
||||||
nor_res <= (x1 nor x2) after 1 ns;
|
|
||||||
|
|
||||||
end process;
|
|
||||||
|
|
||||||
--------------------------------------------------------------------------
|
|
||||||
proc_proc_or:
|
|
||||||
process(op1_in, op2_in)
|
|
||||||
variable x1, x2 : unsigned (data_width-1 downto 0);
|
|
||||||
begin
|
|
||||||
x1 := op1_in;
|
|
||||||
x2 := op2_in;
|
|
||||||
|
|
||||||
or_res <= (x1 or x2) after 1 ns;
|
|
||||||
|
|
||||||
end process;
|
|
||||||
|
|
||||||
--------------------------------------------------------------------------
|
|
||||||
proc_alu_out:
|
|
||||||
process(ctrl, sum_res, and_res, xor_res, nor_res, or_res, op2_shifted, lts, ltu)
|
|
||||||
begin
|
|
||||||
|
|
||||||
result <= sum_res;
|
|
||||||
|
|
||||||
case ctrl.outsel is
|
|
||||||
|
|
||||||
when alu_adder =>
|
|
||||||
result <= sum_res;
|
|
||||||
|
|
||||||
when alu_and =>
|
|
||||||
result <= and_res;
|
|
||||||
|
|
||||||
when alu_xor =>
|
|
||||||
result <= xor_res;
|
|
||||||
|
|
||||||
when alu_nor =>
|
|
||||||
result <= nor_res;
|
|
||||||
|
|
||||||
when alu_or =>
|
|
||||||
result <= or_res;
|
|
||||||
|
|
||||||
when alu_shift2 =>
|
|
||||||
result <= op2_shifted;
|
|
||||||
|
|
||||||
when alu_ltu =>
|
|
||||||
result <= (data_width-1 downto 1 => '0') & ltu;
|
|
||||||
|
|
||||||
when alu_lts =>
|
|
||||||
result <= (data_width-1 downto 1 => '0') & lts;
|
|
||||||
|
|
||||||
when others => null;
|
|
||||||
|
|
||||||
end case;
|
|
||||||
|
|
||||||
end process;
|
|
||||||
|
|
||||||
--------------------------------------------------------------------------
|
|
||||||
alu_addsub:
|
|
||||||
process(op1_in, op2_in, ctrl)
|
|
||||||
variable sum : unsigned(data_width+1 downto 0);
|
|
||||||
variable op1, op2 : unsigned(data_width+1 downto 0);
|
|
||||||
begin
|
|
||||||
|
|
||||||
op1 := '0' & op1_in & not ctrl.add;
|
|
||||||
if (ctrl.add = '1') then
|
|
||||||
op2 := '0' & op2_in & '0';
|
|
||||||
else
|
|
||||||
op2 := '0' & not op2_in & '1';
|
|
||||||
end if;
|
|
||||||
sum := op1 + op2;
|
|
||||||
|
|
||||||
-- Form sum + carry
|
|
||||||
sum_res <= unsigned(sum(data_width downto 1)) after 4 ns;
|
|
||||||
c <= sum(sum'left) after 4 ns;
|
|
||||||
|
|
||||||
end process;
|
|
||||||
|
|
||||||
--------------------------------------------------------------------------
|
|
||||||
end Behavioral;
|
|
||||||
@@ -1,53 +0,0 @@
|
|||||||
--------------------------------------------------------------------------
|
|
||||||
-- Project: JIPS, a portable 32-bit RISC CPU written in VHDL
|
|
||||||
-- This file: The arithmetic logic unit
|
|
||||||
--
|
|
||||||
-- Copyright (C) 2008 J. Ahrensfeld
|
|
||||||
--
|
|
||||||
-- This program is free software: you can redistribute it and/or modify
|
|
||||||
-- it under the terms of the GNU General Public License as published by
|
|
||||||
-- the Free Software Foundation, either version 3 of the License, or
|
|
||||||
-- (at your option) any later version.
|
|
||||||
--
|
|
||||||
-- This program is distributed in the hope that it will be useful,
|
|
||||||
-- but WITHOUT ANY WARRANTY; without even the implied warranty of
|
|
||||||
-- MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
|
||||||
-- GNU General Public License for more details.
|
|
||||||
--
|
|
||||||
-- You should have received a copy of the GNU General Public License
|
|
||||||
-- along with this program. If not, see <http://www.gnu.org/licenses/>.
|
|
||||||
--
|
|
||||||
-- For questions and ideas, please contact the author at jens@jayfield.org
|
|
||||||
--
|
|
||||||
--------------------------------------------------------------------------
|
|
||||||
|
|
||||||
library IEEE;
|
|
||||||
use IEEE.STD_LOGIC_1164.ALL;
|
|
||||||
use IEEE.numeric_std.ALL;
|
|
||||||
|
|
||||||
use work.mips_types.all;
|
|
||||||
|
|
||||||
entity bcu is
|
|
||||||
Generic
|
|
||||||
(
|
|
||||||
data_width : integer := 8
|
|
||||||
);
|
|
||||||
Port
|
|
||||||
(
|
|
||||||
op1_in : in unsigned (data_width-1 downto 0);
|
|
||||||
op2_in : in unsigned (data_width-1 downto 0);
|
|
||||||
flags : out bcu_flags_t
|
|
||||||
);
|
|
||||||
end bcu;
|
|
||||||
|
|
||||||
architecture Behavioral of bcu is
|
|
||||||
|
|
||||||
--------------------------------------------------------------------------
|
|
||||||
begin
|
|
||||||
|
|
||||||
flags.eq <= '1' when op1_in = op2_in else '0' after 3 ns;
|
|
||||||
flags.z <= '1' when op1_in = (data_width-1 downto 0 => '0') else '0' after 2 ns;
|
|
||||||
flags.ltz <= op1_in(op1_in'left) after 1 ns;
|
|
||||||
|
|
||||||
--------------------------------------------------------------------------
|
|
||||||
end Behavioral;
|
|
||||||
@@ -1,396 +0,0 @@
|
|||||||
--------------------------------------------------------------------------
|
|
||||||
-- Project: JIPS, a portable 32-bit RISC CPU written in VHDL
|
|
||||||
-- This file: JIPS top file
|
|
||||||
--
|
|
||||||
-- Copyright (C) 2008 J. Ahrensfeld
|
|
||||||
--
|
|
||||||
-- This program is free software: you can redistribute it and/or modify
|
|
||||||
-- it under the terms of the GNU General Public License as published by
|
|
||||||
-- the Free Software Foundation, either version 3 of the License, or
|
|
||||||
-- (at your option) any later version.
|
|
||||||
--
|
|
||||||
-- This program is distributed in the hope that it will be useful,
|
|
||||||
-- but WITHOUT ANY WARRANTY; without even the implied warranty of
|
|
||||||
-- MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
|
||||||
-- GNU General Public License for more details.
|
|
||||||
--
|
|
||||||
-- You should have received a copy of the GNU General Public License
|
|
||||||
-- along with this program. If not, see <http://www.gnu.org/licenses/>.
|
|
||||||
--
|
|
||||||
-- For questions and ideas, please contact the author at jens@jayfield.org
|
|
||||||
--
|
|
||||||
--------------------------------------------------------------------------
|
|
||||||
|
|
||||||
library IEEE;
|
|
||||||
use IEEE.STD_LOGIC_1164.ALL;
|
|
||||||
use IEEE.numeric_std.ALL;
|
|
||||||
|
|
||||||
library work;
|
|
||||||
use work.mips_types.all;
|
|
||||||
|
|
||||||
entity bui is
|
|
||||||
Port
|
|
||||||
(
|
|
||||||
rst : in STD_LOGIC;
|
|
||||||
clk : in STD_LOGIC;
|
|
||||||
ce : in STD_LOGIC;
|
|
||||||
cpu_wait : out STD_LOGIC;
|
|
||||||
cpu_imem_rdy : out STD_LOGIC;
|
|
||||||
cpu_imem_en : in STD_LOGIC;
|
|
||||||
cpu_imem_addr : in word_t;
|
|
||||||
cpu_imem_din : out word_t;
|
|
||||||
cpu_dmem_rdy : out STD_LOGIC;
|
|
||||||
cpu_dmem_en : in STD_LOGIC;
|
|
||||||
cpu_dmem_re : in STD_LOGIC;
|
|
||||||
cpu_dmem_we : in unsigned(3 downto 0);
|
|
||||||
cpu_dmem_dout : in word_t;
|
|
||||||
cpu_dmem_din : out word_t;
|
|
||||||
cpu_dmem_addr : in word_t;
|
|
||||||
mem_valid : in STD_LOGIC;
|
|
||||||
mem_rdy : in STD_LOGIC;
|
|
||||||
mem_addr : out word_t;
|
|
||||||
mem_din : in word_t;
|
|
||||||
mem_dout : out word_t;
|
|
||||||
mem_re : out STD_LOGIC;
|
|
||||||
mem_we : out unsigned(3 downto 0);
|
|
||||||
mem_ce : out STD_LOGIC
|
|
||||||
);
|
|
||||||
|
|
||||||
end bui;
|
|
||||||
|
|
||||||
architecture behavior of bui is
|
|
||||||
|
|
||||||
COMPONENT icache
|
|
||||||
GENERIC
|
|
||||||
(
|
|
||||||
cache_size : natural := 2048; -- words
|
|
||||||
line_size : natural := 8 -- words
|
|
||||||
);
|
|
||||||
PORT
|
|
||||||
(
|
|
||||||
clk : in STD_LOGIC;
|
|
||||||
rst : in STD_LOGIC;
|
|
||||||
en : in STD_LOGIC;
|
|
||||||
cpu_en : in STD_LOGIC;
|
|
||||||
cpu_addr : in word_t;
|
|
||||||
cpu_dout : out word_t;
|
|
||||||
cpu_busy : out STD_LOGIC;
|
|
||||||
mem_en : out STD_LOGIC;
|
|
||||||
mem_req : out STD_LOGIC;
|
|
||||||
mem_gnt : in STD_LOGIC;
|
|
||||||
mem_addr : out word_t;
|
|
||||||
mem_din : in word_t;
|
|
||||||
mem_valid : in STD_LOGIC;
|
|
||||||
mem_rdy : in STD_LOGIC
|
|
||||||
);
|
|
||||||
END COMPONENT;
|
|
||||||
|
|
||||||
COMPONENT dcache
|
|
||||||
GENERIC
|
|
||||||
(
|
|
||||||
cache_size : natural := 2048; -- words
|
|
||||||
line_size : natural := 8 -- words
|
|
||||||
);
|
|
||||||
PORT
|
|
||||||
(
|
|
||||||
clk : in STD_LOGIC;
|
|
||||||
rst : in STD_LOGIC;
|
|
||||||
en : in STD_LOGIC;
|
|
||||||
cpu_en : in STD_LOGIC;
|
|
||||||
cpu_r_wn : in STD_LOGIC;
|
|
||||||
cpu_we : in unsigned(3 downto 0);
|
|
||||||
cpu_addr : in word_t;
|
|
||||||
cpu_din : in word_t;
|
|
||||||
cpu_dout : out word_t;
|
|
||||||
cpu_busy : out STD_LOGIC;
|
|
||||||
mem_req : out STD_LOGIC;
|
|
||||||
mem_gnt : in STD_LOGIC;
|
|
||||||
mem_en : out STD_LOGIC;
|
|
||||||
mem_addr : out word_t;
|
|
||||||
mem_din : in word_t;
|
|
||||||
mem_valid : in STD_LOGIC;
|
|
||||||
mem_rdy : in STD_LOGIC
|
|
||||||
);
|
|
||||||
END COMPONENT;
|
|
||||||
|
|
||||||
type bus_state_t is (init, ready, i_cache_bus_access, d_cache_bus_access, d_bus_start, d_bus_access, d_bus_finish);
|
|
||||||
|
|
||||||
signal s, sn : bus_state_t;
|
|
||||||
signal dmem_re : std_logic;
|
|
||||||
signal dmem_we : unsigned(3 downto 0);
|
|
||||||
signal dcache_dout : word_t;
|
|
||||||
signal dmem_dout : word_t;
|
|
||||||
signal dmem_din : word_t;
|
|
||||||
signal dmem_addr : word_t;
|
|
||||||
signal imem_addr : word_t;
|
|
||||||
signal imem_mem_out_en : std_logic;
|
|
||||||
signal dmem_mem_out_en : std_logic;
|
|
||||||
signal imem_valid : std_logic;
|
|
||||||
signal dmem_valid : std_logic;
|
|
||||||
signal dmem_ack : std_logic;
|
|
||||||
signal dcache_req : std_logic;
|
|
||||||
signal dcache_busy1 : std_logic;
|
|
||||||
signal dcache_busy2 : std_logic;
|
|
||||||
signal icache_busy : std_logic;
|
|
||||||
signal bus_req : std_logic;
|
|
||||||
signal bus_bsy : std_logic;
|
|
||||||
signal icache_mem_en : std_logic;
|
|
||||||
signal icache_mem_req : std_logic;
|
|
||||||
signal icache_mem_gnt : std_logic;
|
|
||||||
signal icache_mem_addr : word_t;
|
|
||||||
signal dcache_mem_en : std_logic;
|
|
||||||
signal dcache_mem_req : std_logic;
|
|
||||||
signal dcache_mem_gnt : std_logic;
|
|
||||||
signal dcache_mem_addr : word_t;
|
|
||||||
signal contention : std_logic;
|
|
||||||
signal dcached : std_logic;
|
|
||||||
signal duncached_access : std_logic;
|
|
||||||
|
|
||||||
begin
|
|
||||||
|
|
||||||
mem_ce <= mem_rdy and bus_req;
|
|
||||||
contention <= dcache_req and icache_mem_req;
|
|
||||||
|
|
||||||
cpu_imem_rdy <= not icache_busy after 4.5 ns;
|
|
||||||
-- cpu_imem_din <= imem_din;
|
|
||||||
-- cpu_wait <= busy after 5.5 ns;
|
|
||||||
cpu_wait <= '0';
|
|
||||||
cpu_dmem_rdy <= not (dcache_busy1 or dcache_busy2) after 4.5 ns;
|
|
||||||
|
|
||||||
inst_icache : icache
|
|
||||||
GENERIC MAP
|
|
||||||
(
|
|
||||||
cache_size => 2048, -- words
|
|
||||||
line_size => 8
|
|
||||||
)
|
|
||||||
PORT MAP
|
|
||||||
(
|
|
||||||
clk => clk,
|
|
||||||
rst => rst,
|
|
||||||
en => '1',
|
|
||||||
cpu_en => cpu_imem_en,
|
|
||||||
cpu_addr => cpu_imem_addr,
|
|
||||||
cpu_dout => cpu_imem_din,
|
|
||||||
cpu_busy => icache_busy,
|
|
||||||
mem_en => icache_mem_en,
|
|
||||||
mem_req => icache_mem_req,
|
|
||||||
mem_gnt => icache_mem_gnt,
|
|
||||||
mem_addr => icache_mem_addr,
|
|
||||||
mem_din => mem_din,
|
|
||||||
mem_valid => imem_valid,
|
|
||||||
mem_rdy => mem_rdy
|
|
||||||
);
|
|
||||||
|
|
||||||
inst_dcache : dcache
|
|
||||||
GENERIC MAP
|
|
||||||
(
|
|
||||||
cache_size => 2048, -- words
|
|
||||||
line_size => 8
|
|
||||||
)
|
|
||||||
PORT MAP
|
|
||||||
(
|
|
||||||
clk => clk,
|
|
||||||
rst => rst,
|
|
||||||
en => dcached,
|
|
||||||
cpu_en => cpu_dmem_en,
|
|
||||||
cpu_r_wn => cpu_dmem_re,
|
|
||||||
cpu_we => cpu_dmem_we,
|
|
||||||
cpu_addr => cpu_dmem_addr,
|
|
||||||
cpu_din => cpu_dmem_dout,
|
|
||||||
cpu_dout => dcache_dout,
|
|
||||||
cpu_busy => dcache_busy2,
|
|
||||||
mem_req => dcache_mem_req,
|
|
||||||
mem_gnt => dcache_mem_gnt,
|
|
||||||
mem_en => dcache_mem_en,
|
|
||||||
mem_addr => dcache_mem_addr,
|
|
||||||
mem_din => mem_din,
|
|
||||||
mem_valid => dmem_valid,
|
|
||||||
mem_rdy => mem_rdy
|
|
||||||
);
|
|
||||||
|
|
||||||
dcached <= '1' when cpu_dmem_addr(31 downto 28) /= X"A" else '0';
|
|
||||||
cpu_dmem_din <= dmem_din when duncached_access = '1' else dcache_dout; -- when dmem_valid = '1' else ram_dout after 0.5 ns;
|
|
||||||
|
|
||||||
dcache_flags:
|
|
||||||
process(clk)
|
|
||||||
begin
|
|
||||||
if rising_edge(clk) then
|
|
||||||
if rst = '1' then
|
|
||||||
dcache_busy1 <= '0';
|
|
||||||
dcache_req <= '0';
|
|
||||||
else
|
|
||||||
duncached_access <= '0';
|
|
||||||
if dmem_ack = '1' then
|
|
||||||
duncached_access <= '1';
|
|
||||||
dcache_req <= '0';
|
|
||||||
if dmem_re = '1' then
|
|
||||||
if dmem_valid = '1' then
|
|
||||||
dcache_busy1 <= '0';
|
|
||||||
end if;
|
|
||||||
else
|
|
||||||
dcache_busy1 <= '0';
|
|
||||||
end if;
|
|
||||||
end if;
|
|
||||||
if cpu_dmem_en = '1' and dcache_busy1 = '0' and dcache_busy2 = '0' then
|
|
||||||
dcache_req <= '1';
|
|
||||||
dcache_busy1 <= '1';
|
|
||||||
if dcached = '1' and cpu_dmem_re = '1' then
|
|
||||||
dcache_req <= '0';
|
|
||||||
dcache_busy1 <= '0';
|
|
||||||
end if;
|
|
||||||
end if;
|
|
||||||
end if;
|
|
||||||
end if;
|
|
||||||
end process;
|
|
||||||
|
|
||||||
dcache_regs:
|
|
||||||
process(clk)
|
|
||||||
begin
|
|
||||||
if rising_edge(clk) then
|
|
||||||
if cpu_dmem_en = '1' and dcache_busy1 = '0' and dcache_busy2 = '0' then
|
|
||||||
dmem_dout <= cpu_dmem_dout;
|
|
||||||
dmem_addr <= cpu_dmem_addr;
|
|
||||||
dmem_re <= cpu_dmem_re;
|
|
||||||
dmem_we <= cpu_dmem_we;
|
|
||||||
end if;
|
|
||||||
end if;
|
|
||||||
end process;
|
|
||||||
|
|
||||||
dcache_data:
|
|
||||||
process(clk)
|
|
||||||
begin
|
|
||||||
if rising_edge(clk) then
|
|
||||||
if rst = '1' then
|
|
||||||
dmem_din <= (others => '0');
|
|
||||||
elsif dmem_valid = '1' then
|
|
||||||
dmem_din <= mem_din;
|
|
||||||
end if;
|
|
||||||
end if;
|
|
||||||
end process;
|
|
||||||
|
|
||||||
bus_state_next:
|
|
||||||
process(clk)
|
|
||||||
begin
|
|
||||||
if rising_edge(clk) then
|
|
||||||
if rst = '1' then
|
|
||||||
s <= init;
|
|
||||||
elsif ce = '1' then
|
|
||||||
s <= sn;
|
|
||||||
end if;
|
|
||||||
end if;
|
|
||||||
end process;
|
|
||||||
|
|
||||||
bus_state:
|
|
||||||
process(s, icache_mem_en, icache_mem_req, dcache_mem_req, dcache_mem_en, dcache_req, dmem_re, mem_rdy, mem_valid)
|
|
||||||
begin
|
|
||||||
|
|
||||||
imem_mem_out_en <= '0';
|
|
||||||
dmem_mem_out_en <= '0';
|
|
||||||
icache_mem_gnt <= '0';
|
|
||||||
dcache_mem_gnt <= '0';
|
|
||||||
imem_valid <= '0';
|
|
||||||
dmem_valid <= '0';
|
|
||||||
dmem_ack <= '0';
|
|
||||||
bus_bsy <= '1';
|
|
||||||
|
|
||||||
sn <= s;
|
|
||||||
case s is
|
|
||||||
when init =>
|
|
||||||
if mem_rdy = '1' then
|
|
||||||
sn <= ready;
|
|
||||||
end if;
|
|
||||||
when ready =>
|
|
||||||
bus_bsy <= not mem_rdy;
|
|
||||||
if dcache_req = '1' then
|
|
||||||
if dcache_busy1 = '1' then
|
|
||||||
if mem_rdy = '1' then
|
|
||||||
dmem_mem_out_en <= '1';
|
|
||||||
if dmem_re = '0' then
|
|
||||||
dmem_ack <= '1';
|
|
||||||
else
|
|
||||||
sn <= d_bus_access;
|
|
||||||
end if;
|
|
||||||
end if;
|
|
||||||
end if;
|
|
||||||
elsif icache_mem_req = '1' then
|
|
||||||
sn <= i_cache_bus_access;
|
|
||||||
elsif dcache_mem_req = '1' then
|
|
||||||
sn <= d_cache_bus_access;
|
|
||||||
end if;
|
|
||||||
when i_cache_bus_access =>
|
|
||||||
icache_mem_gnt <= '1';
|
|
||||||
if icache_mem_en = '1' then
|
|
||||||
imem_mem_out_en <= '1';
|
|
||||||
elsif icache_mem_req = '0' then
|
|
||||||
sn <= ready;
|
|
||||||
end if;
|
|
||||||
imem_valid <= mem_valid;
|
|
||||||
when d_cache_bus_access =>
|
|
||||||
dcache_mem_gnt <= '1';
|
|
||||||
if dcache_mem_en = '1' then
|
|
||||||
dmem_mem_out_en <= '1';
|
|
||||||
elsif dcache_mem_req = '0' then
|
|
||||||
sn <= ready;
|
|
||||||
end if;
|
|
||||||
dmem_valid <= mem_valid;
|
|
||||||
when d_bus_access =>
|
|
||||||
if mem_valid = '1' then
|
|
||||||
dmem_ack <= '1';
|
|
||||||
dmem_valid <= '1';
|
|
||||||
sn <= ready;
|
|
||||||
end if;
|
|
||||||
when d_bus_finish =>
|
|
||||||
if mem_rdy = '1' then
|
|
||||||
sn <= ready;
|
|
||||||
end if;
|
|
||||||
when others =>
|
|
||||||
sn <= ready;
|
|
||||||
end case;
|
|
||||||
|
|
||||||
end process;
|
|
||||||
|
|
||||||
bus_request:
|
|
||||||
process(clk)
|
|
||||||
begin
|
|
||||||
if rising_edge(clk) then
|
|
||||||
if rst = '1' then
|
|
||||||
bus_req <= '0';
|
|
||||||
elsif dmem_mem_out_en = '1' or imem_mem_out_en = '1' then
|
|
||||||
bus_req <= '1';
|
|
||||||
elsif mem_rdy = '1' then
|
|
||||||
bus_req <= '0';
|
|
||||||
end if;
|
|
||||||
end if;
|
|
||||||
end process;
|
|
||||||
|
|
||||||
bus_out:
|
|
||||||
process(clk)
|
|
||||||
begin
|
|
||||||
if rising_edge(clk) then
|
|
||||||
if rst = '1' then
|
|
||||||
mem_dout <= (others => '0');
|
|
||||||
mem_addr <= (others => '0');
|
|
||||||
mem_re <= '0';
|
|
||||||
mem_we <= (others => '0');
|
|
||||||
elsif dmem_mem_out_en = '1' then
|
|
||||||
if dcache_mem_gnt = '1' then
|
|
||||||
mem_addr <= dcache_mem_addr;
|
|
||||||
mem_re <= '1';
|
|
||||||
mem_we <= (others => '0');
|
|
||||||
else
|
|
||||||
mem_dout <= dmem_dout;
|
|
||||||
mem_addr <= dmem_addr;
|
|
||||||
mem_re <= dmem_re;
|
|
||||||
mem_we <= dmem_we;
|
|
||||||
end if;
|
|
||||||
elsif imem_mem_out_en = '1' then
|
|
||||||
mem_addr <= icache_mem_addr;
|
|
||||||
mem_re <= '1';
|
|
||||||
mem_we <= (others => '0');
|
|
||||||
end if;
|
|
||||||
end if;
|
|
||||||
end process;
|
|
||||||
|
|
||||||
-------------------------------------------------------------------
|
|
||||||
|
|
||||||
end behavior;
|
|
||||||
@@ -1,415 +0,0 @@
|
|||||||
--------------------------------------------------------------------------
|
|
||||||
-- Project: JIPS, a portable 32-bit RISC CPU written in VHDL
|
|
||||||
-- This file: The arithmetic logic unit
|
|
||||||
--
|
|
||||||
-- Copyright (C) 2008 J. Ahrensfeld
|
|
||||||
--
|
|
||||||
-- This program is free software: you can redistribute it and/or modify
|
|
||||||
-- it under the terms of the GNU General Public License as published by
|
|
||||||
-- the Free Software Foundation, either version 3 of the License, or
|
|
||||||
-- (at your option) any later version.
|
|
||||||
--
|
|
||||||
-- This program is distributed in the hope that it will be useful,
|
|
||||||
-- but WITHOUT ANY WARRANTY; without even the implied warranty of
|
|
||||||
-- MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
|
||||||
-- GNU General Public License for more details.
|
|
||||||
--
|
|
||||||
-- You should have received a copy of the GNU General Public License
|
|
||||||
-- along with this program. If not, see <http://www.gnu.org/licenses/>.
|
|
||||||
--
|
|
||||||
-- For questions and ideas, please contact the author at jens@jayfield.org
|
|
||||||
--
|
|
||||||
--------------------------------------------------------------------------
|
|
||||||
|
|
||||||
library IEEE;
|
|
||||||
use IEEE.STD_LOGIC_1164.ALL;
|
|
||||||
use IEEE.numeric_std.ALL;
|
|
||||||
|
|
||||||
use work.mips_types.all;
|
|
||||||
use work.mips_instr.all;
|
|
||||||
|
|
||||||
entity cop is
|
|
||||||
Port
|
|
||||||
(
|
|
||||||
rst : in STD_LOGIC;
|
|
||||||
clk : in STD_LOGIC;
|
|
||||||
sdu : in sdu_t;
|
|
||||||
IR_valid : in STD_LOGIC;
|
|
||||||
IR : in word_t;
|
|
||||||
events : in event_t;
|
|
||||||
ctrl_in : in cop_ctrl_in_t;
|
|
||||||
ctrl_out : out cop_ctrl_out_t;
|
|
||||||
din : in word_t;
|
|
||||||
dout : out word_t
|
|
||||||
);
|
|
||||||
end cop;
|
|
||||||
|
|
||||||
architecture Behavioral of cop is
|
|
||||||
|
|
||||||
signal epc : word_t;
|
|
||||||
signal cause : word_t;
|
|
||||||
signal status : word_t;
|
|
||||||
signal BadVAddr : word_t;
|
|
||||||
signal exc_code : unsigned(4 downto 0);
|
|
||||||
signal test_reg : word_t;
|
|
||||||
signal test_reg_we : STD_LOGIC;
|
|
||||||
signal stat_reg_we : STD_LOGIC;
|
|
||||||
signal eflags_reg_we : STD_LOGIC;
|
|
||||||
signal epc_reg_we : STD_LOGIC;
|
|
||||||
signal code_reg_we : STD_LOGIC;
|
|
||||||
signal ip_reg_we : STD_LOGIC;
|
|
||||||
signal bd : STD_LOGIC;
|
|
||||||
signal ip : unsigned(7 downto 0);
|
|
||||||
signal im : unsigned(7 downto 0);
|
|
||||||
signal status_save : STD_LOGIC;
|
|
||||||
signal status_rest : STD_LOGIC;
|
|
||||||
signal exception : STD_LOGIC;
|
|
||||||
signal exception_end : STD_LOGIC;
|
|
||||||
signal eflags : exc_flags_t;
|
|
||||||
signal exc_enable : STD_LOGIC;
|
|
||||||
signal cop_EX_en : STD_LOGIC;
|
|
||||||
|
|
||||||
type cop_pipe_t is record
|
|
||||||
din : word_t;
|
|
||||||
rs : reg_ptr_t;
|
|
||||||
rd : reg_ptr_t;
|
|
||||||
func : func_t;
|
|
||||||
we : std_logic;
|
|
||||||
re : std_logic;
|
|
||||||
cs : std_logic;
|
|
||||||
end record;
|
|
||||||
|
|
||||||
signal cop_pipe_ID : cop_pipe_t;
|
|
||||||
signal cop_pipe_EX : cop_pipe_t;
|
|
||||||
|
|
||||||
function eval_int(ip, im : unsigned) return STD_LOGIC is
|
|
||||||
variable result : STD_LOGIC;
|
|
||||||
begin
|
|
||||||
result := '0';
|
|
||||||
for i in ip'range loop
|
|
||||||
result := result or (ip(i) and im(i));
|
|
||||||
end loop;
|
|
||||||
|
|
||||||
return result;
|
|
||||||
end eval_int;
|
|
||||||
|
|
||||||
type exc_state_t is (exc_init, exc_idle, exc_commit_ID, exc_commit_EX, exc_commit_MEM);
|
|
||||||
signal exc_state, exc_staten : exc_state_t;
|
|
||||||
|
|
||||||
--------------------------------------------------------------------------
|
|
||||||
begin
|
|
||||||
|
|
||||||
cop_pipe_ID.din <= din;
|
|
||||||
cop_pipe_ID.cs <= IR_valid;
|
|
||||||
cop_pipe_ID.rs <= extract_rs(IR);
|
|
||||||
cop_pipe_ID.rd <= extract_rd(IR);
|
|
||||||
cop_pipe_ID.func <= extract_func(IR);
|
|
||||||
cop_pipe_ID.re <= cop_pipe_ID.cs when cop_pipe_ID.rs = "00000" else '0';
|
|
||||||
cop_pipe_ID.we <= cop_pipe_ID.cs when cop_pipe_ID.rs = "00100" else '0';
|
|
||||||
cop_EX_en <= exc_enable and not status_save;
|
|
||||||
|
|
||||||
ctrl_out.ee <= exc_enable;
|
|
||||||
ctrl_out.ec <= status_save;
|
|
||||||
ctrl_out.RE <= status(25);
|
|
||||||
ctrl_out.user_mode <= status(1);
|
|
||||||
ctrl_out.int <= eflags.Int;
|
|
||||||
|
|
||||||
ctrl_out.cop_read <= cop_pipe_EX.cs and cop_pipe_EX.re after 1 ns;
|
|
||||||
ctrl_out.reg_write <= cop_pipe_ID.re after 1 ns;
|
|
||||||
|
|
||||||
im <= status(15 downto 8);
|
|
||||||
cause <= bd & (30 downto 16 => '0') & ip & '0' & exc_code & "00";
|
|
||||||
|
|
||||||
eflags.Ov <= events.alu_ovf or events.alu_uvf;
|
|
||||||
eflags.DAdEL <= events.data_load_err;
|
|
||||||
eflags.DAdES <= events.data_store_err;
|
|
||||||
eflags.IAdEL <= events.inst_load_err;
|
|
||||||
eflags.IAdEK <= events.inst_priv_addr and status(1);
|
|
||||||
eflags.Sys <= events.syscall;
|
|
||||||
eflags.Bp <= events.break;
|
|
||||||
eflags.RI <= events.illegal;
|
|
||||||
eflags.Int <= eval_int(ip, im) and status(0);
|
|
||||||
|
|
||||||
exception <= eflags.Ov or eflags.Sys or eflags.Bp or eflags.RI or eflags.IAdEL or eflags.IAdEK or eflags.DAdEL or eflags.DAdES or eflags.Int after 1 ns;
|
|
||||||
|
|
||||||
exception_state:
|
|
||||||
process(exc_state, ctrl_in, exception, sdu)
|
|
||||||
begin
|
|
||||||
|
|
||||||
exc_enable <= '0';
|
|
||||||
ctrl_out.exc_commit <= '0';
|
|
||||||
ctrl_out.exc_pending <= '0';
|
|
||||||
epc_reg_we <= '0';
|
|
||||||
code_reg_we <= '0';
|
|
||||||
status_save <= '0';
|
|
||||||
eflags_reg_we <= '0';
|
|
||||||
|
|
||||||
exc_staten <= exc_state;
|
|
||||||
|
|
||||||
case exc_state is
|
|
||||||
|
|
||||||
when exc_init =>
|
|
||||||
exc_staten <= exc_idle;
|
|
||||||
|
|
||||||
when exc_idle =>
|
|
||||||
exc_enable <= '1';
|
|
||||||
if exception = '1' then
|
|
||||||
status_save <= '1';
|
|
||||||
eflags_reg_we <= '1';
|
|
||||||
code_reg_we <= '1';
|
|
||||||
exc_staten <= exc_commit_ID;
|
|
||||||
end if;
|
|
||||||
|
|
||||||
when exc_commit_ID =>
|
|
||||||
ctrl_out.exc_pending <= '1';
|
|
||||||
ctrl_out.exc_commit <= '1';
|
|
||||||
if sdu.ID_stall = '0' then
|
|
||||||
exc_staten <= exc_commit_EX;
|
|
||||||
end if;
|
|
||||||
|
|
||||||
when exc_commit_EX =>
|
|
||||||
ctrl_out.exc_pending <= '1';
|
|
||||||
ctrl_out.exc_commit <= '1';
|
|
||||||
if sdu.EX_stall = '0' then
|
|
||||||
exc_staten <= exc_commit_MEM;
|
|
||||||
end if;
|
|
||||||
|
|
||||||
when exc_commit_MEM =>
|
|
||||||
ctrl_out.exc_pending <= '1';
|
|
||||||
if sdu.MEM_stall = '0' then
|
|
||||||
epc_reg_we <= '1';
|
|
||||||
exc_staten <= exc_idle;
|
|
||||||
end if;
|
|
||||||
|
|
||||||
when others =>
|
|
||||||
exc_staten <= exc_idle;
|
|
||||||
|
|
||||||
end case;
|
|
||||||
end process;
|
|
||||||
|
|
||||||
exception_state_next:
|
|
||||||
process(clk)
|
|
||||||
begin
|
|
||||||
if rising_edge(clk) then
|
|
||||||
if rst = '1' then
|
|
||||||
exc_state <= exc_init;
|
|
||||||
else
|
|
||||||
exc_state <= exc_staten;
|
|
||||||
end if;
|
|
||||||
end if;
|
|
||||||
end process;
|
|
||||||
|
|
||||||
cop_exception_epc_write:
|
|
||||||
process(clk)
|
|
||||||
begin
|
|
||||||
if rising_edge(clk) then
|
|
||||||
if rst = '1' then
|
|
||||||
bd <= '0';
|
|
||||||
epc <= (others => '0');
|
|
||||||
elsif epc_reg_we = '1' then
|
|
||||||
bd <= '0';
|
|
||||||
epc <= ctrl_in.epc_mem;
|
|
||||||
if ctrl_in.bd_wb = '1' then
|
|
||||||
bd <= '1';
|
|
||||||
epc <= ctrl_in.epc_wb;
|
|
||||||
end if;
|
|
||||||
end if;
|
|
||||||
end if;
|
|
||||||
end process;
|
|
||||||
|
|
||||||
cop_exception_map:
|
|
||||||
process(clk)
|
|
||||||
begin
|
|
||||||
if rising_edge(clk) then
|
|
||||||
if rst = '1' then
|
|
||||||
exc_code <= (others => '0');
|
|
||||||
BadVAddr <= (others => '0');
|
|
||||||
elsif code_reg_we = '1' then
|
|
||||||
if eflags.Ov = '1' then
|
|
||||||
exc_code <= "01100";
|
|
||||||
elsif eflags.Sys = '1' then
|
|
||||||
exc_code <= "01000";
|
|
||||||
elsif eflags.Bp = '1' then
|
|
||||||
exc_code <= "01001";
|
|
||||||
elsif eflags.RI = '1' then
|
|
||||||
exc_code <= "01010";
|
|
||||||
elsif eflags.IAdEL = '1' then
|
|
||||||
exc_code <= "00100";
|
|
||||||
BadVAddr <= ctrl_in.imem_addr;
|
|
||||||
elsif eflags.IAdEK = '1' then
|
|
||||||
exc_code <= "00100";
|
|
||||||
BadVAddr <= ctrl_in.imem_addr;
|
|
||||||
elsif eflags.DAdEL = '1' then
|
|
||||||
exc_code <= "00100";
|
|
||||||
BadVAddr <= ctrl_in.dmem_addr;
|
|
||||||
elsif eflags.DAdES = '1' then
|
|
||||||
exc_code <= "00101";
|
|
||||||
BadVAddr <= ctrl_in.dmem_addr;
|
|
||||||
elsif eflags.Int = '1' then
|
|
||||||
exc_code <= "00000";
|
|
||||||
end if;
|
|
||||||
end if;
|
|
||||||
end if;
|
|
||||||
end process;
|
|
||||||
|
|
||||||
status_rest <= exception_end and ctrl_in.exc_left;
|
|
||||||
|
|
||||||
cop_status_restore:
|
|
||||||
process(clk)
|
|
||||||
begin
|
|
||||||
if rising_edge(clk) then
|
|
||||||
if rst = '1' then
|
|
||||||
exception_end <= '0';
|
|
||||||
ctrl_out.exc_exit <= '0';
|
|
||||||
else
|
|
||||||
if cop_pipe_ID.func = "10000" and exception_end = '0' then -- RFE
|
|
||||||
exception_end <= cop_pipe_ID.cs;
|
|
||||||
ctrl_out.exc_exit <= cop_pipe_ID.cs;
|
|
||||||
elsif exception_end = '1' and ctrl_in.exc_left = '1' then
|
|
||||||
exception_end <= '0';
|
|
||||||
ctrl_out.exc_exit <= '0';
|
|
||||||
end if;
|
|
||||||
end if;
|
|
||||||
end if;
|
|
||||||
end process;
|
|
||||||
|
|
||||||
cop_ip_reg_write:
|
|
||||||
process(clk)
|
|
||||||
begin
|
|
||||||
if rising_edge(clk) then
|
|
||||||
if rst = '1' then
|
|
||||||
ip(1 downto 0) <= (others => '0');
|
|
||||||
elsif ip_reg_we = '1' then
|
|
||||||
ip(1 downto 0) <= cop_pipe_EX.din(9 downto 8);
|
|
||||||
end if;
|
|
||||||
ip(7 downto 2) <= events.Int;
|
|
||||||
end if;
|
|
||||||
end process;
|
|
||||||
|
|
||||||
cop_exc_vector:
|
|
||||||
process(clk)
|
|
||||||
begin
|
|
||||||
if rising_edge(clk) then
|
|
||||||
ctrl_out.exc_vec <= X"80000180";
|
|
||||||
if status(22) = '1' then
|
|
||||||
ctrl_out.exc_vec <= X"BFC00180";
|
|
||||||
end if;
|
|
||||||
end if;
|
|
||||||
end process;
|
|
||||||
|
|
||||||
cop_pipe:
|
|
||||||
process(clk)
|
|
||||||
begin
|
|
||||||
if rising_edge(clk) then
|
|
||||||
if rst = '1' then
|
|
||||||
cop_pipe_EX.cs <= '0';
|
|
||||||
cop_pipe_EX.we <= '0';
|
|
||||||
cop_pipe_EX.re <= '0';
|
|
||||||
else
|
|
||||||
if sdu.EX_stall = '0' then
|
|
||||||
cop_pipe_EX <= cop_pipe_ID;
|
|
||||||
end if;
|
|
||||||
end if;
|
|
||||||
end if;
|
|
||||||
end process;
|
|
||||||
|
|
||||||
cop_register_read:
|
|
||||||
process(clk)
|
|
||||||
variable reg : word_t;
|
|
||||||
begin
|
|
||||||
if rising_edge(clk) and cop_pipe_ID.re = '1' and sdu.ID_stall = '0' then
|
|
||||||
case cop_pipe_ID.rd is
|
|
||||||
when "01000" => -- BadVAddr
|
|
||||||
reg := BadVAddr;
|
|
||||||
|
|
||||||
when "01100" => -- Status
|
|
||||||
reg := status;
|
|
||||||
|
|
||||||
when "01101" => -- Cause
|
|
||||||
reg := cause;
|
|
||||||
|
|
||||||
when "01110" => -- EPC (Exception Program Counter)
|
|
||||||
reg := epc;
|
|
||||||
|
|
||||||
when "01111" => -- PRId (Processor Revision Register)
|
|
||||||
reg := X"000002" & to_unsigned(REVISION ,8);
|
|
||||||
|
|
||||||
when "11111" => -- test_reg
|
|
||||||
reg := test_reg;
|
|
||||||
|
|
||||||
when others =>
|
|
||||||
reg := X"DEADBEEF";
|
|
||||||
|
|
||||||
end case;
|
|
||||||
dout <= reg;
|
|
||||||
end if;
|
|
||||||
end process;
|
|
||||||
|
|
||||||
cop_we_gen:
|
|
||||||
process(clk)
|
|
||||||
begin
|
|
||||||
if rising_edge(clk) then
|
|
||||||
if rst = '1' then
|
|
||||||
test_reg_we <= '0';
|
|
||||||
stat_reg_we <= '0';
|
|
||||||
ip_reg_we <= '0';
|
|
||||||
else
|
|
||||||
test_reg_we <= '0';
|
|
||||||
stat_reg_we <= '0';
|
|
||||||
ip_reg_we <= '0';
|
|
||||||
if (cop_EX_en and cop_pipe_EX.we) = '1' then
|
|
||||||
|
|
||||||
case cop_pipe_EX.rd is
|
|
||||||
|
|
||||||
when "01100" =>
|
|
||||||
stat_reg_we <= not status(1) or status(28);
|
|
||||||
when "01101" =>
|
|
||||||
ip_reg_we <= not status(1) or status(28);
|
|
||||||
when "11111" =>
|
|
||||||
test_reg_we <= not status(1) or status(28);
|
|
||||||
when others => null;
|
|
||||||
|
|
||||||
end case;
|
|
||||||
|
|
||||||
end if;
|
|
||||||
end if;
|
|
||||||
end if;
|
|
||||||
end process;
|
|
||||||
|
|
||||||
cop_test_reg_write:
|
|
||||||
process(clk)
|
|
||||||
begin
|
|
||||||
if rising_edge(clk) then
|
|
||||||
if rst = '1' then
|
|
||||||
test_reg <= (others => '0');
|
|
||||||
else --if ce = '1' then
|
|
||||||
if test_reg_we = '1' then
|
|
||||||
test_reg <= cop_pipe_EX.din;
|
|
||||||
end if;
|
|
||||||
end if;
|
|
||||||
end if;
|
|
||||||
end process;
|
|
||||||
|
|
||||||
cop_status_reg_write:
|
|
||||||
process(clk)
|
|
||||||
begin
|
|
||||||
if rising_edge(clk) then
|
|
||||||
if rst = '1' then
|
|
||||||
status <= X"00400000";
|
|
||||||
else
|
|
||||||
if status_save = '1' then
|
|
||||||
status(5 downto 4) <= status(3 downto 2);
|
|
||||||
status(3 downto 2) <= status(1 downto 0);
|
|
||||||
status(1 downto 0) <= "00";
|
|
||||||
elsif status_rest = '1' then
|
|
||||||
status(1 downto 0) <= status(3 downto 2);
|
|
||||||
status(3 downto 2) <= status(5 downto 4);
|
|
||||||
elsif stat_reg_we = '1' then
|
|
||||||
status <= cop_pipe_EX.din;
|
|
||||||
end if;
|
|
||||||
end if;
|
|
||||||
end if;
|
|
||||||
end process;
|
|
||||||
|
|
||||||
--------------------------------------------------------------------------
|
|
||||||
end Behavioral;
|
|
||||||
@@ -1,101 +0,0 @@
|
|||||||
--------------------------------------------------------------------------
|
|
||||||
-- Project: JIPS, a portable 32-bit RISC CPU written in VHDL
|
|
||||||
-- This file: The datapath controller
|
|
||||||
--
|
|
||||||
-- Copyright (C) 2008 J. Ahrensfeld
|
|
||||||
--
|
|
||||||
-- This program is free software: you can redistribute it and/or modify
|
|
||||||
-- it under the terms of the GNU General Public License as published by
|
|
||||||
-- the Free Software Foundation, either version 3 of the License, or
|
|
||||||
-- (at your option) any later version.
|
|
||||||
--
|
|
||||||
-- This program is distributed in the hope that it will be useful,
|
|
||||||
-- but WITHOUT ANY WARRANTY; without even the implied warranty of
|
|
||||||
-- MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
|
||||||
-- GNU General Public License for more details.
|
|
||||||
--
|
|
||||||
-- You should have received a copy of the GNU General Public License
|
|
||||||
-- along with this program. If not, see <http://www.gnu.org/licenses/>.
|
|
||||||
--
|
|
||||||
-- For questions and ideas, please contact the author at jens@jayfield.org
|
|
||||||
--
|
|
||||||
--------------------------------------------------------------------------
|
|
||||||
|
|
||||||
library IEEE;
|
|
||||||
use IEEE.STD_LOGIC_1164.ALL;
|
|
||||||
use IEEE.numeric_std.ALL;
|
|
||||||
|
|
||||||
library work;
|
|
||||||
use work.mips_types.all;
|
|
||||||
use work.mips_instr.all;
|
|
||||||
|
|
||||||
entity idecode_rom is
|
|
||||||
Port
|
|
||||||
(
|
|
||||||
nop : in std_logic;
|
|
||||||
inst_in : in word_t;
|
|
||||||
ctrl_out : out ctrl_lines_t
|
|
||||||
);
|
|
||||||
end idecode_rom;
|
|
||||||
|
|
||||||
architecture Behavioral of idecode_rom is
|
|
||||||
|
|
||||||
signal ctrl_special : ctrl_lines_t;
|
|
||||||
signal ctrl_regimm : ctrl_lines_t;
|
|
||||||
signal ctrl_opcode : ctrl_lines_t;
|
|
||||||
|
|
||||||
signal rom_special : rom_special_t := gen_rom_special;
|
|
||||||
signal rom_regimm : rom_regimm_t := gen_rom_regimm;
|
|
||||||
signal rom_opcode : rom_opcode_t := gen_rom_opcode;
|
|
||||||
|
|
||||||
attribute rom_style : string;
|
|
||||||
|
|
||||||
attribute rom_style of rom_special: signal is "distributed";
|
|
||||||
attribute rom_style of rom_regimm: signal is "distributed";
|
|
||||||
attribute rom_style of rom_opcode: signal is "distributed";
|
|
||||||
|
|
||||||
begin
|
|
||||||
|
|
||||||
i_dec_special:
|
|
||||||
process(inst_in, rom_special)
|
|
||||||
variable func : func_t;
|
|
||||||
begin
|
|
||||||
func := extract_func(inst_in);
|
|
||||||
ctrl_special <= rom_special(to_integer(func));
|
|
||||||
end process;
|
|
||||||
|
|
||||||
i_dec_regimm:
|
|
||||||
process(inst_in, rom_regimm)
|
|
||||||
variable rt : reg_ptr_t;
|
|
||||||
begin
|
|
||||||
rt := extract_rt(inst_in);
|
|
||||||
ctrl_regimm <= rom_regimm(to_integer(rt));
|
|
||||||
end process;
|
|
||||||
|
|
||||||
i_dec_opcode:
|
|
||||||
process(inst_in, rom_opcode)
|
|
||||||
variable opc : opcode_t;
|
|
||||||
begin
|
|
||||||
opc := extract_opc(inst_in);
|
|
||||||
ctrl_opcode <= rom_opcode(to_integer(opc));
|
|
||||||
end process;
|
|
||||||
|
|
||||||
proc_decode:
|
|
||||||
process(inst_in, ctrl_special, ctrl_regimm, ctrl_opcode, nop)
|
|
||||||
variable opclass : opcode_t;
|
|
||||||
begin
|
|
||||||
opclass := extract_opc(inst_in);
|
|
||||||
ctrl_out <= ctrl_lines_default after 2 ns;
|
|
||||||
if nop = '0' then
|
|
||||||
case opclass is
|
|
||||||
when "000000" =>
|
|
||||||
ctrl_out <= ctrl_special after 2 ns;
|
|
||||||
when "000001" =>
|
|
||||||
ctrl_out <= ctrl_regimm after 2 ns;
|
|
||||||
when others =>
|
|
||||||
ctrl_out <= ctrl_opcode after 2 ns;
|
|
||||||
end case;
|
|
||||||
end if;
|
|
||||||
end process;
|
|
||||||
|
|
||||||
end Behavioral;
|
|
||||||
@@ -1,997 +0,0 @@
|
|||||||
--------------------------------------------------------------------------
|
|
||||||
-- Project: JIPS, a portable 32-bit RISC CPU written in VHDL
|
|
||||||
-- This file: Types, constants and functions for JCPU
|
|
||||||
--
|
|
||||||
-- Copyright (C) 2008 J. Ahrensfeld
|
|
||||||
--
|
|
||||||
-- This program is free software: you can redistribute it and/or modify
|
|
||||||
-- it under the terms of the GNU General Public License as published by
|
|
||||||
-- the Free Software Foundation, either version 3 of the License, or
|
|
||||||
-- (at your option) any later version.
|
|
||||||
--
|
|
||||||
-- This program is distributed in the hope that it will be useful,
|
|
||||||
-- but WITHOUT ANY WARRANTY; without even the implied warranty of
|
|
||||||
-- MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
|
||||||
-- GNU General Public License for more details.
|
|
||||||
--
|
|
||||||
-- You should have received a copy of the GNU General Public License
|
|
||||||
-- along with this program. If not, see <http://www.gnu.org/licenses/>.
|
|
||||||
--
|
|
||||||
-- For questions and ideas, please contact the author at jens@jayfield.org
|
|
||||||
--
|
|
||||||
--------------------------------------------------------------------------
|
|
||||||
|
|
||||||
library IEEE;
|
|
||||||
use IEEE.STD_LOGIC_1164.ALL;
|
|
||||||
use IEEE.numeric_std.ALL;
|
|
||||||
|
|
||||||
library work;
|
|
||||||
use work.mips_types.all;
|
|
||||||
|
|
||||||
--------------------------------------------------------------------------
|
|
||||||
package mips_instr is
|
|
||||||
|
|
||||||
function extract_opc(instr : word_t) return opcode_t;
|
|
||||||
function extract_rs(instr : word_t) return reg_ptr_t;
|
|
||||||
function extract_rt(instr : word_t) return reg_ptr_t;
|
|
||||||
function extract_rd(instr : word_t) return reg_ptr_t;
|
|
||||||
function extract_shamt(instr : word_t) return shamt_t;
|
|
||||||
function extract_func(instr : word_t) return func_t;
|
|
||||||
function extract_simm32(instr : word_t) return word_t;
|
|
||||||
function extract_uimm16(instr : word_t) return word_t;
|
|
||||||
function extract_jimm32(instr, pc : word_t) return word_t;
|
|
||||||
function extract_bimm18(instr, pc : word_t) return word_t;
|
|
||||||
function decode_op(instr : word_t) return op_t;
|
|
||||||
function ctrl_lines_default return ctrl_lines_t;
|
|
||||||
function special_ctrl_lines(func : func_t) return ctrl_lines_t;
|
|
||||||
function regimm_ctrl_lines(rt : reg_ptr_t) return ctrl_lines_t;
|
|
||||||
function opcode_ctrl_lines(opc : opcode_t) return ctrl_lines_t;
|
|
||||||
function gen_rom_opcode return rom_opcode_t;
|
|
||||||
function gen_rom_regimm return rom_regimm_t;
|
|
||||||
function gen_rom_special return rom_special_t;
|
|
||||||
|
|
||||||
end mips_instr;
|
|
||||||
|
|
||||||
--------------------------------------------------------------------------
|
|
||||||
library work;
|
|
||||||
use work.mips_types.all;
|
|
||||||
|
|
||||||
package body mips_instr is
|
|
||||||
|
|
||||||
function extract_opc(instr : word_t) return opcode_t is
|
|
||||||
variable result : opcode_t;
|
|
||||||
begin
|
|
||||||
result := instr(31 downto 26);
|
|
||||||
|
|
||||||
return result;
|
|
||||||
|
|
||||||
end extract_opc;
|
|
||||||
|
|
||||||
function extract_rs(instr : word_t) return reg_ptr_t is
|
|
||||||
variable result : reg_ptr_t;
|
|
||||||
begin
|
|
||||||
result := instr(25 downto 21);
|
|
||||||
|
|
||||||
return result;
|
|
||||||
|
|
||||||
end extract_rs;
|
|
||||||
|
|
||||||
function extract_rt(instr : word_t) return reg_ptr_t is
|
|
||||||
variable result : reg_ptr_t;
|
|
||||||
begin
|
|
||||||
result := instr(20 downto 16);
|
|
||||||
|
|
||||||
return result;
|
|
||||||
|
|
||||||
end extract_rt;
|
|
||||||
|
|
||||||
function extract_rd(instr : word_t) return reg_ptr_t is
|
|
||||||
variable result : reg_ptr_t;
|
|
||||||
begin
|
|
||||||
result := instr(15 downto 11);
|
|
||||||
|
|
||||||
return result;
|
|
||||||
|
|
||||||
end extract_rd;
|
|
||||||
|
|
||||||
function extract_shamt(instr : word_t) return shamt_t is
|
|
||||||
variable result : shamt_t;
|
|
||||||
begin
|
|
||||||
result := instr(10 downto 6);
|
|
||||||
|
|
||||||
return result;
|
|
||||||
|
|
||||||
end extract_shamt;
|
|
||||||
|
|
||||||
function extract_func(instr : word_t) return func_t is
|
|
||||||
variable result : func_t;
|
|
||||||
begin
|
|
||||||
result := instr(5 downto 0);
|
|
||||||
|
|
||||||
return result;
|
|
||||||
|
|
||||||
end extract_func;
|
|
||||||
|
|
||||||
function extract_simm32(instr : word_t) return word_t is
|
|
||||||
variable result : word_t;
|
|
||||||
begin
|
|
||||||
result := (31 downto 16 => instr(15)) & instr(15 downto 0);
|
|
||||||
|
|
||||||
return result;
|
|
||||||
|
|
||||||
end extract_simm32;
|
|
||||||
|
|
||||||
function extract_uimm16(instr : word_t) return word_t is
|
|
||||||
variable result : word_t;
|
|
||||||
begin
|
|
||||||
result := (31 downto 16 => '0') & instr(15 downto 0);
|
|
||||||
|
|
||||||
return result;
|
|
||||||
|
|
||||||
end extract_uimm16;
|
|
||||||
|
|
||||||
function extract_jimm32(instr, pc : word_t) return word_t is
|
|
||||||
variable result : word_t;
|
|
||||||
begin
|
|
||||||
result := pc(31 downto 28) & instr(25 downto 0) & "00";
|
|
||||||
|
|
||||||
return result;
|
|
||||||
|
|
||||||
end extract_jimm32;
|
|
||||||
|
|
||||||
function extract_bimm18(instr, pc : word_t) return word_t is
|
|
||||||
variable result : word_t;
|
|
||||||
begin
|
|
||||||
result := (31 downto 18 => instr(15)) & instr(15 downto 0) & "00";
|
|
||||||
|
|
||||||
return result;
|
|
||||||
|
|
||||||
end extract_bimm18;
|
|
||||||
|
|
||||||
function decode_op(instr : word_t) return op_t is
|
|
||||||
variable result : op_t;
|
|
||||||
variable opc : natural range 0 to 63;
|
|
||||||
variable func : natural range 0 to 63;
|
|
||||||
variable rt : natural range 0 to 31;
|
|
||||||
|
|
||||||
begin
|
|
||||||
|
|
||||||
opc := to_integer(extract_opc(instr));
|
|
||||||
func := to_integer(extract_func(instr));
|
|
||||||
rt := to_integer(extract_rt(instr));
|
|
||||||
|
|
||||||
result := op_sll;
|
|
||||||
|
|
||||||
case opc is
|
|
||||||
|
|
||||||
when 0 =>
|
|
||||||
case func is
|
|
||||||
|
|
||||||
when 0 =>
|
|
||||||
result := op_sll;
|
|
||||||
|
|
||||||
when 2 =>
|
|
||||||
result := op_srl;
|
|
||||||
|
|
||||||
when 3 =>
|
|
||||||
result := op_sra;
|
|
||||||
|
|
||||||
when 4 =>
|
|
||||||
result := op_sllv;
|
|
||||||
|
|
||||||
when 6 =>
|
|
||||||
result := op_srlv;
|
|
||||||
|
|
||||||
when 7 =>
|
|
||||||
result := op_srav;
|
|
||||||
|
|
||||||
when 8 =>
|
|
||||||
result := op_jr;
|
|
||||||
|
|
||||||
when 9 =>
|
|
||||||
result := op_jalr;
|
|
||||||
|
|
||||||
when 12 =>
|
|
||||||
result := op_syscall;
|
|
||||||
|
|
||||||
when 13 =>
|
|
||||||
result := op_break;
|
|
||||||
|
|
||||||
when 16 =>
|
|
||||||
result := op_mfhi;
|
|
||||||
|
|
||||||
when 17 =>
|
|
||||||
result := op_mthi;
|
|
||||||
|
|
||||||
when 18 =>
|
|
||||||
result := op_mflo;
|
|
||||||
|
|
||||||
when 19 =>
|
|
||||||
result := op_mtlo;
|
|
||||||
|
|
||||||
when 24 =>
|
|
||||||
result := op_mult;
|
|
||||||
|
|
||||||
when 25 =>
|
|
||||||
result := op_multu;
|
|
||||||
|
|
||||||
when 26 =>
|
|
||||||
result := op_div;
|
|
||||||
|
|
||||||
when 27 =>
|
|
||||||
result := op_divu;
|
|
||||||
|
|
||||||
when 32 =>
|
|
||||||
result := op_add;
|
|
||||||
|
|
||||||
when 33 =>
|
|
||||||
result := op_addu;
|
|
||||||
|
|
||||||
when 34 =>
|
|
||||||
result := op_sub;
|
|
||||||
|
|
||||||
when 35 =>
|
|
||||||
result := op_subu;
|
|
||||||
|
|
||||||
when 36 =>
|
|
||||||
result := op_and;
|
|
||||||
|
|
||||||
when 37 =>
|
|
||||||
result := op_or;
|
|
||||||
|
|
||||||
when 38 =>
|
|
||||||
result := op_xor;
|
|
||||||
|
|
||||||
when 39 =>
|
|
||||||
result := op_nor;
|
|
||||||
|
|
||||||
when 42 =>
|
|
||||||
result := op_slt;
|
|
||||||
|
|
||||||
when 43 =>
|
|
||||||
result := op_sltu;
|
|
||||||
|
|
||||||
when others => null; -- undef
|
|
||||||
|
|
||||||
end case;
|
|
||||||
|
|
||||||
when 1 =>
|
|
||||||
case rt is
|
|
||||||
|
|
||||||
when 0 =>
|
|
||||||
result := op_bltz;
|
|
||||||
|
|
||||||
when 1 =>
|
|
||||||
result := op_bgez;
|
|
||||||
|
|
||||||
when 16 =>
|
|
||||||
result := op_bltzal;
|
|
||||||
|
|
||||||
when 17 =>
|
|
||||||
result := op_bgezal;
|
|
||||||
|
|
||||||
when others => null; -- undef
|
|
||||||
|
|
||||||
end case;
|
|
||||||
|
|
||||||
when 2 =>
|
|
||||||
result := op_j;
|
|
||||||
|
|
||||||
when 3 =>
|
|
||||||
result := op_jal;
|
|
||||||
|
|
||||||
when 4 =>
|
|
||||||
result := op_beq;
|
|
||||||
|
|
||||||
when 5 =>
|
|
||||||
result := op_bne;
|
|
||||||
|
|
||||||
when 6 =>
|
|
||||||
result := op_blez;
|
|
||||||
|
|
||||||
when 7 =>
|
|
||||||
result := op_bgtz;
|
|
||||||
|
|
||||||
when 8 =>
|
|
||||||
result := op_addi;
|
|
||||||
|
|
||||||
when 9 =>
|
|
||||||
result := op_addiu;
|
|
||||||
|
|
||||||
when 10 =>
|
|
||||||
result := op_slti;
|
|
||||||
|
|
||||||
when 11 =>
|
|
||||||
result := op_sltiu;
|
|
||||||
|
|
||||||
when 12 =>
|
|
||||||
result := op_andi;
|
|
||||||
|
|
||||||
when 13 =>
|
|
||||||
result := op_ori;
|
|
||||||
|
|
||||||
when 14 =>
|
|
||||||
result := op_xori;
|
|
||||||
|
|
||||||
when 15 =>
|
|
||||||
result := op_lui;
|
|
||||||
|
|
||||||
when 16 =>
|
|
||||||
result := op_cop0;
|
|
||||||
|
|
||||||
when 17 =>
|
|
||||||
result := op_cop1;
|
|
||||||
|
|
||||||
when 18 =>
|
|
||||||
result := op_cop2;
|
|
||||||
|
|
||||||
when 19 =>
|
|
||||||
result := op_cop3;
|
|
||||||
|
|
||||||
when 32 =>
|
|
||||||
result := op_lb;
|
|
||||||
|
|
||||||
when 33 =>
|
|
||||||
result := op_lh;
|
|
||||||
|
|
||||||
when 34 =>
|
|
||||||
result := op_lwl;
|
|
||||||
|
|
||||||
when 35 =>
|
|
||||||
result := op_lw;
|
|
||||||
|
|
||||||
when 36 =>
|
|
||||||
result := op_lbu;
|
|
||||||
|
|
||||||
when 37 =>
|
|
||||||
result := op_lhu;
|
|
||||||
|
|
||||||
when 38 =>
|
|
||||||
result := op_lwr;
|
|
||||||
|
|
||||||
when 40 =>
|
|
||||||
result := op_sb;
|
|
||||||
|
|
||||||
when 41 =>
|
|
||||||
result := op_sh;
|
|
||||||
|
|
||||||
when 42 =>
|
|
||||||
result := op_swl;
|
|
||||||
|
|
||||||
when 43 =>
|
|
||||||
result := op_sw;
|
|
||||||
|
|
||||||
when 46 =>
|
|
||||||
result := op_swr;
|
|
||||||
|
|
||||||
when 49 =>
|
|
||||||
result := op_lwc1;
|
|
||||||
|
|
||||||
when 50 =>
|
|
||||||
result := op_lwc2;
|
|
||||||
|
|
||||||
when 51 =>
|
|
||||||
result := op_lwc3;
|
|
||||||
|
|
||||||
when 57 =>
|
|
||||||
result := op_swc1;
|
|
||||||
|
|
||||||
when 58 =>
|
|
||||||
result := op_swc2;
|
|
||||||
|
|
||||||
when 59 =>
|
|
||||||
result := op_swc3;
|
|
||||||
|
|
||||||
when others => null; -- undef
|
|
||||||
|
|
||||||
end case;
|
|
||||||
|
|
||||||
return result;
|
|
||||||
|
|
||||||
end decode_op;
|
|
||||||
|
|
||||||
function ctrl_lines_default return ctrl_lines_t is
|
|
||||||
variable result : ctrl_lines_t;
|
|
||||||
begin
|
|
||||||
result.cop_instr_en := '0';
|
|
||||||
result.jump := '0';
|
|
||||||
result.jump_long := '0';
|
|
||||||
result.branch := '0';
|
|
||||||
result.bc_src := bc_eq_ne;
|
|
||||||
result.bc_not := '0';
|
|
||||||
result.alu.outsel := alu_adder;
|
|
||||||
result.alu.add := '1';
|
|
||||||
result.alu.shift_right := '0';
|
|
||||||
result.alu.shift_arith := '0';
|
|
||||||
result.shamt2_srcsel := sa_src_imm;
|
|
||||||
result.alu.op1_src := alu_src_reg;
|
|
||||||
result.alu.op2_src := alu_src_reg;
|
|
||||||
result.imm_src := src_imm16;
|
|
||||||
result.reg_write := '0';
|
|
||||||
result.dmem_we := '0';
|
|
||||||
result.dmem_en := '0';
|
|
||||||
result.wptr_srcsel := wptr_src_imm;
|
|
||||||
result.reg_link := '0';
|
|
||||||
result.shift_offset := "00";
|
|
||||||
result.shift_byp := '1';
|
|
||||||
result.byte_en_byp := '1';
|
|
||||||
result.sign_ext_byp := '1';
|
|
||||||
result.word4_en := '0';
|
|
||||||
result.word2_en := '0';
|
|
||||||
result.align_left := '0';
|
|
||||||
result.load_signed := '0';
|
|
||||||
result.mul_access := '0';
|
|
||||||
result.mul_hilo_we := '0';
|
|
||||||
result.mul_start := '0';
|
|
||||||
result.mul_s_un := '0';
|
|
||||||
result.mul_mul_divn := '0';
|
|
||||||
result.mul_hilo_sel := '1';
|
|
||||||
result.exc_break := '0';
|
|
||||||
result.exc_syscall := '0';
|
|
||||||
result.exc_illegal := '0';
|
|
||||||
result.except_en := '0';
|
|
||||||
result.alu_exc_en := '0';
|
|
||||||
|
|
||||||
return result;
|
|
||||||
|
|
||||||
end ctrl_lines_default;
|
|
||||||
|
|
||||||
|
|
||||||
function special_ctrl_lines(func : func_t) return ctrl_lines_t is
|
|
||||||
variable result : ctrl_lines_t;
|
|
||||||
variable op : integer range 0 to 2**func_t'length-1;
|
|
||||||
begin
|
|
||||||
|
|
||||||
result := ctrl_lines_default;
|
|
||||||
|
|
||||||
op := to_integer(func);
|
|
||||||
case op is
|
|
||||||
|
|
||||||
-- when op_add =>
|
|
||||||
when 32 =>
|
|
||||||
result.alu.outsel := alu_adder;
|
|
||||||
result.alu.add := '1';
|
|
||||||
result.alu.op1_src := alu_src_reg;
|
|
||||||
result.alu.op2_src := alu_src_reg;
|
|
||||||
result.reg_write := '1';
|
|
||||||
result.alu_exc_en := '1';
|
|
||||||
|
|
||||||
-- when op_addu =>
|
|
||||||
when 33 =>
|
|
||||||
result.alu.outsel := alu_adder;
|
|
||||||
result.alu.add := '1';
|
|
||||||
result.alu.op1_src := alu_src_reg;
|
|
||||||
result.alu.op2_src := alu_src_reg;
|
|
||||||
result.reg_write := '1';
|
|
||||||
|
|
||||||
-- when op_and =>
|
|
||||||
when 36 =>
|
|
||||||
result.alu.outsel := alu_and;
|
|
||||||
result.alu.op1_src := alu_src_reg;
|
|
||||||
result.alu.op2_src := alu_src_reg;
|
|
||||||
result.reg_write := '1';
|
|
||||||
|
|
||||||
-- when op_break =>
|
|
||||||
when 13 =>
|
|
||||||
result.exc_break := '1';
|
|
||||||
result.except_en := '1';
|
|
||||||
|
|
||||||
-- when op_div =>
|
|
||||||
when 26 =>
|
|
||||||
result.mul_access := '1';
|
|
||||||
result.mul_start := '1';
|
|
||||||
result.mul_s_un := '1';
|
|
||||||
result.mul_mul_divn := '0';
|
|
||||||
|
|
||||||
-- when op_divu =>
|
|
||||||
when 27 =>
|
|
||||||
result.mul_access := '1';
|
|
||||||
result.mul_start := '1';
|
|
||||||
result.mul_s_un := '0';
|
|
||||||
result.mul_mul_divn := '0';
|
|
||||||
|
|
||||||
-- when op_jalr =>
|
|
||||||
when 9 =>
|
|
||||||
result.jump_long := '1';
|
|
||||||
result.wptr_srcsel := wptr_src_imm;
|
|
||||||
result.reg_write := '1';
|
|
||||||
result.reg_link := '1';
|
|
||||||
|
|
||||||
-- when op_jr =>
|
|
||||||
when 8 =>
|
|
||||||
result.jump_long := '1';
|
|
||||||
|
|
||||||
-- when op_mfhi =>
|
|
||||||
when 16 =>
|
|
||||||
result.reg_write := '1';
|
|
||||||
result.mul_access := '1';
|
|
||||||
result.mul_hilo_sel := '1';
|
|
||||||
|
|
||||||
-- when op_mflo =>
|
|
||||||
when 18 =>
|
|
||||||
result.reg_write := '1';
|
|
||||||
result.mul_access := '1';
|
|
||||||
result.mul_hilo_sel := '0';
|
|
||||||
|
|
||||||
-- when op_mthi =>
|
|
||||||
when 17 =>
|
|
||||||
result.mul_hilo_we := '1';
|
|
||||||
result.mul_hilo_sel := '1';
|
|
||||||
|
|
||||||
-- when op_mtlo =>
|
|
||||||
when 19 =>
|
|
||||||
result.mul_hilo_we := '1';
|
|
||||||
result.mul_hilo_sel := '0';
|
|
||||||
|
|
||||||
-- when op_mult =>
|
|
||||||
when 24 =>
|
|
||||||
result.mul_access := '1';
|
|
||||||
result.mul_start := '1';
|
|
||||||
result.mul_s_un := '1';
|
|
||||||
result.mul_mul_divn := '1';
|
|
||||||
|
|
||||||
-- when op_multu =>
|
|
||||||
when 25 =>
|
|
||||||
result.mul_access := '1';
|
|
||||||
result.mul_start := '1';
|
|
||||||
result.mul_s_un := '0';
|
|
||||||
result.mul_mul_divn := '1';
|
|
||||||
|
|
||||||
-- when op_or =>
|
|
||||||
when 37 =>
|
|
||||||
result.alu.outsel := alu_or;
|
|
||||||
result.alu.op1_src := alu_src_reg;
|
|
||||||
result.alu.op2_src := alu_src_reg;
|
|
||||||
result.reg_write := '1';
|
|
||||||
|
|
||||||
-- when op_nor =>
|
|
||||||
when 39 =>
|
|
||||||
result.alu.outsel := alu_nor;
|
|
||||||
result.alu.op1_src := alu_src_reg;
|
|
||||||
result.alu.op2_src := alu_src_reg;
|
|
||||||
result.reg_write := '1';
|
|
||||||
|
|
||||||
-- when op_sll =>
|
|
||||||
when 0 =>
|
|
||||||
result.alu.op2_src := alu_src_reg;
|
|
||||||
result.alu.outsel := alu_shift2;
|
|
||||||
result.alu.shift_right := '0';
|
|
||||||
result.shamt2_srcsel := sa_src_imm;
|
|
||||||
result.reg_write := '1';
|
|
||||||
|
|
||||||
-- when op_sllv =>
|
|
||||||
when 4 =>
|
|
||||||
result.alu.op2_src := alu_src_reg;
|
|
||||||
result.alu.outsel := alu_shift2;
|
|
||||||
result.alu.shift_right := '0';
|
|
||||||
result.shamt2_srcsel := sa_src_reg;
|
|
||||||
result.reg_write := '1';
|
|
||||||
|
|
||||||
-- when op_slt =>
|
|
||||||
when 42 =>
|
|
||||||
result.alu.outsel := alu_lts;
|
|
||||||
result.alu.add := '0';
|
|
||||||
result.alu.op1_src := alu_src_reg;
|
|
||||||
result.alu.op2_src := alu_src_reg;
|
|
||||||
result.reg_write := '1';
|
|
||||||
|
|
||||||
-- when op_sltu =>
|
|
||||||
when 43 =>
|
|
||||||
result.alu.outsel := alu_ltu;
|
|
||||||
result.alu.add := '0';
|
|
||||||
result.alu.op1_src := alu_src_reg;
|
|
||||||
result.alu.op2_src := alu_src_reg;
|
|
||||||
result.reg_write := '1';
|
|
||||||
|
|
||||||
-- when op_sra =>
|
|
||||||
when 3 =>
|
|
||||||
result.alu.op2_src := alu_src_reg;
|
|
||||||
result.alu.outsel := alu_shift2;
|
|
||||||
result.alu.shift_right := '1';
|
|
||||||
result.alu.shift_arith := '1';
|
|
||||||
result.shamt2_srcsel := sa_src_imm;
|
|
||||||
result.reg_write := '1';
|
|
||||||
|
|
||||||
-- when op_srav =>
|
|
||||||
when 7 =>
|
|
||||||
result.alu.op2_src := alu_src_reg;
|
|
||||||
result.alu.outsel := alu_shift2;
|
|
||||||
result.alu.shift_right := '1';
|
|
||||||
result.alu.shift_arith := '1';
|
|
||||||
result.shamt2_srcsel := sa_src_reg;
|
|
||||||
result.reg_write := '1';
|
|
||||||
|
|
||||||
-- when op_srl =>
|
|
||||||
when 2 =>
|
|
||||||
result.alu.op2_src := alu_src_reg;
|
|
||||||
result.alu.outsel := alu_shift2;
|
|
||||||
result.alu.shift_right := '1';
|
|
||||||
result.alu.shift_arith := '0';
|
|
||||||
result.shamt2_srcsel := sa_src_imm;
|
|
||||||
result.reg_write := '1';
|
|
||||||
|
|
||||||
-- when op_srlv =>
|
|
||||||
when 6 =>
|
|
||||||
result.alu.op2_src := alu_src_reg;
|
|
||||||
result.alu.outsel := alu_shift2;
|
|
||||||
result.alu.shift_right := '1';
|
|
||||||
result.alu.shift_arith := '0';
|
|
||||||
result.shamt2_srcsel := sa_src_reg;
|
|
||||||
result.reg_write := '1';
|
|
||||||
|
|
||||||
-- when op_sub =>
|
|
||||||
when 34 =>
|
|
||||||
result.alu.outsel := alu_adder;
|
|
||||||
result.alu.add := '0';
|
|
||||||
result.alu.op1_src := alu_src_reg;
|
|
||||||
result.alu.op2_src := alu_src_reg;
|
|
||||||
result.reg_write := '1';
|
|
||||||
result.alu_exc_en := '1';
|
|
||||||
|
|
||||||
-- when op_subu =>
|
|
||||||
when 35 =>
|
|
||||||
result.alu.outsel := alu_adder;
|
|
||||||
result.alu.add := '0';
|
|
||||||
result.alu.op1_src := alu_src_reg;
|
|
||||||
result.alu.op2_src := alu_src_reg;
|
|
||||||
result.reg_write := '1';
|
|
||||||
|
|
||||||
-- when op_syscall =>
|
|
||||||
when 12 =>
|
|
||||||
result.exc_syscall := '1';
|
|
||||||
result.except_en := '1';
|
|
||||||
|
|
||||||
-- when op_xor =>
|
|
||||||
when 38 =>
|
|
||||||
result.alu.outsel := alu_xor;
|
|
||||||
result.alu.op1_src := alu_src_reg;
|
|
||||||
result.alu.op2_src := alu_src_reg;
|
|
||||||
result.reg_write := '1';
|
|
||||||
|
|
||||||
when others =>
|
|
||||||
result.exc_illegal := '1';
|
|
||||||
|
|
||||||
end case;
|
|
||||||
|
|
||||||
return result;
|
|
||||||
|
|
||||||
end special_ctrl_lines;
|
|
||||||
|
|
||||||
function gen_rom_special return rom_special_t is
|
|
||||||
variable result : rom_special_t;
|
|
||||||
variable func : func_t;
|
|
||||||
begin
|
|
||||||
|
|
||||||
for i in 0 to 2**func_t'length-1 loop
|
|
||||||
func := to_unsigned(i, func_t'length);
|
|
||||||
result(i) := special_ctrl_lines(func);
|
|
||||||
end loop;
|
|
||||||
|
|
||||||
return result;
|
|
||||||
end gen_rom_special;
|
|
||||||
|
|
||||||
function regimm_ctrl_lines(rt : reg_ptr_t) return ctrl_lines_t is
|
|
||||||
variable result : ctrl_lines_t;
|
|
||||||
variable op : integer range 0 to 2**reg_ptr_t'length-1;
|
|
||||||
begin
|
|
||||||
|
|
||||||
result := ctrl_lines_default;
|
|
||||||
|
|
||||||
op := to_integer(rt);
|
|
||||||
case op is
|
|
||||||
|
|
||||||
-- when op_bgez =>
|
|
||||||
when 1 =>
|
|
||||||
result.branch := '1';
|
|
||||||
result.bc_src := bc_ltz_gez;
|
|
||||||
result.bc_not := '1';
|
|
||||||
|
|
||||||
-- when op_bgezal =>
|
|
||||||
when 17 =>
|
|
||||||
result.branch := '1';
|
|
||||||
result.bc_src := bc_ltz_gez;
|
|
||||||
result.bc_not := '1';
|
|
||||||
result.wptr_srcsel := wptr_src_const;
|
|
||||||
result.reg_write := '1';
|
|
||||||
result.reg_link := '1';
|
|
||||||
|
|
||||||
-- when op_bltz =>
|
|
||||||
when 0 =>
|
|
||||||
result.branch := '1';
|
|
||||||
result.bc_src := bc_ltz_gez;
|
|
||||||
result.bc_not := '0';
|
|
||||||
|
|
||||||
-- when op_bltzal =>
|
|
||||||
when 16 =>
|
|
||||||
result.branch := '1';
|
|
||||||
result.bc_src := bc_ltz_gez;
|
|
||||||
result.bc_not := '0';
|
|
||||||
result.wptr_srcsel := wptr_src_const;
|
|
||||||
result.reg_write := '1';
|
|
||||||
result.reg_link := '1';
|
|
||||||
|
|
||||||
when others =>
|
|
||||||
result.exc_illegal := '1';
|
|
||||||
|
|
||||||
end case;
|
|
||||||
|
|
||||||
return result;
|
|
||||||
|
|
||||||
end regimm_ctrl_lines;
|
|
||||||
|
|
||||||
function gen_rom_regimm return rom_regimm_t is
|
|
||||||
variable result : rom_regimm_t;
|
|
||||||
variable rt : reg_ptr_t;
|
|
||||||
begin
|
|
||||||
|
|
||||||
for i in 0 to 2**reg_ptr_t'length-1 loop
|
|
||||||
rt := to_unsigned(i, reg_ptr_t'length);
|
|
||||||
result(i) := regimm_ctrl_lines(rt);
|
|
||||||
end loop;
|
|
||||||
|
|
||||||
return result;
|
|
||||||
end gen_rom_regimm;
|
|
||||||
|
|
||||||
function opcode_ctrl_lines(opc : opcode_t) return ctrl_lines_t is
|
|
||||||
variable result : ctrl_lines_t;
|
|
||||||
variable op : integer range 0 to 2**opcode_t'length-1;
|
|
||||||
begin
|
|
||||||
|
|
||||||
result := ctrl_lines_default;
|
|
||||||
|
|
||||||
op := to_integer(opc);
|
|
||||||
case op is
|
|
||||||
|
|
||||||
-- when op_addi =>
|
|
||||||
when 8 =>
|
|
||||||
result.imm_src := src_imm32;
|
|
||||||
result.alu.outsel := alu_adder;
|
|
||||||
result.alu.add := '1';
|
|
||||||
result.alu.op1_src := alu_src_reg;
|
|
||||||
result.alu.op2_src := alu_src_imm;
|
|
||||||
result.reg_write := '1';
|
|
||||||
result.alu_exc_en := '1';
|
|
||||||
|
|
||||||
-- when op_addiu =>
|
|
||||||
when 9 =>
|
|
||||||
result.imm_src := src_imm32;
|
|
||||||
result.alu.outsel := alu_adder;
|
|
||||||
result.alu.add := '1';
|
|
||||||
result.alu.op1_src := alu_src_reg;
|
|
||||||
result.alu.op2_src := alu_src_imm;
|
|
||||||
result.reg_write := '1';
|
|
||||||
|
|
||||||
-- when op_andi =>
|
|
||||||
when 12 =>
|
|
||||||
result.imm_src := src_imm16;
|
|
||||||
result.alu.outsel := alu_and;
|
|
||||||
result.alu.op1_src := alu_src_reg;
|
|
||||||
result.alu.op2_src := alu_src_imm;
|
|
||||||
result.reg_write := '1';
|
|
||||||
|
|
||||||
-- when op_beq =>
|
|
||||||
when 4 =>
|
|
||||||
result.branch := '1';
|
|
||||||
result.bc_src := bc_eq_ne;
|
|
||||||
result.bc_not := '0';
|
|
||||||
|
|
||||||
-- when op_bgtz =>
|
|
||||||
when 7 =>
|
|
||||||
result.branch := '1';
|
|
||||||
result.bc_src := bc_lez_gtz;
|
|
||||||
result.bc_not := '1';
|
|
||||||
|
|
||||||
-- when op_blez =>
|
|
||||||
when 6 =>
|
|
||||||
result.branch := '1';
|
|
||||||
result.bc_src := bc_lez_gtz;
|
|
||||||
result.bc_not := '0';
|
|
||||||
|
|
||||||
-- when op_bne =>
|
|
||||||
when 5 =>
|
|
||||||
result.branch := '1';
|
|
||||||
result.bc_src := bc_eq_ne;
|
|
||||||
result.bc_not := '1';
|
|
||||||
|
|
||||||
-- when op_cop =>
|
|
||||||
when 16 | 17 | 18 | 19 =>
|
|
||||||
result.cop_instr_en := '1';
|
|
||||||
|
|
||||||
-- when op_j =>
|
|
||||||
when 2 =>
|
|
||||||
result.jump := '1';
|
|
||||||
|
|
||||||
-- when op_jal =>
|
|
||||||
when 3 =>
|
|
||||||
result.jump := '1';
|
|
||||||
result.wptr_srcsel := wptr_src_const;
|
|
||||||
result.reg_write := '1';
|
|
||||||
result.reg_link := '1';
|
|
||||||
|
|
||||||
-- when op_lb =>
|
|
||||||
when 32 =>
|
|
||||||
result.imm_src := src_imm32;
|
|
||||||
result.dmem_en := '1';
|
|
||||||
result.reg_write := '1';
|
|
||||||
result.shift_byp := '0';
|
|
||||||
result.byte_en_byp := '1';
|
|
||||||
result.sign_ext_byp := '0';
|
|
||||||
result.load_signed := '1';
|
|
||||||
result.word4_en := '1';
|
|
||||||
|
|
||||||
-- when op_lbu =>
|
|
||||||
when 36 =>
|
|
||||||
result.imm_src := src_imm32;
|
|
||||||
result.dmem_en := '1';
|
|
||||||
result.reg_write := '1';
|
|
||||||
result.shift_byp := '0';
|
|
||||||
result.byte_en_byp := '1';
|
|
||||||
result.sign_ext_byp := '0';
|
|
||||||
result.load_signed := '0';
|
|
||||||
result.word4_en := '1';
|
|
||||||
|
|
||||||
-- when op_lh =>
|
|
||||||
when 33 =>
|
|
||||||
result.imm_src := src_imm32;
|
|
||||||
result.dmem_en := '1';
|
|
||||||
result.reg_write := '1';
|
|
||||||
result.shift_byp := '0';
|
|
||||||
result.sign_ext_byp := '0';
|
|
||||||
result.byte_en_byp := '1';
|
|
||||||
result.load_signed := '1';
|
|
||||||
result.word2_en := '1';
|
|
||||||
result.except_en := '1';
|
|
||||||
|
|
||||||
-- when op_lhu =>
|
|
||||||
when 37 =>
|
|
||||||
result.imm_src := src_imm32;
|
|
||||||
result.dmem_en := '1';
|
|
||||||
result.reg_write := '1';
|
|
||||||
result.shift_byp := '0';
|
|
||||||
result.sign_ext_byp := '0';
|
|
||||||
result.byte_en_byp := '1';
|
|
||||||
result.load_signed := '0';
|
|
||||||
result.word2_en := '1';
|
|
||||||
result.except_en := '1';
|
|
||||||
|
|
||||||
-- when op_lui =>
|
|
||||||
when 15 =>
|
|
||||||
result.imm_src := src_imm16_high;
|
|
||||||
result.alu.op1_src := alu_src_reg;
|
|
||||||
result.alu.op2_src := alu_src_imm;
|
|
||||||
result.alu.outsel := alu_adder;
|
|
||||||
result.reg_write := '1';
|
|
||||||
result.alu.add := '1';
|
|
||||||
|
|
||||||
-- when op_lw =>
|
|
||||||
when 35 =>
|
|
||||||
-- result.imm_src := src_imm32;
|
|
||||||
result.dmem_en := '1';
|
|
||||||
result.reg_write := '1';
|
|
||||||
result.except_en := '1';
|
|
||||||
|
|
||||||
-- when op_lwl =>
|
|
||||||
when 34 =>
|
|
||||||
-- result.imm_src := src_imm32;
|
|
||||||
result.dmem_en := '1';
|
|
||||||
result.reg_write := '1';
|
|
||||||
result.shift_byp := '0';
|
|
||||||
result.byte_en_byp := '0';
|
|
||||||
result.shift_offset := "01";
|
|
||||||
result.align_left := '1';
|
|
||||||
|
|
||||||
-- when op_lwr =>
|
|
||||||
when 38 =>
|
|
||||||
-- result.imm_src := src_imm32;
|
|
||||||
result.dmem_en := '1';
|
|
||||||
result.reg_write := '1';
|
|
||||||
result.shift_byp := '0';
|
|
||||||
result.byte_en_byp := '0';
|
|
||||||
result.shift_offset := "00";
|
|
||||||
result.align_left := '0';
|
|
||||||
|
|
||||||
-- when op_ori =>
|
|
||||||
when 13 =>
|
|
||||||
result.imm_src := src_imm16;
|
|
||||||
result.alu.outsel := alu_or;
|
|
||||||
result.alu.op1_src := alu_src_reg;
|
|
||||||
result.alu.op2_src := alu_src_imm;
|
|
||||||
result.reg_write := '1';
|
|
||||||
|
|
||||||
-- when op_sb =>
|
|
||||||
when 40 =>
|
|
||||||
result.dmem_en := '1';
|
|
||||||
result.dmem_we := '1';
|
|
||||||
-- result.imm_src := src_imm32;
|
|
||||||
result.shift_byp := '0';
|
|
||||||
result.byte_en_byp := '0';
|
|
||||||
result.word4_en := '1';
|
|
||||||
|
|
||||||
-- when op_sh =>
|
|
||||||
when 41 =>
|
|
||||||
result.dmem_en := '1';
|
|
||||||
result.dmem_we := '1';
|
|
||||||
-- result.imm_src := src_imm32;
|
|
||||||
result.shift_byp := '0';
|
|
||||||
result.byte_en_byp := '0';
|
|
||||||
result.word2_en := '1';
|
|
||||||
result.except_en := '1';
|
|
||||||
|
|
||||||
-- when op_slti =>
|
|
||||||
when 10 =>
|
|
||||||
result.alu.outsel := alu_lts;
|
|
||||||
result.alu.add := '0';
|
|
||||||
result.alu.op1_src := alu_src_reg;
|
|
||||||
result.alu.op2_src := alu_src_imm;
|
|
||||||
result.imm_src := src_imm32;
|
|
||||||
result.reg_write := '1';
|
|
||||||
|
|
||||||
-- when op_sltiu =>
|
|
||||||
when 11 =>
|
|
||||||
result.alu.outsel := alu_ltu;
|
|
||||||
result.alu.add := '0';
|
|
||||||
result.alu.op1_src := alu_src_reg;
|
|
||||||
result.alu.op2_src := alu_src_imm;
|
|
||||||
result.imm_src := src_imm32;
|
|
||||||
result.reg_write := '1';
|
|
||||||
|
|
||||||
-- when op_sw =>
|
|
||||||
when 43 =>
|
|
||||||
result.dmem_en := '1';
|
|
||||||
result.dmem_we := '1';
|
|
||||||
-- result.imm_src := src_imm32;
|
|
||||||
result.except_en := '1';
|
|
||||||
|
|
||||||
-- when op_swl =>
|
|
||||||
when 42 =>
|
|
||||||
result.dmem_en := '1';
|
|
||||||
result.dmem_we := '1';
|
|
||||||
-- result.imm_src := src_imm32;
|
|
||||||
result.shift_byp := '0';
|
|
||||||
result.byte_en_byp := '0';
|
|
||||||
result.shift_offset := "01";
|
|
||||||
|
|
||||||
-- when op_swr =>
|
|
||||||
when 46 =>
|
|
||||||
result.dmem_en := '1';
|
|
||||||
result.dmem_we := '1';
|
|
||||||
-- result.imm_src := src_imm32;
|
|
||||||
result.shift_byp := '0';
|
|
||||||
result.byte_en_byp := '0';
|
|
||||||
result.align_left := '1';
|
|
||||||
|
|
||||||
-- when op_xori =>
|
|
||||||
when 14 =>
|
|
||||||
result.imm_src := src_imm16;
|
|
||||||
result.alu.outsel := alu_xor;
|
|
||||||
result.alu.op1_src := alu_src_reg;
|
|
||||||
result.alu.op2_src := alu_src_imm;
|
|
||||||
result.reg_write := '1';
|
|
||||||
|
|
||||||
when others =>
|
|
||||||
result.exc_illegal := '1';
|
|
||||||
|
|
||||||
end case;
|
|
||||||
|
|
||||||
return result;
|
|
||||||
|
|
||||||
end opcode_ctrl_lines;
|
|
||||||
|
|
||||||
function gen_rom_opcode return rom_opcode_t is
|
|
||||||
variable result : rom_opcode_t;
|
|
||||||
variable opc : opcode_t;
|
|
||||||
begin
|
|
||||||
|
|
||||||
for i in 0 to 2**opcode_t'length-1 loop
|
|
||||||
opc := to_unsigned(i, opcode_t'length);
|
|
||||||
result(i) := opcode_ctrl_lines(opc);
|
|
||||||
end loop;
|
|
||||||
|
|
||||||
return result;
|
|
||||||
end gen_rom_opcode;
|
|
||||||
|
|
||||||
end mips_instr;
|
|
||||||
|
|
||||||
--------------------------------------------------------------------------
|
|
||||||
--------------------------------------------------------------------------
|
|
||||||
|
|
||||||
@@ -1,454 +0,0 @@
|
|||||||
--------------------------------------------------------------------------
|
|
||||||
-- Project: JIPS, a portable 32-bit RISC CPU written in VHDL
|
|
||||||
-- This file: The arithmetic logic unit
|
|
||||||
--
|
|
||||||
-- Copyright (C) 2007 J. Ahrensfeld
|
|
||||||
--
|
|
||||||
-- This program is free software: you can redistribute it and/or modify
|
|
||||||
-- it under the terms of the GNU General Public License as published by
|
|
||||||
-- the Free Software Foundation, either version 3 of the License, or
|
|
||||||
-- (at your option) any later version.
|
|
||||||
--
|
|
||||||
-- This program is distributed in the hope that it will be useful,
|
|
||||||
-- but WITHOUT ANY WARRANTY; without even the implied warranty of
|
|
||||||
-- MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
|
||||||
-- GNU General Public License for more details.
|
|
||||||
--
|
|
||||||
-- You should have received a copy of the GNU General Public License
|
|
||||||
-- along with this program. If not, see <http://www.gnu.org/licenses/>.
|
|
||||||
--
|
|
||||||
-- For questions and ideas, please contact the author at jens@jayfield.org
|
|
||||||
--
|
|
||||||
--------------------------------------------------------------------------
|
|
||||||
|
|
||||||
library IEEE;
|
|
||||||
use IEEE.STD_LOGIC_1164.ALL;
|
|
||||||
use IEEE.numeric_std.ALL;
|
|
||||||
|
|
||||||
use work.mips_types.all;
|
|
||||||
|
|
||||||
entity muldiv is
|
|
||||||
Port
|
|
||||||
(
|
|
||||||
rst : in std_logic;
|
|
||||||
clk : in std_logic;
|
|
||||||
hilo_we : in std_logic;
|
|
||||||
din_hi : in word_t;
|
|
||||||
din_lo : in word_t;
|
|
||||||
mul_divn : in std_logic;
|
|
||||||
start : in std_logic;
|
|
||||||
s_un : in std_logic;
|
|
||||||
hilo_sel : in std_logic;
|
|
||||||
busy : out std_logic;
|
|
||||||
dout : out word_t
|
|
||||||
);
|
|
||||||
end muldiv;
|
|
||||||
|
|
||||||
architecture Behavioral of muldiv is
|
|
||||||
|
|
||||||
subtype pprod_t is unsigned (39 downto 0);
|
|
||||||
subtype prod_t is unsigned (63 downto 0);
|
|
||||||
subtype byte_t is unsigned (7 downto 0);
|
|
||||||
|
|
||||||
type pprod_array_t is array (natural range <>) of pprod_t;
|
|
||||||
type word_array_t is array (natural range <>) of word_t;
|
|
||||||
type byte_array_t is array (natural range <>) of byte_t;
|
|
||||||
|
|
||||||
signal pprod : pprod_array_t(0 to 3);
|
|
||||||
signal sign1 : std_logic;
|
|
||||||
signal sign2 : std_logic;
|
|
||||||
signal s1_r : std_logic;
|
|
||||||
signal s2_r : std_logic;
|
|
||||||
signal sr_r : std_logic;
|
|
||||||
signal cy : unsigned (3 downto 0);
|
|
||||||
signal mul_start : std_logic;
|
|
||||||
signal mul_en : std_logic;
|
|
||||||
signal sum_en : std_logic;
|
|
||||||
signal pre_sum_vld : std_logic;
|
|
||||||
signal pp_reg : unsigned (63 downto 8);
|
|
||||||
signal pre_const : word_array_t(0 to 1);
|
|
||||||
signal result : prod_t;
|
|
||||||
signal add_op1 : unsigned (39 downto 0);
|
|
||||||
signal add_op2 : unsigned (39 downto 0);
|
|
||||||
signal add_res : unsigned (39 downto 0);
|
|
||||||
signal ppadd_op1 : word_array_t(0 to 3);
|
|
||||||
signal ppadd_op2 : word_array_t(0 to 3);
|
|
||||||
signal ppadd_res : word_array_t(0 to 3);
|
|
||||||
signal ppadd_cyi : unsigned (3 downto 0);
|
|
||||||
signal ppadd_cyo : unsigned (3 downto 0);
|
|
||||||
|
|
||||||
signal pp_op1_r : word_t;
|
|
||||||
signal pp_op1 : word_t;
|
|
||||||
signal pp_op2 : word_t;
|
|
||||||
signal pp_op2_r : byte_array_t(0 to 3);
|
|
||||||
signal bsy : std_logic;
|
|
||||||
|
|
||||||
signal div_add_res : unsigned (32 downto 0);
|
|
||||||
signal div_add_op1 : unsigned (32 downto 0);
|
|
||||||
signal div_add_op2 : unsigned (32 downto 0);
|
|
||||||
signal div_add_cyi : std_logic;
|
|
||||||
signal div_qbit : std_logic;
|
|
||||||
signal div_start : std_logic;
|
|
||||||
signal div_en : std_logic;
|
|
||||||
|
|
||||||
signal div_A : unsigned (32 downto 0);
|
|
||||||
signal div_M : unsigned (32 downto 0);
|
|
||||||
signal div_M_n : unsigned (32 downto 0);
|
|
||||||
signal div_Q : word_t;
|
|
||||||
|
|
||||||
type md_state_t is (md_rdy, mul_pre1, mul_pre2, mul_pp, mul_sum, div_process, div_post1, div_post2, div_post3);
|
|
||||||
signal s, sn : md_state_t;
|
|
||||||
signal cycle_cnt : natural range 0 to 31;
|
|
||||||
signal cycle_cnt_preset : natural range 0 to 31;
|
|
||||||
signal cycle_cnt_load : std_logic;
|
|
||||||
signal div_fin_en : unsigned (2 downto 0);
|
|
||||||
|
|
||||||
--------------------------------------------------------------------------
|
|
||||||
begin
|
|
||||||
-- 9A0CD0570B88D78
|
|
||||||
|
|
||||||
busy <= bsy;
|
|
||||||
|
|
||||||
sign1 <= din_hi(din_hi'left) and s_un;
|
|
||||||
sign2 <= din_lo(din_lo'left) and s_un;
|
|
||||||
pp_op1 <= not din_hi when sign1 = '1' else din_hi;
|
|
||||||
pp_op2 <= not din_lo when sign2 = '1' else din_lo;
|
|
||||||
|
|
||||||
--------------------------------------------------------------------------
|
|
||||||
md_state:
|
|
||||||
process(s, start, mul_divn, cycle_cnt)
|
|
||||||
begin
|
|
||||||
|
|
||||||
bsy <= '1';
|
|
||||||
cycle_cnt_load <= '0';
|
|
||||||
cycle_cnt_preset <= 7;
|
|
||||||
|
|
||||||
mul_en <= '0';
|
|
||||||
div_en <= '0';
|
|
||||||
sum_en <= '0';
|
|
||||||
pre_sum_vld <= '0';
|
|
||||||
mul_start <= '0';
|
|
||||||
div_start <= '0';
|
|
||||||
div_fin_en <= "000";
|
|
||||||
sn <= s;
|
|
||||||
case s is
|
|
||||||
when md_rdy =>
|
|
||||||
bsy <= '0';
|
|
||||||
if start = '1' then
|
|
||||||
if mul_divn = '1' then
|
|
||||||
sn <= mul_pre1;
|
|
||||||
cycle_cnt_load <= '1';
|
|
||||||
cycle_cnt_preset <= 7;
|
|
||||||
mul_start <= '1';
|
|
||||||
else
|
|
||||||
sn <= div_process;
|
|
||||||
cycle_cnt_load <= '1';
|
|
||||||
cycle_cnt_preset <= 31;
|
|
||||||
div_start <= '1';
|
|
||||||
end if;
|
|
||||||
end if;
|
|
||||||
when mul_pre1 =>
|
|
||||||
pre_sum_vld <= '1';
|
|
||||||
mul_en <= '1';
|
|
||||||
sn <= mul_pre2;
|
|
||||||
when mul_pre2 =>
|
|
||||||
pre_sum_vld <= '1';
|
|
||||||
mul_en <= '1';
|
|
||||||
sn <= mul_pp;
|
|
||||||
when mul_pp =>
|
|
||||||
mul_en <= '1';
|
|
||||||
if cycle_cnt = 0 then
|
|
||||||
cycle_cnt_load <= '1';
|
|
||||||
cycle_cnt_preset <= 3;
|
|
||||||
sn <= mul_sum;
|
|
||||||
end if;
|
|
||||||
when mul_sum =>
|
|
||||||
sum_en <= '1';
|
|
||||||
if cycle_cnt = 0 then
|
|
||||||
bsy <= '0';
|
|
||||||
sn <= md_rdy;
|
|
||||||
end if;
|
|
||||||
when div_process =>
|
|
||||||
div_en <= '1';
|
|
||||||
if cycle_cnt = 0 then
|
|
||||||
sn <= div_post1;
|
|
||||||
end if;
|
|
||||||
when div_post1 =>
|
|
||||||
div_fin_en <= "001";
|
|
||||||
sn <= div_post2;
|
|
||||||
when div_post2 =>
|
|
||||||
div_fin_en <= "010";
|
|
||||||
sn <= div_post3;
|
|
||||||
when div_post3 =>
|
|
||||||
div_fin_en <= "100";
|
|
||||||
sn <= md_rdy;
|
|
||||||
bsy <= '0';
|
|
||||||
when others =>
|
|
||||||
sn <= md_rdy;
|
|
||||||
end case;
|
|
||||||
|
|
||||||
end process;
|
|
||||||
|
|
||||||
md_state_next:
|
|
||||||
process(clk)
|
|
||||||
begin
|
|
||||||
if rising_edge(clk) then
|
|
||||||
if rst = '1' then
|
|
||||||
s <= md_rdy;
|
|
||||||
else
|
|
||||||
s <= sn;
|
|
||||||
end if;
|
|
||||||
end if;
|
|
||||||
end process;
|
|
||||||
|
|
||||||
md_cycle_cnt:
|
|
||||||
process(clk)
|
|
||||||
begin
|
|
||||||
if rising_edge(clk) then
|
|
||||||
if rst = '1' then
|
|
||||||
cycle_cnt <= 0;
|
|
||||||
elsif cycle_cnt_load = '1' then
|
|
||||||
cycle_cnt <= cycle_cnt_preset;
|
|
||||||
elsif cycle_cnt /= 0 then
|
|
||||||
cycle_cnt <= cycle_cnt - 1;
|
|
||||||
end if;
|
|
||||||
end if;
|
|
||||||
end process;
|
|
||||||
|
|
||||||
proc_out_reg:
|
|
||||||
process(hilo_sel, result)
|
|
||||||
begin
|
|
||||||
if hilo_sel = '1' then
|
|
||||||
dout <= result(63 downto 32);
|
|
||||||
else
|
|
||||||
dout <= result(31 downto 0);
|
|
||||||
end if;
|
|
||||||
end process;
|
|
||||||
|
|
||||||
proc_in_reg:
|
|
||||||
process(clk)
|
|
||||||
variable pre_cond : unsigned(1 downto 0);
|
|
||||||
begin
|
|
||||||
if rising_edge(clk) then
|
|
||||||
if mul_start = '1' or div_start = '1' then
|
|
||||||
pp_op1_r <= pp_op1;
|
|
||||||
pre_const(0) <= (others => '0');
|
|
||||||
pre_const(1) <= (others => '0');
|
|
||||||
pre_cond := (din_hi(din_hi'left) and s_un) & (din_lo(din_lo'left) and s_un);
|
|
||||||
s1_r <= pre_cond(1);
|
|
||||||
s2_r <= pre_cond(0);
|
|
||||||
sr_r <= pre_cond(0) xor pre_cond(1);
|
|
||||||
case pre_cond is
|
|
||||||
when "01" =>
|
|
||||||
pre_const(0) <= din_hi;
|
|
||||||
pre_const(1) <= X"FFFF_FFFF";
|
|
||||||
when "10" =>
|
|
||||||
pre_const(0) <= X"0000_0000";
|
|
||||||
pre_const(1) <= X"FFFF_FFFF";
|
|
||||||
when "11" =>
|
|
||||||
pre_const(0) <= not din_hi;
|
|
||||||
pre_const(1) <= X"0000_0001";
|
|
||||||
when others => null;
|
|
||||||
end case;
|
|
||||||
elsif pre_sum_vld = '1' then
|
|
||||||
pre_const(0) <= pre_const(1);
|
|
||||||
end if;
|
|
||||||
end if;
|
|
||||||
end process;
|
|
||||||
|
|
||||||
proc_mul_sr:
|
|
||||||
process(clk)
|
|
||||||
begin
|
|
||||||
if rising_edge(clk) then
|
|
||||||
if mul_start = '1' then
|
|
||||||
for i in 0 to 3 loop
|
|
||||||
cy(i) <= '0';
|
|
||||||
pprod(i) <= ppadd_res(i) & X"00";
|
|
||||||
end loop;
|
|
||||||
elsif mul_en = '1' then
|
|
||||||
for i in 0 to 3 loop
|
|
||||||
cy(i) <= ppadd_cyo(i);
|
|
||||||
pprod(i) <= ppadd_res(i) & pprod(i)(8 downto 1);
|
|
||||||
end loop;
|
|
||||||
elsif sum_en = '1' then
|
|
||||||
for i in 1 to 3 loop
|
|
||||||
pprod(i-1) <= pprod(i);
|
|
||||||
end loop;
|
|
||||||
end if;
|
|
||||||
end if;
|
|
||||||
end process;
|
|
||||||
|
|
||||||
gen_mul32x8pp:
|
|
||||||
for i in 0 to 3 generate
|
|
||||||
begin
|
|
||||||
|
|
||||||
pp_adder_mux:
|
|
||||||
process(mul_start, pp_op1, pp_op2, pp_op1_r, pp_op2_r(i), s1_r, sign1, pprod(i), cy(i))
|
|
||||||
variable v2 : unsigned(7 downto 0);
|
|
||||||
begin
|
|
||||||
ppadd_cyi(i) <= '0';
|
|
||||||
ppadd_op1(i) <= (others => '0');
|
|
||||||
if mul_start = '1' then
|
|
||||||
ppadd_op2(i) <= (others => '0');
|
|
||||||
v2 := pp_op2(8*(i+1)-1 downto 8*i);
|
|
||||||
if v2(0) = '1' then
|
|
||||||
ppadd_cyi(i) <= sign1;
|
|
||||||
ppadd_op1(i) <= pp_op1;
|
|
||||||
end if;
|
|
||||||
else
|
|
||||||
ppadd_op2(i) <= cy(i) & pprod(i)(39 downto 9);
|
|
||||||
v2 := pp_op2_r(i);
|
|
||||||
if v2(0) = '1' then
|
|
||||||
ppadd_cyi(i) <= s1_r;
|
|
||||||
ppadd_op1(i) <= pp_op1_r;
|
|
||||||
end if;
|
|
||||||
end if;
|
|
||||||
end process;
|
|
||||||
|
|
||||||
pp_adder:
|
|
||||||
process(ppadd_op1(i), ppadd_op2(i), ppadd_cyi(i))
|
|
||||||
variable sum_pp : unsigned(33 downto 0);
|
|
||||||
begin
|
|
||||||
sum_pp := ('0' & ppadd_op1(i) & ppadd_cyi(i)) + ('0' & ppadd_op2(i) & ppadd_cyi(i));
|
|
||||||
ppadd_res(i) <= sum_pp(sum_pp'left-1 downto 1);
|
|
||||||
ppadd_cyo(i) <= sum_pp(sum_pp'left);
|
|
||||||
end process;
|
|
||||||
|
|
||||||
proc_mul_ctrl:
|
|
||||||
process(clk)
|
|
||||||
begin
|
|
||||||
if rising_edge(clk) then
|
|
||||||
if mul_start = '1' then
|
|
||||||
pp_op2_r(i) <= '0' & pp_op2(8*(i+1)-1 downto 8*i+1);
|
|
||||||
elsif mul_en = '1' then
|
|
||||||
pp_op2_r(i) <= '0' & pp_op2_r(i)(7 downto 1);
|
|
||||||
end if;
|
|
||||||
end if;
|
|
||||||
end process;
|
|
||||||
|
|
||||||
end generate;
|
|
||||||
|
|
||||||
comb_mul_adder:
|
|
||||||
process(add_op1, add_op2)
|
|
||||||
variable sum_mul : unsigned(39 downto 0);
|
|
||||||
begin
|
|
||||||
sum_mul := (add_op1) + (add_op2);
|
|
||||||
add_res <= sum_mul(sum_mul'left downto 0);
|
|
||||||
end process;
|
|
||||||
|
|
||||||
comb_mul_adder_mux:
|
|
||||||
process(pre_const, pre_sum_vld, pp_reg, pprod, sr_r)
|
|
||||||
variable s_ext : std_logic;
|
|
||||||
begin
|
|
||||||
if pre_sum_vld = '1' then
|
|
||||||
add_op1 <= pp_reg(63 downto 24);
|
|
||||||
add_op2 <= pre_const(0) & X"00";
|
|
||||||
else
|
|
||||||
s_ext := pp_reg(63) and sr_r;
|
|
||||||
add_op1 <= (7 downto 0 => s_ext) & pp_reg(63 downto 32);
|
|
||||||
add_op2 <= pprod(0);
|
|
||||||
end if;
|
|
||||||
end process;
|
|
||||||
|
|
||||||
comb_mul:
|
|
||||||
process(clk)
|
|
||||||
variable tmp : prod_t;
|
|
||||||
begin
|
|
||||||
if rising_edge(clk) then
|
|
||||||
if mul_start = '1' then
|
|
||||||
pp_reg <= (others => '0');
|
|
||||||
elsif pre_sum_vld = '1' then
|
|
||||||
pp_reg <= add_res & X"0000";
|
|
||||||
elsif sum_en = '1' then
|
|
||||||
tmp := add_res & pp_reg(31 downto 8);
|
|
||||||
pp_reg <= tmp(63 downto 8);
|
|
||||||
result <= tmp;
|
|
||||||
if sr_r = '1' then
|
|
||||||
result <= not tmp;
|
|
||||||
end if;
|
|
||||||
elsif div_fin_en(1) = '1' then
|
|
||||||
result(63 downto 32) <= div_A(31 downto 0);
|
|
||||||
if s1_r = '1' then
|
|
||||||
result(63 downto 32) <= div_add_res(31 downto 0);
|
|
||||||
end if;
|
|
||||||
elsif div_fin_en(2) = '1' then
|
|
||||||
result(31 downto 0) <= div_Q;
|
|
||||||
if sr_r = '1' then
|
|
||||||
result(31 downto 0) <= div_add_res(31 downto 0);
|
|
||||||
end if;
|
|
||||||
elsif hilo_we = '1' then
|
|
||||||
if hilo_sel = '1' then
|
|
||||||
result(63 downto 32) <= din_hi;
|
|
||||||
else
|
|
||||||
result(31 downto 0) <= din_hi;
|
|
||||||
end if;
|
|
||||||
end if;
|
|
||||||
end if;
|
|
||||||
end process;
|
|
||||||
|
|
||||||
div_adder:
|
|
||||||
process(div_add_op1, div_add_op2, div_add_cyi)
|
|
||||||
variable sum_div : unsigned(33 downto 0);
|
|
||||||
begin
|
|
||||||
sum_div := (div_add_op1 & div_add_cyi) + (div_add_op2 & div_add_cyi);
|
|
||||||
div_add_res <= sum_div(sum_div'left downto 1);
|
|
||||||
end process;
|
|
||||||
|
|
||||||
div_adder_mux:
|
|
||||||
process(div_start, div_en, div_fin_en, div_A, div_Q, pp_op1, sign1, s1_r, s2_r, sr_r, div_qbit, div_M, div_M_n)
|
|
||||||
begin
|
|
||||||
|
|
||||||
div_add_cyi <= s2_r xor div_qbit;
|
|
||||||
div_add_op1 <= div_A(31 downto 0) & div_Q(31);
|
|
||||||
div_add_op2 <= (others => '0');
|
|
||||||
if div_start = '1' then
|
|
||||||
div_add_op1 <= '0' & pp_op1;
|
|
||||||
div_add_cyi <= sign1;
|
|
||||||
elsif div_en = '1' then
|
|
||||||
div_add_op2 <= div_M;
|
|
||||||
if div_qbit = '1' then
|
|
||||||
div_add_op2 <= div_M_n;
|
|
||||||
end if;
|
|
||||||
elsif div_fin_en(0) = '1' then
|
|
||||||
div_add_op2 <= div_M;
|
|
||||||
div_add_cyi <= s2_r;
|
|
||||||
div_add_op1 <= '0' & div_A(31 downto 0);
|
|
||||||
elsif div_fin_en(1) = '1' then
|
|
||||||
div_add_cyi <= s1_r;
|
|
||||||
div_add_op1 <= '0' & not div_A(31 downto 0);
|
|
||||||
elsif div_fin_en(2) = '1' then
|
|
||||||
div_add_cyi <= sr_r;
|
|
||||||
div_add_op1 <= '0' & not div_Q;
|
|
||||||
end if;
|
|
||||||
end process;
|
|
||||||
|
|
||||||
divide:
|
|
||||||
process(clk)
|
|
||||||
variable quo : std_logic;
|
|
||||||
begin
|
|
||||||
if rising_edge(clk) then
|
|
||||||
if div_start = '1' then
|
|
||||||
div_qbit <= '1';
|
|
||||||
div_Q <= div_add_res(31 downto 0);
|
|
||||||
div_A <= (others => '0');
|
|
||||||
if sign2 = '1' then
|
|
||||||
div_M_n <= '1' & din_lo;
|
|
||||||
div_M <= '0' & not din_lo;
|
|
||||||
else
|
|
||||||
div_M_n <= '1' & not din_lo;
|
|
||||||
div_M <= '0' & din_lo;
|
|
||||||
end if;
|
|
||||||
elsif div_en = '1' then
|
|
||||||
div_qbit <= not div_add_res(32);
|
|
||||||
div_A <= div_add_res(32 downto 0);
|
|
||||||
div_Q <= div_Q(30 downto 0) & not div_add_res(32);
|
|
||||||
elsif div_fin_en(0) = '1' then
|
|
||||||
if div_A(32) = '1' then
|
|
||||||
div_A <= '0' & div_add_res(31 downto 0);
|
|
||||||
end if;
|
|
||||||
end if;
|
|
||||||
end if;
|
|
||||||
end process;
|
|
||||||
|
|
||||||
--------------------------------------------------------------------------
|
|
||||||
end Behavioral;
|
|
||||||
@@ -1,914 +0,0 @@
|
|||||||
--------------------------------------------------------------------------
|
|
||||||
-- Project: JIPS, a portable 32-bit RISC CPU written in VHDL
|
|
||||||
-- This file: The pipeline
|
|
||||||
--
|
|
||||||
-- Copyright (C) 2008 J. Ahrensfeld
|
|
||||||
--
|
|
||||||
-- This program is free software: you can redistribute it and/or modify
|
|
||||||
-- it under the terms of the GNU General Public License as published by
|
|
||||||
-- the Free Software Foundation, either version 3 of the License, or
|
|
||||||
-- (at your option) any later version.
|
|
||||||
--
|
|
||||||
-- This program is distributed in the hope that it will be useful,
|
|
||||||
-- but WITHOUT ANY WARRANTY; without even the implied warranty of
|
|
||||||
-- MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
|
||||||
-- GNU General Public License for more details.
|
|
||||||
--
|
|
||||||
-- You should have received a copy of the GNU General Public License
|
|
||||||
-- along with this program. If not, see <http://www.gnu.org/licenses/>.
|
|
||||||
--
|
|
||||||
-- For questions and ideas, please contact the author at jens@jayfield.org
|
|
||||||
--
|
|
||||||
--------------------------------------------------------------------------
|
|
||||||
library IEEE;
|
|
||||||
use IEEE.STD_LOGIC_1164.ALL;
|
|
||||||
use IEEE.numeric_std.ALL;
|
|
||||||
|
|
||||||
library work;
|
|
||||||
use work.mips_types.all;
|
|
||||||
use work.mips_instr.all;
|
|
||||||
|
|
||||||
entity pipeline is
|
|
||||||
Port
|
|
||||||
(
|
|
||||||
rst : in STD_LOGIC;
|
|
||||||
clk : in STD_LOGIC;
|
|
||||||
halt : in STD_LOGIC;
|
|
||||||
int : in unsigned(5 downto 0);
|
|
||||||
imem_rdy : in STD_LOGIC;
|
|
||||||
imem_en : out STD_LOGIC;
|
|
||||||
imem_addr : out word_t;
|
|
||||||
imem_data : in word_t;
|
|
||||||
dmem_rdy : in STD_LOGIC;
|
|
||||||
dmem_en : out STD_LOGIC;
|
|
||||||
dmem_re : out STD_LOGIC;
|
|
||||||
dmem_we : out unsigned(3 downto 0);
|
|
||||||
dmem_addr : out word_t;
|
|
||||||
dmem_din : in word_t;
|
|
||||||
dmem_dout : out word_t
|
|
||||||
);
|
|
||||||
end pipeline;
|
|
||||||
|
|
||||||
architecture Behavioral of pipeline is
|
|
||||||
|
|
||||||
--------------------------------------------------------------------------
|
|
||||||
COMPONENT reg_dual is
|
|
||||||
Generic
|
|
||||||
(
|
|
||||||
addr_width : integer := 3;
|
|
||||||
data_width : integer := 8
|
|
||||||
);
|
|
||||||
Port
|
|
||||||
(
|
|
||||||
clk_w : in STD_LOGIC;
|
|
||||||
en : in STD_LOGIC;
|
|
||||||
we : in STD_LOGIC;
|
|
||||||
wptr : in unsigned (addr_width-1 downto 0);
|
|
||||||
din : in unsigned (data_width-1 downto 0);
|
|
||||||
rptr_a : in unsigned (addr_width-1 downto 0);
|
|
||||||
rptr_b : in unsigned (addr_width-1 downto 0);
|
|
||||||
dout_a : out unsigned (data_width-1 downto 0);
|
|
||||||
dout_b : out unsigned (data_width-1 downto 0)
|
|
||||||
);
|
|
||||||
END COMPONENT;
|
|
||||||
|
|
||||||
--------------------------------------------------------------------------
|
|
||||||
COMPONENT idecode_rom is
|
|
||||||
Port
|
|
||||||
(
|
|
||||||
nop : in std_logic;
|
|
||||||
inst_in : in word_t;
|
|
||||||
ctrl_out : out ctrl_lines_t
|
|
||||||
);
|
|
||||||
END COMPONENT;
|
|
||||||
|
|
||||||
--------------------------------------------------------------------------
|
|
||||||
COMPONENT shifter is
|
|
||||||
Generic
|
|
||||||
(
|
|
||||||
data_width : integer
|
|
||||||
);
|
|
||||||
Port
|
|
||||||
(
|
|
||||||
shift_ctrl : in shift_ctrl_t;
|
|
||||||
din : in unsigned (data_width-1 downto 0);
|
|
||||||
dout : out unsigned (data_width-1 downto 0)
|
|
||||||
);
|
|
||||||
END COMPONENT;
|
|
||||||
|
|
||||||
--------------------------------------------------------------------------
|
|
||||||
COMPONENT alu is
|
|
||||||
Generic
|
|
||||||
(
|
|
||||||
data_width : integer
|
|
||||||
);
|
|
||||||
Port
|
|
||||||
(
|
|
||||||
op1_in : in unsigned (data_width-1 downto 0);
|
|
||||||
op2_in : in unsigned (data_width-1 downto 0);
|
|
||||||
op2_shifted : in unsigned (data_width-1 downto 0);
|
|
||||||
ctrl : in alu_ctrl_t;
|
|
||||||
result : out unsigned (data_width-1 downto 0);
|
|
||||||
flags : out alu_flags_t
|
|
||||||
);
|
|
||||||
END COMPONENT;
|
|
||||||
|
|
||||||
--------------------------------------------------------------------------
|
|
||||||
COMPONENT bcu is
|
|
||||||
Generic
|
|
||||||
(
|
|
||||||
data_width : integer
|
|
||||||
);
|
|
||||||
Port
|
|
||||||
(
|
|
||||||
op1_in : in unsigned (data_width-1 downto 0);
|
|
||||||
op2_in : in unsigned (data_width-1 downto 0);
|
|
||||||
flags : out bcu_flags_t
|
|
||||||
);
|
|
||||||
END COMPONENT;
|
|
||||||
|
|
||||||
--------------------------------------------------------------------------
|
|
||||||
COMPONENT cop is
|
|
||||||
Port
|
|
||||||
(
|
|
||||||
rst : in STD_LOGIC;
|
|
||||||
clk : in STD_LOGIC;
|
|
||||||
sdu : in sdu_t;
|
|
||||||
IR_valid : in STD_LOGIC;
|
|
||||||
IR : in word_t;
|
|
||||||
events : in event_t;
|
|
||||||
ctrl_in : in cop_ctrl_in_t;
|
|
||||||
ctrl_out : out cop_ctrl_out_t;
|
|
||||||
din : in word_t;
|
|
||||||
dout : out word_t
|
|
||||||
);
|
|
||||||
END COMPONENT;
|
|
||||||
|
|
||||||
--------------------------------------------------------------------------
|
|
||||||
COMPONENT muldiv is
|
|
||||||
Port
|
|
||||||
(
|
|
||||||
rst : in std_logic;
|
|
||||||
clk : in std_logic;
|
|
||||||
hilo_we : in std_logic;
|
|
||||||
din_hi : in word_t;
|
|
||||||
din_lo : in word_t;
|
|
||||||
mul_divn : in std_logic;
|
|
||||||
start : in std_logic;
|
|
||||||
s_un : in std_logic;
|
|
||||||
hilo_sel : in std_logic;
|
|
||||||
busy : out std_logic;
|
|
||||||
dout : out word_t
|
|
||||||
);
|
|
||||||
END COMPONENT;
|
|
||||||
|
|
||||||
--------------------------------------------------------------------------
|
|
||||||
constant RESET_VECTOR : word_t := X"BFC00000";
|
|
||||||
|
|
||||||
signal ID_stage : ID_t;
|
|
||||||
signal EX_stage : EX_t;
|
|
||||||
signal MEM_stage : MEM_t;
|
|
||||||
signal WB_stage : WB_t;
|
|
||||||
signal clk_2, clk_1 : STD_LOGIC;
|
|
||||||
signal hdu : hdu_t;
|
|
||||||
signal sdu : sdu_t;
|
|
||||||
signal cpu_rst : STD_LOGIC;
|
|
||||||
signal reg_a : word_t;
|
|
||||||
signal reg_b : word_t;
|
|
||||||
signal ctrl_lines : ctrl_lines_t;
|
|
||||||
signal cpu_run : STD_LOGIC;
|
|
||||||
signal branch_ce : STD_LOGIC;
|
|
||||||
signal run_en : STD_LOGIC;
|
|
||||||
signal mul_dep : STD_LOGIC;
|
|
||||||
signal imem_dep : STD_LOGIC;
|
|
||||||
signal dmem_dep : STD_LOGIC;
|
|
||||||
signal cop_ctrl : cop_ctrl_in_t;
|
|
||||||
signal cop_stat : cop_ctrl_out_t;
|
|
||||||
signal cop_din : word_t;
|
|
||||||
signal cop_dout : word_t;
|
|
||||||
signal alu_result : word_t;
|
|
||||||
signal mul_result : word_t;
|
|
||||||
signal mul_busy : STD_LOGIC;
|
|
||||||
signal EX_events_instr : event_t;
|
|
||||||
signal EX_events_alu : event_t;
|
|
||||||
signal EX_events_mem : event_t;
|
|
||||||
signal EX_events : event_t;
|
|
||||||
signal MEM_events : event_t;
|
|
||||||
signal bcu_op_a : word_t;
|
|
||||||
signal bcu_op_b : word_t;
|
|
||||||
signal bcu_flags : bcu_flags_t;
|
|
||||||
signal vaddr : word_t;
|
|
||||||
|
|
||||||
attribute ram_style : string;
|
|
||||||
|
|
||||||
attribute ram_style of reg_a: signal is "distributed";
|
|
||||||
attribute ram_style of reg_b: signal is "distributed";
|
|
||||||
|
|
||||||
signal pc : pc_t;
|
|
||||||
|
|
||||||
--------------------------------------------------------------------------
|
|
||||||
begin
|
|
||||||
|
|
||||||
clk_1 <= clk;
|
|
||||||
clk_2 <= not clk;
|
|
||||||
cpu_run <= run_en;
|
|
||||||
|
|
||||||
-- Stall Detection Unit ---------------------------------------------------
|
|
||||||
sdu.ID_nop <= imem_dep or cop_stat.exc_pending or EX_stage.exc or MEM_stage.exc;
|
|
||||||
sdu.EX_nop <= mul_dep or ID_stage.nop or ID_stage.exc;
|
|
||||||
sdu.MEM_nop <= EX_stage.nop or EX_stage.exc;
|
|
||||||
sdu.WB_nop <= dmem_dep or MEM_stage.nop;
|
|
||||||
|
|
||||||
sdu.ID_stall <= dmem_dep or imem_dep or mul_dep or ID_stage.exc;
|
|
||||||
sdu.EX_stall <= dmem_dep;
|
|
||||||
sdu.MEM_stall <= dmem_dep;
|
|
||||||
sdu.WB_stall <= '0';
|
|
||||||
|
|
||||||
mul_dep <= ID_stage.ctrl.mul_access and (EX_stage.ctrl.mul_start or mul_busy);
|
|
||||||
imem_dep <= not imem_rdy;
|
|
||||||
dmem_dep <= not dmem_rdy and MEM_stage.ctrl.dmem_en;
|
|
||||||
---------------------------------------------------------------------------
|
|
||||||
imem_en <= cpu_run and not (mul_dep or dmem_dep or cop_stat.exc_commit);
|
|
||||||
|
|
||||||
--------------------------------------------------------------------------
|
|
||||||
-- Muldiv
|
|
||||||
--------------------------------------------------------------------------
|
|
||||||
inst_muldiv: muldiv
|
|
||||||
PORT MAP
|
|
||||||
(
|
|
||||||
rst => cpu_rst,
|
|
||||||
clk => clk,
|
|
||||||
hilo_we => EX_stage.ctrl.mul_hilo_we,
|
|
||||||
din_hi => EX_stage.reg_a,
|
|
||||||
din_lo => EX_stage.reg_b,
|
|
||||||
mul_divn => EX_stage.ctrl.mul_mul_divn,
|
|
||||||
start => EX_stage.ctrl.mul_start,
|
|
||||||
s_un => EX_stage.ctrl.mul_s_un,
|
|
||||||
hilo_sel => EX_stage.ctrl.mul_hilo_sel,
|
|
||||||
busy => mul_busy,
|
|
||||||
dout => mul_result
|
|
||||||
);
|
|
||||||
|
|
||||||
--------------------------------------------------------------------------
|
|
||||||
-- Coprocessor
|
|
||||||
--------------------------------------------------------------------------
|
|
||||||
inst_cop: cop
|
|
||||||
PORT MAP
|
|
||||||
(
|
|
||||||
rst => cpu_rst,
|
|
||||||
clk => clk,
|
|
||||||
sdu => sdu,
|
|
||||||
events => MEM_stage.events,
|
|
||||||
IR_valid => ID_stage.ctrl.cop_instr_en,
|
|
||||||
IR => ID_stage.IR,
|
|
||||||
ctrl_in => cop_ctrl,
|
|
||||||
ctrl_out => cop_stat,
|
|
||||||
dout => cop_dout,
|
|
||||||
din => cop_din
|
|
||||||
);
|
|
||||||
|
|
||||||
cop_ctrl.bd_wb <= WB_stage.bd;
|
|
||||||
cop_ctrl.epc_mem <= MEM_stage.pcn;
|
|
||||||
cop_ctrl.epc_wb <= MEM_stage.epc;
|
|
||||||
cop_ctrl.imem_addr <= pc.nxt;
|
|
||||||
cop_ctrl.dmem_addr <= MEM_stage.va;
|
|
||||||
|
|
||||||
--------------------------------------------------------------------------
|
|
||||||
-- IF stage
|
|
||||||
--------------------------------------------------------------------------
|
|
||||||
imem_addr <= pc.curr;
|
|
||||||
|
|
||||||
proc_stage_pc:
|
|
||||||
process(pc, rst, cop_stat)
|
|
||||||
begin
|
|
||||||
if rst = '1' then
|
|
||||||
pc.curr <= RESET_VECTOR after 2 ns;
|
|
||||||
else
|
|
||||||
if pc.is_branch and cop_stat.exc_pending = '0' then
|
|
||||||
pc.curr <= pc.pc_branch after 2 ns;
|
|
||||||
else
|
|
||||||
pc.curr <= pc.nxt after 2 ns;
|
|
||||||
end if;
|
|
||||||
end if;
|
|
||||||
end process;
|
|
||||||
|
|
||||||
proc_stage_pc_branch:
|
|
||||||
process(clk_1)
|
|
||||||
begin
|
|
||||||
if rising_edge(clk_1) then
|
|
||||||
if sdu.ID_stall = '0' then
|
|
||||||
pc.pc_branch <= pc.curr + ID_stage.bimm18;
|
|
||||||
end if;
|
|
||||||
end if;
|
|
||||||
end process;
|
|
||||||
|
|
||||||
proc_stage_pc_next:
|
|
||||||
process(clk_1)
|
|
||||||
begin
|
|
||||||
if rising_edge(clk_1) then
|
|
||||||
branch_ce <= '0';
|
|
||||||
cop_ctrl.exc_left <= '0';
|
|
||||||
if rst = '1' then
|
|
||||||
pc.nxt <= RESET_VECTOR;
|
|
||||||
pc.last <= RESET_VECTOR;
|
|
||||||
elsif cop_stat.exc_commit = '1' then
|
|
||||||
pc.nxt <= cop_stat.exc_vec;
|
|
||||||
elsif sdu.ID_stall = '0' then
|
|
||||||
cop_ctrl.exc_left <= cop_stat.exc_exit;
|
|
||||||
branch_ce <= '1';
|
|
||||||
pc.last <= pc.curr;
|
|
||||||
if ID_stage.ctrl.jump = '1' then
|
|
||||||
pc.nxt <= ID_stage.jimm32;
|
|
||||||
elsif ID_stage.ctrl.jump_long = '1' then
|
|
||||||
pc.nxt <= ID_stage.reg_a;
|
|
||||||
else
|
|
||||||
pc.nxt <= pc.curr + 4;
|
|
||||||
end if;
|
|
||||||
end if;
|
|
||||||
end if;
|
|
||||||
end process;
|
|
||||||
|
|
||||||
proc_stage_branch:
|
|
||||||
process(clk_2)
|
|
||||||
begin
|
|
||||||
if rising_edge(clk_2) and branch_ce = '1' then
|
|
||||||
pc.is_branch <= false;
|
|
||||||
if EX_stage.ctrl.branch = '1' then
|
|
||||||
|
|
||||||
case EX_stage.ctrl.bc_src is
|
|
||||||
|
|
||||||
when bc_eq_ne =>
|
|
||||||
if (EX_stage.ctrl.bc_not xor bcu_flags.eq) = '1' then
|
|
||||||
pc.is_branch <= true;
|
|
||||||
end if;
|
|
||||||
|
|
||||||
when bc_lez_gtz =>
|
|
||||||
if (EX_stage.ctrl.bc_not xor (bcu_flags.z or bcu_flags.ltz)) = '1' then
|
|
||||||
pc.is_branch <= true;
|
|
||||||
end if;
|
|
||||||
|
|
||||||
when bc_ltz_gez =>
|
|
||||||
if (EX_stage.ctrl.bc_not xor bcu_flags.ltz) = '1' then
|
|
||||||
pc.is_branch <= true;
|
|
||||||
end if;
|
|
||||||
|
|
||||||
when others => null;
|
|
||||||
end case;
|
|
||||||
end if;
|
|
||||||
end if;
|
|
||||||
end process;
|
|
||||||
|
|
||||||
process(rst, clk_1)
|
|
||||||
variable reset_delay : unsigned (5 downto 0);
|
|
||||||
begin
|
|
||||||
if rising_edge(clk_1) then
|
|
||||||
if rst = '1' then
|
|
||||||
reset_delay := (others => '1');
|
|
||||||
cpu_rst <= '1';
|
|
||||||
run_en <= '0';
|
|
||||||
elsif reset_delay /= (5 downto 0 => '0') then
|
|
||||||
reset_delay := reset_delay - 1;
|
|
||||||
else
|
|
||||||
cpu_rst <= '0';
|
|
||||||
end if;
|
|
||||||
if reset_delay(reset_delay'left-1) = '0' then
|
|
||||||
run_en <= '1';
|
|
||||||
end if;
|
|
||||||
end if;
|
|
||||||
end process;
|
|
||||||
|
|
||||||
--------------------------------------------------------------------------
|
|
||||||
-- ID stage
|
|
||||||
--------------------------------------------------------------------------
|
|
||||||
ID_stage.IR <= to_01(imem_data);
|
|
||||||
ID_stage.pcn <= pc.curr;
|
|
||||||
ID_stage.op <= decode_op(ID_stage.IR);
|
|
||||||
ID_stage.jimm32 <= extract_jimm32(ID_stage.IR, ID_stage.pcn);
|
|
||||||
ID_stage.bimm18 <= extract_bimm18(ID_stage.IR, ID_stage.pcn);
|
|
||||||
ID_stage.shamt <= extract_shamt(ID_stage.IR);
|
|
||||||
ID_stage.reg_a_rptr <= extract_rs(ID_stage.IR);
|
|
||||||
ID_stage.reg_b_rptr <= extract_rt(ID_stage.IR);
|
|
||||||
ID_stage.ctrl <= ctrl_lines;
|
|
||||||
ID_stage.reg_write <= ID_stage.ctrl.reg_write or cop_stat.reg_write;
|
|
||||||
ID_stage.epc <= pc.last;
|
|
||||||
ID_stage.exc <= event_is_active(ID_stage.events); -- Todo: works
|
|
||||||
ID_stage.nop <= sdu.ID_nop;
|
|
||||||
|
|
||||||
proc_ID_except:
|
|
||||||
process(ID_stage, cop_stat, pc)
|
|
||||||
begin
|
|
||||||
ID_stage.events <= events_clr;
|
|
||||||
ID_stage.events.inst_load_err <= pc.nxt(1) or pc.nxt(0);
|
|
||||||
ID_stage.events.inst_priv_addr <= pc.nxt(word_t'left) and cop_stat.user_mode;
|
|
||||||
end process;
|
|
||||||
|
|
||||||
proc_stage_hdu:
|
|
||||||
process(ID_stage, EX_stage, MEM_stage, WB_stage)
|
|
||||||
variable read_a, read_b : boolean;
|
|
||||||
variable raw_a_EX, raw_a_MEM, raw_a_WB : boolean;
|
|
||||||
variable raw_b_EX, raw_b_MEM, raw_b_WB : boolean;
|
|
||||||
variable reg_ptr_a : reg_ptr_t;
|
|
||||||
variable reg_ptr_b : reg_ptr_t;
|
|
||||||
begin
|
|
||||||
|
|
||||||
reg_ptr_a := ID_stage.reg_a_rptr;
|
|
||||||
reg_ptr_b := ID_stage.reg_b_rptr;
|
|
||||||
raw_a_EX := reg_ptr_a = EX_stage.reg_wptr and EX_stage.wreg_we = '1';
|
|
||||||
raw_a_MEM := reg_ptr_a = MEM_stage.reg_wptr and MEM_stage.wreg_we = '1';
|
|
||||||
raw_a_WB := reg_ptr_a = WB_stage.reg_wptr and WB_stage.wreg_we = '1';
|
|
||||||
raw_b_EX := reg_ptr_b = EX_stage.reg_wptr and EX_stage.wreg_we = '1';
|
|
||||||
raw_b_MEM := reg_ptr_b = MEM_stage.reg_wptr and MEM_stage.wreg_we = '1';
|
|
||||||
raw_b_WB := reg_ptr_b = WB_stage.reg_wptr and WB_stage.wreg_we = '1';
|
|
||||||
|
|
||||||
hdu.alu_fwd_a_ex <= raw_a_EX after 1 ns;
|
|
||||||
hdu.alu_fwd_a_mem <= raw_a_MEM after 1 ns;
|
|
||||||
hdu.alu_fwd_a_wb <= raw_a_WB after 1 ns;
|
|
||||||
hdu.alu_fwd_b_ex <= raw_b_EX after 1 ns;
|
|
||||||
hdu.alu_fwd_b_mem <= raw_b_MEM after 1 ns;
|
|
||||||
hdu.alu_fwd_b_wb <= raw_b_WB after 1 ns;
|
|
||||||
|
|
||||||
end process;
|
|
||||||
|
|
||||||
proc_stage_fwd_a:
|
|
||||||
process(reg_a, hdu, EX_stage, MEM_stage, WB_stage)
|
|
||||||
variable data : word_t;
|
|
||||||
begin
|
|
||||||
data := reg_a;
|
|
||||||
if hdu.alu_fwd_a_ex then
|
|
||||||
data := EX_stage.result;
|
|
||||||
elsif hdu.alu_fwd_a_mem then
|
|
||||||
data := MEM_stage.data;
|
|
||||||
elsif hdu.alu_fwd_a_wb then
|
|
||||||
data := WB_stage.data;
|
|
||||||
end if;
|
|
||||||
ID_stage.reg_a <= to_01(data) after 2 ns;
|
|
||||||
end process;
|
|
||||||
|
|
||||||
proc_stage_fwd_b:
|
|
||||||
process(reg_b, hdu, EX_stage, MEM_stage, WB_stage)
|
|
||||||
variable data : word_t;
|
|
||||||
begin
|
|
||||||
data := reg_b;
|
|
||||||
if hdu.alu_fwd_b_ex then
|
|
||||||
data := EX_stage.result;
|
|
||||||
elsif hdu.alu_fwd_b_mem then
|
|
||||||
data := MEM_stage.data;
|
|
||||||
elsif hdu.alu_fwd_b_wb then
|
|
||||||
data := WB_stage.data;
|
|
||||||
end if;
|
|
||||||
ID_stage.reg_b <= to_01(data) after 2 ns;
|
|
||||||
end process;
|
|
||||||
|
|
||||||
proc_imm_mux:
|
|
||||||
process(ID_stage)
|
|
||||||
variable data : word_t;
|
|
||||||
begin
|
|
||||||
data := extract_uimm16(ID_stage.IR);
|
|
||||||
|
|
||||||
case ID_stage.ctrl.imm_src is
|
|
||||||
|
|
||||||
when src_imm32 =>
|
|
||||||
data := extract_simm32(ID_stage.IR);
|
|
||||||
|
|
||||||
when src_imm16 =>
|
|
||||||
data := extract_uimm16(ID_stage.IR);
|
|
||||||
|
|
||||||
when src_imm16_high =>
|
|
||||||
data := ID_stage.IR(word_t'length/2-1 downto 0) & (word_t'length/2-1 downto 0 => '0');
|
|
||||||
|
|
||||||
when others => null;
|
|
||||||
|
|
||||||
end case;
|
|
||||||
|
|
||||||
ID_stage.imm <= data after 2 ns;
|
|
||||||
|
|
||||||
end process;
|
|
||||||
|
|
||||||
--------------------------------------------------------------------------
|
|
||||||
inst_idecode_rom: idecode_rom
|
|
||||||
PORT MAP
|
|
||||||
(
|
|
||||||
nop => sdu.ID_nop,
|
|
||||||
inst_in => ID_stage.IR,
|
|
||||||
ctrl_out => ctrl_lines
|
|
||||||
);
|
|
||||||
|
|
||||||
inst_reg_dual: reg_dual
|
|
||||||
GENERIC MAP
|
|
||||||
(
|
|
||||||
addr_width => reg_ptr_t'length,
|
|
||||||
data_width => word_t'length
|
|
||||||
)
|
|
||||||
PORT MAP
|
|
||||||
(
|
|
||||||
clk_w => clk_1,
|
|
||||||
we => WB_stage.wreg_we,
|
|
||||||
en => '1',
|
|
||||||
wptr => WB_stage.reg_wptr,
|
|
||||||
din => WB_stage.data,
|
|
||||||
rptr_a => ID_stage.reg_a_rptr,
|
|
||||||
rptr_b => ID_stage.reg_b_rptr,
|
|
||||||
dout_a => reg_a,
|
|
||||||
dout_b => reg_b
|
|
||||||
);
|
|
||||||
|
|
||||||
--------------------------------------------------------------------------
|
|
||||||
-- EX stage
|
|
||||||
--------------------------------------------------------------------------
|
|
||||||
EX_stage.reg_a_rptr <= extract_rs(EX_stage.IR);
|
|
||||||
EX_stage.reg_b_rptr <= extract_rt(EX_stage.IR);
|
|
||||||
EX_stage.result <= mul_result when EX_stage.ctrl.mul_access = '1' else alu_result;
|
|
||||||
|
|
||||||
proc_stage_ID_EX_1:
|
|
||||||
process(clk_1)
|
|
||||||
begin
|
|
||||||
if rising_edge(clk_1) then
|
|
||||||
if rst = '1' then
|
|
||||||
EX_stage.op <= NOP;
|
|
||||||
EX_stage.IR <= (others => '0');
|
|
||||||
EX_stage.ctrl <= ctrl_lines_default;
|
|
||||||
EX_stage.reg_write <= '0';
|
|
||||||
EX_stage.epc <= (others => '0');
|
|
||||||
EX_stage.pcn <= (others => '0');
|
|
||||||
EX_stage.events_in <= events_clr;
|
|
||||||
elsif sdu.EX_stall = '0' then
|
|
||||||
EX_stage.reg_a <= ID_stage.reg_a;
|
|
||||||
EX_stage.reg_b <= ID_stage.reg_b;
|
|
||||||
EX_stage.events_in <= ID_stage.events;
|
|
||||||
EX_stage.op <= ID_stage.op;
|
|
||||||
EX_stage.ctrl <= ID_stage.ctrl;
|
|
||||||
EX_stage.reg_write <= ID_stage.reg_write;
|
|
||||||
EX_stage.nop <= sdu.EX_nop;
|
|
||||||
EX_stage.IR <= ID_stage.IR;
|
|
||||||
EX_stage.pcn <= ID_stage.pcn;
|
|
||||||
if sdu.EX_nop = '1' then
|
|
||||||
EX_stage.op <= NOP;
|
|
||||||
EX_stage.IR <= (others => '0');
|
|
||||||
EX_stage.ctrl <= ctrl_lines_default;
|
|
||||||
EX_stage.reg_write <= '0';
|
|
||||||
else
|
|
||||||
EX_stage.epc <= ID_stage.epc;
|
|
||||||
end if;
|
|
||||||
end if;
|
|
||||||
end if;
|
|
||||||
end process;
|
|
||||||
|
|
||||||
proc_stage_EX_instr_except:
|
|
||||||
process(EX_stage)
|
|
||||||
begin
|
|
||||||
EX_events_instr <= events_clr;
|
|
||||||
EX_events_instr.illegal <= EX_stage.ctrl.exc_illegal;
|
|
||||||
EX_events_instr.break <= EX_stage.ctrl.exc_break;
|
|
||||||
EX_events_instr.syscall <= EX_stage.ctrl.exc_syscall;
|
|
||||||
end process;
|
|
||||||
|
|
||||||
proc_stage_EX_alu_except:
|
|
||||||
process(EX_stage)
|
|
||||||
begin
|
|
||||||
EX_events_alu <= events_clr;
|
|
||||||
if EX_stage.ctrl.alu_exc_en = '1' then
|
|
||||||
if EX_stage.alu_flags.ovf = '1' then
|
|
||||||
EX_events_alu.alu_ovf <= '1';
|
|
||||||
end if;
|
|
||||||
if EX_stage.alu_flags.uvf = '1' then
|
|
||||||
EX_events_alu.alu_uvf <= '1';
|
|
||||||
end if;
|
|
||||||
end if;
|
|
||||||
end process;
|
|
||||||
|
|
||||||
vaddr <= ID_stage.reg_a + extract_simm32(ID_stage.IR);
|
|
||||||
|
|
||||||
proc_stage_EX_mem_except:
|
|
||||||
process(clk_1)
|
|
||||||
begin
|
|
||||||
if rising_edge(clk_1) then
|
|
||||||
if rst = '1' then
|
|
||||||
dmem_en <= '0';
|
|
||||||
elsif sdu.EX_stall = '0' then
|
|
||||||
EX_events_mem <= events_clr;
|
|
||||||
dmem_en <= '0';
|
|
||||||
if ID_stage.ctrl.dmem_en = '1' then
|
|
||||||
dmem_en <= '1';
|
|
||||||
if ID_stage.ctrl.except_en = '1' then
|
|
||||||
if ID_stage.ctrl.word2_en = '1' then
|
|
||||||
if vaddr(0) = '1' then
|
|
||||||
EX_events_mem.data_load_err <= not ID_stage.ctrl.dmem_we;
|
|
||||||
EX_events_mem.data_store_err <= ID_stage.ctrl.dmem_we;
|
|
||||||
dmem_en <= '0';
|
|
||||||
end if;
|
|
||||||
elsif vaddr(1 downto 0) /= "00" then
|
|
||||||
EX_events_mem.data_load_err <= not ID_stage.ctrl.dmem_we;
|
|
||||||
EX_events_mem.data_store_err <= ID_stage.ctrl.dmem_we;
|
|
||||||
dmem_en <= '0';
|
|
||||||
end if;
|
|
||||||
end if;
|
|
||||||
end if;
|
|
||||||
end if;
|
|
||||||
end if;
|
|
||||||
end process;
|
|
||||||
|
|
||||||
proc_stage_DMEM_ADDR:
|
|
||||||
process(clk_1)
|
|
||||||
begin
|
|
||||||
if rising_edge(clk_1) then
|
|
||||||
if sdu.EX_stall = '0' then --and ID_stage.ctrl.dmem_en = '1' then
|
|
||||||
EX_stage.va <= vaddr;
|
|
||||||
if cop_stat.RE = '1' then
|
|
||||||
EX_stage.pa_off <= not vaddr(1 downto 0);
|
|
||||||
else
|
|
||||||
EX_stage.pa_off <= vaddr(1 downto 0);
|
|
||||||
end if;
|
|
||||||
end if;
|
|
||||||
end if;
|
|
||||||
end process;
|
|
||||||
dmem_we <= store_be(EX_stage.pa_off, EX_stage.ctrl.dmem_we, EX_stage.ctrl.word2_en, EX_stage.ctrl.word4_en, EX_stage.ctrl.align_left, EX_stage.ctrl.byte_en_byp) after 1 ns;
|
|
||||||
dmem_re <= not EX_stage.ctrl.dmem_we;
|
|
||||||
dmem_dout <= store_shift(EX_stage.reg_b, EX_stage.pa_off, EX_stage.ctrl.shift_offset, EX_stage.ctrl.shift_byp) after 1ns;
|
|
||||||
dmem_addr <= EX_stage.va;
|
|
||||||
cop_din <= EX_stage.reg_b;
|
|
||||||
EX_stage.events <= EX_events_instr or EX_events_mem or EX_events_alu or EX_stage.events_in;
|
|
||||||
EX_stage.exc <= event_is_active(EX_stage.events);
|
|
||||||
|
|
||||||
--------------------------------------------------------------------------
|
|
||||||
proc_wptr_mux:
|
|
||||||
process(EX_stage)
|
|
||||||
variable opclass : opcode_t;
|
|
||||||
variable reg_wptr : reg_ptr_t;
|
|
||||||
begin
|
|
||||||
|
|
||||||
opclass := extract_opc(EX_stage.IR);
|
|
||||||
case opclass is
|
|
||||||
when "000000" =>
|
|
||||||
reg_wptr := extract_rd(EX_stage.IR);
|
|
||||||
when others =>
|
|
||||||
reg_wptr := extract_rt(EX_stage.IR);
|
|
||||||
end case;
|
|
||||||
|
|
||||||
EX_stage.wreg_we <= EX_stage.reg_write after 1 ns;
|
|
||||||
if reg_wptr = "00000" then
|
|
||||||
EX_stage.wreg_we <= '0' after 1 ns;
|
|
||||||
end if;
|
|
||||||
|
|
||||||
EX_stage.reg_wptr <= reg_wptr after 1 ns;
|
|
||||||
case EX_stage.ctrl.wptr_srcsel is
|
|
||||||
when wptr_src_imm =>
|
|
||||||
EX_stage.reg_wptr <= reg_wptr after 1 ns;
|
|
||||||
|
|
||||||
when wptr_src_const =>
|
|
||||||
EX_stage.reg_wptr <= to_unsigned(31, reg_ptr_t'length) after 1 ns;
|
|
||||||
EX_stage.wreg_we <= '1' after 1 ns;
|
|
||||||
|
|
||||||
when others => null;
|
|
||||||
end case;
|
|
||||||
|
|
||||||
end process;
|
|
||||||
|
|
||||||
--------------------------------------------------------------------------
|
|
||||||
proc_stage_bcu_op:
|
|
||||||
process(clk_1)
|
|
||||||
begin
|
|
||||||
if rising_edge(clk_1) then
|
|
||||||
bcu_op_a <= ID_stage.reg_a;
|
|
||||||
bcu_op_b <= ID_stage.reg_b;
|
|
||||||
end if;
|
|
||||||
end process;
|
|
||||||
|
|
||||||
alu_op1_mux:
|
|
||||||
process(EX_stage)
|
|
||||||
variable data : word_t;
|
|
||||||
begin
|
|
||||||
|
|
||||||
data := EX_stage.reg_a;
|
|
||||||
|
|
||||||
-- case EX_stage.ctrl.alu.op1_src is
|
|
||||||
--
|
|
||||||
-- when alu_src_reg =>
|
|
||||||
-- data := EX_stage.reg_a;
|
|
||||||
--
|
|
||||||
-- when alu_src_muldiv =>
|
|
||||||
-- data := mul_result;
|
|
||||||
--
|
|
||||||
-- when others => null;
|
|
||||||
--
|
|
||||||
-- end case;
|
|
||||||
|
|
||||||
EX_stage.alu_op1 <= data;
|
|
||||||
|
|
||||||
end process;
|
|
||||||
|
|
||||||
alu_op2_mux:
|
|
||||||
process(clk_1)
|
|
||||||
variable data : word_t;
|
|
||||||
begin
|
|
||||||
|
|
||||||
if rising_edge(clk_1) and sdu.EX_stall = '0' then
|
|
||||||
data := ID_stage.reg_b;
|
|
||||||
|
|
||||||
case ID_stage.ctrl.alu.op2_src is
|
|
||||||
|
|
||||||
when alu_src_reg =>
|
|
||||||
data := ID_stage.reg_b;
|
|
||||||
|
|
||||||
when alu_src_imm =>
|
|
||||||
data := ID_stage.imm;
|
|
||||||
|
|
||||||
when others => null;
|
|
||||||
|
|
||||||
end case;
|
|
||||||
|
|
||||||
EX_stage.alu_op2 <= data;
|
|
||||||
end if;
|
|
||||||
|
|
||||||
end process;
|
|
||||||
|
|
||||||
shifter_sa_mux:
|
|
||||||
process(clk_1)
|
|
||||||
variable data : shamt_t;
|
|
||||||
variable data_inv : shamt_t;
|
|
||||||
|
|
||||||
begin
|
|
||||||
if rising_edge(clk_1) and sdu.EX_stall = '0' then
|
|
||||||
data := ID_stage.reg_a(4 downto 0);
|
|
||||||
case ID_stage.ctrl.shamt2_srcsel is
|
|
||||||
|
|
||||||
when sa_src_reg =>
|
|
||||||
data := ID_stage.reg_a(4 downto 0);
|
|
||||||
|
|
||||||
when sa_src_imm =>
|
|
||||||
data := ID_stage.shamt;
|
|
||||||
|
|
||||||
when others => null;
|
|
||||||
|
|
||||||
end case;
|
|
||||||
data_inv := not data + 1;
|
|
||||||
if ID_stage.ctrl.alu.shift_right = '0' then
|
|
||||||
EX_stage.shift_ctrl.shamt_rnd <= data_inv after 2 ns;
|
|
||||||
else
|
|
||||||
EX_stage.shift_ctrl.shamt_rnd <= data after 2 ns;
|
|
||||||
end if;
|
|
||||||
EX_stage.shift_ctrl.shamt_nrm <= data after 1 ns;
|
|
||||||
EX_stage.shift_ctrl.shift_right <= ID_stage.ctrl.alu.shift_right;
|
|
||||||
EX_stage.shift_ctrl.shift_arith <= ID_stage.ctrl.alu.shift_arith;
|
|
||||||
end if;
|
|
||||||
|
|
||||||
end process;
|
|
||||||
|
|
||||||
--------------------------------------------------------------------------
|
|
||||||
inst_shifter: shifter
|
|
||||||
GENERIC MAP
|
|
||||||
(
|
|
||||||
data_width => word_t'length
|
|
||||||
)
|
|
||||||
PORT MAP
|
|
||||||
(
|
|
||||||
shift_ctrl => EX_stage.shift_ctrl,
|
|
||||||
din => EX_stage.reg_b,
|
|
||||||
dout => EX_stage.alu_op2_s
|
|
||||||
);
|
|
||||||
|
|
||||||
inst_alu: alu
|
|
||||||
GENERIC MAP
|
|
||||||
(
|
|
||||||
data_width => word_t'length
|
|
||||||
)
|
|
||||||
PORT MAP
|
|
||||||
(
|
|
||||||
op1_in => EX_stage.alu_op1,
|
|
||||||
op2_in => EX_stage.alu_op2,
|
|
||||||
op2_shifted => EX_stage.alu_op2_s,
|
|
||||||
ctrl => EX_stage.ctrl.alu,
|
|
||||||
result => alu_result,
|
|
||||||
flags => EX_stage.alu_flags
|
|
||||||
);
|
|
||||||
|
|
||||||
inst_bcu: bcu
|
|
||||||
GENERIC MAP
|
|
||||||
(
|
|
||||||
data_width => word_t'length
|
|
||||||
)
|
|
||||||
PORT MAP
|
|
||||||
(
|
|
||||||
op1_in => bcu_op_a,
|
|
||||||
op2_in => bcu_op_b,
|
|
||||||
flags => bcu_flags
|
|
||||||
);
|
|
||||||
|
|
||||||
--------------------------------------------------------------------------
|
|
||||||
-- MEM stage
|
|
||||||
--------------------------------------------------------------------------
|
|
||||||
proc_stage_MEM_n:
|
|
||||||
process(clk_1)
|
|
||||||
begin
|
|
||||||
if rising_edge(clk_1) then
|
|
||||||
if rst = '1' then
|
|
||||||
MEM_stage.op <= NOP;
|
|
||||||
MEM_stage.wreg_we <= '0';
|
|
||||||
MEM_stage.ctrl <= ctrl_lines_default;
|
|
||||||
MEM_stage.pa_off <= (others => '0');
|
|
||||||
MEM_stage.events_in <= events_clr;
|
|
||||||
-- MEM_stage.epc <= (others => '0');
|
|
||||||
-- MEM_stage.pcn <= (others => '0');
|
|
||||||
-- MEM_stage.va <= (others => '0');
|
|
||||||
-- MEM_stage.reg_wptr <= (others => '0');
|
|
||||||
-- MEM_stage.ex_result <= (others => '0');
|
|
||||||
elsif sdu.MEM_stall = '0' then
|
|
||||||
MEM_stage.events_in <= EX_stage.events;
|
|
||||||
MEM_stage.op <= EX_stage.op;
|
|
||||||
MEM_stage.wreg_we <= EX_stage.wreg_we;
|
|
||||||
MEM_stage.ctrl <= EX_stage.ctrl;
|
|
||||||
MEM_stage.va <= EX_stage.va;
|
|
||||||
MEM_stage.pa_off <= EX_stage.pa_off;
|
|
||||||
MEM_stage.reg_wptr <= EX_stage.reg_wptr;
|
|
||||||
MEM_stage.nop <= sdu.MEM_nop;
|
|
||||||
if EX_stage.ctrl.dmem_en = '1' then
|
|
||||||
MEM_stage.ex_result <= EX_stage.reg_b;
|
|
||||||
else
|
|
||||||
MEM_stage.ex_result <= EX_stage.result;
|
|
||||||
if cop_stat.cop_read = '1' then
|
|
||||||
MEM_stage.ex_result <= cop_dout;
|
|
||||||
end if;
|
|
||||||
end if;
|
|
||||||
if sdu.MEM_nop = '1' then
|
|
||||||
MEM_stage.op <= NOP;
|
|
||||||
MEM_stage.wreg_we <= '0';
|
|
||||||
MEM_stage.ctrl <= ctrl_lines_default;
|
|
||||||
else
|
|
||||||
MEM_stage.pcn <= EX_stage.pcn;
|
|
||||||
MEM_stage.epc <= EX_stage.epc;
|
|
||||||
end if;
|
|
||||||
end if;
|
|
||||||
end if;
|
|
||||||
end process;
|
|
||||||
|
|
||||||
proc_stage_MEM_mux:
|
|
||||||
process(MEM_stage, dmem_din)
|
|
||||||
variable temp1 : word_t;
|
|
||||||
variable temp2 : word_t;
|
|
||||||
variable data : word_t;
|
|
||||||
variable be : unsigned(3 downto 0);
|
|
||||||
begin
|
|
||||||
data := MEM_stage.ex_result;
|
|
||||||
be := load_be(MEM_stage.pa_off, MEM_stage.ctrl.align_left, MEM_stage.ctrl.byte_en_byp);
|
|
||||||
if MEM_stage.ctrl.reg_link = '1' then
|
|
||||||
data := MEM_stage.pcn + 4;
|
|
||||||
elsif MEM_stage.ctrl.dmem_en = '1' then
|
|
||||||
temp1 := load_shift(dmem_din, MEM_stage.pa_off, MEM_stage.ctrl.shift_offset, MEM_stage.ctrl.shift_byp);
|
|
||||||
temp2 := load_sign_ext(temp1, MEM_stage.ctrl.sign_ext_byp, MEM_stage.ctrl.load_signed, MEM_stage.ctrl.word2_en, MEM_stage.ctrl.word4_en);
|
|
||||||
if be(0) = '1' then
|
|
||||||
data(7 downto 0) := temp2(7 downto 0);
|
|
||||||
end if;
|
|
||||||
if be(1) = '1' then
|
|
||||||
data(15 downto 8) := temp2(15 downto 8);
|
|
||||||
end if;
|
|
||||||
if be(2) = '1' then
|
|
||||||
data(23 downto 16) := temp2(23 downto 16);
|
|
||||||
end if;
|
|
||||||
if be(3) = '1' then
|
|
||||||
data(31 downto 24) := temp2(31 downto 24);
|
|
||||||
end if;
|
|
||||||
end if;
|
|
||||||
MEM_stage.data <= data after 1 ns;
|
|
||||||
|
|
||||||
end process;
|
|
||||||
|
|
||||||
proc_stage_MEM_except:
|
|
||||||
process(MEM_stage, int)
|
|
||||||
begin
|
|
||||||
MEM_stage.events <= MEM_stage.events_in;
|
|
||||||
MEM_stage.events.Int <= int;
|
|
||||||
end process;
|
|
||||||
|
|
||||||
MEM_stage.exc <= cop_stat.int or event_is_active(MEM_stage.events_in);
|
|
||||||
|
|
||||||
--------------------------------------------------------------------------
|
|
||||||
-- WB stage
|
|
||||||
--------------------------------------------------------------------------
|
|
||||||
proc_stage_WB_p:
|
|
||||||
process(clk_1)
|
|
||||||
begin
|
|
||||||
if rising_edge(clk_1) then
|
|
||||||
if rst = '1' then
|
|
||||||
WB_stage.op <= NOP;
|
|
||||||
WB_stage.wreg_we <= '0';
|
|
||||||
-- WB_stage.epc <= (others => '0');
|
|
||||||
-- WB_stage.reg_wptr <= (others => '0');
|
|
||||||
-- WB_stage.data <= (others => '0');
|
|
||||||
elsif sdu.WB_stall = '0' then
|
|
||||||
WB_stage.op <= MEM_stage.op;
|
|
||||||
WB_stage.wreg_we <= MEM_stage.wreg_we;
|
|
||||||
WB_stage.reg_wptr <= MEM_stage.reg_wptr;
|
|
||||||
WB_stage.data <= MEM_stage.data;
|
|
||||||
WB_stage.nop <= sdu.WB_nop;
|
|
||||||
if sdu.WB_nop = '1' then
|
|
||||||
WB_stage.op <= NOP;
|
|
||||||
WB_stage.wreg_we <= '0';
|
|
||||||
else
|
|
||||||
WB_stage.epc <= MEM_stage.epc;
|
|
||||||
WB_stage.bd <= MEM_stage.ctrl.branch or MEM_stage.ctrl.jump or MEM_stage.ctrl.jump_long; -- Todo: works
|
|
||||||
end if;
|
|
||||||
end if;
|
|
||||||
end if;
|
|
||||||
end process;
|
|
||||||
|
|
||||||
--------------------------------------------------------------------------
|
|
||||||
end Behavioral;
|
|
||||||
@@ -1,81 +0,0 @@
|
|||||||
--------------------------------------------------------------------------
|
|
||||||
-- Project: JIPS, a portable 32-bit RISC CPU written in VHDL
|
|
||||||
-- This file: On-Chip work registers
|
|
||||||
--
|
|
||||||
-- Copyright (C) 2008 J. Ahrensfeld
|
|
||||||
--
|
|
||||||
-- This program is free software: you can redistribute it and/or modify
|
|
||||||
-- it under the terms of the GNU General Public License as published by
|
|
||||||
-- the Free Software Foundation, either version 3 of the License, or
|
|
||||||
-- (at your option) any later version.
|
|
||||||
--
|
|
||||||
-- This program is distributed in the hope that it will be useful,
|
|
||||||
-- but WITHOUT ANY WARRANTY; without even the implied warranty of
|
|
||||||
-- MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
|
||||||
-- GNU General Public License for more details.
|
|
||||||
--
|
|
||||||
-- You should have received a copy of the GNU General Public License
|
|
||||||
-- along with this program. If not, see <http://www.gnu.org/licenses/>.
|
|
||||||
--
|
|
||||||
-- For questions and ideas, please contact the author at jens@jayfield.org
|
|
||||||
--
|
|
||||||
--------------------------------------------------------------------------
|
|
||||||
|
|
||||||
library IEEE;
|
|
||||||
use IEEE.STD_LOGIC_1164.ALL;
|
|
||||||
use IEEE.numeric_std.ALL;
|
|
||||||
|
|
||||||
use work.mips_types.all;
|
|
||||||
|
|
||||||
entity reg_dual is
|
|
||||||
Generic
|
|
||||||
(
|
|
||||||
addr_width : integer := 3;
|
|
||||||
data_width : integer := 8
|
|
||||||
);
|
|
||||||
Port (
|
|
||||||
clk_w : in STD_LOGIC;
|
|
||||||
we : in STD_LOGIC;
|
|
||||||
en : in STD_LOGIC;
|
|
||||||
wptr : in unsigned (addr_width-1 downto 0);
|
|
||||||
din : in unsigned (data_width-1 downto 0);
|
|
||||||
rptr_a : in unsigned (addr_width-1 downto 0);
|
|
||||||
rptr_b : in unsigned (addr_width-1 downto 0);
|
|
||||||
dout_a : out unsigned (data_width-1 downto 0);
|
|
||||||
dout_b : out unsigned (data_width-1 downto 0)
|
|
||||||
);
|
|
||||||
end reg_dual;
|
|
||||||
|
|
||||||
architecture Behavioral of reg_dual is
|
|
||||||
|
|
||||||
constant depth : integer := 2**addr_width;
|
|
||||||
type mem_t is array (0 to depth-1) of unsigned (data_width-1 downto 0);
|
|
||||||
|
|
||||||
function mem_clear(depth : natural) return mem_t is
|
|
||||||
variable result : mem_t;
|
|
||||||
begin
|
|
||||||
for i in 0 to depth-1 loop
|
|
||||||
result(i) := (others => '0');
|
|
||||||
end loop;
|
|
||||||
return result;
|
|
||||||
end mem_clear;
|
|
||||||
|
|
||||||
signal reg_mem : mem_t := mem_clear(depth);
|
|
||||||
|
|
||||||
begin
|
|
||||||
|
|
||||||
reg_in:
|
|
||||||
process(clk_w)
|
|
||||||
begin
|
|
||||||
if rising_edge(clk_w) then
|
|
||||||
if we = '1' and en = '1' then
|
|
||||||
reg_mem(to_integer(wptr)) <= din;
|
|
||||||
end if;
|
|
||||||
end if;
|
|
||||||
end process;
|
|
||||||
|
|
||||||
dout_a <= reg_mem(to_integer(rptr_a)) after 2 ns;
|
|
||||||
dout_b <= reg_mem(to_integer(rptr_b)) after 2 ns;
|
|
||||||
|
|
||||||
end Behavioral;
|
|
||||||
|
|
||||||
@@ -1,114 +0,0 @@
|
|||||||
--------------------------------------------------------------------------
|
|
||||||
-- Project: JIPS, a portable 32-bit RISC CPU written in VHDL
|
|
||||||
-- This file: The shifter unit
|
|
||||||
--
|
|
||||||
-- Copyright (C) 2008 J. Ahrensfeld
|
|
||||||
--
|
|
||||||
-- This program is free software: you can redistribute it and/or modify
|
|
||||||
-- it under the terms of the GNU General Public License as published by
|
|
||||||
-- the Free Software Foundation, either version 3 of the License, or
|
|
||||||
-- (at your option) any later version.
|
|
||||||
--
|
|
||||||
-- This program is distributed in the hope that it will be useful,
|
|
||||||
-- but WITHOUT ANY WARRANTY; without even the implied warranty of
|
|
||||||
-- MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
|
||||||
-- GNU General Public License for more details.
|
|
||||||
--
|
|
||||||
-- You should have received a copy of the GNU General Public License
|
|
||||||
-- along with this program. If not, see <http://www.gnu.org/licenses/>.
|
|
||||||
--
|
|
||||||
-- For questions and ideas, please contact the author at jens@jayfield.org
|
|
||||||
--
|
|
||||||
--------------------------------------------------------------------------
|
|
||||||
|
|
||||||
library IEEE;
|
|
||||||
use IEEE.STD_LOGIC_1164.ALL;
|
|
||||||
use IEEE.numeric_std.ALL;
|
|
||||||
|
|
||||||
use work.mips_types.all;
|
|
||||||
|
|
||||||
entity shifter is
|
|
||||||
Generic
|
|
||||||
(
|
|
||||||
data_width : integer := 8
|
|
||||||
);
|
|
||||||
Port
|
|
||||||
(
|
|
||||||
shift_ctrl : in shift_ctrl_t;
|
|
||||||
din : in unsigned (data_width-1 downto 0);
|
|
||||||
dout : out unsigned (data_width-1 downto 0)
|
|
||||||
);
|
|
||||||
end shifter;
|
|
||||||
|
|
||||||
architecture Behavioral of shifter is
|
|
||||||
|
|
||||||
subtype word_t is unsigned(data_width-1 downto 0);
|
|
||||||
type word_array_t is array (0 to 5) of word_t;
|
|
||||||
|
|
||||||
signal rot_data : word_array_t;
|
|
||||||
signal sa_rnd : unsigned (4 downto 0);
|
|
||||||
signal fill : std_logic;
|
|
||||||
|
|
||||||
--------------------------------------------------------------------------
|
|
||||||
function rot_stage(x : unsigned; en : std_logic; stage_num : natural) return unsigned is
|
|
||||||
variable result : unsigned(x'range);
|
|
||||||
constant sa : natural := 2**stage_num;
|
|
||||||
begin
|
|
||||||
if en = '1' then
|
|
||||||
result := x(sa-1 downto 0) & x(x'left downto sa);
|
|
||||||
else
|
|
||||||
result := x;
|
|
||||||
end if;
|
|
||||||
return result;
|
|
||||||
|
|
||||||
end rot_stage;
|
|
||||||
|
|
||||||
function rot_fill(x : unsigned; fill : std_logic; shift_right : std_logic; sa : natural) return unsigned is
|
|
||||||
variable result : unsigned(x'range) := (others => '0');
|
|
||||||
variable j : integer;
|
|
||||||
begin
|
|
||||||
|
|
||||||
if shift_right = '0' then
|
|
||||||
for i in 0 to x'left loop
|
|
||||||
if i >= sa then
|
|
||||||
result(i) := x(i);
|
|
||||||
else
|
|
||||||
result(i) := fill;
|
|
||||||
end if;
|
|
||||||
end loop;
|
|
||||||
else
|
|
||||||
j := x'left;
|
|
||||||
for i in 0 to x'left loop
|
|
||||||
if i < sa then
|
|
||||||
result(j) := fill;
|
|
||||||
else
|
|
||||||
result(j) := x(j);
|
|
||||||
end if;
|
|
||||||
j := j - 1;
|
|
||||||
end loop;
|
|
||||||
end if;
|
|
||||||
return result;
|
|
||||||
|
|
||||||
end rot_fill;
|
|
||||||
|
|
||||||
--------------------------------------------------------------------------
|
|
||||||
begin
|
|
||||||
|
|
||||||
rot_data(0) <= din;
|
|
||||||
|
|
||||||
gen_rotate_right:
|
|
||||||
for stage in 0 to 4 generate
|
|
||||||
begin
|
|
||||||
rot_data(stage+1) <= rot_stage(rot_data(stage), sa_rnd(stage), stage);
|
|
||||||
end generate;
|
|
||||||
|
|
||||||
sa_rnd <= shift_ctrl.shamt_rnd;
|
|
||||||
fill <= shift_ctrl.shift_arith and din(data_width-1);
|
|
||||||
dout <= rot_fill(rot_data(5), fill, shift_ctrl.shift_right, to_integer(shift_ctrl.shamt_nrm)) after 5 ns;
|
|
||||||
-- dout <= rot_data(5);
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
--------------------------------------------------------------------------
|
|
||||||
end Behavioral;
|
|
||||||
|
|
||||||
@@ -1,164 +0,0 @@
|
|||||||
--------------------------------------------------------------------------
|
|
||||||
-- Project: JIPS, a portable 32-bit RISC CPU written in VHDL
|
|
||||||
-- This file: JIPS top file
|
|
||||||
--
|
|
||||||
-- Copyright (C) 2008 J. Ahrensfeld
|
|
||||||
--
|
|
||||||
-- This program is free software: you can redistribute it and/or modify
|
|
||||||
-- it under the terms of the GNU General Public License as published by
|
|
||||||
-- the Free Software Foundation, either version 3 of the License, or
|
|
||||||
-- (at your option) any later version.
|
|
||||||
--
|
|
||||||
-- This program is distributed in the hope that it will be useful,
|
|
||||||
-- but WITHOUT ANY WARRANTY; without even the implied warranty of
|
|
||||||
-- MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
|
||||||
-- GNU General Public License for more details.
|
|
||||||
--
|
|
||||||
-- You should have received a copy of the GNU General Public License
|
|
||||||
-- along with this program. If not, see <http://www.gnu.org/licenses/>.
|
|
||||||
--
|
|
||||||
-- For questions and ideas, please contact the author at jens@jayfield.org
|
|
||||||
--
|
|
||||||
--------------------------------------------------------------------------
|
|
||||||
|
|
||||||
library IEEE;
|
|
||||||
use IEEE.STD_LOGIC_1164.ALL;
|
|
||||||
use IEEE.numeric_std.ALL;
|
|
||||||
|
|
||||||
library work;
|
|
||||||
use work.mips_types.all;
|
|
||||||
|
|
||||||
entity mips_top is
|
|
||||||
Port
|
|
||||||
(
|
|
||||||
rst : in STD_LOGIC;
|
|
||||||
clk : in STD_LOGIC;
|
|
||||||
int : in unsigned (5 downto 0);
|
|
||||||
mem_valid : in STD_LOGIC;
|
|
||||||
mem_rdy : in STD_LOGIC;
|
|
||||||
mem_en : out STD_LOGIC;
|
|
||||||
mem_re : out STD_LOGIC;
|
|
||||||
mem_we : out unsigned(3 downto 0);
|
|
||||||
mem_din : in unsigned (WORD_WIDTH-1 downto 0);
|
|
||||||
mem_dout : out unsigned (WORD_WIDTH-1 downto 0);
|
|
||||||
mem_addr : out unsigned (WORD_WIDTH-1 downto 0)
|
|
||||||
);
|
|
||||||
|
|
||||||
end mips_top;
|
|
||||||
|
|
||||||
architecture rtl of mips_top is
|
|
||||||
|
|
||||||
COMPONENT pipeline is
|
|
||||||
Port (
|
|
||||||
rst : in STD_LOGIC;
|
|
||||||
clk : in STD_LOGIC;
|
|
||||||
halt : in STD_LOGIC;
|
|
||||||
int : in unsigned (5 downto 0);
|
|
||||||
imem_rdy : in STD_LOGIC;
|
|
||||||
imem_en : out STD_LOGIC;
|
|
||||||
imem_addr : out word_t;
|
|
||||||
imem_data : in word_t;
|
|
||||||
dmem_rdy : in STD_LOGIC;
|
|
||||||
dmem_en : out STD_LOGIC;
|
|
||||||
dmem_re : out STD_LOGIC;
|
|
||||||
dmem_we : out unsigned(3 downto 0);
|
|
||||||
dmem_addr : out word_t;
|
|
||||||
dmem_din : in word_t;
|
|
||||||
dmem_dout : out word_t
|
|
||||||
);
|
|
||||||
END COMPONENT;
|
|
||||||
signal halt : std_logic;
|
|
||||||
signal imem_rdy : std_logic;
|
|
||||||
signal imem_en : std_logic;
|
|
||||||
signal imem_addr : word_t;
|
|
||||||
signal imem_din : word_t;
|
|
||||||
signal dmem_rdy : std_logic;
|
|
||||||
signal dmem_en : std_logic;
|
|
||||||
signal dmem_re : std_logic;
|
|
||||||
signal dmem_addr : word_t;
|
|
||||||
signal dmem_dout : word_t;
|
|
||||||
signal dmem_din : word_t;
|
|
||||||
signal dmem_we : unsigned(3 downto 0);
|
|
||||||
|
|
||||||
COMPONENT bui
|
|
||||||
Port
|
|
||||||
(
|
|
||||||
rst : in STD_LOGIC;
|
|
||||||
clk : in STD_LOGIC;
|
|
||||||
ce : in STD_LOGIC;
|
|
||||||
cpu_wait : out STD_LOGIC;
|
|
||||||
cpu_imem_rdy : out STD_LOGIC;
|
|
||||||
cpu_imem_en : in STD_LOGIC;
|
|
||||||
cpu_imem_addr : in word_t;
|
|
||||||
cpu_imem_din : out word_t;
|
|
||||||
cpu_dmem_rdy : out STD_LOGIC;
|
|
||||||
cpu_dmem_en : in STD_LOGIC;
|
|
||||||
cpu_dmem_re : in STD_LOGIC;
|
|
||||||
cpu_dmem_we : in unsigned(3 downto 0);
|
|
||||||
cpu_dmem_addr : in word_t;
|
|
||||||
cpu_dmem_din : out word_t;
|
|
||||||
cpu_dmem_dout : in word_t;
|
|
||||||
mem_valid : in STD_LOGIC;
|
|
||||||
mem_rdy : in STD_LOGIC;
|
|
||||||
mem_addr : out word_t;
|
|
||||||
mem_din : in word_t;
|
|
||||||
mem_dout : out word_t;
|
|
||||||
mem_re : out STD_LOGIC;
|
|
||||||
mem_we : out unsigned(3 downto 0);
|
|
||||||
mem_ce : out STD_LOGIC
|
|
||||||
);
|
|
||||||
END COMPONENT;
|
|
||||||
|
|
||||||
begin
|
|
||||||
|
|
||||||
-------------------------------------------------------------------
|
|
||||||
|
|
||||||
inst_pipeline: pipeline
|
|
||||||
PORT MAP
|
|
||||||
(
|
|
||||||
rst => rst,
|
|
||||||
clk => clk,
|
|
||||||
halt => halt,
|
|
||||||
int => int,
|
|
||||||
imem_rdy => imem_rdy,
|
|
||||||
imem_en => imem_en,
|
|
||||||
imem_addr => imem_addr,
|
|
||||||
imem_data => imem_din,
|
|
||||||
dmem_rdy => dmem_rdy,
|
|
||||||
dmem_en => dmem_en,
|
|
||||||
dmem_re => dmem_re,
|
|
||||||
dmem_we => dmem_we,
|
|
||||||
dmem_addr => dmem_addr,
|
|
||||||
dmem_din => dmem_din,
|
|
||||||
dmem_dout => dmem_dout
|
|
||||||
);
|
|
||||||
|
|
||||||
inst_bui: bui
|
|
||||||
PORT MAP
|
|
||||||
(
|
|
||||||
rst => rst,
|
|
||||||
clk => clk,
|
|
||||||
ce => '1',
|
|
||||||
cpu_wait => halt,
|
|
||||||
cpu_imem_rdy => imem_rdy,
|
|
||||||
cpu_imem_en => imem_en,
|
|
||||||
cpu_imem_addr => imem_addr,
|
|
||||||
cpu_imem_din => imem_din,
|
|
||||||
cpu_dmem_rdy => dmem_rdy,
|
|
||||||
cpu_dmem_en => dmem_en,
|
|
||||||
cpu_dmem_re => dmem_re,
|
|
||||||
cpu_dmem_we => dmem_we,
|
|
||||||
cpu_dmem_addr => dmem_addr,
|
|
||||||
cpu_dmem_din => dmem_din,
|
|
||||||
cpu_dmem_dout => dmem_dout,
|
|
||||||
mem_valid => mem_valid,
|
|
||||||
mem_rdy => mem_rdy,
|
|
||||||
mem_addr => mem_addr,
|
|
||||||
mem_din => mem_din,
|
|
||||||
mem_dout => mem_dout,
|
|
||||||
mem_re => mem_re,
|
|
||||||
mem_we => mem_we,
|
|
||||||
mem_ce => mem_en
|
|
||||||
);
|
|
||||||
|
|
||||||
end rtl;
|
|
||||||
@@ -1,620 +0,0 @@
|
|||||||
--------------------------------------------------------------------------
|
|
||||||
-- Project: JIPS, a portable 32-bit RISC CPU written in VHDL
|
|
||||||
-- This file: Types, constants and functions for JIPS
|
|
||||||
--
|
|
||||||
-- Copyright (C) 2008 J. Ahrensfeld
|
|
||||||
--
|
|
||||||
-- This program is free software: you can redistribute it and/or modify
|
|
||||||
-- it under the terms of the GNU General Public License as published by
|
|
||||||
-- the Free Software Foundation, either version 3 of the License, or
|
|
||||||
-- (at your option) any later version.
|
|
||||||
--
|
|
||||||
-- This program is distributed in the hope that it will be useful,
|
|
||||||
-- but WITHOUT ANY WARRANTY; without even the implied warranty of
|
|
||||||
-- MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
|
||||||
-- GNU General Public License for more details.
|
|
||||||
--
|
|
||||||
-- You should have received a copy of the GNU General Public License
|
|
||||||
-- along with this program. If not, see <http://www.gnu.org/licenses/>.
|
|
||||||
--
|
|
||||||
-- For questions and ideas, please contact the author at jens@jayfield.org
|
|
||||||
--
|
|
||||||
--------------------------------------------------------------------------
|
|
||||||
|
|
||||||
library IEEE;
|
|
||||||
use IEEE.STD_LOGIC_1164.ALL;
|
|
||||||
use IEEE.numeric_std.ALL;
|
|
||||||
|
|
||||||
|
|
||||||
--------------------------------------------------------------------------
|
|
||||||
package mips_types is
|
|
||||||
|
|
||||||
-- Revision of the CPU
|
|
||||||
constant REVISION : integer := 1;
|
|
||||||
constant WORD_WIDTH : integer := 32;
|
|
||||||
|
|
||||||
--Types
|
|
||||||
subtype instr_name_t is string(1 to 12);
|
|
||||||
type instr_name_array_t is array (0 to 63) of instr_name_t;
|
|
||||||
subtype opcode_t is unsigned (5 downto 0);
|
|
||||||
subtype word_t is unsigned (WORD_WIDTH-1 downto 0);
|
|
||||||
subtype reg_ptr_t is unsigned (4 downto 0);
|
|
||||||
subtype shamt_t is unsigned(4 downto 0);
|
|
||||||
subtype sa_t is natural range 0 to 63;
|
|
||||||
subtype func_t is unsigned(5 downto 0);
|
|
||||||
|
|
||||||
type opclass_t is (special, regimm, opcode);
|
|
||||||
|
|
||||||
type op_t is
|
|
||||||
(
|
|
||||||
nop,
|
|
||||||
op_sll,
|
|
||||||
op_srl,
|
|
||||||
op_sra,
|
|
||||||
op_sllv,
|
|
||||||
op_srlv,
|
|
||||||
op_srav,
|
|
||||||
op_jr,
|
|
||||||
op_jalr,
|
|
||||||
op_syscall,
|
|
||||||
op_break,
|
|
||||||
op_mfhi,
|
|
||||||
op_mthi,
|
|
||||||
op_mflo,
|
|
||||||
op_mtlo,
|
|
||||||
op_mult,
|
|
||||||
op_multu,
|
|
||||||
op_div,
|
|
||||||
op_divu,
|
|
||||||
op_add,
|
|
||||||
op_addu,
|
|
||||||
op_sub,
|
|
||||||
op_subu,
|
|
||||||
op_and,
|
|
||||||
op_or,
|
|
||||||
op_xor,
|
|
||||||
op_nor,
|
|
||||||
op_slt,
|
|
||||||
op_sltu,
|
|
||||||
op_bltz,
|
|
||||||
op_bgez,
|
|
||||||
op_bltzal,
|
|
||||||
op_bgezal,
|
|
||||||
op_j,
|
|
||||||
op_jal,
|
|
||||||
op_beq,
|
|
||||||
op_bne,
|
|
||||||
op_blez,
|
|
||||||
op_bgtz,
|
|
||||||
op_addi,
|
|
||||||
op_addiu,
|
|
||||||
op_slti,
|
|
||||||
op_sltiu,
|
|
||||||
op_andi,
|
|
||||||
op_ori,
|
|
||||||
op_xori,
|
|
||||||
op_lui,
|
|
||||||
op_lb,
|
|
||||||
op_lh,
|
|
||||||
op_lwl,
|
|
||||||
op_lw,
|
|
||||||
op_lbu,
|
|
||||||
op_lhu,
|
|
||||||
op_lwr,
|
|
||||||
op_sb,
|
|
||||||
op_sh,
|
|
||||||
op_swl,
|
|
||||||
op_sw,
|
|
||||||
op_swr,
|
|
||||||
op_cop0,
|
|
||||||
op_cop1,
|
|
||||||
op_cop2,
|
|
||||||
op_cop3,
|
|
||||||
op_lwc1,
|
|
||||||
op_lwc2,
|
|
||||||
op_lwc3,
|
|
||||||
op_swc1,
|
|
||||||
op_swc2,
|
|
||||||
op_swc3
|
|
||||||
);
|
|
||||||
|
|
||||||
attribute ENUM_ENCODING : string;
|
|
||||||
|
|
||||||
type imm_src_t is (src_imm32, src_imm16, src_imm16_high);
|
|
||||||
type sa_src_t is (sa_src_reg, sa_src_imm);
|
|
||||||
type alu_src1_t is (alu_src_reg);
|
|
||||||
type alu_src2_t is (alu_src_reg, alu_src_imm);
|
|
||||||
type bc_src_t is (bc_eq_ne, bc_lez_gtz, bc_ltz_gez);
|
|
||||||
type shift_opsel_t is (shift_sll, shift_srl, shift_sra);
|
|
||||||
type wptr_src_t is (wptr_src_imm, wptr_src_const);
|
|
||||||
|
|
||||||
-- attribute ENUM_ENCODING of itype_t: type is "ONE-HOT";
|
|
||||||
|
|
||||||
type pc_t is record
|
|
||||||
curr : word_t;
|
|
||||||
last : word_t;
|
|
||||||
nxt : word_t;
|
|
||||||
pc_branch : word_t;
|
|
||||||
is_branch : boolean;
|
|
||||||
end record;
|
|
||||||
|
|
||||||
type alu_outsel_t is
|
|
||||||
(
|
|
||||||
alu_adder,
|
|
||||||
alu_shift2,
|
|
||||||
alu_and,
|
|
||||||
alu_or,
|
|
||||||
alu_xor,
|
|
||||||
alu_nor,
|
|
||||||
alu_ltu,
|
|
||||||
alu_lts
|
|
||||||
);
|
|
||||||
|
|
||||||
type alu_flags_t is record
|
|
||||||
c : STD_LOGIC;
|
|
||||||
uvf : STD_LOGIC;
|
|
||||||
ovf : STD_LOGIC;
|
|
||||||
ltu : STD_LOGIC;
|
|
||||||
lts : STD_LOGIC;
|
|
||||||
end record;
|
|
||||||
|
|
||||||
type bcu_flags_t is record
|
|
||||||
z : STD_LOGIC;
|
|
||||||
eq : STD_LOGIC;
|
|
||||||
ltz : STD_LOGIC;
|
|
||||||
end record;
|
|
||||||
|
|
||||||
type event_t is record
|
|
||||||
Int : unsigned(5 downto 0);
|
|
||||||
data_load_err : STD_LOGIC;
|
|
||||||
data_store_err : STD_LOGIC;
|
|
||||||
inst_load_err : STD_LOGIC;
|
|
||||||
inst_priv_addr : STD_LOGIC;
|
|
||||||
alu_ovf : STD_LOGIC;
|
|
||||||
alu_uvf : STD_LOGIC;
|
|
||||||
syscall : STD_LOGIC;
|
|
||||||
break : STD_LOGIC;
|
|
||||||
illegal : STD_LOGIC;
|
|
||||||
end record;
|
|
||||||
|
|
||||||
type exc_flags_t is record
|
|
||||||
Int : STD_LOGIC;
|
|
||||||
DAdEL : STD_LOGIC;
|
|
||||||
DAdES : STD_LOGIC;
|
|
||||||
IAdEL : STD_LOGIC;
|
|
||||||
IAdEK : STD_LOGIC;
|
|
||||||
Ov : STD_LOGIC;
|
|
||||||
Sys : STD_LOGIC;
|
|
||||||
Bp : STD_LOGIC;
|
|
||||||
RI : STD_LOGIC;
|
|
||||||
IBE : STD_LOGIC;
|
|
||||||
DBE : STD_LOGIC;
|
|
||||||
end record;
|
|
||||||
|
|
||||||
type except_t is record
|
|
||||||
act : STD_LOGIC;
|
|
||||||
epc : word_t;
|
|
||||||
cause : word_t;
|
|
||||||
end record;
|
|
||||||
|
|
||||||
type cop_ctrl_in_t is record
|
|
||||||
bd_wb : STD_LOGIC;
|
|
||||||
epc_mem : word_t;
|
|
||||||
epc_wb : word_t;
|
|
||||||
imem_addr : word_t;
|
|
||||||
dmem_addr : word_t;
|
|
||||||
exc_left : STD_LOGIC;
|
|
||||||
end record;
|
|
||||||
|
|
||||||
type cop_ctrl_out_t is record
|
|
||||||
RE : STD_LOGIC;
|
|
||||||
ee : STD_LOGIC;
|
|
||||||
ec : STD_LOGIC;
|
|
||||||
exc_commit : STD_LOGIC;
|
|
||||||
exc_pending : STD_LOGIC;
|
|
||||||
exc_exit : STD_LOGIC;
|
|
||||||
reg_write : STD_LOGIC;
|
|
||||||
cop_read : STD_LOGIC;
|
|
||||||
user_mode : STD_LOGIC;
|
|
||||||
int : STD_LOGIC;
|
|
||||||
exc_vec : word_t;
|
|
||||||
end record;
|
|
||||||
|
|
||||||
type sdu_t is record
|
|
||||||
ID_nop : STD_LOGIC;
|
|
||||||
EX_nop : STD_LOGIC;
|
|
||||||
MEM_nop : STD_LOGIC;
|
|
||||||
WB_nop : STD_LOGIC;
|
|
||||||
ID_stall : STD_LOGIC;
|
|
||||||
EX_stall : STD_LOGIC;
|
|
||||||
MEM_stall : STD_LOGIC;
|
|
||||||
WB_stall : STD_LOGIC;
|
|
||||||
end record;
|
|
||||||
|
|
||||||
type hdu_t is record
|
|
||||||
alu_fwd_a_ex : boolean;
|
|
||||||
alu_fwd_a_mem : boolean;
|
|
||||||
alu_fwd_a_wb : boolean;
|
|
||||||
alu_fwd_b_ex : boolean;
|
|
||||||
alu_fwd_b_mem : boolean;
|
|
||||||
alu_fwd_b_wb : boolean;
|
|
||||||
end record;
|
|
||||||
|
|
||||||
type alu_ctrl_t is record
|
|
||||||
outsel : alu_outsel_t;
|
|
||||||
add : STD_LOGIC;
|
|
||||||
shift_right : STD_LOGIC;
|
|
||||||
shift_arith : STD_LOGIC;
|
|
||||||
op1_src : alu_src1_t;
|
|
||||||
op2_src : alu_src2_t;
|
|
||||||
end record;
|
|
||||||
|
|
||||||
type shift_ctrl_t is record
|
|
||||||
shamt_nrm : shamt_t;
|
|
||||||
shamt_rnd : shamt_t;
|
|
||||||
shift_right : STD_LOGIC;
|
|
||||||
shift_arith : STD_LOGIC;
|
|
||||||
end record;
|
|
||||||
|
|
||||||
type ctrl_lines_t is record
|
|
||||||
branch : STD_LOGIC;
|
|
||||||
jump_long : STD_LOGIC;
|
|
||||||
jump : STD_LOGIC;
|
|
||||||
bc_not : STD_LOGIC;
|
|
||||||
bc_src : bc_src_t;
|
|
||||||
imm_src : imm_src_t;
|
|
||||||
alu : alu_ctrl_t;
|
|
||||||
reg_write : STD_LOGIC;
|
|
||||||
reg_link : STD_LOGIC;
|
|
||||||
dmem_we : STD_LOGIC;
|
|
||||||
dmem_en : STD_LOGIC;
|
|
||||||
shamt2_srcsel : sa_src_t;
|
|
||||||
wptr_srcsel : wptr_src_t;
|
|
||||||
cop_instr_en : STD_LOGIC;
|
|
||||||
shift_offset : unsigned(1 downto 0);
|
|
||||||
shift_byp : STD_LOGIC;
|
|
||||||
byte_en_byp : STD_LOGIC;
|
|
||||||
sign_ext_byp : STD_LOGIC;
|
|
||||||
word4_en : STD_LOGIC;
|
|
||||||
word2_en : STD_LOGIC;
|
|
||||||
align_left : STD_LOGIC;
|
|
||||||
load_signed : STD_LOGIC;
|
|
||||||
mul_access : STD_LOGIC;
|
|
||||||
mul_hilo_we : STD_LOGIC;
|
|
||||||
mul_mul_divn : STD_LOGIC;
|
|
||||||
mul_start : STD_LOGIC;
|
|
||||||
mul_s_un : STD_LOGIC;
|
|
||||||
mul_hilo_sel : STD_LOGIC;
|
|
||||||
exc_break : STD_LOGIC;
|
|
||||||
exc_syscall : STD_LOGIC;
|
|
||||||
exc_illegal : STD_LOGIC;
|
|
||||||
except_en : STD_LOGIC;
|
|
||||||
alu_exc_en : STD_LOGIC;
|
|
||||||
end record;
|
|
||||||
|
|
||||||
type ID_t is record
|
|
||||||
nop : STD_LOGIC;
|
|
||||||
exc : std_logic;
|
|
||||||
IR : word_t;
|
|
||||||
op : op_t;
|
|
||||||
pcn : word_t;
|
|
||||||
epc : word_t;
|
|
||||||
jimm32 : word_t;
|
|
||||||
bimm18 : word_t;
|
|
||||||
imm : word_t;
|
|
||||||
shamt : shamt_t;
|
|
||||||
ctrl : ctrl_lines_t;
|
|
||||||
reg_write : STD_LOGIC;
|
|
||||||
reg_a_rptr : reg_ptr_t;
|
|
||||||
reg_b_rptr : reg_ptr_t;
|
|
||||||
reg_a : word_t;
|
|
||||||
reg_b : word_t;
|
|
||||||
events : event_t;
|
|
||||||
end record;
|
|
||||||
|
|
||||||
type EX_t is record
|
|
||||||
nop : STD_LOGIC;
|
|
||||||
exc : std_logic;
|
|
||||||
IR : word_t;
|
|
||||||
op : op_t;
|
|
||||||
pcn : word_t;
|
|
||||||
epc : word_t;
|
|
||||||
reg_a : word_t;
|
|
||||||
reg_b : word_t;
|
|
||||||
ctrl : ctrl_lines_t;
|
|
||||||
shift_ctrl : shift_ctrl_t;
|
|
||||||
alu_op1 : word_t;
|
|
||||||
alu_op2 : word_t;
|
|
||||||
alu_op2_s : word_t;
|
|
||||||
alu_flags : alu_flags_t;
|
|
||||||
result : word_t;
|
|
||||||
reg_write : STD_LOGIC;
|
|
||||||
wreg_we : STD_LOGIC;
|
|
||||||
reg_wptr : reg_ptr_t;
|
|
||||||
reg_a_rptr : reg_ptr_t;
|
|
||||||
reg_b_rptr : reg_ptr_t;
|
|
||||||
va : word_t;
|
|
||||||
pa_off : unsigned(1 downto 0);
|
|
||||||
events_in : event_t;
|
|
||||||
events : event_t;
|
|
||||||
end record;
|
|
||||||
|
|
||||||
type MEM_t is record
|
|
||||||
nop : STD_LOGIC;
|
|
||||||
exc : std_logic;
|
|
||||||
op : op_t;
|
|
||||||
pcn : word_t;
|
|
||||||
epc : word_t;
|
|
||||||
ctrl : ctrl_lines_t;
|
|
||||||
ex_result : word_t;
|
|
||||||
reg_wptr : reg_ptr_t;
|
|
||||||
wreg_we : STD_LOGIC;
|
|
||||||
data : word_t;
|
|
||||||
va : word_t;
|
|
||||||
pa_off : unsigned(1 downto 0);
|
|
||||||
events_in : event_t;
|
|
||||||
events : event_t;
|
|
||||||
end record;
|
|
||||||
|
|
||||||
type WB_t is record
|
|
||||||
nop : STD_LOGIC;
|
|
||||||
op : op_t;
|
|
||||||
epc : word_t;
|
|
||||||
reg_wptr : reg_ptr_t;
|
|
||||||
wreg_we : STD_LOGIC;
|
|
||||||
data : word_t;
|
|
||||||
bd : STD_LOGIC;
|
|
||||||
end record;
|
|
||||||
|
|
||||||
|
|
||||||
type rom_special_t is array (0 to 2**func_t'length-1) of ctrl_lines_t;
|
|
||||||
type rom_regimm_t is array (0 to 2**reg_ptr_t'length-1) of ctrl_lines_t;
|
|
||||||
type rom_opcode_t is array (0 to 2**opcode_t'length-1) of ctrl_lines_t;
|
|
||||||
|
|
||||||
function store_shift(x : word_t; va, shift_off : unsigned(1 downto 0); bypass : std_logic) return word_t;
|
|
||||||
function store_be(va : unsigned(1 downto 0); be_src, word2_en, word4_en, align_left, bypass : std_logic) return unsigned;
|
|
||||||
function load_shift(x : word_t; va, shift_off : unsigned(1 downto 0); bypass : std_logic) return word_t;
|
|
||||||
function load_be(va : unsigned(1 downto 0); align_left, bypass : std_logic) return unsigned;
|
|
||||||
function load_sign_ext(x : word_t; bypass, signed, word2_en, word4_en : std_logic) return word_t;
|
|
||||||
function events_clr return event_t;
|
|
||||||
function event_is_active(e : event_t) return std_logic;
|
|
||||||
function "or" (a, b : event_t) return event_t;
|
|
||||||
|
|
||||||
end mips_types;
|
|
||||||
|
|
||||||
--------------------------------------------------------------------------
|
|
||||||
package body mips_types is
|
|
||||||
|
|
||||||
function store_shift(x : word_t; va, shift_off : unsigned(1 downto 0); bypass : std_logic) return word_t is
|
|
||||||
variable stage1 : word_t;
|
|
||||||
variable result : word_t;
|
|
||||||
variable sa : unsigned(1 downto 0);
|
|
||||||
begin
|
|
||||||
|
|
||||||
if bypass = '1' then
|
|
||||||
sa := "00";
|
|
||||||
else
|
|
||||||
sa := va + shift_off;
|
|
||||||
end if;
|
|
||||||
|
|
||||||
stage1 := x;
|
|
||||||
if sa(0) = '1' then
|
|
||||||
stage1 := x(23 downto 0) & x(31 downto 24);
|
|
||||||
end if;
|
|
||||||
result := stage1;
|
|
||||||
if sa(1) = '1' then
|
|
||||||
result := stage1(15 downto 0) & stage1(31 downto 16);
|
|
||||||
end if;
|
|
||||||
|
|
||||||
return result;
|
|
||||||
end store_shift;
|
|
||||||
|
|
||||||
--------------------------------------------------------------------------
|
|
||||||
function store_be(va : unsigned(1 downto 0); be_src, word2_en, word4_en, align_left, bypass : std_logic) return unsigned is
|
|
||||||
variable result : unsigned(3 downto 0);
|
|
||||||
begin
|
|
||||||
if bypass = '1' then
|
|
||||||
result := (3 downto 0 => be_src);
|
|
||||||
elsif word2_en = '1' then
|
|
||||||
case va is
|
|
||||||
when "00" | "01" =>
|
|
||||||
result := "00" & be_src & be_src;
|
|
||||||
when "10" | "11" =>
|
|
||||||
result := be_src & be_src & "00";
|
|
||||||
when others =>
|
|
||||||
result := "0000";
|
|
||||||
end case;
|
|
||||||
elsif word4_en = '1' then
|
|
||||||
case va is
|
|
||||||
when "00" =>
|
|
||||||
result := "000" & be_src;
|
|
||||||
when "01" =>
|
|
||||||
result := "00" & be_src & '0';
|
|
||||||
when "10" =>
|
|
||||||
result := '0' & be_src & "00";
|
|
||||||
when "11" =>
|
|
||||||
result := be_src & "000";
|
|
||||||
when others =>
|
|
||||||
result := "0000";
|
|
||||||
end case;
|
|
||||||
elsif align_left = '1' then
|
|
||||||
case va is
|
|
||||||
when "00" =>
|
|
||||||
result := be_src & be_src & be_src & be_src;
|
|
||||||
when "01" =>
|
|
||||||
result := be_src & be_src & be_src & '0';
|
|
||||||
when "10" =>
|
|
||||||
result := be_src & be_src & "00";
|
|
||||||
when "11" =>
|
|
||||||
result := be_src & "000";
|
|
||||||
when others =>
|
|
||||||
result := "0000";
|
|
||||||
end case;
|
|
||||||
else
|
|
||||||
case va is
|
|
||||||
when "00" =>
|
|
||||||
result := "000" & be_src;
|
|
||||||
when "01" =>
|
|
||||||
result := "00" & be_src & be_src;
|
|
||||||
when "10" =>
|
|
||||||
result := '0' & be_src & be_src & be_src;
|
|
||||||
when "11" =>
|
|
||||||
result := be_src & be_src & be_src & be_src;
|
|
||||||
when others =>
|
|
||||||
result := "0000";
|
|
||||||
end case;
|
|
||||||
end if;
|
|
||||||
|
|
||||||
return result;
|
|
||||||
|
|
||||||
end store_be;
|
|
||||||
|
|
||||||
--------------------------------------------------------------------------
|
|
||||||
function load_shift(x : word_t; va, shift_off : unsigned(1 downto 0); bypass : std_logic) return word_t is
|
|
||||||
variable stage1 : word_t;
|
|
||||||
variable result : word_t;
|
|
||||||
variable sa : unsigned(1 downto 0);
|
|
||||||
|
|
||||||
begin
|
|
||||||
if bypass = '1' then
|
|
||||||
sa := "00";
|
|
||||||
else
|
|
||||||
sa := va + shift_off;
|
|
||||||
end if;
|
|
||||||
|
|
||||||
stage1 := x;
|
|
||||||
if sa(0) = '1' then
|
|
||||||
stage1 := x(7 downto 0) & x(31 downto 8);
|
|
||||||
end if;
|
|
||||||
result := stage1;
|
|
||||||
if sa(1) = '1' then
|
|
||||||
result := stage1(15 downto 0) & stage1(31 downto 16);
|
|
||||||
end if;
|
|
||||||
|
|
||||||
return result;
|
|
||||||
end load_shift;
|
|
||||||
|
|
||||||
--------------------------------------------------------------------------
|
|
||||||
function load_be(va : unsigned(1 downto 0); align_left, bypass : std_logic) return unsigned is
|
|
||||||
variable result : unsigned(3 downto 0);
|
|
||||||
begin
|
|
||||||
if bypass = '1' then
|
|
||||||
result := (3 downto 0 => '1');
|
|
||||||
elsif align_left = '1' then
|
|
||||||
case va is
|
|
||||||
when "00" =>
|
|
||||||
result := "1000";
|
|
||||||
when "01" =>
|
|
||||||
result := "1100";
|
|
||||||
when "10" =>
|
|
||||||
result := "1110";
|
|
||||||
when "11" =>
|
|
||||||
result := "1111";
|
|
||||||
when others =>
|
|
||||||
result := "0000";
|
|
||||||
end case;
|
|
||||||
else
|
|
||||||
case va is
|
|
||||||
when "00" =>
|
|
||||||
result := "1111";
|
|
||||||
when "01" =>
|
|
||||||
result := "0111";
|
|
||||||
when "10" =>
|
|
||||||
result := "0011";
|
|
||||||
when "11" =>
|
|
||||||
result := "0001";
|
|
||||||
when others =>
|
|
||||||
result := "0000";
|
|
||||||
end case;
|
|
||||||
end if;
|
|
||||||
|
|
||||||
return result;
|
|
||||||
|
|
||||||
end load_be;
|
|
||||||
|
|
||||||
--------------------------------------------------------------------------
|
|
||||||
function load_sign_ext(x : word_t; bypass, signed, word2_en, word4_en : std_logic) return word_t is
|
|
||||||
variable result : word_t;
|
|
||||||
variable sign : std_logic;
|
|
||||||
|
|
||||||
begin
|
|
||||||
if bypass = '1' then
|
|
||||||
result := x;
|
|
||||||
elsif word2_en = '1' then
|
|
||||||
sign := signed and x(15);
|
|
||||||
result := (31 downto 16 => sign) & x(15 downto 0);
|
|
||||||
else
|
|
||||||
sign := signed and x(7);
|
|
||||||
result := (31 downto 8 => sign) & x(7 downto 0);
|
|
||||||
end if;
|
|
||||||
|
|
||||||
return result;
|
|
||||||
end load_sign_ext;
|
|
||||||
|
|
||||||
--------------------------------------------------------------------------
|
|
||||||
function events_clr return event_t is
|
|
||||||
variable result : event_t;
|
|
||||||
begin
|
|
||||||
result.Int := (others => '0');
|
|
||||||
result.data_load_err := '0';
|
|
||||||
result.data_store_err := '0';
|
|
||||||
result.inst_load_err := '0';
|
|
||||||
result.inst_priv_addr := '0';
|
|
||||||
result.alu_ovf := '0';
|
|
||||||
result.alu_uvf := '0';
|
|
||||||
result.syscall := '0';
|
|
||||||
result.break := '0';
|
|
||||||
result.illegal := '0';
|
|
||||||
|
|
||||||
return result;
|
|
||||||
|
|
||||||
end events_clr;
|
|
||||||
|
|
||||||
function event_is_active(e : event_t) return std_logic is
|
|
||||||
variable result : std_logic;
|
|
||||||
begin
|
|
||||||
result := '0';
|
|
||||||
|
|
||||||
for i in e.Int'range loop
|
|
||||||
result := result or e.Int(i);
|
|
||||||
end loop;
|
|
||||||
|
|
||||||
result := result or e.data_load_err;
|
|
||||||
result := result or e.data_store_err;
|
|
||||||
result := result or e.inst_load_err;
|
|
||||||
result := result or e.inst_priv_addr;
|
|
||||||
result := result or e.alu_ovf;
|
|
||||||
result := result or e.alu_uvf;
|
|
||||||
result := result or e.syscall;
|
|
||||||
result := result or e.break;
|
|
||||||
result := result or e.illegal;
|
|
||||||
|
|
||||||
return result;
|
|
||||||
|
|
||||||
end event_is_active;
|
|
||||||
|
|
||||||
function "or" (a, b : event_t) return event_t is
|
|
||||||
variable result : event_t;
|
|
||||||
begin
|
|
||||||
for i in a.Int'range loop
|
|
||||||
result.Int(i) := a.Int(i) or b.Int(i);
|
|
||||||
end loop;
|
|
||||||
result.data_load_err := a.data_load_err or b.data_load_err;
|
|
||||||
result.data_store_err := a.data_store_err or b.data_store_err;
|
|
||||||
result.inst_load_err := a.inst_load_err or b.inst_load_err;
|
|
||||||
result.inst_priv_addr := a.inst_priv_addr or b.inst_priv_addr;
|
|
||||||
result.alu_ovf := a.alu_ovf or b.alu_ovf;
|
|
||||||
result.alu_uvf := a.alu_uvf or b.alu_uvf;
|
|
||||||
result.syscall := a.syscall or b.syscall;
|
|
||||||
result.break := a.break or b.break;
|
|
||||||
result.illegal := a.illegal or b.illegal;
|
|
||||||
|
|
||||||
return result;
|
|
||||||
|
|
||||||
end "or";
|
|
||||||
|
|
||||||
--------------------------------------------------------------------------
|
|
||||||
end mips_types;
|
|
||||||
|
|
||||||
--------------------------------------------------------------------------
|
|
||||||
--------------------------------------------------------------------------
|
|
||||||
File diff suppressed because it is too large
Load Diff
@@ -1,320 +0,0 @@
|
|||||||
-------------------------------------------------------------------------
|
|
||||||
-- Project: JIPS, a portable 32-bit RISC CPU written in VHDL
|
|
||||||
-- This file: The ROM file for use in your VHDL design
|
|
||||||
--
|
|
||||||
-- Copyright (C) 2008 J. Ahrensfeld
|
|
||||||
--
|
|
||||||
-- This program is free software: you can redistribute it and/or modify
|
|
||||||
-- it under the terms of the GNU General Public License as published by
|
|
||||||
-- the Free Software Foundation, either version 3 of the License, or
|
|
||||||
-- (at your option) any later version.
|
|
||||||
--
|
|
||||||
-- This program is distributed in the hope that it will be useful,
|
|
||||||
-- but WITHOUT ANY WARRANTY; without even the implied warranty of
|
|
||||||
-- MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
|
||||||
-- GNU General Public License for more details.
|
|
||||||
--
|
|
||||||
-- You should have received a copy of the GNU General Public License
|
|
||||||
-- along with this program. If not, see <http://www.gnu.org/licenses/>.
|
|
||||||
--
|
|
||||||
-- For questions and ideas, please contact the author at jens@jayfield.org
|
|
||||||
--
|
|
||||||
--------------------------------------------------------------------------
|
|
||||||
|
|
||||||
LIBRARY ieee;
|
|
||||||
use IEEE.STD_LOGIC_1164.ALL;
|
|
||||||
USE ieee.numeric_std.ALL;
|
|
||||||
|
|
||||||
|
|
||||||
ENTITY rom IS
|
|
||||||
Generic
|
|
||||||
(
|
|
||||||
addr_width : integer := 2;
|
|
||||||
data_width : integer := 32
|
|
||||||
);
|
|
||||||
Port
|
|
||||||
(
|
|
||||||
clk : in STD_LOGIC;
|
|
||||||
addr : in unsigned(addr_width-1 downto 0);
|
|
||||||
dout : out unsigned(data_width-1 downto 0)
|
|
||||||
);
|
|
||||||
END rom;
|
|
||||||
|
|
||||||
ARCHITECTURE itest OF rom IS
|
|
||||||
|
|
||||||
subtype word_t is unsigned(data_width-1 downto 0);
|
|
||||||
type word_array_t is array (0 to 2**addr_width-1) of word_t;
|
|
||||||
|
|
||||||
-- Assembled from itest.jsm
|
|
||||||
constant word_array : word_array_t :=
|
|
||||||
(
|
|
||||||
X"3C1D7FFF", -- 00000000
|
|
||||||
X"0C100014", -- 00000004
|
|
||||||
X"37BDEFFC", -- 00000008
|
|
||||||
X"24080002", -- 0000000C
|
|
||||||
X"0107102A", -- 00000010
|
|
||||||
X"ACC40000", -- 00000014
|
|
||||||
X"1040000B", -- 00000018
|
|
||||||
X"ACC50004", -- 0000001C
|
|
||||||
X"24C60008", -- 00000020
|
|
||||||
X"24E8FFFE", -- 00000024
|
|
||||||
X"8CC2FFF8", -- 00000028
|
|
||||||
X"8CC3FFFC", -- 0000002C
|
|
||||||
X"2508FFFF", -- 00000030
|
|
||||||
X"00431021", -- 00000034
|
|
||||||
X"ACC20000", -- 00000038
|
|
||||||
X"1500FFFA", -- 0000003C
|
|
||||||
X"24C60004", -- 00000040
|
|
||||||
X"00E04021", -- 00000044
|
|
||||||
X"03E00008", -- 00000048
|
|
||||||
X"01001021", -- 0000004C
|
|
||||||
X"27BDFF78", -- 00000050
|
|
||||||
X"3C021003", -- 00000054
|
|
||||||
X"3C030001", -- 00000058
|
|
||||||
X"AFB60078", -- 0000005C
|
|
||||||
X"3456FFFC", -- 00000060
|
|
||||||
X"3C02AAAA", -- 00000064
|
|
||||||
X"AFB7007C", -- 00000068
|
|
||||||
X"AFB50074", -- 0000006C
|
|
||||||
X"AFB40070", -- 00000070
|
|
||||||
X"AFB20068", -- 00000074
|
|
||||||
X"AFB00060", -- 00000078
|
|
||||||
X"AFBF0080", -- 0000007C
|
|
||||||
X"AFB3006C", -- 00000080
|
|
||||||
X"AFB10064", -- 00000084
|
|
||||||
X"AEC00000", -- 00000088
|
|
||||||
X"3450AAAA", -- 0000008C
|
|
||||||
X"347786A0", -- 00000090
|
|
||||||
X"27B20010", -- 00000094
|
|
||||||
X"24150014", -- 00000098
|
|
||||||
X"3474869F", -- 0000009C
|
|
||||||
X"00009821", -- 000000A0
|
|
||||||
X"00002021", -- 000000A4
|
|
||||||
X"02401021", -- 000000A8
|
|
||||||
X"24060013", -- 000000AC
|
|
||||||
X"24C6FFFF", -- 000000B0
|
|
||||||
X"AC500000", -- 000000B4
|
|
||||||
X"04C1FFFD", -- 000000B8
|
|
||||||
X"24420004", -- 000000BC
|
|
||||||
X"02041026", -- 000000C0
|
|
||||||
X"24910001", -- 000000C4
|
|
||||||
X"24420001", -- 000000C8
|
|
||||||
X"02202821", -- 000000CC
|
|
||||||
X"27A60010", -- 000000D0
|
|
||||||
X"24070014", -- 000000D4
|
|
||||||
X"0C100003", -- 000000D8
|
|
||||||
X"00028040", -- 000000DC
|
|
||||||
X"24070002", -- 000000E0
|
|
||||||
X"26450008", -- 000000E4
|
|
||||||
X"0810003E", -- 000000E8
|
|
||||||
X"24060011", -- 000000EC
|
|
||||||
X"04C0000A", -- 000000F0
|
|
||||||
X"00000000", -- 000000F4
|
|
||||||
X"8CA20000", -- 000000F8
|
|
||||||
X"8CA3FFFC", -- 000000FC
|
|
||||||
X"8CA4FFF8", -- 00000100
|
|
||||||
X"00431023", -- 00000104
|
|
||||||
X"24C6FFFF", -- 00000108
|
|
||||||
X"1482FFF8", -- 0000010C
|
|
||||||
X"24A50004", -- 00000110
|
|
||||||
X"04C1FFF8", -- 00000114
|
|
||||||
X"24E70001", -- 00000118
|
|
||||||
X"10F5000C", -- 0000011C
|
|
||||||
X"00000000", -- 00000120
|
|
||||||
X"0291102A", -- 00000124
|
|
||||||
X"1040FFDF", -- 00000128
|
|
||||||
X"02202021", -- 0000012C
|
|
||||||
X"1677FFDB", -- 00000130
|
|
||||||
X"00009821", -- 00000134
|
|
||||||
X"8EC20000", -- 00000138
|
|
||||||
X"00000000", -- 0000013C
|
|
||||||
X"24420001", -- 00000140
|
|
||||||
X"AEC20000", -- 00000144
|
|
||||||
X"0810002A", -- 00000148
|
|
||||||
X"00002021", -- 0000014C
|
|
||||||
X"08100049", -- 00000150
|
|
||||||
X"26730001", -- 00000154
|
|
||||||
X"00000000", -- 00000158
|
|
||||||
X"00000000", -- 0000015C
|
|
||||||
X"00000000", -- 00000160
|
|
||||||
X"00000000", -- 00000164
|
|
||||||
X"00000000", -- 00000168
|
|
||||||
X"00000000", -- 0000016C
|
|
||||||
X"00000000", -- 00000170
|
|
||||||
X"00000000", -- 00000174
|
|
||||||
X"00000000", -- 00000178
|
|
||||||
X"00000000", -- 0000017C
|
|
||||||
X"00000000", -- 00000180
|
|
||||||
X"00000000", -- 00000184
|
|
||||||
X"00000000", -- 00000188
|
|
||||||
X"00000000", -- 0000018C
|
|
||||||
X"00000000", -- 00000190
|
|
||||||
X"00000000", -- 00000194
|
|
||||||
X"00000000", -- 00000198
|
|
||||||
X"00000000", -- 0000019C
|
|
||||||
X"00000000", -- 000001A0
|
|
||||||
X"00000000", -- 000001A4
|
|
||||||
X"00000000", -- 000001A8
|
|
||||||
X"00000000", -- 000001AC
|
|
||||||
X"00000000", -- 000001B0
|
|
||||||
X"00000000", -- 000001B4
|
|
||||||
X"00000000", -- 000001B8
|
|
||||||
X"00000000", -- 000001BC
|
|
||||||
X"00000000", -- 000001C0
|
|
||||||
X"00000000", -- 000001C4
|
|
||||||
X"00000000", -- 000001C8
|
|
||||||
X"00000000", -- 000001CC
|
|
||||||
X"00000000", -- 000001D0
|
|
||||||
X"00000000", -- 000001D4
|
|
||||||
X"00000000", -- 000001D8
|
|
||||||
X"00000000", -- 000001DC
|
|
||||||
X"00000000", -- 000001E0
|
|
||||||
X"00000000", -- 000001E4
|
|
||||||
X"00000000", -- 000001E8
|
|
||||||
X"00000000", -- 000001EC
|
|
||||||
X"00000000", -- 000001F0
|
|
||||||
X"00000000", -- 000001F4
|
|
||||||
X"00000000", -- 000001F8
|
|
||||||
X"00000000", -- 000001FC
|
|
||||||
X"00000000", -- 00000200
|
|
||||||
X"00000000", -- 00000204
|
|
||||||
X"00000000", -- 00000208
|
|
||||||
X"00000000", -- 0000020C
|
|
||||||
X"00000000", -- 00000210
|
|
||||||
X"00000000", -- 00000214
|
|
||||||
X"00000000", -- 00000218
|
|
||||||
X"00000000", -- 0000021C
|
|
||||||
X"00000000", -- 00000220
|
|
||||||
X"00000000", -- 00000224
|
|
||||||
X"00000000", -- 00000228
|
|
||||||
X"00000000", -- 0000022C
|
|
||||||
X"00000000", -- 00000230
|
|
||||||
X"00000000", -- 00000234
|
|
||||||
X"00000000", -- 00000238
|
|
||||||
X"00000000", -- 0000023C
|
|
||||||
X"00000000", -- 00000240
|
|
||||||
X"00000000", -- 00000244
|
|
||||||
X"00000000", -- 00000248
|
|
||||||
X"00000000", -- 0000024C
|
|
||||||
X"00000000", -- 00000250
|
|
||||||
X"00000000", -- 00000254
|
|
||||||
X"00000000", -- 00000258
|
|
||||||
X"00000000", -- 0000025C
|
|
||||||
X"00000000", -- 00000260
|
|
||||||
X"00000000", -- 00000264
|
|
||||||
X"00000000", -- 00000268
|
|
||||||
X"00000000", -- 0000026C
|
|
||||||
X"00000000", -- 00000270
|
|
||||||
X"00000000", -- 00000274
|
|
||||||
X"00000000", -- 00000278
|
|
||||||
X"00000000", -- 0000027C
|
|
||||||
X"00000000", -- 00000280
|
|
||||||
X"00000000", -- 00000284
|
|
||||||
X"00000000", -- 00000288
|
|
||||||
X"00000000", -- 0000028C
|
|
||||||
X"00000000", -- 00000290
|
|
||||||
X"00000000", -- 00000294
|
|
||||||
X"00000000", -- 00000298
|
|
||||||
X"00000000", -- 0000029C
|
|
||||||
X"00000000", -- 000002A0
|
|
||||||
X"00000000", -- 000002A4
|
|
||||||
X"00000000", -- 000002A8
|
|
||||||
X"00000000", -- 000002AC
|
|
||||||
X"00000000", -- 000002B0
|
|
||||||
X"00000000", -- 000002B4
|
|
||||||
X"00000000", -- 000002B8
|
|
||||||
X"00000000", -- 000002BC
|
|
||||||
X"00000000", -- 000002C0
|
|
||||||
X"00000000", -- 000002C4
|
|
||||||
X"00000000", -- 000002C8
|
|
||||||
X"00000000", -- 000002CC
|
|
||||||
X"00000000", -- 000002D0
|
|
||||||
X"00000000", -- 000002D4
|
|
||||||
X"00000000", -- 000002D8
|
|
||||||
X"00000000", -- 000002DC
|
|
||||||
X"00000000", -- 000002E0
|
|
||||||
X"00000000", -- 000002E4
|
|
||||||
X"00000000", -- 000002E8
|
|
||||||
X"00000000", -- 000002EC
|
|
||||||
X"00000000", -- 000002F0
|
|
||||||
X"00000000", -- 000002F4
|
|
||||||
X"00000000", -- 000002F8
|
|
||||||
X"00000000", -- 000002FC
|
|
||||||
X"00000000", -- 00000300
|
|
||||||
X"00000000", -- 00000304
|
|
||||||
X"00000000", -- 00000308
|
|
||||||
X"00000000", -- 0000030C
|
|
||||||
X"00000000", -- 00000310
|
|
||||||
X"00000000", -- 00000314
|
|
||||||
X"00000000", -- 00000318
|
|
||||||
X"00000000", -- 0000031C
|
|
||||||
X"00000000", -- 00000320
|
|
||||||
X"00000000", -- 00000324
|
|
||||||
X"00000000", -- 00000328
|
|
||||||
X"00000000", -- 0000032C
|
|
||||||
X"00000000", -- 00000330
|
|
||||||
X"00000000", -- 00000334
|
|
||||||
X"00000000", -- 00000338
|
|
||||||
X"00000000", -- 0000033C
|
|
||||||
X"00000000", -- 00000340
|
|
||||||
X"00000000", -- 00000344
|
|
||||||
X"00000000", -- 00000348
|
|
||||||
X"00000000", -- 0000034C
|
|
||||||
X"00000000", -- 00000350
|
|
||||||
X"00000000", -- 00000354
|
|
||||||
X"00000000", -- 00000358
|
|
||||||
X"00000000", -- 0000035C
|
|
||||||
X"00000000", -- 00000360
|
|
||||||
X"00000000", -- 00000364
|
|
||||||
X"00000000", -- 00000368
|
|
||||||
X"00000000", -- 0000036C
|
|
||||||
X"00000000", -- 00000370
|
|
||||||
X"00000000", -- 00000374
|
|
||||||
X"00000000", -- 00000378
|
|
||||||
X"00000000", -- 0000037C
|
|
||||||
X"00000000", -- 00000380
|
|
||||||
X"00000000", -- 00000384
|
|
||||||
X"00000000", -- 00000388
|
|
||||||
X"00000000", -- 0000038C
|
|
||||||
X"00000000", -- 00000390
|
|
||||||
X"00000000", -- 00000394
|
|
||||||
X"00000000", -- 00000398
|
|
||||||
X"00000000", -- 0000039C
|
|
||||||
X"00000000", -- 000003A0
|
|
||||||
X"00000000", -- 000003A4
|
|
||||||
X"00000000", -- 000003A8
|
|
||||||
X"00000000", -- 000003AC
|
|
||||||
X"00000000", -- 000003B0
|
|
||||||
X"00000000", -- 000003B4
|
|
||||||
X"00000000", -- 000003B8
|
|
||||||
X"00000000", -- 000003BC
|
|
||||||
X"00000000", -- 000003C0
|
|
||||||
X"00000000", -- 000003C4
|
|
||||||
X"00000000", -- 000003C8
|
|
||||||
X"00000000", -- 000003CC
|
|
||||||
X"00000000", -- 000003D0
|
|
||||||
X"00000000", -- 000003D4
|
|
||||||
X"00000000", -- 000003D8
|
|
||||||
X"00000000", -- 000003DC
|
|
||||||
X"00000000", -- 000003E0
|
|
||||||
X"00000000", -- 000003E4
|
|
||||||
X"00000000", -- 000003E8
|
|
||||||
X"00000000", -- 000003EC
|
|
||||||
X"00000000", -- 000003F0
|
|
||||||
X"00000000", -- 000003F4
|
|
||||||
X"00000000", -- 000003F8
|
|
||||||
X"00000000" -- 000003FC
|
|
||||||
);
|
|
||||||
|
|
||||||
begin
|
|
||||||
|
|
||||||
PROM_READ:
|
|
||||||
process(clk)
|
|
||||||
begin
|
|
||||||
if rising_edge(clk) then
|
|
||||||
dout <= word_array(to_integer(addr));
|
|
||||||
end if;
|
|
||||||
end process;
|
|
||||||
|
|
||||||
|
|
||||||
end itest;
|
|
||||||
@@ -1,121 +0,0 @@
|
|||||||
-------------------------------------------------------------------------
|
|
||||||
-- Project: JCPU, a portable 8-bit RISC CPU written in VHDL
|
|
||||||
-- This file: The ROM file for use in your VHDL design
|
|
||||||
--
|
|
||||||
-- Copyright (C) 2007 J. Ahrensfeld
|
|
||||||
--
|
|
||||||
-- This program is free software: you can redistribute it and/or modify
|
|
||||||
-- it under the terms of the GNU General Public License as published by
|
|
||||||
-- the Free Software Foundation, either version 3 of the License, or
|
|
||||||
-- (at your option) any later version.
|
|
||||||
--
|
|
||||||
-- This program is distributed in the hope that it will be useful,
|
|
||||||
-- but WITHOUT ANY WARRANTY; without even the implied warranty of
|
|
||||||
-- MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
|
||||||
-- GNU General Public License for more details.
|
|
||||||
--
|
|
||||||
-- You should have received a copy of the GNU General Public License
|
|
||||||
-- along with this program. If not, see <http://www.gnu.org/licenses/>.
|
|
||||||
--
|
|
||||||
-- For questions and ideas, please contact the author at jens@jayfield.org
|
|
||||||
--
|
|
||||||
--------------------------------------------------------------------------
|
|
||||||
|
|
||||||
LIBRARY ieee;
|
|
||||||
use IEEE.STD_LOGIC_1164.ALL;
|
|
||||||
USE ieee.numeric_std.ALL;
|
|
||||||
|
|
||||||
|
|
||||||
ENTITY rom IS
|
|
||||||
Generic
|
|
||||||
(
|
|
||||||
addr_width : integer := 2;
|
|
||||||
data_width : integer := 32
|
|
||||||
);
|
|
||||||
Port
|
|
||||||
(
|
|
||||||
addr : in unsigned(addr_width-1 downto 0);
|
|
||||||
dout : out unsigned(data_width-1 downto 0)
|
|
||||||
);
|
|
||||||
END rom;
|
|
||||||
|
|
||||||
ARCHITECTURE itest OF rom IS
|
|
||||||
|
|
||||||
subtype word_t is unsigned(data_width-1 downto 0);
|
|
||||||
type word_array_t is array (0 to 2**addr_width-1) of word_t;
|
|
||||||
|
|
||||||
-- Assembled from itest.jsm
|
|
||||||
constant word_array : word_array_t :=
|
|
||||||
(
|
|
||||||
X"08100001", -- [0x00400000] j 0x00400004 [main]
|
|
||||||
X"3c011234", -- [0x00400004] lui $1, 4660
|
|
||||||
X"34215678", -- [0x00400008] ori $1, $1, 22136
|
|
||||||
X"3021f00f", -- [0x0040000c] andi $1, $1, -4081
|
|
||||||
X"2021affc", -- [0x00400010] addi $1, $1, -20484
|
|
||||||
X"2021ffff", -- [0x00400014] addi $1, $1, -1
|
|
||||||
X"1c20fffe", -- [0x00400018] bgtz $1 -8 [loop-0x00400018]
|
|
||||||
X"3c020000", -- [0x0040001c] lui $2, 0
|
|
||||||
X"34420001", -- [0x00400020] ori $2, $2, 1
|
|
||||||
X"3c010000", -- [0x00400024] lui $1, 0
|
|
||||||
X"34210004", -- [0x00400028] ori $1, $1, 4
|
|
||||||
X"00220822", -- [0x0040002c] sub $1, $1, $2
|
|
||||||
X"1c20fffe", -- [0x00400030] bgtz $1 -8 [loop2-0x00400030]
|
|
||||||
X"3c1f0040", -- [0x00400034] lui $31, 64
|
|
||||||
X"03e00008", -- [0x00400038] jr $31
|
|
||||||
X"00000000", -- [0x0040003c] nop
|
|
||||||
X"00000000", -- [0x00400040] nop
|
|
||||||
X"00000000", -- [0x00400044] nop
|
|
||||||
X"00000000", -- [0x00400048] nop
|
|
||||||
X"00000000", -- [0x0040004c] nop
|
|
||||||
X"00000000", -- [0x00400050] nop
|
|
||||||
X"00000000", -- [0x00400054] nop
|
|
||||||
X"00000000", -- [0x00400058] nop
|
|
||||||
X"00000000", -- [0x0040005c] nop
|
|
||||||
X"00000000", -- [0x00400060] nop
|
|
||||||
X"00000000", -- [0x00400064] nop
|
|
||||||
X"00000000", -- [0x00400068] nop
|
|
||||||
X"00000000", -- [0x0040006c] nop
|
|
||||||
X"00000000", -- [0x00400070] nop
|
|
||||||
X"00000000", -- [0x00400074] nop
|
|
||||||
X"00000000", -- [0x00400078] nop
|
|
||||||
X"00000000", -- [0x0040007c] nop
|
|
||||||
X"00000000", -- [0x00400080] nop
|
|
||||||
X"00000000", -- [0x00400084] nop
|
|
||||||
X"00000000", -- [0x00400088] nop
|
|
||||||
X"00000000", -- [0x0040008c] nop
|
|
||||||
X"00000000", -- [0x00400090] nop
|
|
||||||
X"00000000", -- [0x00400094] nop
|
|
||||||
X"00000000", -- [0x00400098] nop
|
|
||||||
X"00000000", -- [0x0040009c] nop
|
|
||||||
X"00000000", -- [0x004000a0] nop
|
|
||||||
X"00000000", -- [0x004000a4] nop
|
|
||||||
X"00000000", -- [0x004000a8] nop
|
|
||||||
X"00000000", -- [0x004000ac] nop
|
|
||||||
X"00000000", -- [0x004000b0] nop
|
|
||||||
X"00000000", -- [0x004000b4] nop
|
|
||||||
X"00000000", -- [0x004000b8] nop
|
|
||||||
X"00000000", -- [0x004000bc] nop
|
|
||||||
X"00000000", -- [0x004000c0] nop
|
|
||||||
X"00000000", -- [0x004000c4] nop
|
|
||||||
X"00000000", -- [0x004000c8] nop
|
|
||||||
X"00000000", -- [0x004000cc] nop
|
|
||||||
X"00000000", -- [0x004000d0] nop
|
|
||||||
X"00000000", -- [0x004000d4] nop
|
|
||||||
X"00000000", -- [0x004000d8] nop
|
|
||||||
X"00000000", -- [0x004000dc] nop
|
|
||||||
X"00000000", -- [0x004000e0] nop
|
|
||||||
X"00000000", -- [0x004000e4] nop
|
|
||||||
X"00000000", -- [0x004000e8] nop
|
|
||||||
X"00000000", -- [0x004000ec] nop
|
|
||||||
X"00000000", -- [0x004000f0] nop
|
|
||||||
X"00000000", -- [0x004000f4] nop
|
|
||||||
X"00000000", -- [0x004000f8] nop
|
|
||||||
X"00000000" -- [0x004000fc] nop
|
|
||||||
);
|
|
||||||
|
|
||||||
begin
|
|
||||||
|
|
||||||
PROM_READ:
|
|
||||||
dout <= word_array(to_integer(addr));
|
|
||||||
|
|
||||||
end itest;
|
|
||||||
@@ -1,73 +0,0 @@
|
|||||||
-------------------------------------------------------------------------
|
|
||||||
-- Project: JCPU, a portable 8-bit RISC CPU written in VHDL
|
|
||||||
-- This file: The ROM file for use in your VHDL design
|
|
||||||
--
|
|
||||||
-- Copyright (C) 2007 J. Ahrensfeld
|
|
||||||
--
|
|
||||||
-- This program is free software: you can redistribute it and/or modify
|
|
||||||
-- it under the terms of the GNU General Public License as published by
|
|
||||||
-- the Free Software Foundation, either version 3 of the License, or
|
|
||||||
-- (at your option) any later version.
|
|
||||||
--
|
|
||||||
-- This program is distributed in the hope that it will be useful,
|
|
||||||
-- but WITHOUT ANY WARRANTY; without even the implied warranty of
|
|
||||||
-- MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
|
||||||
-- GNU General Public License for more details.
|
|
||||||
--
|
|
||||||
-- You should have received a copy of the GNU General Public License
|
|
||||||
-- along with this program. If not, see <http://www.gnu.org/licenses/>.
|
|
||||||
--
|
|
||||||
-- For questions and ideas, please contact the author at jens@jayfield.org
|
|
||||||
--
|
|
||||||
--------------------------------------------------------------------------
|
|
||||||
|
|
||||||
LIBRARY ieee;
|
|
||||||
use IEEE.STD_LOGIC_1164.ALL;
|
|
||||||
USE ieee.numeric_std.ALL;
|
|
||||||
|
|
||||||
|
|
||||||
ENTITY rom IS
|
|
||||||
Generic
|
|
||||||
(
|
|
||||||
addr_width : integer := 2;
|
|
||||||
data_width : integer := 32
|
|
||||||
);
|
|
||||||
Port
|
|
||||||
(
|
|
||||||
addr : in unsigned(addr_width-1 downto 0);
|
|
||||||
dout : out unsigned(data_width-1 downto 0)
|
|
||||||
);
|
|
||||||
END rom;
|
|
||||||
|
|
||||||
ARCHITECTURE itest OF rom IS
|
|
||||||
|
|
||||||
subtype word_t is unsigned(data_width-1 downto 0);
|
|
||||||
type word_array_t is array (0 to 2**addr_width-1) of word_t;
|
|
||||||
|
|
||||||
-- Assembled from itest.jsm
|
|
||||||
constant word_array : word_array_t :=
|
|
||||||
(
|
|
||||||
X"08100001", -- j 0x00400004 [main] ; 5: j main
|
|
||||||
X"3c011234", -- lui $1, 4660 ; 7: lui $1, 0x1234
|
|
||||||
X"34215678", -- ori $1, $1, 22136 ; 8: ori $1, $1, 0x5678
|
|
||||||
X"3c035555", -- lui $3, 21845 ; 9: lui $3, 0x5555
|
|
||||||
X"3463aaaa", -- ori $3, $3, -21846 ; 10: ori $3, $3, 0xAAAA
|
|
||||||
X"3c021000", -- lui $2, 4096 ; 11: lui $2, 0x1000
|
|
||||||
X"ac410000", -- sw $1, 0($2) ; 12: sw $1, 0($2)
|
|
||||||
X"ac430004", -- sw $3, 4($2) ; 13: sw $3, 4($2)
|
|
||||||
X"00000000", -- nop ; 14: sll $0, $0, 0
|
|
||||||
X"ac400000", -- sw $0, 0($2) ; 15: sw $0, 0($2)
|
|
||||||
X"ac400004", -- sw $0, 4($2) ; 16: sw $0, 4($2)
|
|
||||||
X"8c410000", -- lw $1, 0($2) ; 17: lw $1, 0($2)
|
|
||||||
X"8c430004", -- lw $3, 4($2) ; 18: lw $3, 4($2)
|
|
||||||
X"00000000", -- nop ; 19: sll $0, $0, 0
|
|
||||||
X"00000000", -- nop ; 20: sll $0, $0, 0
|
|
||||||
X"08100001" -- j 0x00400004 [main] ; 21: j main
|
|
||||||
);
|
|
||||||
|
|
||||||
begin
|
|
||||||
|
|
||||||
PROM_READ:
|
|
||||||
dout <= word_array(to_integer(addr));
|
|
||||||
|
|
||||||
end itest;
|
|
||||||
@@ -1,122 +0,0 @@
|
|||||||
-------------------------------------------------------------------------
|
|
||||||
-- Project: JCPU, a portable 8-bit RISC CPU written in VHDL
|
|
||||||
-- This file: The ROM file for use in your VHDL design
|
|
||||||
--
|
|
||||||
-- Copyright (C) 2007 J. Ahrensfeld
|
|
||||||
--
|
|
||||||
-- This program is free software: you can redistribute it and/or modify
|
|
||||||
-- it under the terms of the GNU General Public License as published by
|
|
||||||
-- the Free Software Foundation, either version 3 of the License, or
|
|
||||||
-- (at your option) any later version.
|
|
||||||
--
|
|
||||||
-- This program is distributed in the hope that it will be useful,
|
|
||||||
-- but WITHOUT ANY WARRANTY; without even the implied warranty of
|
|
||||||
-- MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
|
||||||
-- GNU General Public License for more details.
|
|
||||||
--
|
|
||||||
-- You should have received a copy of the GNU General Public License
|
|
||||||
-- along with this program. If not, see <http://www.gnu.org/licenses/>.
|
|
||||||
--
|
|
||||||
-- For questions and ideas, please contact the author at jens@jayfield.org
|
|
||||||
--
|
|
||||||
--------------------------------------------------------------------------
|
|
||||||
|
|
||||||
LIBRARY ieee;
|
|
||||||
use IEEE.STD_LOGIC_1164.ALL;
|
|
||||||
USE ieee.numeric_std.ALL;
|
|
||||||
|
|
||||||
|
|
||||||
ENTITY rom IS
|
|
||||||
Generic
|
|
||||||
(
|
|
||||||
addr_width : integer := 2;
|
|
||||||
data_width : integer := 32
|
|
||||||
);
|
|
||||||
Port
|
|
||||||
(
|
|
||||||
addr : in unsigned(addr_width-1 downto 0);
|
|
||||||
dout : out unsigned(data_width-1 downto 0)
|
|
||||||
);
|
|
||||||
END rom;
|
|
||||||
|
|
||||||
ARCHITECTURE itest OF rom IS
|
|
||||||
|
|
||||||
subtype word_t is unsigned(data_width-1 downto 0);
|
|
||||||
type word_array_t is array (0 to 2**addr_width-1) of word_t;
|
|
||||||
|
|
||||||
-- Assembled from itest.jsm
|
|
||||||
constant word_array : word_array_t :=
|
|
||||||
(
|
|
||||||
|
|
||||||
X"08100001", -- [0x00400000] j 0x00400004 [main]
|
|
||||||
X"3c011234", -- [0x00400004] lui $1, 4660
|
|
||||||
X"34215a5a", -- [0x00400008] ori $1, $1, 23130
|
|
||||||
X"00010840", -- [0x0040000c] sll $1, $1, 1
|
|
||||||
X"00010900", -- [0x00400010] sll $1, $1, 4
|
|
||||||
X"00010880", -- [0x00400014] sll $1, $1, 2
|
|
||||||
X"00010840", -- [0x00400018] sll $1, $1, 1
|
|
||||||
X"00010a00", -- [0x0040001c] sll $1, $1, 8
|
|
||||||
X"00010882", -- [0x00400020] srl $1, $1, 2
|
|
||||||
X"00010942", -- [0x00400024] srl $1, $1, 5
|
|
||||||
X"00010842", -- [0x00400028] srl $1, $1, 1
|
|
||||||
X"00010a02", -- [0x0040002c] srl $1, $1, 8
|
|
||||||
X"3821ffff", -- [0x00400030] xori $1, $1, -1
|
|
||||||
X"3c1f0040", -- [0x00400034] lui $31, 64
|
|
||||||
X"03e00008", -- [0x00400038] jr $31
|
|
||||||
X"003f0826", -- [0x0040003c] xor $1, $1, $31
|
|
||||||
X"00000000", -- [0x00400040] nop
|
|
||||||
X"00000000", -- [0x00400044] nop
|
|
||||||
X"00000000", -- [0x00400048] nop
|
|
||||||
X"00000000", -- [0x0040004c] nop
|
|
||||||
X"00000000", -- [0x00400050] nop
|
|
||||||
X"00000000", -- [0x00400054] nop
|
|
||||||
X"00000000", -- [0x00400058] nop
|
|
||||||
X"00000000", -- [0x0040005c] nop
|
|
||||||
X"00000000", -- [0x00400060] nop
|
|
||||||
X"00000000", -- [0x00400064] nop
|
|
||||||
X"00000000", -- [0x00400068] nop
|
|
||||||
X"00000000", -- [0x0040006c] nop
|
|
||||||
X"00000000", -- [0x00400070] nop
|
|
||||||
X"00000000", -- [0x00400074] nop
|
|
||||||
X"00000000", -- [0x00400078] nop
|
|
||||||
X"00000000", -- [0x0040007c] nop
|
|
||||||
X"00000000", -- [0x00400080] nop
|
|
||||||
X"00000000", -- [0x00400084] nop
|
|
||||||
X"00000000", -- [0x00400088] nop
|
|
||||||
X"00000000", -- [0x0040008c] nop
|
|
||||||
X"00000000", -- [0x00400090] nop
|
|
||||||
X"00000000", -- [0x00400094] nop
|
|
||||||
X"00000000", -- [0x00400098] nop
|
|
||||||
X"00000000", -- [0x0040009c] nop
|
|
||||||
X"00000000", -- [0x004000a0] nop
|
|
||||||
X"00000000", -- [0x004000a4] nop
|
|
||||||
X"00000000", -- [0x004000a8] nop
|
|
||||||
X"00000000", -- [0x004000ac] nop
|
|
||||||
X"00000000", -- [0x004000b0] nop
|
|
||||||
X"00000000", -- [0x004000b4] nop
|
|
||||||
X"00000000", -- [0x004000b8]
|
|
||||||
X"00000000", -- [0x004000bc]
|
|
||||||
X"00000000", -- [0x004000c0]
|
|
||||||
X"00000000", -- [0x004000c4]
|
|
||||||
X"00000000", -- [0x004000c8]
|
|
||||||
X"00000000", -- [0x004000cc]
|
|
||||||
X"00000000", -- [0x004000d0]
|
|
||||||
X"00000000", -- [0x004000d4]
|
|
||||||
X"00000000", -- [0x004000d8]
|
|
||||||
X"00000000", -- [0x004000dc]
|
|
||||||
X"00000000", -- [0x004000e0]
|
|
||||||
X"00000000", -- [0x004000e4]
|
|
||||||
X"00000000", -- [0x004000e8]
|
|
||||||
X"00000000", -- [0x004000ec]
|
|
||||||
X"00000000", -- [0x004000f0]
|
|
||||||
X"00000000", -- [0x004000f4]
|
|
||||||
X"00000000", -- [0x004000f8]
|
|
||||||
X"00000000" -- [0x004000fc]
|
|
||||||
);
|
|
||||||
|
|
||||||
begin
|
|
||||||
|
|
||||||
PROM_READ:
|
|
||||||
dout <= word_array(to_integer(addr));
|
|
||||||
|
|
||||||
end itest;
|
|
||||||
@@ -1,122 +0,0 @@
|
|||||||
-------------------------------------------------------------------------
|
|
||||||
-- Project: JCPU, a portable 8-bit RISC CPU written in VHDL
|
|
||||||
-- This file: The ROM file for use in your VHDL design
|
|
||||||
--
|
|
||||||
-- Copyright (C) 2007 J. Ahrensfeld
|
|
||||||
--
|
|
||||||
-- This program is free software: you can redistribute it and/or modify
|
|
||||||
-- it under the terms of the GNU General Public License as published by
|
|
||||||
-- the Free Software Foundation, either version 3 of the License, or
|
|
||||||
-- (at your option) any later version.
|
|
||||||
--
|
|
||||||
-- This program is distributed in the hope that it will be useful,
|
|
||||||
-- but WITHOUT ANY WARRANTY; without even the implied warranty of
|
|
||||||
-- MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
|
||||||
-- GNU General Public License for more details.
|
|
||||||
--
|
|
||||||
-- You should have received a copy of the GNU General Public License
|
|
||||||
-- along with this program. If not, see <http://www.gnu.org/licenses/>.
|
|
||||||
--
|
|
||||||
-- For questions and ideas, please contact the author at jens@jayfield.org
|
|
||||||
--
|
|
||||||
--------------------------------------------------------------------------
|
|
||||||
|
|
||||||
LIBRARY ieee;
|
|
||||||
use IEEE.STD_LOGIC_1164.ALL;
|
|
||||||
USE ieee.numeric_std.ALL;
|
|
||||||
|
|
||||||
|
|
||||||
ENTITY rom IS
|
|
||||||
Generic
|
|
||||||
(
|
|
||||||
addr_width : integer := 2;
|
|
||||||
data_width : integer := 32
|
|
||||||
);
|
|
||||||
Port
|
|
||||||
(
|
|
||||||
addr : in unsigned(addr_width-1 downto 0);
|
|
||||||
dout : out unsigned(data_width-1 downto 0)
|
|
||||||
);
|
|
||||||
END rom;
|
|
||||||
|
|
||||||
ARCHITECTURE itest OF rom IS
|
|
||||||
|
|
||||||
subtype word_t is unsigned(data_width-1 downto 0);
|
|
||||||
type word_array_t is array (0 to 2**addr_width-1) of word_t;
|
|
||||||
|
|
||||||
-- Assembled from itest.jsm
|
|
||||||
constant word_array : word_array_t :=
|
|
||||||
(
|
|
||||||
|
|
||||||
X"08100001", -- [0x00400000] j 0x00400004 [main] ; 5: j main
|
|
||||||
X"00000000", -- [0x00400004] nop ; 7: sll $0, $0, 0
|
|
||||||
X"3c011000", -- [0x00400008] lui $1, 4096 ; 8: lui $1, 0x1000
|
|
||||||
X"20220000", -- [0x0040000c] addi $2, $1, 0 ; 9: addi $2, $1, 0
|
|
||||||
X"3c071234", -- [0x00400010] lui $7, 4660 ; 10: lui $7, 0x1234
|
|
||||||
X"3c050001", -- [0x00400014] lui $5, 1 ; 11: lui $5, 0x0001
|
|
||||||
X"ac270000", -- [0x00400018] sw $7, 0($1) ; 12: sw $7, 0($1)
|
|
||||||
X"8c430000", -- [0x0040001c] lw $3, 0($2) ; 13: lw $3, 0($2)
|
|
||||||
X"00654020", -- [0x00400020] add $8, $3, $5 ; 14: add $8, $3, $5
|
|
||||||
X"00654820", -- [0x00400024] add $9, $3, $5 ; 15: add $9, $3, $5
|
|
||||||
X"00655020", -- [0x00400028] add $10, $3, $5 ; 16: add $10, $3, $5
|
|
||||||
X"00655820", -- [0x0040002c] add $11, $3, $5 ; 17: add $11, $3, $5
|
|
||||||
X"00000000", -- [0x00400030] nop ; 18: sll $0, $0, 0
|
|
||||||
X"00000000", -- [0x00400034] nop ; 19: sll $0, $0, 0
|
|
||||||
X"08100001", -- [0x00400038] j 0x00400004 [main] ; 20: j main
|
|
||||||
X"00000000", -- [0x0040003c] nop ; 21: sll $0, $0, 0
|
|
||||||
X"00000000", -- [0x00400040] nop ; 21: sll $0, $0, 0
|
|
||||||
X"00000000", -- [0x00400044] nop ; 21: sll $0, $0, 0
|
|
||||||
X"00000000", -- [0x00400048] nop ; 21: sll $0, $0, 0
|
|
||||||
X"00000000", -- [0x0040004c] nop ; 21: sll $0, $0, 0
|
|
||||||
X"00000000", -- [0x00400050] nop ; 21: sll $0, $0, 0
|
|
||||||
X"00000000", -- [0x00400054] nop ; 21: sll $0, $0, 0
|
|
||||||
X"00000000", -- [0x00400058] nop ; 21: sll $0, $0, 0
|
|
||||||
X"00000000", -- [0x0040005c] nop ; 21: sll $0, $0, 0
|
|
||||||
X"00000000", -- [0x00400060] nop ; 21: sll $0, $0, 0
|
|
||||||
X"00000000", -- [0x00400064] nop ; 21: sll $0, $0, 0
|
|
||||||
X"00000000", -- [0x00400068] nop ; 21: sll $0, $0, 0
|
|
||||||
X"00000000", -- [0x0040006c] nop ; 21: sll $0, $0, 0
|
|
||||||
X"00000000", -- [0x00400070] nop ; 21: sll $0, $0, 0
|
|
||||||
X"00000000", -- [0x00400074] nop ; 21: sll $0, $0, 0
|
|
||||||
X"00000000", -- [0x00400078] nop ; 21: sll $0, $0, 0
|
|
||||||
X"00000000", -- [0x0040007c] nop ; 21: sll $0, $0, 0
|
|
||||||
X"00000000", -- [0x00400080] nop ; 21: sll $0, $0, 0
|
|
||||||
X"00000000", -- [0x00400084] nop ; 21: sll $0, $0, 0
|
|
||||||
X"00000000", -- [0x00400088] nop ; 21: sll $0, $0, 0
|
|
||||||
X"00000000", -- [0x0040008c] nop ; 21: sll $0, $0, 0
|
|
||||||
X"00000000", -- [0x00400090] nop ; 21: sll $0, $0, 0
|
|
||||||
X"00000000", -- [0x00400094] nop ; 21: sll $0, $0, 0
|
|
||||||
X"00000000", -- [0x00400098] nop ; 21: sll $0, $0, 0
|
|
||||||
X"00000000", -- [0x0040009c] nop ; 21: sll $0, $0, 0
|
|
||||||
X"00000000", -- [0x004000a0] nop ; 21: sll $0, $0, 0
|
|
||||||
X"00000000", -- [0x004000a4] nop ; 21: sll $0, $0, 0
|
|
||||||
X"00000000", -- [0x004000a8] nop ; 21: sll $0, $0, 0
|
|
||||||
X"00000000", -- [0x004000ac] nop ; 21: sll $0, $0, 0
|
|
||||||
X"00000000", -- [0x004000b0] nop ; 21: sll $0, $0, 0
|
|
||||||
X"00000000", -- [0x004000b4] nop ; 21: sll $0, $0, 0
|
|
||||||
X"00000000", -- [0x004000b8] nop ; 21: sll $0, $0, 0
|
|
||||||
X"00000000", -- [0x004000bc] nop ; 21: sll $0, $0, 0
|
|
||||||
X"00000000", -- [0x004000c0] nop ; 21: sll $0, $0, 0
|
|
||||||
X"00000000", -- [0x004000c4] nop ; 21: sll $0, $0, 0
|
|
||||||
X"00000000", -- [0x004000c8] nop ; 21: sll $0, $0, 0
|
|
||||||
X"00000000", -- [0x004000cc] nop ; 21: sll $0, $0, 0
|
|
||||||
X"00000000", -- [0x004000d0] nop ; 21: sll $0, $0, 0
|
|
||||||
X"00000000", -- [0x004000d4] nop ; 21: sll $0, $0, 0
|
|
||||||
X"00000000", -- [0x004000d8] nop ; 21: sll $0, $0, 0
|
|
||||||
X"00000000", -- [0x004000dc] nop ; 21: sll $0, $0, 0
|
|
||||||
X"00000000", -- [0x004000e0] nop ; 21: sll $0, $0, 0
|
|
||||||
X"00000000", -- [0x004000e4] nop ; 21: sll $0, $0, 0
|
|
||||||
X"00000000", -- [0x004000e8] nop ; 21: sll $0, $0, 0
|
|
||||||
X"00000000", -- [0x004000ec] nop ; 21: sll $0, $0, 0
|
|
||||||
X"00000000", -- [0x004000f0] nop ; 21: sll $0, $0, 0
|
|
||||||
X"00000000", -- [0x004000f4] nop ; 21: sll $0, $0, 0
|
|
||||||
X"00000000", -- [0x004000f8] nop ; 21: sll $0, $0, 0
|
|
||||||
X"00000000" -- [0x004000fc] nop ; 21: sll $0, $0, 0
|
|
||||||
);
|
|
||||||
|
|
||||||
begin
|
|
||||||
|
|
||||||
PROM_READ:
|
|
||||||
dout <= word_array(to_integer(addr));
|
|
||||||
|
|
||||||
end itest;
|
|
||||||
@@ -1,122 +0,0 @@
|
|||||||
-------------------------------------------------------------------------
|
|
||||||
-- Project: JCPU, a portable 8-bit RISC CPU written in VHDL
|
|
||||||
-- This file: The ROM file for use in your VHDL design
|
|
||||||
--
|
|
||||||
-- Copyright (C) 2007 J. Ahrensfeld
|
|
||||||
--
|
|
||||||
-- This program is free software: you can redistribute it and/or modify
|
|
||||||
-- it under the terms of the GNU General Public License as published by
|
|
||||||
-- the Free Software Foundation, either version 3 of the License, or
|
|
||||||
-- (at your option) any later version.
|
|
||||||
--
|
|
||||||
-- This program is distributed in the hope that it will be useful,
|
|
||||||
-- but WITHOUT ANY WARRANTY; without even the implied warranty of
|
|
||||||
-- MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
|
||||||
-- GNU General Public License for more details.
|
|
||||||
--
|
|
||||||
-- You should have received a copy of the GNU General Public License
|
|
||||||
-- along with this program. If not, see <http://www.gnu.org/licenses/>.
|
|
||||||
--
|
|
||||||
-- For questions and ideas, please contact the author at jens@jayfield.org
|
|
||||||
--
|
|
||||||
--------------------------------------------------------------------------
|
|
||||||
|
|
||||||
LIBRARY ieee;
|
|
||||||
use IEEE.STD_LOGIC_1164.ALL;
|
|
||||||
USE ieee.numeric_std.ALL;
|
|
||||||
|
|
||||||
|
|
||||||
ENTITY rom IS
|
|
||||||
Generic
|
|
||||||
(
|
|
||||||
addr_width : integer := 2;
|
|
||||||
data_width : integer := 32
|
|
||||||
);
|
|
||||||
Port
|
|
||||||
(
|
|
||||||
addr : in unsigned(addr_width-1 downto 0);
|
|
||||||
dout : out unsigned(data_width-1 downto 0)
|
|
||||||
);
|
|
||||||
END rom;
|
|
||||||
|
|
||||||
ARCHITECTURE itest OF rom IS
|
|
||||||
|
|
||||||
subtype word_t is unsigned(data_width-1 downto 0);
|
|
||||||
type word_array_t is array (0 to 2**addr_width-1) of word_t;
|
|
||||||
|
|
||||||
-- Assembled from itest.jsm
|
|
||||||
constant word_array : word_array_t :=
|
|
||||||
(
|
|
||||||
|
|
||||||
X"08100001", -- [0x00400000] j 0x00400004 [main]
|
|
||||||
X"3c018000", -- [0x00400004] lui $1, -32768
|
|
||||||
X"3c020000", -- [0x00400008] lui $2, 0
|
|
||||||
X"3c030000", -- [0x0040000c] lui $3, 0
|
|
||||||
X"34420001", -- [0x00400010] ori $2, $2, 1
|
|
||||||
X"34630003", -- [0x00400014] ori $3, $3, 3
|
|
||||||
X"00010842", -- [0x00400018] srl $1, $1, 1
|
|
||||||
X"00010840", -- [0x0040001c] sll $1, $1, 1
|
|
||||||
X"00010843", -- [0x00400020] sra $1, $1, 1
|
|
||||||
X"000108c3", -- [0x00400024] sra $1, $1, 3
|
|
||||||
X"00612004", -- [0x00400028] sllv $4, $1, $3
|
|
||||||
X"00412807", -- [0x0040002c] srav $5, $1, $2
|
|
||||||
X"00613007", -- [0x00400030] srav $6, $1, $3
|
|
||||||
X"3c1f0040", -- [0x00400034] lui $31, 64
|
|
||||||
X"03e00008", -- [0x00400038] jr $31
|
|
||||||
X"00000000", -- [0x0040003c] nop
|
|
||||||
X"00000000", -- [0x00400040] nop
|
|
||||||
X"00000000", -- [0x00400044] nop
|
|
||||||
X"00000000", -- [0x00400048] nop
|
|
||||||
X"00000000", -- [0x0040004c] nop
|
|
||||||
X"00000000", -- [0x00400050] nop
|
|
||||||
X"00000000", -- [0x00400054] nop
|
|
||||||
X"00000000", -- [0x00400058] nop
|
|
||||||
X"00000000", -- [0x0040005c] nop
|
|
||||||
X"00000000", -- [0x00400060] nop
|
|
||||||
X"00000000", -- [0x00400064] nop
|
|
||||||
X"00000000", -- [0x00400068] nop
|
|
||||||
X"00000000", -- [0x0040006c] nop
|
|
||||||
X"00000000", -- [0x00400070] nop
|
|
||||||
X"00000000", -- [0x00400074] nop
|
|
||||||
X"00000000", -- [0x00400078] nop
|
|
||||||
X"00000000", -- [0x0040007c] nop
|
|
||||||
X"00000000", -- [0x00400080] nop
|
|
||||||
X"00000000", -- [0x00400084] nop
|
|
||||||
X"00000000", -- [0x00400088] nop
|
|
||||||
X"00000000", -- [0x0040008c] nop
|
|
||||||
X"00000000", -- [0x00400090] nop
|
|
||||||
X"00000000", -- [0x00400094] nop
|
|
||||||
X"00000000", -- [0x00400098] nop
|
|
||||||
X"00000000", -- [0x0040009c] nop
|
|
||||||
X"00000000", -- [0x004000a0] nop
|
|
||||||
X"00000000", -- [0x004000a4] nop
|
|
||||||
X"00000000", -- [0x004000a8] nop
|
|
||||||
X"00000000", -- [0x004000ac] nop
|
|
||||||
X"00000000", -- [0x004000b0] nop
|
|
||||||
X"00000000", -- [0x004000b4] nop
|
|
||||||
X"00000000", -- [0x004000b8] nop
|
|
||||||
X"00000000", -- [0x004000bc] nop
|
|
||||||
X"00000000", -- [0x004000c0] nop
|
|
||||||
X"00000000", -- [0x004000c4] nop
|
|
||||||
X"00000000", -- [0x004000c8] nop
|
|
||||||
X"00000000", -- [0x004000cc] nop
|
|
||||||
X"00000000", -- [0x004000d0] nop
|
|
||||||
X"00000000", -- [0x004000d4] nop
|
|
||||||
X"00000000", -- [0x004000d8] nop
|
|
||||||
X"00000000", -- [0x004000dc] nop
|
|
||||||
X"00000000", -- [0x004000e0] nop
|
|
||||||
X"00000000", -- [0x004000e4] nop
|
|
||||||
X"00000000", -- [0x004000e8] nop
|
|
||||||
X"00000000", -- [0x004000ec] nop
|
|
||||||
X"00000000", -- [0x004000f0] nop
|
|
||||||
X"00000000", -- [0x004000f4] nop
|
|
||||||
X"00000000", -- [0x004000f8] nop
|
|
||||||
X"00000000" -- [0x004000fc] nop
|
|
||||||
);
|
|
||||||
|
|
||||||
begin
|
|
||||||
|
|
||||||
PROM_READ:
|
|
||||||
dout <= word_array(to_integer(addr));
|
|
||||||
|
|
||||||
end itest;
|
|
||||||
@@ -1,121 +0,0 @@
|
|||||||
-------------------------------------------------------------------------
|
|
||||||
-- Project: JCPU, a portable 8-bit RISC CPU written in VHDL
|
|
||||||
-- This file: The ROM file for use in your VHDL design
|
|
||||||
--
|
|
||||||
-- Copyright (C) 2007 J. Ahrensfeld
|
|
||||||
--
|
|
||||||
-- This program is free software: you can redistribute it and/or modify
|
|
||||||
-- it under the terms of the GNU General Public License as published by
|
|
||||||
-- the Free Software Foundation, either version 3 of the License, or
|
|
||||||
-- (at your option) any later version.
|
|
||||||
--
|
|
||||||
-- This program is distributed in the hope that it will be useful,
|
|
||||||
-- but WITHOUT ANY WARRANTY; without even the implied warranty of
|
|
||||||
-- MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
|
||||||
-- GNU General Public License for more details.
|
|
||||||
--
|
|
||||||
-- You should have received a copy of the GNU General Public License
|
|
||||||
-- along with this program. If not, see <http://www.gnu.org/licenses/>.
|
|
||||||
--
|
|
||||||
-- For questions and ideas, please contact the author at jens@jayfield.org
|
|
||||||
--
|
|
||||||
--------------------------------------------------------------------------
|
|
||||||
|
|
||||||
LIBRARY ieee;
|
|
||||||
use IEEE.STD_LOGIC_1164.ALL;
|
|
||||||
USE ieee.numeric_std.ALL;
|
|
||||||
|
|
||||||
|
|
||||||
ENTITY rom IS
|
|
||||||
Generic
|
|
||||||
(
|
|
||||||
addr_width : integer := 2;
|
|
||||||
data_width : integer := 32
|
|
||||||
);
|
|
||||||
Port
|
|
||||||
(
|
|
||||||
addr : in unsigned(addr_width-1 downto 0);
|
|
||||||
dout : out unsigned(data_width-1 downto 0)
|
|
||||||
);
|
|
||||||
END rom;
|
|
||||||
|
|
||||||
ARCHITECTURE itest OF rom IS
|
|
||||||
|
|
||||||
subtype word_t is unsigned(data_width-1 downto 0);
|
|
||||||
type word_array_t is array (0 to 2**addr_width-1) of word_t;
|
|
||||||
|
|
||||||
-- Assembled from itest.jsm
|
|
||||||
constant word_array : word_array_t :=
|
|
||||||
(
|
|
||||||
X"08100001", -- [0x00400000] j 0x00400004 [main] ; 5: j main
|
|
||||||
X"3c080000", -- [0x00400004] lui $8, 0 ; 7: lui $8, 0
|
|
||||||
X"00000000", -- [0x00400008] nop ; 8: sll $0, $0, 0
|
|
||||||
X"0c100009", -- [0x0040000c] jal 0x00400024 [subr1] ; 9: jal subr1
|
|
||||||
X"3c010040", -- [0x00400010] lui $1, 64 [subr2] ; 10: la $2, subr2
|
|
||||||
X"34220030", -- [0x00400014] ori $2, $1, 48 [subr2]
|
|
||||||
X"00407809", -- [0x00400018] jalr $15, $2 ; 11: jalr $15, $2
|
|
||||||
X"00000000", -- [0x0040001c] nop ; 12: sll $0, $0, 0
|
|
||||||
X"08100002", -- [0x00400020] j 0x00400008 [loop] ; 13: j loop
|
|
||||||
X"21080001", -- [0x00400024] addi $8, $8, 1 ; 15: addi $8, 1
|
|
||||||
X"00000000", -- [0x00400028] nop ; 16: sll $0, $0, 0
|
|
||||||
X"03e00008", -- [0x0040002c] jr $31 ; 17: jr $31
|
|
||||||
X"21080010", -- [0x00400030] addi $8, $8, 16 ; 18: addi $8, 16
|
|
||||||
X"00000000", -- [0x00400034] nop ; 19: sll $0, $0, 0
|
|
||||||
X"01e00008", -- [0x00400038] jr $15 ; 20: jr $15
|
|
||||||
X"00000000", -- [0x0040003c] nop ; 21: sll $0, $0, 0
|
|
||||||
X"00000000", -- [0x00400040] nop ; 21: sll $0, $0, 0
|
|
||||||
X"00000000", -- [0x00400044] nop ; 21: sll $0, $0, 0
|
|
||||||
X"00000000", -- [0x00400048] nop ; 21: sll $0, $0, 0
|
|
||||||
X"00000000", -- [0x0040004c] nop ; 21: sll $0, $0, 0
|
|
||||||
X"00000000", -- [0x00400050] nop ; 21: sll $0, $0, 0
|
|
||||||
X"00000000", -- [0x00400054] nop ; 21: sll $0, $0, 0
|
|
||||||
X"00000000", -- [0x00400058] nop ; 21: sll $0, $0, 0
|
|
||||||
X"00000000", -- [0x0040005c] nop ; 21: sll $0, $0, 0
|
|
||||||
X"00000000", -- [0x00400060] nop ; 21: sll $0, $0, 0
|
|
||||||
X"00000000", -- [0x00400064] nop ; 21: sll $0, $0, 0
|
|
||||||
X"00000000", -- [0x00400068] nop ; 21: sll $0, $0, 0
|
|
||||||
X"00000000", -- [0x0040006c] nop ; 21: sll $0, $0, 0
|
|
||||||
X"00000000", -- [0x00400070] nop ; 21: sll $0, $0, 0
|
|
||||||
X"00000000", -- [0x00400074] nop ; 21: sll $0, $0, 0
|
|
||||||
X"00000000", -- [0x00400078] nop ; 21: sll $0, $0, 0
|
|
||||||
X"00000000", -- [0x0040007c] nop ; 21: sll $0, $0, 0
|
|
||||||
X"00000000", -- [0x00400080] nop ; 21: sll $0, $0, 0
|
|
||||||
X"00000000", -- [0x00400084] nop ; 21: sll $0, $0, 0
|
|
||||||
X"00000000", -- [0x00400088] nop ; 21: sll $0, $0, 0
|
|
||||||
X"00000000", -- [0x0040008c] nop ; 21: sll $0, $0, 0
|
|
||||||
X"00000000", -- [0x00400090] nop ; 21: sll $0, $0, 0
|
|
||||||
X"00000000", -- [0x00400094] nop ; 21: sll $0, $0, 0
|
|
||||||
X"00000000", -- [0x00400098] nop ; 21: sll $0, $0, 0
|
|
||||||
X"00000000", -- [0x0040009c] nop ; 21: sll $0, $0, 0
|
|
||||||
X"00000000", -- [0x004000a0] nop ; 21: sll $0, $0, 0
|
|
||||||
X"00000000", -- [0x004000a4] nop ; 21: sll $0, $0, 0
|
|
||||||
X"00000000", -- [0x004000a8] nop ; 21: sll $0, $0, 0
|
|
||||||
X"00000000", -- [0x004000ac] nop ; 21: sll $0, $0, 0
|
|
||||||
X"00000000", -- [0x004000b0] nop ; 21: sll $0, $0, 0
|
|
||||||
X"00000000", -- [0x004000b4] nop ; 21: sll $0, $0, 0
|
|
||||||
X"00000000", -- [0x004000b8] nop ; 21: sll $0, $0, 0
|
|
||||||
X"00000000", -- [0x004000bc] nop ; 21: sll $0, $0, 0
|
|
||||||
X"00000000", -- [0x004000c0] nop ; 21: sll $0, $0, 0
|
|
||||||
X"00000000", -- [0x004000c4] nop ; 21: sll $0, $0, 0
|
|
||||||
X"00000000", -- [0x004000c8] nop ; 21: sll $0, $0, 0
|
|
||||||
X"00000000", -- [0x004000cc] nop ; 21: sll $0, $0, 0
|
|
||||||
X"00000000", -- [0x004000d0] nop ; 21: sll $0, $0, 0
|
|
||||||
X"00000000", -- [0x004000d4] nop ; 21: sll $0, $0, 0
|
|
||||||
X"00000000", -- [0x004000d8] nop ; 21: sll $0, $0, 0
|
|
||||||
X"00000000", -- [0x004000dc] nop ; 21: sll $0, $0, 0
|
|
||||||
X"00000000", -- [0x004000e0] nop ; 21: sll $0, $0, 0
|
|
||||||
X"00000000", -- [0x004000e4] nop ; 21: sll $0, $0, 0
|
|
||||||
X"00000000", -- [0x004000e8] nop ; 21: sll $0, $0, 0
|
|
||||||
X"00000000", -- [0x004000ec] nop ; 21: sll $0, $0, 0
|
|
||||||
X"00000000", -- [0x004000f0] nop ; 21: sll $0, $0, 0
|
|
||||||
X"00000000", -- [0x004000f4] nop ; 21: sll $0, $0, 0
|
|
||||||
X"00000000", -- [0x004000f8] nop ; 21: sll $0, $0, 0
|
|
||||||
X"00000000" -- [0x004000fc] nop ; 21: sll $0, $0, 0
|
|
||||||
);
|
|
||||||
|
|
||||||
begin
|
|
||||||
|
|
||||||
PROM_READ:
|
|
||||||
dout <= word_array(to_integer(addr));
|
|
||||||
|
|
||||||
end itest;
|
|
||||||
@@ -1,121 +0,0 @@
|
|||||||
-------------------------------------------------------------------------
|
|
||||||
-- Project: JCPU, a portable 8-bit RISC CPU written in VHDL
|
|
||||||
-- This file: The ROM file for use in your VHDL design
|
|
||||||
--
|
|
||||||
-- Copyright (C) 2007 J. Ahrensfeld
|
|
||||||
--
|
|
||||||
-- This program is free software: you can redistribute it and/or modify
|
|
||||||
-- it under the terms of the GNU General Public License as published by
|
|
||||||
-- the Free Software Foundation, either version 3 of the License, or
|
|
||||||
-- (at your option) any later version.
|
|
||||||
--
|
|
||||||
-- This program is distributed in the hope that it will be useful,
|
|
||||||
-- but WITHOUT ANY WARRANTY; without even the implied warranty of
|
|
||||||
-- MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
|
||||||
-- GNU General Public License for more details.
|
|
||||||
--
|
|
||||||
-- You should have received a copy of the GNU General Public License
|
|
||||||
-- along with this program. If not, see <http://www.gnu.org/licenses/>.
|
|
||||||
--
|
|
||||||
-- For questions and ideas, please contact the author at jens@jayfield.org
|
|
||||||
--
|
|
||||||
--------------------------------------------------------------------------
|
|
||||||
|
|
||||||
LIBRARY ieee;
|
|
||||||
use IEEE.STD_LOGIC_1164.ALL;
|
|
||||||
USE ieee.numeric_std.ALL;
|
|
||||||
|
|
||||||
|
|
||||||
ENTITY rom IS
|
|
||||||
Generic
|
|
||||||
(
|
|
||||||
addr_width : integer := 2;
|
|
||||||
data_width : integer := 32
|
|
||||||
);
|
|
||||||
Port
|
|
||||||
(
|
|
||||||
addr : in unsigned(addr_width-1 downto 0);
|
|
||||||
dout : out unsigned(data_width-1 downto 0)
|
|
||||||
);
|
|
||||||
END rom;
|
|
||||||
|
|
||||||
ARCHITECTURE itest OF rom IS
|
|
||||||
|
|
||||||
subtype word_t is unsigned(data_width-1 downto 0);
|
|
||||||
type word_array_t is array (0 to 2**addr_width-1) of word_t;
|
|
||||||
|
|
||||||
-- Assembled from itest.jsm
|
|
||||||
constant word_array : word_array_t :=
|
|
||||||
(
|
|
||||||
X"3c011234", -- [0x00400000] lui $1, 4660
|
|
||||||
X"34225678", -- [0x00400004] ori $2, $1, 22136
|
|
||||||
X"3c012345", -- [0x00400008] lui $1, 9029
|
|
||||||
X"34236789", -- [0x0040000c] ori $3, $1, 26505
|
|
||||||
X"3c018765", -- [0x00400010] lui $1, -30875
|
|
||||||
X"34244321", -- [0x00400014] ori $4, $1, 17185
|
|
||||||
X"3c019876", -- [0x00400018] lui $1, -26506
|
|
||||||
X"34255432", -- [0x0040001c] ori $5, $1, 21554
|
|
||||||
X"00000000", -- [0x00400020] nop
|
|
||||||
X"00427823", -- [0x00400024] subu $15, $2, $2
|
|
||||||
X"00437823", -- [0x00400028] subu $15, $2, $3
|
|
||||||
X"00447823", -- [0x0040002c] subu $15, $2, $4
|
|
||||||
X"00457823", -- [0x00400030] subu $15, $2, $5
|
|
||||||
X"00627823", -- [0x00400034] subu $15, $3, $2
|
|
||||||
X"00637823", -- [0x00400038] subu $15, $3, $3
|
|
||||||
X"00647823", -- [0x0040003c] subu $15, $3, $4
|
|
||||||
X"00657823", -- [0x00400040] subu $15, $3, $5
|
|
||||||
X"00827823", -- [0x00400044] subu $15, $4, $2
|
|
||||||
X"00837823", -- [0x00400048] subu $15, $4, $3
|
|
||||||
X"00847823", -- [0x0040004c] subu $15, $4, $4
|
|
||||||
X"00857823", -- [0x00400050] subu $15, $4, $5
|
|
||||||
X"00a27823", -- [0x00400054] subu $15, $5, $2
|
|
||||||
X"00a37823", -- [0x00400058] subu $15, $5, $3
|
|
||||||
X"00a47823", -- [0x0040005c] subu $15, $5, $4
|
|
||||||
X"00a57823", -- [0x00400060] subu $15, $5, $5
|
|
||||||
X"00000000", -- [0x00400064] nop
|
|
||||||
X"00427822", -- [0x00400068] sub $15, $2, $2
|
|
||||||
X"00437822", -- [0x0040006c] sub $15, $2, $3
|
|
||||||
X"00447822", -- [0x00400070] sub $15, $2, $4
|
|
||||||
X"00457822", -- [0x00400074] sub $15, $2, $5
|
|
||||||
X"00627822", -- [0x00400078] sub $15, $3, $2
|
|
||||||
X"00637822", -- [0x0040007c] sub $15, $3, $3
|
|
||||||
X"00647822", -- [0x00400080] sub $15, $3, $4
|
|
||||||
X"00657822", -- [0x00400084] sub $15, $3, $5
|
|
||||||
X"00827822", -- [0x00400088] sub $15, $4, $2
|
|
||||||
X"00837822", -- [0x0040008c] sub $15, $4, $3
|
|
||||||
X"00847822", -- [0x00400090] sub $15, $4, $4
|
|
||||||
X"00857822", -- [0x00400094] sub $15, $4, $5
|
|
||||||
X"00a27822", -- [0x00400098] sub $15, $5, $2
|
|
||||||
X"00a37822", -- [0x0040009c] sub $15, $5, $3
|
|
||||||
X"00a47822", -- [0x004000a0] sub $15, $5, $4
|
|
||||||
X"00a57822", -- [0x004000a4] sub $15, $5, $5
|
|
||||||
X"00000000", -- [0x004000a8] nop
|
|
||||||
X"08104000", -- [0x004000ac] j 0x00410000 [main]
|
|
||||||
X"00000000", -- [0x004000b0] nop
|
|
||||||
X"00000000", -- [0x004000b4]
|
|
||||||
X"00000000", -- [0x004000b8]
|
|
||||||
X"00000000", -- [0x004000bc]
|
|
||||||
X"00000000", -- [0x004000c0]
|
|
||||||
X"00000000", -- [0x004000c4]
|
|
||||||
X"00000000", -- [0x004000c8]
|
|
||||||
X"00000000", -- [0x004000cc]
|
|
||||||
X"00000000", -- [0x004000d0]
|
|
||||||
X"00000000", -- [0x004000d4]
|
|
||||||
X"00000000", -- [0x004000d8]
|
|
||||||
X"00000000", -- [0x004000dc]
|
|
||||||
X"00000000", -- [0x004000e0]
|
|
||||||
X"00000000", -- [0x004000e4]
|
|
||||||
X"00000000", -- [0x004000e8]
|
|
||||||
X"00000000", -- [0x004000ec]
|
|
||||||
X"00000000", -- [0x004000f0]
|
|
||||||
X"00000000", -- [0x004000f4]
|
|
||||||
X"00000000", -- [0x004000f8]
|
|
||||||
X"00000000" -- [0x004000fc]
|
|
||||||
);
|
|
||||||
|
|
||||||
begin
|
|
||||||
|
|
||||||
PROM_READ:
|
|
||||||
dout <= word_array(to_integer(addr));
|
|
||||||
|
|
||||||
end itest;
|
|
||||||
@@ -1,121 +0,0 @@
|
|||||||
-------------------------------------------------------------------------
|
|
||||||
-- Project: JCPU, a portable 8-bit RISC CPU written in VHDL
|
|
||||||
-- This file: The ROM file for use in your VHDL design
|
|
||||||
--
|
|
||||||
-- Copyright (C) 2007 J. Ahrensfeld
|
|
||||||
--
|
|
||||||
-- This program is free software: you can redistribute it and/or modify
|
|
||||||
-- it under the terms of the GNU General Public License as published by
|
|
||||||
-- the Free Software Foundation, either version 3 of the License, or
|
|
||||||
-- (at your option) any later version.
|
|
||||||
--
|
|
||||||
-- This program is distributed in the hope that it will be useful,
|
|
||||||
-- but WITHOUT ANY WARRANTY; without even the implied warranty of
|
|
||||||
-- MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
|
||||||
-- GNU General Public License for more details.
|
|
||||||
--
|
|
||||||
-- You should have received a copy of the GNU General Public License
|
|
||||||
-- along with this program. If not, see <http://www.gnu.org/licenses/>.
|
|
||||||
--
|
|
||||||
-- For questions and ideas, please contact the author at jens@jayfield.org
|
|
||||||
--
|
|
||||||
--------------------------------------------------------------------------
|
|
||||||
|
|
||||||
LIBRARY ieee;
|
|
||||||
use IEEE.STD_LOGIC_1164.ALL;
|
|
||||||
USE ieee.numeric_std.ALL;
|
|
||||||
|
|
||||||
|
|
||||||
ENTITY rom IS
|
|
||||||
Generic
|
|
||||||
(
|
|
||||||
addr_width : integer := 2;
|
|
||||||
data_width : integer := 32
|
|
||||||
);
|
|
||||||
Port
|
|
||||||
(
|
|
||||||
addr : in unsigned(addr_width-1 downto 0);
|
|
||||||
dout : out unsigned(data_width-1 downto 0)
|
|
||||||
);
|
|
||||||
END rom;
|
|
||||||
|
|
||||||
ARCHITECTURE itest OF rom IS
|
|
||||||
|
|
||||||
subtype word_t is unsigned(data_width-1 downto 0);
|
|
||||||
type word_array_t is array (0 to 2**addr_width-1) of word_t;
|
|
||||||
|
|
||||||
-- Assembled from itest.jsm
|
|
||||||
constant word_array : word_array_t :=
|
|
||||||
(
|
|
||||||
X"3c011234", -- [0x00400000] lui $1, 4660
|
|
||||||
X"34225678", -- [0x00400004] ori $2, $1, 22136
|
|
||||||
X"3c012345", -- [0x00400008] lui $1, 9029
|
|
||||||
X"34236789", -- [0x0040000c] ori $3, $1, 26505
|
|
||||||
X"3c018765", -- [0x00400010] lui $1, -30875
|
|
||||||
X"34244321", -- [0x00400014] ori $4, $1, 17185
|
|
||||||
X"3c019876", -- [0x00400018] lui $1, -26506
|
|
||||||
X"34255432", -- [0x0040001c] ori $5, $1, 21554
|
|
||||||
X"3c081000", -- [0x00400020] lui $8, 4096
|
|
||||||
X"00000000", -- [0x00400024] nop
|
|
||||||
X"0042782b", -- [0x00400028] sltu $15, $2, $2
|
|
||||||
X"0043782b", -- [0x0040002c] sltu $15, $2, $3
|
|
||||||
X"0044782b", -- [0x00400030] sltu $15, $2, $4
|
|
||||||
X"0045782b", -- [0x00400034] sltu $15, $2, $5
|
|
||||||
X"0062782b", -- [0x00400038] sltu $15, $3, $2
|
|
||||||
X"0063782b", -- [0x0040003c] sltu $15, $3, $3
|
|
||||||
X"0064782b", -- [0x00400040] sltu $15, $3, $4
|
|
||||||
X"0065782b", -- [0x00400044] sltu $15, $3, $5
|
|
||||||
X"0082782b", -- [0x00400048] sltu $15, $4, $2
|
|
||||||
X"0083782b", -- [0x0040004c] sltu $15, $4, $3
|
|
||||||
X"0084782b", -- [0x00400050] sltu $15, $4, $4
|
|
||||||
X"0085782b", -- [0x00400054] sltu $15, $4, $5
|
|
||||||
X"00a2782b", -- [0x00400058] sltu $15, $5, $2
|
|
||||||
X"00a3782b", -- [0x0040005c] sltu $15, $5, $3
|
|
||||||
X"00a4782b", -- [0x00400060] sltu $15, $5, $4
|
|
||||||
X"00a5782b", -- [0x00400064] sltu $15, $5, $5
|
|
||||||
X"00000000", -- [0x00400068] nop
|
|
||||||
X"0042782a", -- [0x0040006c] slt $15, $2, $2
|
|
||||||
X"0043782a", -- [0x00400070] slt $15, $2, $3
|
|
||||||
X"0044782a", -- [0x00400074] slt $15, $2, $4
|
|
||||||
X"0045782a", -- [0x00400078] slt $15, $2, $5
|
|
||||||
X"0062782a", -- [0x0040007c] slt $15, $3, $2
|
|
||||||
X"0063782a", -- [0x00400080] slt $15, $3, $3
|
|
||||||
X"0064782a", -- [0x00400084] slt $15, $3, $4
|
|
||||||
X"0065782a", -- [0x00400088] slt $15, $3, $5
|
|
||||||
X"0082782a", -- [0x0040008c] slt $15, $4, $2
|
|
||||||
X"0083782a", -- [0x00400090] slt $15, $4, $3
|
|
||||||
X"0084782a", -- [0x00400094] slt $15, $4, $4
|
|
||||||
X"0085782a", -- [0x00400098] slt $15, $4, $5
|
|
||||||
X"00a2782a", -- [0x0040009c] slt $15, $5, $2
|
|
||||||
X"00a3782a", -- [0x004000a0] slt $15, $5, $3
|
|
||||||
X"00a4782a", -- [0x004000a4] slt $15, $5, $4
|
|
||||||
X"00a5782a", -- [0x004000a8] slt $15, $5, $5
|
|
||||||
X"00000000", -- [0x004000ac] nop
|
|
||||||
X"08104000", -- [0x004000b0] j 0x00410000 [main]
|
|
||||||
X"00000000", -- [0x004000b4] nop
|
|
||||||
X"00000000", -- [0x004000b8]
|
|
||||||
X"00000000", -- [0x004000bc]
|
|
||||||
X"00000000", -- [0x004000c0]
|
|
||||||
X"00000000", -- [0x004000c4]
|
|
||||||
X"00000000", -- [0x004000c8]
|
|
||||||
X"00000000", -- [0x004000cc]
|
|
||||||
X"00000000", -- [0x004000d0]
|
|
||||||
X"00000000", -- [0x004000d4]
|
|
||||||
X"00000000", -- [0x004000d8]
|
|
||||||
X"00000000", -- [0x004000dc]
|
|
||||||
X"00000000", -- [0x004000e0]
|
|
||||||
X"00000000", -- [0x004000e4]
|
|
||||||
X"00000000", -- [0x004000e8]
|
|
||||||
X"00000000", -- [0x004000ec]
|
|
||||||
X"00000000", -- [0x004000f0]
|
|
||||||
X"00000000", -- [0x004000f4]
|
|
||||||
X"00000000", -- [0x004000f8]
|
|
||||||
X"00000000" -- [0x004000fc]
|
|
||||||
);
|
|
||||||
|
|
||||||
begin
|
|
||||||
|
|
||||||
PROM_READ:
|
|
||||||
dout <= word_array(to_integer(addr));
|
|
||||||
|
|
||||||
end itest;
|
|
||||||
@@ -1,121 +0,0 @@
|
|||||||
-------------------------------------------------------------------------
|
|
||||||
-- Project: JCPU, a portable 8-bit RISC CPU written in VHDL
|
|
||||||
-- This file: The ROM file for use in your VHDL design
|
|
||||||
--
|
|
||||||
-- Copyright (C) 2007 J. Ahrensfeld
|
|
||||||
--
|
|
||||||
-- This program is free software: you can redistribute it and/or modify
|
|
||||||
-- it under the terms of the GNU General Public License as published by
|
|
||||||
-- the Free Software Foundation, either version 3 of the License, or
|
|
||||||
-- (at your option) any later version.
|
|
||||||
--
|
|
||||||
-- This program is distributed in the hope that it will be useful,
|
|
||||||
-- but WITHOUT ANY WARRANTY; without even the implied warranty of
|
|
||||||
-- MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
|
||||||
-- GNU General Public License for more details.
|
|
||||||
--
|
|
||||||
-- You should have received a copy of the GNU General Public License
|
|
||||||
-- along with this program. If not, see <http://www.gnu.org/licenses/>.
|
|
||||||
--
|
|
||||||
-- For questions and ideas, please contact the author at jens@jayfield.org
|
|
||||||
--
|
|
||||||
--------------------------------------------------------------------------
|
|
||||||
|
|
||||||
LIBRARY ieee;
|
|
||||||
use IEEE.STD_LOGIC_1164.ALL;
|
|
||||||
USE ieee.numeric_std.ALL;
|
|
||||||
|
|
||||||
|
|
||||||
ENTITY rom IS
|
|
||||||
Generic
|
|
||||||
(
|
|
||||||
addr_width : integer := 2;
|
|
||||||
data_width : integer := 32
|
|
||||||
);
|
|
||||||
Port
|
|
||||||
(
|
|
||||||
addr : in unsigned(addr_width-1 downto 0);
|
|
||||||
dout : out unsigned(data_width-1 downto 0)
|
|
||||||
);
|
|
||||||
END rom;
|
|
||||||
|
|
||||||
ARCHITECTURE itest OF rom IS
|
|
||||||
|
|
||||||
subtype word_t is unsigned(data_width-1 downto 0);
|
|
||||||
type word_array_t is array (0 to 2**addr_width-1) of word_t;
|
|
||||||
|
|
||||||
-- Assembled from itest.jsm
|
|
||||||
constant word_array : word_array_t :=
|
|
||||||
(
|
|
||||||
X"3c011234", -- [0x00400000] lui $1, 4660
|
|
||||||
X"34225678", -- [0x00400004] ori $2, $1, 22136
|
|
||||||
X"3c012345", -- [0x00400008] lui $1, 9029
|
|
||||||
X"34236789", -- [0x0040000c] ori $3, $1, 26505
|
|
||||||
X"3c018765", -- [0x00400010] lui $1, -30875
|
|
||||||
X"34244321", -- [0x00400014] ori $4, $1, 17185
|
|
||||||
X"3c019876", -- [0x00400018] lui $1, -26506
|
|
||||||
X"34255432", -- [0x0040001c] ori $5, $1, 21554
|
|
||||||
X"3c081000", -- [0x00400020] lui $8, 4096
|
|
||||||
X"00000000", -- [0x00400024] nop
|
|
||||||
X"2c4f1234", -- [0x00400028] sltiu $15, $2, 4660
|
|
||||||
X"2c4f2345", -- [0x0040002c] sltiu $15, $2, 9029
|
|
||||||
X"2c4fedcc", -- [0x00400030] sltiu $15, $2, -4660
|
|
||||||
X"2c4fdcbb", -- [0x00400034] sltiu $15, $2, -9029
|
|
||||||
X"2c6f1234", -- [0x00400038] sltiu $15, $3, 4660
|
|
||||||
X"2c6f2345", -- [0x0040003c] sltiu $15, $3, 9029
|
|
||||||
X"2c6fedcc", -- [0x00400040] sltiu $15, $3, -4660
|
|
||||||
X"2c6fdcbb", -- [0x00400044] sltiu $15, $3, -9029
|
|
||||||
X"2c8f1234", -- [0x00400048] sltiu $15, $4, 4660
|
|
||||||
X"2c8f2345", -- [0x0040004c] sltiu $15, $4, 9029
|
|
||||||
X"2c8fedcc", -- [0x00400050] sltiu $15, $4, -4660
|
|
||||||
X"2c8fdcbb", -- [0x00400054] sltiu $15, $4, -9029
|
|
||||||
X"2caf1234", -- [0x00400058] sltiu $15, $5, 4660
|
|
||||||
X"2caf2345", -- [0x0040005c] sltiu $15, $5, 9029
|
|
||||||
X"2cafedcc", -- [0x00400060] sltiu $15, $5, -4660
|
|
||||||
X"2cafdcbb", -- [0x00400064] sltiu $15, $5, -9029
|
|
||||||
X"00000000", -- [0x00400068] nop
|
|
||||||
X"284f1234", -- [0x0040006c] slti $15, $2, 4660
|
|
||||||
X"284f2345", -- [0x00400070] slti $15, $2, 9029
|
|
||||||
X"284fedcc", -- [0x00400074] slti $15, $2, -4660
|
|
||||||
X"284fdcbb", -- [0x00400078] slti $15, $2, -9029
|
|
||||||
X"286f1234", -- [0x0040007c] slti $15, $3, 4660
|
|
||||||
X"286f2345", -- [0x00400080] slti $15, $3, 9029
|
|
||||||
X"286fedcc", -- [0x00400084] slti $15, $3, -4660
|
|
||||||
X"286fdcbb", -- [0x00400088] slti $15, $3, -9029
|
|
||||||
X"288f1234", -- [0x0040008c] slti $15, $4, 4660
|
|
||||||
X"288f2345", -- [0x00400090] slti $15, $4, 9029
|
|
||||||
X"288fedcc", -- [0x00400094] slti $15, $4, -4660
|
|
||||||
X"288fdcbb", -- [0x00400098] slti $15, $4, -9029
|
|
||||||
X"28af1234", -- [0x0040009c] slti $15, $5, 4660
|
|
||||||
X"28af2345", -- [0x004000a0] slti $15, $5, 9029
|
|
||||||
X"28afedcc", -- [0x004000a4] slti $15, $5, -4660
|
|
||||||
X"28afdcbb", -- [0x004000a8] slti $15, $5, -9029
|
|
||||||
X"00000000", -- [0x004000ac] nop
|
|
||||||
X"08104000", -- [0x004000b0] j 0x00410000 [main]
|
|
||||||
X"00000000", -- [0x004000b4] nop
|
|
||||||
X"00000000", -- [0x004000b8]
|
|
||||||
X"00000000", -- [0x004000bc]
|
|
||||||
X"00000000", -- [0x004000c0]
|
|
||||||
X"00000000", -- [0x004000c4]
|
|
||||||
X"00000000", -- [0x004000c8]
|
|
||||||
X"00000000", -- [0x004000cc]
|
|
||||||
X"00000000", -- [0x004000d0]
|
|
||||||
X"00000000", -- [0x004000d4]
|
|
||||||
X"00000000", -- [0x004000d8]
|
|
||||||
X"00000000", -- [0x004000dc]
|
|
||||||
X"00000000", -- [0x004000e0]
|
|
||||||
X"00000000", -- [0x004000e4]
|
|
||||||
X"00000000", -- [0x004000e8]
|
|
||||||
X"00000000", -- [0x004000ec]
|
|
||||||
X"00000000", -- [0x004000f0]
|
|
||||||
X"00000000", -- [0x004000f4]
|
|
||||||
X"00000000", -- [0x004000f8]
|
|
||||||
X"00000000" -- [0x004000fc]
|
|
||||||
);
|
|
||||||
|
|
||||||
begin
|
|
||||||
|
|
||||||
PROM_READ:
|
|
||||||
dout <= word_array(to_integer(addr));
|
|
||||||
|
|
||||||
end itest;
|
|
||||||
@@ -1,121 +0,0 @@
|
|||||||
-------------------------------------------------------------------------
|
|
||||||
-- Project: JCPU, a portable 8-bit RISC CPU written in VHDL
|
|
||||||
-- This file: The ROM file for use in your VHDL design
|
|
||||||
--
|
|
||||||
-- Copyright (C) 2007 J. Ahrensfeld
|
|
||||||
--
|
|
||||||
-- This program is free software: you can redistribute it and/or modify
|
|
||||||
-- it under the terms of the GNU General Public License as published by
|
|
||||||
-- the Free Software Foundation, either version 3 of the License, or
|
|
||||||
-- (at your option) any later version.
|
|
||||||
--
|
|
||||||
-- This program is distributed in the hope that it will be useful,
|
|
||||||
-- but WITHOUT ANY WARRANTY; without even the implied warranty of
|
|
||||||
-- MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
|
||||||
-- GNU General Public License for more details.
|
|
||||||
--
|
|
||||||
-- You should have received a copy of the GNU General Public License
|
|
||||||
-- along with this program. If not, see <http://www.gnu.org/licenses/>.
|
|
||||||
--
|
|
||||||
-- For questions and ideas, please contact the author at jens@jayfield.org
|
|
||||||
--
|
|
||||||
--------------------------------------------------------------------------
|
|
||||||
|
|
||||||
LIBRARY ieee;
|
|
||||||
use IEEE.STD_LOGIC_1164.ALL;
|
|
||||||
USE ieee.numeric_std.ALL;
|
|
||||||
|
|
||||||
|
|
||||||
ENTITY rom IS
|
|
||||||
Generic
|
|
||||||
(
|
|
||||||
addr_width : integer := 2;
|
|
||||||
data_width : integer := 32
|
|
||||||
);
|
|
||||||
Port
|
|
||||||
(
|
|
||||||
addr : in unsigned(addr_width-1 downto 0);
|
|
||||||
dout : out unsigned(data_width-1 downto 0)
|
|
||||||
);
|
|
||||||
END rom;
|
|
||||||
|
|
||||||
ARCHITECTURE itest OF rom IS
|
|
||||||
|
|
||||||
subtype word_t is unsigned(data_width-1 downto 0);
|
|
||||||
type word_array_t is array (0 to 2**addr_width-1) of word_t;
|
|
||||||
|
|
||||||
-- Assembled from itest.jsm
|
|
||||||
constant word_array : word_array_t :=
|
|
||||||
(
|
|
||||||
X"3c011234", -- [0x00400000] lui $1, 4660
|
|
||||||
X"34225678", -- [0x00400004] ori $2, $1, 22136
|
|
||||||
X"3c012345", -- [0x00400008] lui $1, 9029
|
|
||||||
X"34236789", -- [0x0040000c] ori $3, $1, 26505
|
|
||||||
X"3c018765", -- [0x00400010] lui $1, -30875
|
|
||||||
X"34244321", -- [0x00400014] ori $4, $1, 17185
|
|
||||||
X"3c019876", -- [0x00400018] lui $1, -26506
|
|
||||||
X"34255432", -- [0x0040001c] ori $5, $1, 21554
|
|
||||||
X"00000000", -- [0x00400020] nop
|
|
||||||
X"00427823", -- [0x00400024] subu $15, $2, $2
|
|
||||||
X"00437823", -- [0x00400028] subu $15, $2, $3
|
|
||||||
X"00447823", -- [0x0040002c] subu $15, $2, $4
|
|
||||||
X"00457823", -- [0x00400030] subu $15, $2, $5
|
|
||||||
X"00627823", -- [0x00400034] subu $15, $3, $2
|
|
||||||
X"00637823", -- [0x00400038] subu $15, $3, $3
|
|
||||||
X"00647823", -- [0x0040003c] subu $15, $3, $4
|
|
||||||
X"00657823", -- [0x00400040] subu $15, $3, $5
|
|
||||||
X"00827823", -- [0x00400044] subu $15, $4, $2
|
|
||||||
X"00837823", -- [0x00400048] subu $15, $4, $3
|
|
||||||
X"00847823", -- [0x0040004c] subu $15, $4, $4
|
|
||||||
X"00857823", -- [0x00400050] subu $15, $4, $5
|
|
||||||
X"00a27823", -- [0x00400054] subu $15, $5, $2
|
|
||||||
X"00a37823", -- [0x00400058] subu $15, $5, $3
|
|
||||||
X"00a47823", -- [0x0040005c] subu $15, $5, $4
|
|
||||||
X"00a57823", -- [0x00400060] subu $15, $5, $5
|
|
||||||
X"00000000", -- [0x00400064] nop
|
|
||||||
X"00427822", -- [0x00400068] sub $15, $2, $2
|
|
||||||
X"00437822", -- [0x0040006c] sub $15, $2, $3
|
|
||||||
X"00447822", -- [0x00400070] sub $15, $2, $4
|
|
||||||
X"00457822", -- [0x00400074] sub $15, $2, $5
|
|
||||||
X"00627822", -- [0x00400078] sub $15, $3, $2
|
|
||||||
X"00637822", -- [0x0040007c] sub $15, $3, $3
|
|
||||||
X"00647822", -- [0x00400080] sub $15, $3, $4
|
|
||||||
X"00657822", -- [0x00400084] sub $15, $3, $5
|
|
||||||
X"00827822", -- [0x00400088] sub $15, $4, $2
|
|
||||||
X"00837822", -- [0x0040008c] sub $15, $4, $3
|
|
||||||
X"00847822", -- [0x00400090] sub $15, $4, $4
|
|
||||||
X"00857822", -- [0x00400094] sub $15, $4, $5
|
|
||||||
X"00a27822", -- [0x00400098] sub $15, $5, $2
|
|
||||||
X"00a37822", -- [0x0040009c] sub $15, $5, $3
|
|
||||||
X"00a47822", -- [0x004000a0] sub $15, $5, $4
|
|
||||||
X"00a57822", -- [0x004000a4] sub $15, $5, $5
|
|
||||||
X"00000000", -- [0x004000a8] nop
|
|
||||||
X"08104000", -- [0x004000ac] j 0x00410000 [main]
|
|
||||||
X"00000000", -- [0x004000b0] nop
|
|
||||||
X"00000000", -- [0x004000b4]
|
|
||||||
X"00000000", -- [0x004000b8]
|
|
||||||
X"00000000", -- [0x004000bc]
|
|
||||||
X"00000000", -- [0x004000c0]
|
|
||||||
X"00000000", -- [0x004000c4]
|
|
||||||
X"00000000", -- [0x004000c8]
|
|
||||||
X"00000000", -- [0x004000cc]
|
|
||||||
X"00000000", -- [0x004000d0]
|
|
||||||
X"00000000", -- [0x004000d4]
|
|
||||||
X"00000000", -- [0x004000d8]
|
|
||||||
X"00000000", -- [0x004000dc]
|
|
||||||
X"00000000", -- [0x004000e0]
|
|
||||||
X"00000000", -- [0x004000e4]
|
|
||||||
X"00000000", -- [0x004000e8]
|
|
||||||
X"00000000", -- [0x004000ec]
|
|
||||||
X"00000000", -- [0x004000f0]
|
|
||||||
X"00000000", -- [0x004000f4]
|
|
||||||
X"00000000", -- [0x004000f8]
|
|
||||||
X"00000000" -- [0x004000fc]
|
|
||||||
);
|
|
||||||
|
|
||||||
begin
|
|
||||||
|
|
||||||
PROM_READ:
|
|
||||||
dout <= word_array(to_integer(addr));
|
|
||||||
|
|
||||||
end itest;
|
|
||||||
@@ -1,332 +0,0 @@
|
|||||||
-------------------------------------------------------------------------
|
|
||||||
-- Project: JCPU, a portable 8-bit RISC CPU written in VHDL
|
|
||||||
-- This file: cpu_embedded using cpu_core and rom
|
|
||||||
--
|
|
||||||
-- Copyright (C) 2007 J. Ahrensfeld
|
|
||||||
--
|
|
||||||
-- This program is free software: you can redistribute it and/or modify
|
|
||||||
-- it under the terms of the GNU General Public License as published by
|
|
||||||
-- the Free Software Foundation, either version 3 of the License, or
|
|
||||||
-- (at your option) any later version.
|
|
||||||
--
|
|
||||||
-- This program is distributed in the hope that it will be useful,
|
|
||||||
-- but WITHOUT ANY WARRANTY; without even the implied warranty of
|
|
||||||
-- MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
|
||||||
-- GNU General Public License for more details.
|
|
||||||
--
|
|
||||||
-- You should have received a copy of the GNU General Public License
|
|
||||||
-- along with this program. If not, see <http://www.gnu.org/licenses/>.
|
|
||||||
--
|
|
||||||
-- For questions and ideas, please contact the author at jens@jayfield.org
|
|
||||||
--
|
|
||||||
--------------------------------------------------------------------------
|
|
||||||
|
|
||||||
library IEEE;
|
|
||||||
use IEEE.STD_LOGIC_1164.ALL;
|
|
||||||
use IEEE.numeric_std.ALL;
|
|
||||||
|
|
||||||
library work;
|
|
||||||
use work.mips_types.all;
|
|
||||||
|
|
||||||
entity mips_embedded is
|
|
||||||
Port
|
|
||||||
(
|
|
||||||
rst : in STD_LOGIC;
|
|
||||||
clk : in STD_LOGIC;
|
|
||||||
halt : in STD_LOGIC;
|
|
||||||
int : in unsigned(5 downto 0);
|
|
||||||
rxd : in STD_LOGIC;
|
|
||||||
txd : out STD_LOGIC;
|
|
||||||
dout : out word_t
|
|
||||||
);
|
|
||||||
end mips_embedded;
|
|
||||||
|
|
||||||
architecture rtl of mips_embedded is
|
|
||||||
|
|
||||||
COMPONENT mips_top
|
|
||||||
Port
|
|
||||||
(
|
|
||||||
rst : in STD_LOGIC;
|
|
||||||
clk : in STD_LOGIC;
|
|
||||||
int : in unsigned(5 downto 0);
|
|
||||||
mem_rdy : in STD_LOGIC;
|
|
||||||
mem_re : out STD_LOGIC;
|
|
||||||
mem_en : out STD_LOGIC;
|
|
||||||
mem_we : out unsigned(3 downto 0);
|
|
||||||
mem_din : in word_t;
|
|
||||||
mem_dout : out word_t;
|
|
||||||
mem_addr : out word_t
|
|
||||||
|
|
||||||
);
|
|
||||||
END COMPONENT;
|
|
||||||
|
|
||||||
signal mem_din : word_t;
|
|
||||||
signal mem_dout : word_t;
|
|
||||||
signal mem_addr : word_t;
|
|
||||||
signal mem_re : std_logic;
|
|
||||||
signal mem_en : std_logic;
|
|
||||||
signal mem_we : unsigned(3 downto 0);
|
|
||||||
signal mem_rdy : std_logic;
|
|
||||||
|
|
||||||
subtype tick_usec_t is natural range 0 to 99;
|
|
||||||
signal tick_usec : tick_usec_t;
|
|
||||||
signal cnt_usec : word_t;
|
|
||||||
signal cnt_sec : word_t;
|
|
||||||
signal cnt_usec_preset : word_t;
|
|
||||||
signal cnt_sec_preset : word_t;
|
|
||||||
signal cnt_usec_en : std_logic;
|
|
||||||
signal cnt_usec_we : std_logic;
|
|
||||||
signal cnt_sec_en : std_logic;
|
|
||||||
signal cnt_sec_we : std_logic;
|
|
||||||
|
|
||||||
COMPONENT uart_tx
|
|
||||||
Port
|
|
||||||
(
|
|
||||||
data_in : in std_logic_vector(7 downto 0);
|
|
||||||
write_buffer : in std_logic;
|
|
||||||
reset_buffer : in std_logic;
|
|
||||||
en_16_x_baud : in std_logic;
|
|
||||||
serial_out : out std_logic;
|
|
||||||
buffer_full : out std_logic;
|
|
||||||
buffer_half_full : out std_logic;
|
|
||||||
clk : in std_logic
|
|
||||||
);
|
|
||||||
END COMPONENT;
|
|
||||||
|
|
||||||
COMPONENT uart_rx
|
|
||||||
Port
|
|
||||||
(
|
|
||||||
serial_in : in std_logic;
|
|
||||||
data_out : out std_logic_vector(7 downto 0);
|
|
||||||
read_buffer : in std_logic;
|
|
||||||
reset_buffer : in std_logic;
|
|
||||||
en_16_x_baud : in std_logic;
|
|
||||||
buffer_data_present : out std_logic;
|
|
||||||
buffer_full : out std_logic;
|
|
||||||
buffer_half_full : out std_logic;
|
|
||||||
clk : in std_logic
|
|
||||||
);
|
|
||||||
END COMPONENT;
|
|
||||||
|
|
||||||
signal baud_count : unsigned(7 downto 0);
|
|
||||||
signal en_16_x_baud : std_logic;
|
|
||||||
signal reg_we_uart_tx : std_logic;
|
|
||||||
signal tx_full : std_logic;
|
|
||||||
signal tx_half_full : std_logic;
|
|
||||||
signal reg_uart_tx : unsigned(7 downto 0);
|
|
||||||
signal reg_re_uart_rx : std_logic;
|
|
||||||
signal reg_uart_rx : std_logic_vector(7 downto 0);
|
|
||||||
signal rx_data_present : std_logic;
|
|
||||||
signal rx_full : std_logic;
|
|
||||||
signal rx_half_full : std_logic;
|
|
||||||
signal uart_status_port : unsigned(7 downto 0);
|
|
||||||
signal reg_uart_ctrl : unsigned(7 downto 0);
|
|
||||||
signal reg_uart_baud : unsigned(7 downto 0);
|
|
||||||
|
|
||||||
begin
|
|
||||||
|
|
||||||
registers_write:
|
|
||||||
process(clk)
|
|
||||||
begin
|
|
||||||
if rising_edge(clk) then
|
|
||||||
reg_we_uart_tx <= '0';
|
|
||||||
cnt_usec_we <= '0';
|
|
||||||
cnt_sec_we <= '0';
|
|
||||||
if rst = '1' then
|
|
||||||
dout <= (others => '0');
|
|
||||||
reg_uart_baud <= to_unsigned(53, 8);
|
|
||||||
reg_uart_ctrl <= to_unsigned(0, 8);
|
|
||||||
elsif mem_en = '1' then
|
|
||||||
case mem_addr(5 downto 2) is
|
|
||||||
|
|
||||||
when "0000" =>
|
|
||||||
if mem_we(0) = '1' then
|
|
||||||
dout(7 downto 0) <= mem_dout(7 downto 0);
|
|
||||||
end if;
|
|
||||||
if mem_we(1) = '1' then
|
|
||||||
dout(15 downto 8) <= mem_dout(15 downto 8);
|
|
||||||
end if;
|
|
||||||
if mem_we(2) = '1' then
|
|
||||||
dout(23 downto 16) <= mem_dout(23 downto 16);
|
|
||||||
end if;
|
|
||||||
if mem_we(3) = '1' then
|
|
||||||
dout(31 downto 24) <= mem_dout(31 downto 24);
|
|
||||||
end if;
|
|
||||||
|
|
||||||
when "0001" =>
|
|
||||||
if mem_we(0) = '1' then
|
|
||||||
reg_we_uart_tx <= '1';
|
|
||||||
reg_uart_tx <= mem_dout(7 downto 0);
|
|
||||||
end if;
|
|
||||||
|
|
||||||
when "0010" =>
|
|
||||||
if mem_we(0) = '1' then
|
|
||||||
reg_uart_ctrl <= mem_dout(7 downto 0);
|
|
||||||
end if;
|
|
||||||
if mem_we(1) = '1' then
|
|
||||||
reg_uart_baud <= mem_dout(15 downto 8);
|
|
||||||
end if;
|
|
||||||
|
|
||||||
when "0100" =>
|
|
||||||
if mem_we(3) = '1' then
|
|
||||||
cnt_usec_we <= '1';
|
|
||||||
cnt_usec_preset <= mem_dout;
|
|
||||||
end if;
|
|
||||||
|
|
||||||
when "0101" =>
|
|
||||||
if mem_we(3) = '1' then
|
|
||||||
cnt_sec_we <= '1';
|
|
||||||
cnt_sec_preset <= mem_dout;
|
|
||||||
end if;
|
|
||||||
|
|
||||||
when others => null;
|
|
||||||
end case;
|
|
||||||
end if;
|
|
||||||
end if;
|
|
||||||
end process;
|
|
||||||
|
|
||||||
registers_read:
|
|
||||||
process(clk)
|
|
||||||
begin
|
|
||||||
if rising_edge(clk) then
|
|
||||||
reg_re_uart_rx <= '0';
|
|
||||||
if mem_en = '1' then
|
|
||||||
mem_din <= (others => '0');
|
|
||||||
case mem_addr(5 downto 2) is
|
|
||||||
|
|
||||||
when "0000" => null;
|
|
||||||
|
|
||||||
when "0001" =>
|
|
||||||
reg_re_uart_rx <= '1';
|
|
||||||
mem_din(7 downto 0) <= unsigned(reg_uart_rx);
|
|
||||||
|
|
||||||
when "0010" =>
|
|
||||||
mem_din(7 downto 0) <= uart_status_port;
|
|
||||||
mem_din(15 downto 8) <= reg_uart_baud;
|
|
||||||
|
|
||||||
when "0100" =>
|
|
||||||
mem_din <= cnt_usec;
|
|
||||||
|
|
||||||
when "0101" =>
|
|
||||||
mem_din <= cnt_sec;
|
|
||||||
|
|
||||||
when others => null;
|
|
||||||
end case;
|
|
||||||
end if;
|
|
||||||
end if;
|
|
||||||
end process;
|
|
||||||
|
|
||||||
mem_rdy <= not halt;
|
|
||||||
|
|
||||||
inst_mips_top: mips_top
|
|
||||||
PORT MAP
|
|
||||||
(
|
|
||||||
rst => rst,
|
|
||||||
clk => clk,
|
|
||||||
int => int,
|
|
||||||
mem_rdy => mem_rdy,
|
|
||||||
mem_en => mem_en,
|
|
||||||
mem_we => mem_we,
|
|
||||||
mem_din => mem_din,
|
|
||||||
mem_dout => mem_dout,
|
|
||||||
mem_addr => mem_addr
|
|
||||||
);
|
|
||||||
|
|
||||||
inst_uart_tx: uart_tx
|
|
||||||
port map
|
|
||||||
(
|
|
||||||
data_in => std_logic_vector(reg_uart_tx),
|
|
||||||
write_buffer => reg_we_uart_tx,
|
|
||||||
reset_buffer => rst,
|
|
||||||
en_16_x_baud => en_16_x_baud,
|
|
||||||
serial_out => txd,
|
|
||||||
buffer_full => tx_full,
|
|
||||||
buffer_half_full => tx_half_full,
|
|
||||||
clk => clk
|
|
||||||
);
|
|
||||||
|
|
||||||
inst_uart_rx: uart_rx
|
|
||||||
port map
|
|
||||||
(
|
|
||||||
serial_in => rxd,
|
|
||||||
data_out => reg_uart_rx,
|
|
||||||
read_buffer => reg_re_uart_rx,
|
|
||||||
reset_buffer => rst,
|
|
||||||
en_16_x_baud => en_16_x_baud,
|
|
||||||
buffer_data_present => rx_data_present,
|
|
||||||
buffer_full => rx_full,
|
|
||||||
buffer_half_full => rx_half_full,
|
|
||||||
clk => clk
|
|
||||||
);
|
|
||||||
|
|
||||||
uart_status_port <= (7 downto 5 => '0') & rx_data_present & rx_full & rx_half_full & tx_full & tx_half_full;
|
|
||||||
|
|
||||||
tick_usec_timer:
|
|
||||||
process(clk)
|
|
||||||
begin
|
|
||||||
if clk'event and clk='1' then
|
|
||||||
cnt_usec_en <= '0';
|
|
||||||
if rst = '1' then
|
|
||||||
tick_usec <= 0;
|
|
||||||
cnt_usec_en <= '0';
|
|
||||||
elsif tick_usec = tick_usec_t'high then
|
|
||||||
tick_usec <= 0;
|
|
||||||
cnt_usec_en <= '1';
|
|
||||||
else
|
|
||||||
tick_usec <= tick_usec + 1;
|
|
||||||
end if;
|
|
||||||
end if;
|
|
||||||
end process;
|
|
||||||
|
|
||||||
cnt_usec_timer:
|
|
||||||
process(clk)
|
|
||||||
begin
|
|
||||||
if clk'event and clk='1' then
|
|
||||||
cnt_sec_en <= '0';
|
|
||||||
if rst = '1' then
|
|
||||||
cnt_usec <= (others => '0');
|
|
||||||
cnt_sec_en <= '0';
|
|
||||||
elsif cnt_usec_we = '1' then
|
|
||||||
cnt_usec <= cnt_usec_preset;
|
|
||||||
elsif cnt_usec_en = '1' then
|
|
||||||
if cnt_usec = to_unsigned(1E6 - 1, word_t'length) then
|
|
||||||
cnt_usec <= (others => '0');
|
|
||||||
cnt_sec_en <= '1';
|
|
||||||
else
|
|
||||||
cnt_usec <= cnt_usec + 1;
|
|
||||||
end if;
|
|
||||||
end if;
|
|
||||||
end if;
|
|
||||||
end process;
|
|
||||||
|
|
||||||
cnt_sec_timer:
|
|
||||||
process(clk)
|
|
||||||
begin
|
|
||||||
if clk'event and clk='1' then
|
|
||||||
if rst = '1' then
|
|
||||||
cnt_sec <= (others => '0');
|
|
||||||
elsif cnt_sec_we = '1' then
|
|
||||||
cnt_sec <= cnt_sec_preset;
|
|
||||||
elsif cnt_sec_en = '1' then
|
|
||||||
cnt_sec <= cnt_sec + 1;
|
|
||||||
end if;
|
|
||||||
end if;
|
|
||||||
end process;
|
|
||||||
|
|
||||||
baud_timer:
|
|
||||||
process(clk)
|
|
||||||
begin
|
|
||||||
if clk'event and clk='1' then
|
|
||||||
if rst = '1' then
|
|
||||||
baud_count <= (others => '0');
|
|
||||||
elsif baud_count = reg_uart_baud then
|
|
||||||
baud_count <= (others => '0');
|
|
||||||
en_16_x_baud <= '1';
|
|
||||||
else
|
|
||||||
baud_count <= baud_count + 1;
|
|
||||||
en_16_x_baud <= '0';
|
|
||||||
end if;
|
|
||||||
end if;
|
|
||||||
end process;
|
|
||||||
|
|
||||||
end rtl;
|
|
||||||
@@ -1,137 +0,0 @@
|
|||||||
--------------------------------------------------------------------------
|
|
||||||
-- Project: JIPS, a portable 32-bit RISC CPU written in VHDL
|
|
||||||
-- This file: JIPS top file
|
|
||||||
--
|
|
||||||
-- Copyright (C) 2007 J. Ahrensfeld
|
|
||||||
--
|
|
||||||
-- This program is free software: you can redistribute it and/or modify
|
|
||||||
-- it under the terms of the GNU General Public License as published by
|
|
||||||
-- the Free Software Foundation, either version 3 of the License, or
|
|
||||||
-- (at your option) any later version.
|
|
||||||
--
|
|
||||||
-- This program is distributed in the hope that it will be useful,
|
|
||||||
-- but WITHOUT ANY WARRANTY; without even the implied warranty of
|
|
||||||
-- MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
|
||||||
-- GNU General Public License for more details.
|
|
||||||
--
|
|
||||||
-- You should have received a copy of the GNU General Public License
|
|
||||||
-- along with this program. If not, see <http://www.gnu.org/licenses/>.
|
|
||||||
--
|
|
||||||
-- For questions and ideas, please contact the author at jens@jayfield.org
|
|
||||||
--
|
|
||||||
--------------------------------------------------------------------------
|
|
||||||
|
|
||||||
library IEEE;
|
|
||||||
use IEEE.STD_LOGIC_1164.ALL;
|
|
||||||
use IEEE.numeric_std.ALL;
|
|
||||||
|
|
||||||
library work;
|
|
||||||
use work.mips_types.all;
|
|
||||||
|
|
||||||
entity mips_embedded_syn is
|
|
||||||
Port
|
|
||||||
(
|
|
||||||
sys_rst_n_in : in STD_LOGIC;
|
|
||||||
sys_clk_in : in STD_LOGIC;
|
|
||||||
sys_dip : in STD_LOGIC_VECTOR (7 downto 0);
|
|
||||||
sys_btn : in STD_LOGIC_VECTOR (8 downto 0);
|
|
||||||
sys_led : out STD_LOGIC_VECTOR (7 downto 0);
|
|
||||||
sys_rx : in STD_LOGIC;
|
|
||||||
sys_tx : out STD_LOGIC;
|
|
||||||
sys_error : out STD_LOGIC_VECTOR (1 downto 0)
|
|
||||||
);
|
|
||||||
|
|
||||||
end mips_embedded_syn;
|
|
||||||
|
|
||||||
architecture struct of mips_embedded_syn is
|
|
||||||
|
|
||||||
COMPONENT mips_embedded
|
|
||||||
Port
|
|
||||||
(
|
|
||||||
rst : in STD_LOGIC;
|
|
||||||
clk : in STD_LOGIC;
|
|
||||||
halt : in STD_LOGIC;
|
|
||||||
int : in unsigned(5 downto 0);
|
|
||||||
rxd : in STD_LOGIC;
|
|
||||||
txd : out STD_LOGIC;
|
|
||||||
dout : out word_t
|
|
||||||
);
|
|
||||||
END COMPONENT;
|
|
||||||
|
|
||||||
signal dout : word_t;
|
|
||||||
signal rst : STD_LOGIC;
|
|
||||||
signal clk : STD_LOGIC;
|
|
||||||
signal halt : STD_LOGIC;
|
|
||||||
signal int : unsigned(5 downto 0);
|
|
||||||
signal btn_r : unsigned (8 downto 0);
|
|
||||||
signal dip_r : unsigned (7 downto 0);
|
|
||||||
|
|
||||||
begin
|
|
||||||
|
|
||||||
-------------------------------------------------------------------
|
|
||||||
inst_mips_embedded: mips_embedded
|
|
||||||
PORT MAP
|
|
||||||
(
|
|
||||||
rst => rst,
|
|
||||||
clk => clk,
|
|
||||||
halt => halt,
|
|
||||||
int => int,
|
|
||||||
rxd => sys_rx,
|
|
||||||
txd => sys_tx,
|
|
||||||
dout => dout
|
|
||||||
);
|
|
||||||
|
|
||||||
clk <= sys_clk_in;
|
|
||||||
rst <= not sys_rst_n_in;
|
|
||||||
|
|
||||||
ERR_LED_reg:
|
|
||||||
process(rst, clk)
|
|
||||||
begin
|
|
||||||
if rst = '1' then
|
|
||||||
sys_error <= (others => '1');
|
|
||||||
elsif rising_edge(clk) then
|
|
||||||
sys_error <= STD_LOGIC_VECTOR(dout(31 downto 30));
|
|
||||||
end if;
|
|
||||||
end process;
|
|
||||||
|
|
||||||
LED_reg:
|
|
||||||
process(rst, clk)
|
|
||||||
begin
|
|
||||||
if rst = '1' then
|
|
||||||
sys_led <= (others => '0');
|
|
||||||
elsif rising_edge(clk) then
|
|
||||||
sys_led <= STD_LOGIC_VECTOR(dout(7 downto 0));
|
|
||||||
end if;
|
|
||||||
end process;
|
|
||||||
|
|
||||||
DIP_reg:
|
|
||||||
process(rst, clk)
|
|
||||||
begin
|
|
||||||
if rst = '1' then
|
|
||||||
dip_r <= (others => '0');
|
|
||||||
elsif rising_edge(clk) then
|
|
||||||
dip_r <= unsigned(sys_dip);
|
|
||||||
end if;
|
|
||||||
end process;
|
|
||||||
|
|
||||||
BTN_reg:
|
|
||||||
process(rst, clk)
|
|
||||||
begin
|
|
||||||
if rst = '1' then
|
|
||||||
btn_r <= (others => '0');
|
|
||||||
elsif rising_edge(clk) then
|
|
||||||
btn_r <= unsigned(sys_btn);
|
|
||||||
end if;
|
|
||||||
end process;
|
|
||||||
|
|
||||||
halt <= btn_r(4) after 6.5 ns;
|
|
||||||
int(0) <= dip_r(0) and btn_r(3) after 1 ns;
|
|
||||||
int(1) <= dip_r(1) and btn_r(3) after 1 ns;
|
|
||||||
int(2) <= dip_r(2) and btn_r(3) after 1 ns;
|
|
||||||
int(3) <= dip_r(3) and btn_r(3) after 1 ns;
|
|
||||||
int(4) <= dip_r(4) and btn_r(3) after 1 ns;
|
|
||||||
int(5) <= dip_r(5) and btn_r(3) after 1 ns;
|
|
||||||
|
|
||||||
-------------------------------------------------------------------
|
|
||||||
|
|
||||||
end struct;
|
|
||||||
@@ -1,83 +0,0 @@
|
|||||||
--------------------------------------------------------------------------
|
|
||||||
-- Project: JIPS, a portable 32-bit RISC CPU written in VHDL
|
|
||||||
-- This file: The arithmetic logic unit
|
|
||||||
--
|
|
||||||
-- Copyright (C) 2008 J. Ahrensfeld
|
|
||||||
--
|
|
||||||
-- This program is free software: you can redistribute it and/or modify
|
|
||||||
-- it under the terms of the GNU General Public License as published by
|
|
||||||
-- the Free Software Foundation, either version 3 of the License, or
|
|
||||||
-- (at your option) any later version.
|
|
||||||
--
|
|
||||||
-- This program is distributed in the hope that it will be useful,
|
|
||||||
-- but WITHOUT ANY WARRANTY; without even the implied warranty of
|
|
||||||
-- MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
|
||||||
-- GNU General Public License for more details.
|
|
||||||
--
|
|
||||||
-- You should have received a copy of the GNU General Public License
|
|
||||||
-- along with this program. If not, see <http://www.gnu.org/licenses/>.
|
|
||||||
--
|
|
||||||
-- For questions and ideas, please contact the author at jens@jayfield.org
|
|
||||||
--
|
|
||||||
--------------------------------------------------------------------------
|
|
||||||
|
|
||||||
library IEEE;
|
|
||||||
use IEEE.STD_LOGIC_1164.ALL;
|
|
||||||
use IEEE.numeric_std.ALL;
|
|
||||||
|
|
||||||
use work.mips_types.all;
|
|
||||||
|
|
||||||
entity muldiv is
|
|
||||||
Port
|
|
||||||
(
|
|
||||||
rst : in std_logic;
|
|
||||||
clk : in std_logic;
|
|
||||||
din_vld_hi : in std_logic;
|
|
||||||
din_vld_lo : in std_logic;
|
|
||||||
din_hi : in word_t;
|
|
||||||
din_lo : in word_t;
|
|
||||||
hilo_sel : in std_logic;
|
|
||||||
dout : out word_t
|
|
||||||
);
|
|
||||||
end muldiv;
|
|
||||||
|
|
||||||
architecture Behavioral of muldiv is
|
|
||||||
|
|
||||||
signal reg_hi, reg_lo : word_t;
|
|
||||||
|
|
||||||
--------------------------------------------------------------------------
|
|
||||||
begin
|
|
||||||
|
|
||||||
--------------------------------------------------------------------------
|
|
||||||
proc_reg_out:
|
|
||||||
process(hilo_sel, reg_hi, reg_lo)
|
|
||||||
begin
|
|
||||||
if hilo_sel = '1' then
|
|
||||||
dout <= reg_hi;
|
|
||||||
else
|
|
||||||
dout <= reg_lo;
|
|
||||||
end if;
|
|
||||||
end process;
|
|
||||||
|
|
||||||
proc_reg_in:
|
|
||||||
process(clk)
|
|
||||||
begin
|
|
||||||
if rising_edge(clk) then
|
|
||||||
if rst = '1' then
|
|
||||||
reg_hi <= (others => '0');
|
|
||||||
reg_lo <= (others => '0');
|
|
||||||
elsif din_vld_hi = '1' then
|
|
||||||
if hilo_sel = '1' then
|
|
||||||
reg_hi <= din_hi;
|
|
||||||
else
|
|
||||||
reg_lo <= din_hi;
|
|
||||||
end if;
|
|
||||||
end if;
|
|
||||||
if din_vld_lo = '1' then
|
|
||||||
reg_lo <= din_lo;
|
|
||||||
end if;
|
|
||||||
end if;
|
|
||||||
end process;
|
|
||||||
|
|
||||||
--------------------------------------------------------------------------
|
|
||||||
end Behavioral;
|
|
||||||
@@ -1,115 +0,0 @@
|
|||||||
-------------------------------------------------------------------------
|
|
||||||
-- Project: JCPU, a portable 8-bit RISC CPU written in VHDL
|
|
||||||
-- This file: The ROM file for use in your VHDL design
|
|
||||||
--
|
|
||||||
-- Copyright (C) 2007 J. Ahrensfeld
|
|
||||||
--
|
|
||||||
-- This program is free software: you can redistribute it and/or modify
|
|
||||||
-- it under the terms of the GNU General Public License as published by
|
|
||||||
-- the Free Software Foundation, either version 3 of the License, or
|
|
||||||
-- (at your option) any later version.
|
|
||||||
--
|
|
||||||
-- This program is distributed in the hope that it will be useful,
|
|
||||||
-- but WITHOUT ANY WARRANTY; without even the implied warranty of
|
|
||||||
-- MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
|
||||||
-- GNU General Public License for more details.
|
|
||||||
--
|
|
||||||
-- You should have received a copy of the GNU General Public License
|
|
||||||
-- along with this program. If not, see <http://www.gnu.org/licenses/>.
|
|
||||||
--
|
|
||||||
-- For questions and ideas, please contact the author at jens@jayfield.org
|
|
||||||
--
|
|
||||||
--------------------------------------------------------------------------
|
|
||||||
|
|
||||||
LIBRARY ieee;
|
|
||||||
use IEEE.STD_LOGIC_1164.ALL;
|
|
||||||
USE ieee.numeric_std.ALL;
|
|
||||||
|
|
||||||
|
|
||||||
ENTITY ram IS
|
|
||||||
Generic
|
|
||||||
(
|
|
||||||
word_addr_width : integer := 6
|
|
||||||
);
|
|
||||||
Port
|
|
||||||
(
|
|
||||||
clk : in STD_LOGIC;
|
|
||||||
we : in unsigned(3 downto 0);
|
|
||||||
ce : in STD_LOGIC;
|
|
||||||
addr : in unsigned(31 downto 0);
|
|
||||||
din : in unsigned(31 downto 0);
|
|
||||||
dout : out unsigned(31 downto 0)
|
|
||||||
);
|
|
||||||
END ram;
|
|
||||||
|
|
||||||
ARCHITECTURE behavior OF ram IS
|
|
||||||
|
|
||||||
constant depth : natural := 2**word_addr_width;
|
|
||||||
|
|
||||||
type sram_t is array (0 to depth-1) of unsigned(7 downto 0);
|
|
||||||
|
|
||||||
function sram_clear return sram_t is
|
|
||||||
|
|
||||||
variable result : sram_t;
|
|
||||||
begin
|
|
||||||
for i in 0 to sram_t'length-1 loop
|
|
||||||
result(i) := (others => '0');
|
|
||||||
end loop;
|
|
||||||
return result;
|
|
||||||
end sram_clear;
|
|
||||||
|
|
||||||
signal sram0, sram1, sram2, sram3 : sram_t := sram_clear;
|
|
||||||
|
|
||||||
BEGIN
|
|
||||||
|
|
||||||
|
|
||||||
SRAM_RW:
|
|
||||||
process(clk)
|
|
||||||
variable index : natural range 0 to depth-1;
|
|
||||||
begin
|
|
||||||
if rising_edge(clk) and ce = '1' then
|
|
||||||
index := to_integer(addr(word_addr_width+1 downto 2));
|
|
||||||
if we(0) = '1' then
|
|
||||||
sram0(index)<= din(7 downto 0);
|
|
||||||
end if;
|
|
||||||
dout(7 downto 0) <= sram0(index);
|
|
||||||
end if;
|
|
||||||
end process;
|
|
||||||
|
|
||||||
process(clk)
|
|
||||||
variable index : natural range 0 to depth-1;
|
|
||||||
begin
|
|
||||||
if rising_edge(clk) and ce = '1' then
|
|
||||||
index := to_integer(addr(word_addr_width+1 downto 2));
|
|
||||||
if we(1) = '1' then
|
|
||||||
sram1(index)<= din(15 downto 8);
|
|
||||||
end if;
|
|
||||||
dout(15 downto 8) <= sram1(index);
|
|
||||||
end if;
|
|
||||||
end process;
|
|
||||||
|
|
||||||
process(clk)
|
|
||||||
variable index : natural range 0 to depth-1;
|
|
||||||
begin
|
|
||||||
if rising_edge(clk) and ce = '1' then
|
|
||||||
index := to_integer(addr(word_addr_width+1 downto 2));
|
|
||||||
if we(2) = '1' then
|
|
||||||
sram2(index)<= din(23 downto 16);
|
|
||||||
end if;
|
|
||||||
dout(23 downto 16) <= sram2(index);
|
|
||||||
end if;
|
|
||||||
end process;
|
|
||||||
|
|
||||||
process(clk)
|
|
||||||
variable index : natural range 0 to depth-1;
|
|
||||||
begin
|
|
||||||
if rising_edge(clk) and ce = '1' then
|
|
||||||
index := to_integer(addr(word_addr_width+1 downto 2));
|
|
||||||
if we(3) = '1' then
|
|
||||||
sram3(index)<= din(31 downto 24);
|
|
||||||
end if;
|
|
||||||
dout(31 downto 24) <= sram3(index);
|
|
||||||
end if;
|
|
||||||
end process;
|
|
||||||
|
|
||||||
end behavior;
|
|
||||||
@@ -1,177 +0,0 @@
|
|||||||
-------------------------------------------------------------------------
|
|
||||||
-- Project: JCPU, a portable 8-bit RISC CPU written in VHDL
|
|
||||||
-- This file: The ROM file for use in your VHDL design
|
|
||||||
--
|
|
||||||
-- Copyright (C) 2007 J. Ahrensfeld
|
|
||||||
--
|
|
||||||
-- This program is free software: you can redistribute it and/or modify
|
|
||||||
-- it under the terms of the GNU General Public License as published by
|
|
||||||
-- the Free Software Foundation, either version 3 of the License, or
|
|
||||||
-- (at your option) any later version.
|
|
||||||
--
|
|
||||||
-- This program is distributed in the hope that it will be useful,
|
|
||||||
-- but WITHOUT ANY WARRANTY; without even the implied warranty of
|
|
||||||
-- MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
|
||||||
-- GNU General Public License for more details.
|
|
||||||
--
|
|
||||||
-- You should have received a copy of the GNU General Public License
|
|
||||||
-- along with this program. If not, see <http://www.gnu.org/licenses/>.
|
|
||||||
--
|
|
||||||
-- For questions and ideas, please contact the author at jens@jayfield.org
|
|
||||||
--
|
|
||||||
--------------------------------------------------------------------------
|
|
||||||
|
|
||||||
LIBRARY ieee;
|
|
||||||
use IEEE.STD_LOGIC_1164.ALL;
|
|
||||||
USE ieee.numeric_std.ALL;
|
|
||||||
|
|
||||||
library UNISIM;
|
|
||||||
use UNISIM.VComponents.all;
|
|
||||||
|
|
||||||
ENTITY ram IS
|
|
||||||
Generic
|
|
||||||
(
|
|
||||||
word_addr_width : integer := 6
|
|
||||||
);
|
|
||||||
Port
|
|
||||||
(
|
|
||||||
clk : in STD_LOGIC;
|
|
||||||
ce : in STD_LOGIC;
|
|
||||||
we : in unsigned(3 downto 0);
|
|
||||||
addr : in unsigned(31 downto 0);
|
|
||||||
din : in unsigned(31 downto 0);
|
|
||||||
dout : out unsigned(31 downto 0)
|
|
||||||
);
|
|
||||||
END ram;
|
|
||||||
|
|
||||||
ARCHITECTURE behavior OF ram IS
|
|
||||||
|
|
||||||
COMPONENT dpram_2w2r
|
|
||||||
Generic
|
|
||||||
(
|
|
||||||
addr_width : integer;
|
|
||||||
data_width : integer
|
|
||||||
);
|
|
||||||
Port
|
|
||||||
(
|
|
||||||
clk_a : in STD_LOGIC;
|
|
||||||
clk_b : in STD_LOGIC;
|
|
||||||
en_a : in STD_LOGIC;
|
|
||||||
en_b : in STD_LOGIC;
|
|
||||||
we_a : in STD_LOGIC;
|
|
||||||
we_b : in STD_LOGIC;
|
|
||||||
addr_a : in unsigned (addr_width-1 downto 0);
|
|
||||||
addr_b : in unsigned (addr_width-1 downto 0);
|
|
||||||
din_a : in unsigned (data_width-1 downto 0);
|
|
||||||
din_b : in unsigned (data_width-1 downto 0);
|
|
||||||
dout_a : out unsigned (data_width-1 downto 0);
|
|
||||||
dout_b : out unsigned (data_width-1 downto 0)
|
|
||||||
);
|
|
||||||
END COMPONENT;
|
|
||||||
|
|
||||||
signal jtag_clk : STD_LOGIC;
|
|
||||||
signal jtag_we : unsigned(3 downto 0);
|
|
||||||
signal jtag_addr : unsigned (15 downto 0);
|
|
||||||
signal jtag_dout : unsigned (31 downto 0);
|
|
||||||
signal jtag_din : unsigned (31 downto 0);
|
|
||||||
signal bs_rst, bs_sel, bs_shift, bs_tdi, bs_tdo : std_logic;
|
|
||||||
signal bs_capture, bs_clk0, bs_clk1, bs_update0, bs_update1 : std_logic;
|
|
||||||
signal user_regi, user_rego : unsigned (47 downto 0);
|
|
||||||
|
|
||||||
BEGIN
|
|
||||||
|
|
||||||
gen_sram:
|
|
||||||
for i in 0 to 3 generate
|
|
||||||
begin
|
|
||||||
inst_dpram_2w2r : dpram_2w2r
|
|
||||||
GENERIC MAP
|
|
||||||
(
|
|
||||||
addr_width => word_addr_width,
|
|
||||||
data_width => 8
|
|
||||||
)
|
|
||||||
PORT MAP
|
|
||||||
(
|
|
||||||
clk_a => clk,
|
|
||||||
en_a => ce,
|
|
||||||
we_a => we(i),
|
|
||||||
addr_a => addr(word_addr_width+1 downto 2),
|
|
||||||
din_a => din((i+1)*8-1 downto i*8),
|
|
||||||
dout_a => dout((i+1)*8-1 downto i*8),
|
|
||||||
|
|
||||||
clk_b => jtag_clk,
|
|
||||||
en_b => jtag_we(i),
|
|
||||||
we_b => jtag_we(i),
|
|
||||||
addr_b => jtag_addr(word_addr_width-1 downto 0),
|
|
||||||
din_b => jtag_din((i+1)*8-1 downto i*8),
|
|
||||||
dout_b => jtag_dout((i+1)*8-1 downto i*8)
|
|
||||||
);
|
|
||||||
end generate;
|
|
||||||
|
|
||||||
--------------------------------------------------------------------------
|
|
||||||
-- Virtex-4: JTAG Loader
|
|
||||||
--------------------------------------------------------------------------
|
|
||||||
i00_BUFG : BUFG
|
|
||||||
port map
|
|
||||||
(
|
|
||||||
O => bs_clk1,
|
|
||||||
I => bs_clk0
|
|
||||||
);
|
|
||||||
|
|
||||||
i01_BUFG : BUFG
|
|
||||||
port map
|
|
||||||
(
|
|
||||||
O => bs_update1,
|
|
||||||
I => bs_update0
|
|
||||||
);
|
|
||||||
|
|
||||||
BSCAN_VIRTEX4_inst2 : BSCAN_VIRTEX4
|
|
||||||
generic map
|
|
||||||
(
|
|
||||||
JTAG_CHAIN => 2 -- Value to set BSCAN site of device. Possible values: (1,2,3 or 4)
|
|
||||||
)
|
|
||||||
port map
|
|
||||||
(
|
|
||||||
CAPTURE => bs_capture, -- CAPTURE output from TAP controller
|
|
||||||
DRCK => bs_clk0, -- Data register output for USER functions
|
|
||||||
RESET => bs_rst, -- Reset output from TAP controller
|
|
||||||
SEL => bs_sel, -- USER active output
|
|
||||||
SHIFT => bs_shift, -- SHIFT output from TAP controller
|
|
||||||
TDI => bs_tdi, -- TDI output from TAP controller
|
|
||||||
UPDATE => bs_update0, -- UPDATE output from TAP controller
|
|
||||||
TDO => bs_tdo -- Data input for USER function
|
|
||||||
);
|
|
||||||
|
|
||||||
jtag_addr <= user_regi(user_regi'left downto jtag_dout'length);
|
|
||||||
jtag_din <= user_regi(jtag_dout'length-1 downto 0);
|
|
||||||
jtag_clk <= bs_update1;
|
|
||||||
jtag_we <= (3 downto 0 => bs_sel);
|
|
||||||
|
|
||||||
sipo:
|
|
||||||
process (bs_rst, bs_clk1, bs_tdi, bs_shift)
|
|
||||||
begin
|
|
||||||
if bs_rst = '1' then
|
|
||||||
user_regi <= (others => '0');
|
|
||||||
elsif rising_edge(bs_clk1) then
|
|
||||||
if bs_shift = '1' then
|
|
||||||
user_regi <= bs_tdi & user_regi(user_regi'left downto 1);
|
|
||||||
end if;
|
|
||||||
end if;
|
|
||||||
end process;
|
|
||||||
|
|
||||||
piso:
|
|
||||||
process (bs_rst, bs_clk1, bs_shift, user_rego)
|
|
||||||
begin
|
|
||||||
bs_tdo <= user_rego(0);
|
|
||||||
if bs_rst = '1' then
|
|
||||||
user_rego <= (others => '0');
|
|
||||||
elsif rising_edge(bs_clk1) then
|
|
||||||
if bs_shift = '1' then
|
|
||||||
user_rego <= user_rego(0) & user_rego(user_rego'left downto 1);
|
|
||||||
else
|
|
||||||
user_rego <= (user_rego'left downto jtag_dout'length => '0') & jtag_dout;
|
|
||||||
end if;
|
|
||||||
end if;
|
|
||||||
end process;
|
|
||||||
|
|
||||||
--------------------------------------------------------------------------
|
|
||||||
end behavior;
|
|
||||||
@@ -1,88 +0,0 @@
|
|||||||
-------------------------------------------------------------------------
|
|
||||||
-- Project: JCPU, a portable 8-bit RISC CPU written in VHDL
|
|
||||||
-- This file: The ROM file for use in your VHDL design
|
|
||||||
--
|
|
||||||
-- Copyright (C) 2007 J. Ahrensfeld
|
|
||||||
--
|
|
||||||
-- This program is free software: you can redistribute it and/or modify
|
|
||||||
-- it under the terms of the GNU General Public License as published by
|
|
||||||
-- the Free Software Foundation, either version 3 of the License, or
|
|
||||||
-- (at your option) any later version.
|
|
||||||
--
|
|
||||||
-- This program is distributed in the hope that it will be useful,
|
|
||||||
-- but WITHOUT ANY WARRANTY; without even the implied warranty of
|
|
||||||
-- MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
|
||||||
-- GNU General Public License for more details.
|
|
||||||
--
|
|
||||||
-- You should have received a copy of the GNU General Public License
|
|
||||||
-- along with this program. If not, see <http://www.gnu.org/licenses/>.
|
|
||||||
--
|
|
||||||
-- For questions and ideas, please contact the author at jens@jayfield.org
|
|
||||||
--
|
|
||||||
--------------------------------------------------------------------------
|
|
||||||
|
|
||||||
LIBRARY ieee;
|
|
||||||
use IEEE.STD_LOGIC_1164.ALL;
|
|
||||||
USE ieee.numeric_std.ALL;
|
|
||||||
|
|
||||||
|
|
||||||
ENTITY ram IS
|
|
||||||
Generic
|
|
||||||
(
|
|
||||||
word_addr_width : integer := 6
|
|
||||||
);
|
|
||||||
Port
|
|
||||||
(
|
|
||||||
clk : in STD_LOGIC;
|
|
||||||
ce : in STD_LOGIC;
|
|
||||||
we : in unsigned(3 downto 0);
|
|
||||||
addr : in unsigned(31 downto 0);
|
|
||||||
din : in unsigned(31 downto 0);
|
|
||||||
dout : out unsigned(31 downto 0)
|
|
||||||
);
|
|
||||||
END ram;
|
|
||||||
|
|
||||||
ARCHITECTURE behavior OF ram IS
|
|
||||||
|
|
||||||
constant depth : natural := 2**word_addr_width;
|
|
||||||
|
|
||||||
type sram_t is array (0 to depth-1) of unsigned(31 downto 0);
|
|
||||||
|
|
||||||
function sram_clear return sram_t is
|
|
||||||
|
|
||||||
variable result : sram_t;
|
|
||||||
begin
|
|
||||||
for i in 0 to sram_t'length-1 loop
|
|
||||||
result(i) := (others => '0');
|
|
||||||
end loop;
|
|
||||||
return result;
|
|
||||||
end sram_clear;
|
|
||||||
|
|
||||||
signal sram : sram_t := sram_clear;
|
|
||||||
|
|
||||||
BEGIN
|
|
||||||
|
|
||||||
|
|
||||||
SRAM_RW:
|
|
||||||
process(clk)
|
|
||||||
variable index : natural range 0 to depth-1;
|
|
||||||
begin
|
|
||||||
if rising_edge(clk) and ce = '1' then
|
|
||||||
index := to_integer(addr(word_addr_width+1 downto 2));
|
|
||||||
if we(0) = '1' then
|
|
||||||
sram(index)(7 downto 0) <= din(7 downto 0);
|
|
||||||
end if;
|
|
||||||
if we(1) = '1' then
|
|
||||||
sram(index)(15 downto 8) <= din(15 downto 8);
|
|
||||||
end if;
|
|
||||||
if we(2) = '1' then
|
|
||||||
sram(index)(23 downto 16) <= din(23 downto 16);
|
|
||||||
end if;
|
|
||||||
if we(3) = '1' then
|
|
||||||
sram(index)(31 downto 24) <= din(31 downto 24);
|
|
||||||
end if;
|
|
||||||
dout <= sram(index);
|
|
||||||
end if;
|
|
||||||
end process;
|
|
||||||
|
|
||||||
end behavior;
|
|
||||||
File diff suppressed because it is too large
Load Diff
@@ -1,156 +0,0 @@
|
|||||||
-------------------------------------------------------------------------
|
|
||||||
-- Project: JIPS, a portable 32-bit RISC CPU written in VHDL
|
|
||||||
-- This file: Testbench for JCPU
|
|
||||||
-- also writes 'opc.lst' for JASM-assembler
|
|
||||||
--
|
|
||||||
-- Copyright (C) 2007 J. Ahrensfeld
|
|
||||||
--
|
|
||||||
-- This program is free software: you can redistribute it and/or modify
|
|
||||||
-- it under the terms of the GNU General Public License as published by
|
|
||||||
-- the Free Software Foundation, either version 3 of the License, or
|
|
||||||
-- (at your option) any later version.
|
|
||||||
--
|
|
||||||
-- This program is distributed in the hope that it will be useful,
|
|
||||||
-- but WITHOUT ANY WARRANTY; without even the implied warranty of
|
|
||||||
-- MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
|
||||||
-- GNU General Public License for more details.
|
|
||||||
--
|
|
||||||
-- You should have received a copy of the GNU General Public License
|
|
||||||
-- along with this program. If not, see <http://www.gnu.org/licenses/>.
|
|
||||||
--
|
|
||||||
-- For questions and ideas, please contact the author at jens@jayfield.org
|
|
||||||
--
|
|
||||||
--------------------------------------------------------------------------
|
|
||||||
|
|
||||||
LIBRARY ieee;
|
|
||||||
use IEEE.STD_LOGIC_1164.ALL;
|
|
||||||
USE ieee.numeric_std.ALL;
|
|
||||||
use std.textio.all; -- Imports the standard textio package.
|
|
||||||
|
|
||||||
library work;
|
|
||||||
use work.mips_types.all;
|
|
||||||
use work.mips_instr.all;
|
|
||||||
|
|
||||||
ENTITY tb_eval_muldiv IS
|
|
||||||
END tb_eval_muldiv;
|
|
||||||
|
|
||||||
ARCHITECTURE behavior OF tb_eval_muldiv IS
|
|
||||||
|
|
||||||
constant CLK_PERIOD : time := 10 ns;
|
|
||||||
signal rst : std_logic := '1';
|
|
||||||
signal clk : std_logic := '1';
|
|
||||||
signal ce : std_logic := '0';
|
|
||||||
signal mul_divn : std_logic := '1';
|
|
||||||
signal op_valid : std_logic := '0';
|
|
||||||
signal op1_in : word_t := (others => '-');
|
|
||||||
signal op2_in : word_t := (others => '-');
|
|
||||||
signal result : unsigned (2*word_t'length-1 downto 0);
|
|
||||||
signal res_valid : std_logic;
|
|
||||||
signal busy : std_logic;
|
|
||||||
signal result_reg : unsigned (2*word_t'length-1 downto 0);
|
|
||||||
subtype pp_t is unsigned (39 downto 0);
|
|
||||||
|
|
||||||
signal pp0, pp1, pp2, pp3 : pp_t;
|
|
||||||
|
|
||||||
signal signed_mul : std_logic := '1';
|
|
||||||
signal sign1 : std_logic;
|
|
||||||
signal sign2 : std_logic;
|
|
||||||
signal cy : std_logic;
|
|
||||||
|
|
||||||
BEGIN
|
|
||||||
|
|
||||||
sign1 <= signed_mul and op1_in(op1_in'left);
|
|
||||||
sign2 <= signed_mul and op2_in(op1_in'left);
|
|
||||||
cy <= sign1;
|
|
||||||
|
|
||||||
pp0 <= op1_in * op2_in(7 downto 0);
|
|
||||||
pp1 <= op1_in * op2_in(15 downto 8);
|
|
||||||
pp2 <= op1_in * op2_in(23 downto 16);
|
|
||||||
pp3 <= op1_in * op2_in(31 downto 24);
|
|
||||||
|
|
||||||
result <= ((63 downto 40 => '0') & pp0)
|
|
||||||
+ ((63 downto 48 => '0') & pp1 & (7 downto 0 => '0'))
|
|
||||||
+ ((63 downto 56 => '0') & pp2 & (15 downto 0 => '0'))
|
|
||||||
+ (pp3 & (23 downto 0 => '0'));
|
|
||||||
|
|
||||||
result_reg <= (63 downto 0 => sign1) xor (result + ((63 downto 0 => sign1) and X"0000_0000_0000_0000"));
|
|
||||||
|
|
||||||
CLK_GEN: process
|
|
||||||
begin
|
|
||||||
wait for CLK_PERIOD/2;
|
|
||||||
clk <= not clk;
|
|
||||||
end process;
|
|
||||||
|
|
||||||
STIMULUS: process
|
|
||||||
|
|
||||||
begin
|
|
||||||
|
|
||||||
wait for 3*CLK_PERIOD;
|
|
||||||
wait until rising_edge(clk);
|
|
||||||
rst <= '0';
|
|
||||||
wait for 10*CLK_PERIOD;
|
|
||||||
|
|
||||||
wait until rising_edge(clk);
|
|
||||||
ce <= '1';
|
|
||||||
|
|
||||||
wait for 10*CLK_PERIOD;
|
|
||||||
op1_in <= X"FFFF_FFFA"; -- (-6)
|
|
||||||
op2_in <= X"0000_0005"; -- (+5)
|
|
||||||
op_valid <= '1';
|
|
||||||
wait until rising_edge(clk);
|
|
||||||
op_valid <= '0';
|
|
||||||
|
|
||||||
wait for 10*CLK_PERIOD;
|
|
||||||
op1_in <= X"0000_0006"; -- (+6)
|
|
||||||
op2_in <= X"FFFF_FFFB"; -- (-5)
|
|
||||||
op_valid <= '1';
|
|
||||||
wait until rising_edge(clk);
|
|
||||||
op_valid <= '0';
|
|
||||||
|
|
||||||
wait for 10*CLK_PERIOD;
|
|
||||||
op1_in <= X"1234_5678";
|
|
||||||
op2_in <= X"8765_4321";
|
|
||||||
op_valid <= '1';
|
|
||||||
wait until rising_edge(clk);
|
|
||||||
op_valid <= '0';
|
|
||||||
|
|
||||||
wait for 10*CLK_PERIOD;
|
|
||||||
op1_in <= X"8765_4321";
|
|
||||||
op2_in <= X"1234_5678";
|
|
||||||
op_valid <= '1';
|
|
||||||
wait until rising_edge(clk);
|
|
||||||
op_valid <= '0';
|
|
||||||
|
|
||||||
wait for 10*CLK_PERIOD;
|
|
||||||
op1_in <= X"1234_5678";
|
|
||||||
op2_in <= X"1234_5678";
|
|
||||||
op_valid <= '1';
|
|
||||||
wait until rising_edge(clk);
|
|
||||||
op_valid <= '0';
|
|
||||||
|
|
||||||
wait for 10*CLK_PERIOD;
|
|
||||||
op1_in <= X"8765_4321";
|
|
||||||
op2_in <= X"8765_4321";
|
|
||||||
op_valid <= '1';
|
|
||||||
wait until rising_edge(clk);
|
|
||||||
op_valid <= '0';
|
|
||||||
|
|
||||||
wait for 10*CLK_PERIOD;
|
|
||||||
op1_in <= X"789A_BCDE";
|
|
||||||
op2_in <= X"8765_4321";
|
|
||||||
op_valid <= '1';
|
|
||||||
wait until rising_edge(clk);
|
|
||||||
op_valid <= '0';
|
|
||||||
|
|
||||||
wait for 10*CLK_PERIOD;
|
|
||||||
op1_in <= X"8765_4321";
|
|
||||||
op2_in <= X"789A_BCDE";
|
|
||||||
op_valid <= '1';
|
|
||||||
wait until rising_edge(clk);
|
|
||||||
op_valid <= '0';
|
|
||||||
|
|
||||||
wait;
|
|
||||||
|
|
||||||
end process;
|
|
||||||
|
|
||||||
END;
|
|
||||||
@@ -1,82 +0,0 @@
|
|||||||
-------------------------------------------------------------------------
|
|
||||||
-- Project: JIPS, a portable 32-bit RISC CPU written in VHDL
|
|
||||||
-- This file: Testbench for JCPU
|
|
||||||
-- also writes 'opc.lst' for JASM-assembler
|
|
||||||
--
|
|
||||||
-- Copyright (C) 2007 J. Ahrensfeld
|
|
||||||
--
|
|
||||||
-- This program is free software: you can redistribute it and/or modify
|
|
||||||
-- it under the terms of the GNU General Public License as published by
|
|
||||||
-- the Free Software Foundation, either version 3 of the License, or
|
|
||||||
-- (at your option) any later version.
|
|
||||||
--
|
|
||||||
-- This program is distributed in the hope that it will be useful,
|
|
||||||
-- but WITHOUT ANY WARRANTY; without even the implied warranty of
|
|
||||||
-- MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
|
||||||
-- GNU General Public License for more details.
|
|
||||||
--
|
|
||||||
-- You should have received a copy of the GNU General Public License
|
|
||||||
-- along with this program. If not, see <http://www.gnu.org/licenses/>.
|
|
||||||
--
|
|
||||||
-- For questions and ideas, please contact the author at jens@jayfield.org
|
|
||||||
--
|
|
||||||
--------------------------------------------------------------------------
|
|
||||||
|
|
||||||
LIBRARY ieee;
|
|
||||||
use IEEE.STD_LOGIC_1164.ALL;
|
|
||||||
USE ieee.numeric_std.ALL;
|
|
||||||
use std.textio.all; -- Imports the standard textio package.
|
|
||||||
|
|
||||||
library work;
|
|
||||||
use work.mips_types.all;
|
|
||||||
|
|
||||||
ENTITY tb_mips_embedded IS
|
|
||||||
END tb_mips_embedded;
|
|
||||||
|
|
||||||
ARCHITECTURE behavior OF tb_mips_embedded IS
|
|
||||||
|
|
||||||
COMPONENT mips_embedded
|
|
||||||
Port
|
|
||||||
(
|
|
||||||
rst : in STD_LOGIC;
|
|
||||||
clk : in STD_LOGIC;
|
|
||||||
halt : in STD_LOGIC;
|
|
||||||
dout : out word_t
|
|
||||||
);
|
|
||||||
END COMPONENT;
|
|
||||||
|
|
||||||
constant CLK_PERIOD : time := 10 ns;
|
|
||||||
|
|
||||||
signal rst : std_logic := '1';
|
|
||||||
signal clk : std_logic := '1';
|
|
||||||
signal halt : std_logic := '0';
|
|
||||||
signal dout : word_t;
|
|
||||||
|
|
||||||
BEGIN
|
|
||||||
|
|
||||||
uut: mips_embedded
|
|
||||||
PORT MAP(
|
|
||||||
rst => rst,
|
|
||||||
clk => clk,
|
|
||||||
halt => halt,
|
|
||||||
dout => dout
|
|
||||||
);
|
|
||||||
|
|
||||||
CLK_GEN: process
|
|
||||||
begin
|
|
||||||
wait for CLK_PERIOD/2;
|
|
||||||
clk <= not clk;
|
|
||||||
end process;
|
|
||||||
|
|
||||||
STIMULUS: process
|
|
||||||
begin
|
|
||||||
|
|
||||||
wait for 3*CLK_PERIOD;
|
|
||||||
wait until rising_edge(clk);
|
|
||||||
rst <= '0';
|
|
||||||
|
|
||||||
wait;
|
|
||||||
|
|
||||||
end process;
|
|
||||||
|
|
||||||
END;
|
|
||||||
@@ -1,123 +0,0 @@
|
|||||||
-------------------------------------------------------------------------
|
|
||||||
-- Project: JIPS, a portable 32-bit RISC CPU written in VHDL
|
|
||||||
-- This file: Testbench for JCPU
|
|
||||||
-- also writes 'opc.lst' for JASM-assembler
|
|
||||||
--
|
|
||||||
-- Copyright (C) 2007 J. Ahrensfeld
|
|
||||||
--
|
|
||||||
-- This program is free software: you can redistribute it and/or modify
|
|
||||||
-- it under the terms of the GNU General Public License as published by
|
|
||||||
-- the Free Software Foundation, either version 3 of the License, or
|
|
||||||
-- (at your option) any later version.
|
|
||||||
--
|
|
||||||
-- This program is distributed in the hope that it will be useful,
|
|
||||||
-- but WITHOUT ANY WARRANTY; without even the implied warranty of
|
|
||||||
-- MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
|
||||||
-- GNU General Public License for more details.
|
|
||||||
--
|
|
||||||
-- You should have received a copy of the GNU General Public License
|
|
||||||
-- along with this program. If not, see <http://www.gnu.org/licenses/>.
|
|
||||||
--
|
|
||||||
-- For questions and ideas, please contact the author at jens@jayfield.org
|
|
||||||
--
|
|
||||||
--------------------------------------------------------------------------
|
|
||||||
|
|
||||||
LIBRARY ieee;
|
|
||||||
use IEEE.STD_LOGIC_1164.ALL;
|
|
||||||
USE ieee.numeric_std.ALL;
|
|
||||||
use std.textio.all; -- Imports the standard textio package.
|
|
||||||
|
|
||||||
ENTITY tb_mips_embedded_syn IS
|
|
||||||
END tb_mips_embedded_syn;
|
|
||||||
|
|
||||||
ARCHITECTURE behavior OF tb_mips_embedded_syn IS
|
|
||||||
|
|
||||||
COMPONENT mips_embedded_syn
|
|
||||||
Port
|
|
||||||
(
|
|
||||||
sys_rst_n_in : in STD_LOGIC;
|
|
||||||
sys_clk_in : in STD_LOGIC;
|
|
||||||
sys_dip : in STD_LOGIC_VECTOR (7 downto 0);
|
|
||||||
sys_btn : in STD_LOGIC_VECTOR (8 downto 0);
|
|
||||||
sys_led : out STD_LOGIC_VECTOR (7 downto 0);
|
|
||||||
sys_rx : in STD_LOGIC;
|
|
||||||
sys_tx : out STD_LOGIC;
|
|
||||||
sys_error : out STD_LOGIC_VECTOR (1 downto 0)
|
|
||||||
);
|
|
||||||
END COMPONENT;
|
|
||||||
|
|
||||||
constant CLK_PERIOD : time := 10.0 ns;
|
|
||||||
|
|
||||||
signal sys_rst_n_in : std_logic := '0';
|
|
||||||
signal sys_clk_in : std_logic := '1';
|
|
||||||
signal sys_led : STD_LOGIC_VECTOR (7 downto 0);
|
|
||||||
signal sys_btn : STD_LOGIC_VECTOR (8 downto 0) := "000000000";
|
|
||||||
signal sys_dip : STD_LOGIC_VECTOR (7 downto 0) := "10001001";
|
|
||||||
signal sys_error : STD_LOGIC_VECTOR (1 downto 0);
|
|
||||||
signal sys_rx : std_logic := '1';
|
|
||||||
signal sys_tx : std_logic;
|
|
||||||
|
|
||||||
BEGIN
|
|
||||||
|
|
||||||
uut: mips_embedded_syn
|
|
||||||
PORT MAP
|
|
||||||
(
|
|
||||||
sys_rst_n_in => sys_rst_n_in,
|
|
||||||
sys_clk_in => sys_clk_in,
|
|
||||||
sys_btn => sys_btn,
|
|
||||||
sys_dip => sys_dip,
|
|
||||||
sys_led => sys_led,
|
|
||||||
sys_rx => sys_rx,
|
|
||||||
sys_tx => sys_tx,
|
|
||||||
sys_error => sys_error
|
|
||||||
);
|
|
||||||
|
|
||||||
CLK_GEN: process
|
|
||||||
begin
|
|
||||||
wait for CLK_PERIOD/2;
|
|
||||||
sys_clk_in <= not sys_clk_in;
|
|
||||||
end process;
|
|
||||||
|
|
||||||
STIMULUS1: process
|
|
||||||
begin
|
|
||||||
|
|
||||||
wait for 3*CLK_PERIOD;
|
|
||||||
wait until rising_edge(sys_clk_in);
|
|
||||||
sys_rst_n_in <= '1';
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
-- wait for 9994999*CLK_PERIOD;
|
|
||||||
-- for i in 1 to 10000 loop
|
|
||||||
-- wait for 100*CLK_PERIOD;
|
|
||||||
-- sys_btn(3) <= '1';
|
|
||||||
-- wait for 10*CLK_PERIOD;
|
|
||||||
-- sys_btn(3) <= '0';
|
|
||||||
-- end loop;
|
|
||||||
|
|
||||||
wait until rising_edge(sys_clk_in) and now = 38980 ns;
|
|
||||||
sys_btn <= "000001000";
|
|
||||||
wait until rising_edge(sys_clk_in);
|
|
||||||
sys_btn <= "000000000";
|
|
||||||
|
|
||||||
wait;
|
|
||||||
|
|
||||||
end process;
|
|
||||||
|
|
||||||
STIMULUS2: process
|
|
||||||
begin
|
|
||||||
|
|
||||||
|
|
||||||
wait for 9999999*CLK_PERIOD;
|
|
||||||
for i in 1 to 10000 loop
|
|
||||||
wait for 137*CLK_PERIOD;
|
|
||||||
sys_btn(4) <= '1';
|
|
||||||
wait for 21*CLK_PERIOD;
|
|
||||||
sys_btn(4) <= '0';
|
|
||||||
end loop;
|
|
||||||
|
|
||||||
wait;
|
|
||||||
|
|
||||||
end process;
|
|
||||||
|
|
||||||
END;
|
|
||||||
@@ -1,308 +0,0 @@
|
|||||||
-------------------------------------------------------------------------
|
|
||||||
-- Project: JIPS, a portable 32-bit RISC CPU written in VHDL
|
|
||||||
-- This file: Testbench for JCPU
|
|
||||||
-- also writes 'opc.lst' for JASM-assembler
|
|
||||||
--
|
|
||||||
-- Copyright (C) 2007 J. Ahrensfeld
|
|
||||||
--
|
|
||||||
-- This program is free software: you can redistribute it and/or modify
|
|
||||||
-- it under the terms of the GNU General Public License as published by
|
|
||||||
-- the Free Software Foundation, either version 3 of the License, or
|
|
||||||
-- (at your option) any later version.
|
|
||||||
--
|
|
||||||
-- This program is distributed in the hope that it will be useful,
|
|
||||||
-- but WITHOUT ANY WARRANTY; without even the implied warranty of
|
|
||||||
-- MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
|
||||||
-- GNU General Public License for more details.
|
|
||||||
--
|
|
||||||
-- You should have received a copy of the GNU General Public License
|
|
||||||
-- along with this program. If not, see <http://www.gnu.org/licenses/>.
|
|
||||||
--
|
|
||||||
-- For questions and ideas, please contact the author at jens@jayfield.org
|
|
||||||
--
|
|
||||||
--------------------------------------------------------------------------
|
|
||||||
|
|
||||||
LIBRARY ieee;
|
|
||||||
use IEEE.STD_LOGIC_1164.ALL;
|
|
||||||
USE ieee.numeric_std.ALL;
|
|
||||||
|
|
||||||
library work;
|
|
||||||
use work.mips_types.all;
|
|
||||||
use work.mips_instr.all;
|
|
||||||
|
|
||||||
ENTITY tb_mips_muldiv IS
|
|
||||||
END tb_mips_muldiv;
|
|
||||||
|
|
||||||
ARCHITECTURE behavior OF tb_mips_muldiv IS
|
|
||||||
|
|
||||||
COMPONENT muldiv is
|
|
||||||
Port
|
|
||||||
(
|
|
||||||
rst : in std_logic;
|
|
||||||
clk : in std_logic;
|
|
||||||
hilo_we : in std_logic;
|
|
||||||
din_hi : in word_t;
|
|
||||||
din_lo : in word_t;
|
|
||||||
mul_divn : in std_logic;
|
|
||||||
s_un : in std_logic;
|
|
||||||
start : in std_logic;
|
|
||||||
hilo_sel : in std_logic;
|
|
||||||
busy : out std_logic;
|
|
||||||
dout : out word_t
|
|
||||||
);
|
|
||||||
END COMPONENT;
|
|
||||||
|
|
||||||
constant CLK_PERIOD : time := 10 ns;
|
|
||||||
signal ENABLE_FAIL_REPORT : boolean := true;
|
|
||||||
signal rst : std_logic := '1';
|
|
||||||
signal clk : std_logic := '1';
|
|
||||||
signal busy : std_logic;
|
|
||||||
signal mul_divn : std_logic := '0';
|
|
||||||
signal s_un : std_logic := '1';
|
|
||||||
signal hilo_we : std_logic := '0';
|
|
||||||
signal start : std_logic := '0';
|
|
||||||
signal din_hi : word_t := (others => '-');
|
|
||||||
signal din_lo : word_t := (others => '-');
|
|
||||||
signal ref_hi : word_t := (others => '-');
|
|
||||||
signal ref_lo : word_t := (others => '-');
|
|
||||||
signal dout : word_t;
|
|
||||||
signal hilo_sel : std_logic := '0';
|
|
||||||
signal result : unsigned (2*word_t'length-1 downto 0);
|
|
||||||
signal ref_result : unsigned (2*word_t'length-1 downto 0);
|
|
||||||
|
|
||||||
type word_array_t is array (natural range <>) of word_t;
|
|
||||||
|
|
||||||
constant operands : word_array_t(0 to 63) :=
|
|
||||||
(
|
|
||||||
X"00000000",
|
|
||||||
X"00000001",
|
|
||||||
X"00000010",
|
|
||||||
X"00000100",
|
|
||||||
X"00001000",
|
|
||||||
X"00010000",
|
|
||||||
X"00100000",
|
|
||||||
X"01000000",
|
|
||||||
X"10000000",
|
|
||||||
X"0000000F",
|
|
||||||
X"000000FF",
|
|
||||||
X"00000FFF",
|
|
||||||
X"0000FFFF",
|
|
||||||
X"000FFFFF",
|
|
||||||
X"00FFFFFF",
|
|
||||||
X"0FFFFFFF",
|
|
||||||
X"12345678",
|
|
||||||
X"23456789",
|
|
||||||
X"7FFFFFFF",
|
|
||||||
X"80000000",
|
|
||||||
X"A541B3B9",
|
|
||||||
X"80000001",
|
|
||||||
X"80000010",
|
|
||||||
X"80000100",
|
|
||||||
X"80001000",
|
|
||||||
X"80010000",
|
|
||||||
X"80100000",
|
|
||||||
X"81000000",
|
|
||||||
X"87654321",
|
|
||||||
X"98765432",
|
|
||||||
X"FFFFFFFF",
|
|
||||||
X"FFFFFFFE",
|
|
||||||
X"FFFFFFFD",
|
|
||||||
X"FFFFFFFB",
|
|
||||||
X"FFFFFFF7",
|
|
||||||
X"FFFFFFEF",
|
|
||||||
X"FFFFFFDF",
|
|
||||||
X"FFFFFFBF",
|
|
||||||
X"FFFFFF7F",
|
|
||||||
X"FFFFFEFF",
|
|
||||||
X"FFFFFDFF",
|
|
||||||
X"FFFFFBFF",
|
|
||||||
X"FFFFF7FF",
|
|
||||||
X"FFFFEFFF",
|
|
||||||
X"FFFFDFFF",
|
|
||||||
X"FFFFBFFF",
|
|
||||||
X"FFFF7FFF",
|
|
||||||
X"FFFEFFFF",
|
|
||||||
X"FFFDFFFF",
|
|
||||||
X"FFFBFFFF",
|
|
||||||
X"FFF7FFFF",
|
|
||||||
X"FFEFFFFF",
|
|
||||||
X"FFDFFFFF",
|
|
||||||
X"FFBFFFFF",
|
|
||||||
X"FF7FFFFF",
|
|
||||||
X"FEFFFFFF",
|
|
||||||
X"FDFFFFFF",
|
|
||||||
X"FBFFFFFF",
|
|
||||||
X"F7FFFFFF",
|
|
||||||
X"EFFFFFFF",
|
|
||||||
X"DFFFFFFF",
|
|
||||||
X"BFFFFFFF",
|
|
||||||
X"CFFFFFFF",
|
|
||||||
X"7FFFFFFF"
|
|
||||||
);
|
|
||||||
|
|
||||||
BEGIN
|
|
||||||
|
|
||||||
uut: muldiv
|
|
||||||
PORT MAP(
|
|
||||||
rst => rst,
|
|
||||||
clk => clk,
|
|
||||||
hilo_we => hilo_we,
|
|
||||||
din_hi => din_hi,
|
|
||||||
din_lo => din_lo,
|
|
||||||
mul_divn => mul_divn,
|
|
||||||
s_un => s_un,
|
|
||||||
start => start,
|
|
||||||
hilo_sel => hilo_sel,
|
|
||||||
busy => busy,
|
|
||||||
dout => dout
|
|
||||||
);
|
|
||||||
|
|
||||||
CLK_GEN: process
|
|
||||||
begin
|
|
||||||
wait for CLK_PERIOD/2;
|
|
||||||
clk <= not clk;
|
|
||||||
end process;
|
|
||||||
|
|
||||||
REF_GEN: process
|
|
||||||
variable tmp : unsigned (2*word_t'length-1 downto 0);
|
|
||||||
variable tmp2 : unsigned (word_t'length-1 downto 0);
|
|
||||||
begin
|
|
||||||
if mul_divn = '0' then
|
|
||||||
wait until rising_edge(clk) and start = '1';
|
|
||||||
ref_lo <= din_lo;
|
|
||||||
ref_hi <= din_hi;
|
|
||||||
wait until rising_edge(clk) and busy = '0';
|
|
||||||
wait until rising_edge(clk);
|
|
||||||
wait until rising_edge(clk);
|
|
||||||
if s_un = '1' then
|
|
||||||
tmp := unsigned(signed(result(31 downto 0)) * signed(ref_lo));
|
|
||||||
tmp2 := unsigned(signed(tmp(31 downto 0)) + signed(result(63 downto 32)));
|
|
||||||
ref_result <= X"00000000" & tmp2(31 downto 0);
|
|
||||||
else
|
|
||||||
tmp := result(31 downto 0) * ref_lo;
|
|
||||||
tmp2 := tmp(31 downto 0) + result(63 downto 32);
|
|
||||||
ref_result <= X"00000000" & tmp2(31 downto 0);
|
|
||||||
end if;
|
|
||||||
wait until rising_edge(clk);
|
|
||||||
|
|
||||||
if ref_lo /= X"00000000" then
|
|
||||||
if ENABLE_FAIL_REPORT then
|
|
||||||
assert ref_hi = ref_result(31 downto 0) report "Error on divison" severity failure;
|
|
||||||
end if;
|
|
||||||
end if;
|
|
||||||
else
|
|
||||||
wait until rising_edge(clk) and start = '1';
|
|
||||||
wait until rising_edge(clk) and busy = '0';
|
|
||||||
if s_un = '1' then
|
|
||||||
ref_result <= unsigned(signed(din_hi) * signed(din_lo));
|
|
||||||
else
|
|
||||||
ref_result <= unsigned(din_hi) * unsigned(din_lo);
|
|
||||||
end if;
|
|
||||||
wait until rising_edge(clk);
|
|
||||||
wait until rising_edge(clk);
|
|
||||||
wait until rising_edge(clk);
|
|
||||||
if ENABLE_FAIL_REPORT then
|
|
||||||
assert ref_result = result report "Error on multiplication" severity failure;
|
|
||||||
end if;
|
|
||||||
end if;
|
|
||||||
|
|
||||||
end process;
|
|
||||||
|
|
||||||
STIMULUS: process
|
|
||||||
|
|
||||||
begin
|
|
||||||
|
|
||||||
wait for 3*CLK_PERIOD;
|
|
||||||
wait until rising_edge(clk);
|
|
||||||
rst <= '0';
|
|
||||||
wait for 2*CLK_PERIOD;
|
|
||||||
|
|
||||||
mul_divn <= '0';
|
|
||||||
s_un <= '0';
|
|
||||||
for i in 0 to operands'length-1 loop
|
|
||||||
for j in 0 to operands'length-1 loop
|
|
||||||
wait until rising_edge(clk) and busy = '0';
|
|
||||||
din_hi <= operands(i);
|
|
||||||
din_lo <= operands(j);
|
|
||||||
start <= '1';
|
|
||||||
wait until rising_edge(clk);
|
|
||||||
start <= '0';
|
|
||||||
hilo_sel <= '0';
|
|
||||||
|
|
||||||
-- Read result
|
|
||||||
wait until rising_edge(clk) and busy = '0';
|
|
||||||
result(31 downto 0) <= dout;
|
|
||||||
hilo_sel <= '1';
|
|
||||||
wait until rising_edge(clk);
|
|
||||||
result(63 downto 32) <= dout;
|
|
||||||
wait for 2*CLK_PERIOD;
|
|
||||||
end loop;
|
|
||||||
end loop;
|
|
||||||
|
|
||||||
s_un <= '1';
|
|
||||||
for i in 0 to operands'length-1 loop
|
|
||||||
for j in 0 to operands'length-1 loop
|
|
||||||
wait until rising_edge(clk) and busy = '0';
|
|
||||||
din_hi <= operands(i);
|
|
||||||
din_lo <= operands(j);
|
|
||||||
start <= '1';
|
|
||||||
wait until rising_edge(clk);
|
|
||||||
start <= '0';
|
|
||||||
hilo_sel <= '0';
|
|
||||||
|
|
||||||
-- Read result
|
|
||||||
wait until rising_edge(clk) and busy = '0';
|
|
||||||
result(31 downto 0) <= dout;
|
|
||||||
hilo_sel <= '1';
|
|
||||||
wait until rising_edge(clk);
|
|
||||||
result(63 downto 32) <= dout;
|
|
||||||
wait for 2*CLK_PERIOD;
|
|
||||||
end loop;
|
|
||||||
end loop;
|
|
||||||
|
|
||||||
mul_divn <= '1';
|
|
||||||
s_un <= '0';
|
|
||||||
for i in 0 to operands'length-1 loop
|
|
||||||
for j in 0 to operands'length-1 loop
|
|
||||||
wait until rising_edge(clk) and busy = '0';
|
|
||||||
din_hi <= operands(i);
|
|
||||||
din_lo <= operands(j);
|
|
||||||
start <= '1';
|
|
||||||
wait until rising_edge(clk);
|
|
||||||
start <= '0';
|
|
||||||
hilo_sel <= '0';
|
|
||||||
|
|
||||||
-- Read result
|
|
||||||
wait until rising_edge(clk) and busy = '0';
|
|
||||||
result(31 downto 0) <= dout;
|
|
||||||
hilo_sel <= '1';
|
|
||||||
wait until rising_edge(clk);
|
|
||||||
result(63 downto 32) <= dout;
|
|
||||||
end loop;
|
|
||||||
end loop;
|
|
||||||
|
|
||||||
s_un <= '1';
|
|
||||||
for i in 0 to operands'length-1 loop
|
|
||||||
for j in 0 to operands'length-1 loop
|
|
||||||
wait until rising_edge(clk) and busy = '0';
|
|
||||||
din_hi <= operands(i);
|
|
||||||
din_lo <= operands(j);
|
|
||||||
start <= '1';
|
|
||||||
wait until rising_edge(clk);
|
|
||||||
start <= '0';
|
|
||||||
hilo_sel <= '0';
|
|
||||||
|
|
||||||
-- Read result
|
|
||||||
wait until rising_edge(clk) and busy = '0';
|
|
||||||
result(31 downto 0) <= dout;
|
|
||||||
hilo_sel <= '1';
|
|
||||||
wait until rising_edge(clk);
|
|
||||||
result(63 downto 32) <= dout;
|
|
||||||
end loop;
|
|
||||||
end loop;
|
|
||||||
|
|
||||||
wait;
|
|
||||||
|
|
||||||
end process;
|
|
||||||
|
|
||||||
END;
|
|
||||||
@@ -1,174 +0,0 @@
|
|||||||
-------------------------------------------------------------------------
|
|
||||||
-- Project: JIPS, a portable 32-bit RISC CPU written in VHDL
|
|
||||||
-- This file: Testbench for JCPU
|
|
||||||
-- also writes 'opc.lst' for JASM-assembler
|
|
||||||
--
|
|
||||||
-- Copyright (C) 2007 J. Ahrensfeld
|
|
||||||
--
|
|
||||||
-- This program is free software: you can redistribute it and/or modify
|
|
||||||
-- it under the terms of the GNU General Public License as published by
|
|
||||||
-- the Free Software Foundation, either version 3 of the License, or
|
|
||||||
-- (at your option) any later version.
|
|
||||||
--
|
|
||||||
-- This program is distributed in the hope that it will be useful,
|
|
||||||
-- but WITHOUT ANY WARRANTY; without even the implied warranty of
|
|
||||||
-- MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
|
||||||
-- GNU General Public License for more details.
|
|
||||||
--
|
|
||||||
-- You should have received a copy of the GNU General Public License
|
|
||||||
-- along with this program. If not, see <http://www.gnu.org/licenses/>.
|
|
||||||
--
|
|
||||||
-- For questions and ideas, please contact the author at jens@jayfield.org
|
|
||||||
--
|
|
||||||
--------------------------------------------------------------------------
|
|
||||||
|
|
||||||
LIBRARY ieee;
|
|
||||||
use IEEE.STD_LOGIC_1164.ALL;
|
|
||||||
USE ieee.numeric_std.ALL;
|
|
||||||
use std.textio.all; -- Imports the standard textio package.
|
|
||||||
|
|
||||||
library work;
|
|
||||||
use work.mips_types.all;
|
|
||||||
use work.mips_instr.all;
|
|
||||||
|
|
||||||
ENTITY tb_mips_top IS
|
|
||||||
END tb_mips_top;
|
|
||||||
|
|
||||||
ARCHITECTURE behavior OF tb_mips_top IS
|
|
||||||
|
|
||||||
COMPONENT mips_top
|
|
||||||
Port
|
|
||||||
(
|
|
||||||
rst : in STD_LOGIC;
|
|
||||||
clk : in STD_LOGIC;
|
|
||||||
halt : in STD_LOGIC;
|
|
||||||
imem_din : in unsigned (WORD_WIDTH-1 downto 0);
|
|
||||||
imem_addr : out unsigned (WORD_WIDTH-1 downto 0);
|
|
||||||
dmem_we : out STD_LOGIC;
|
|
||||||
dmem_re : out STD_LOGIC;
|
|
||||||
dmem_din : in unsigned (WORD_WIDTH-1 downto 0);
|
|
||||||
dmem_dout : out unsigned (WORD_WIDTH-1 downto 0);
|
|
||||||
dmem_addr : out unsigned (WORD_WIDTH-1 downto 0)
|
|
||||||
|
|
||||||
);
|
|
||||||
END COMPONENT;
|
|
||||||
|
|
||||||
COMPONENT rom
|
|
||||||
Port
|
|
||||||
(
|
|
||||||
clk : in STD_LOGIC;
|
|
||||||
addr : in word_t;
|
|
||||||
dout : out word_t
|
|
||||||
);
|
|
||||||
END COMPONENT;
|
|
||||||
|
|
||||||
COMPONENT ram
|
|
||||||
Generic
|
|
||||||
(
|
|
||||||
word_addr_width : integer
|
|
||||||
);
|
|
||||||
Port
|
|
||||||
(
|
|
||||||
clk : in STD_LOGIC;
|
|
||||||
we : in STD_LOGIC;
|
|
||||||
addr : in word_t;
|
|
||||||
din : in word_t;
|
|
||||||
dout : out word_t
|
|
||||||
);
|
|
||||||
END COMPONENT;
|
|
||||||
|
|
||||||
constant CLK_PERIOD : time := 10 ns;
|
|
||||||
|
|
||||||
signal rst : std_logic := '1';
|
|
||||||
signal clk : std_logic := '1';
|
|
||||||
signal cpu_halt : std_logic;
|
|
||||||
signal irom_data : word_t := (others => '-');
|
|
||||||
signal irom_addr : word_t;
|
|
||||||
signal dmem_din : word_t := (others => '-');
|
|
||||||
signal dmem_dout : word_t;
|
|
||||||
signal dmem_addr : word_t;
|
|
||||||
signal dmem_we : std_logic;
|
|
||||||
signal dmem_re : std_logic;
|
|
||||||
|
|
||||||
BEGIN
|
|
||||||
|
|
||||||
uut: mips_top
|
|
||||||
PORT MAP(
|
|
||||||
rst => rst,
|
|
||||||
clk => clk,
|
|
||||||
halt => cpu_halt,
|
|
||||||
imem_din => irom_data,
|
|
||||||
imem_addr => irom_addr,
|
|
||||||
dmem_we => dmem_we,
|
|
||||||
dmem_re => dmem_re,
|
|
||||||
dmem_din => dmem_din,
|
|
||||||
dmem_dout => dmem_dout,
|
|
||||||
dmem_addr => dmem_addr
|
|
||||||
);
|
|
||||||
|
|
||||||
inst_rom: rom
|
|
||||||
PORT MAP
|
|
||||||
(
|
|
||||||
clk => clk,
|
|
||||||
addr => irom_addr,
|
|
||||||
dout => irom_data
|
|
||||||
);
|
|
||||||
|
|
||||||
inst_ram: ram
|
|
||||||
GENERIC MAP
|
|
||||||
(
|
|
||||||
word_addr_width => 6
|
|
||||||
)
|
|
||||||
PORT MAP
|
|
||||||
(
|
|
||||||
clk => clk,
|
|
||||||
we => dmem_we,
|
|
||||||
addr => dmem_addr,
|
|
||||||
din => dmem_dout,
|
|
||||||
dout => dmem_din
|
|
||||||
);
|
|
||||||
|
|
||||||
CLK_GEN: process
|
|
||||||
begin
|
|
||||||
wait for CLK_PERIOD/2;
|
|
||||||
clk <= not clk;
|
|
||||||
end process;
|
|
||||||
|
|
||||||
HLT_GEN:
|
|
||||||
process(rst, clk)
|
|
||||||
subtype cnt_t is natural range 0 to 2;
|
|
||||||
variable cnt : cnt_t;
|
|
||||||
begin
|
|
||||||
if rst = '1' then
|
|
||||||
cnt := cnt_t'high;
|
|
||||||
cpu_halt <= '0';
|
|
||||||
elsif rising_edge(clk) then
|
|
||||||
cpu_halt <= '0';
|
|
||||||
if cnt /= 0 then
|
|
||||||
cnt := cnt - 1;
|
|
||||||
else
|
|
||||||
cnt := cnt_t'high;
|
|
||||||
cpu_halt <= '1';
|
|
||||||
end if;
|
|
||||||
end if;
|
|
||||||
end process;
|
|
||||||
|
|
||||||
STIMULUS: process
|
|
||||||
|
|
||||||
begin
|
|
||||||
|
|
||||||
-- for i in 0 to instr_name_array'length-1 loop
|
|
||||||
-- fprint(RESULT, L,"%d %s\n", fo(i), instr_name_array(i));
|
|
||||||
-- end loop;
|
|
||||||
|
|
||||||
wait for 3*CLK_PERIOD;
|
|
||||||
wait until rising_edge(clk);
|
|
||||||
rst <= '0';
|
|
||||||
wait for 2*CLK_PERIOD;
|
|
||||||
|
|
||||||
-- assert false report "Test finished" severity error;
|
|
||||||
wait;
|
|
||||||
|
|
||||||
end process;
|
|
||||||
|
|
||||||
END;
|
|
||||||
File diff suppressed because it is too large
Load Diff
@@ -1,8 +0,0 @@
|
|||||||
all: ramgen romgen
|
|
||||||
|
|
||||||
ramgen: src/ramgen.c
|
|
||||||
gcc -o ./ramgen.exe src/ramgen.c
|
|
||||||
|
|
||||||
romgen: src/romgen.c
|
|
||||||
gcc -o ./romgen.exe src/romgen.c
|
|
||||||
|
|
||||||
@@ -1,46 +0,0 @@
|
|||||||
#!/usr/bin/env ruby
|
|
||||||
|
|
||||||
# ----------------------------------------------------------------------
|
|
||||||
# Project: JIPS, a portable 32-bit RISC CPU written in VHDL
|
|
||||||
# This file: Insertion of code fragments into templates
|
|
||||||
#
|
|
||||||
# Copyright (C) 2008 J. Ahrensfeld
|
|
||||||
#
|
|
||||||
# This program is free software: you can redistribute it and/or modify
|
|
||||||
# it under the terms of the GNU General Public License as published by
|
|
||||||
# the Free Software Foundation, either version 3 of the License, or
|
|
||||||
# (at your option) any later version.
|
|
||||||
#
|
|
||||||
# This program is distributed in the hope that it will be useful,
|
|
||||||
# but WITHOUT ANY WARRANTY; without even the implied warranty of
|
|
||||||
# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
|
||||||
# GNU General Public License for more details.
|
|
||||||
#
|
|
||||||
# You should have received a copy of the GNU General Public License
|
|
||||||
# along with this program. If not, see <http://www.gnu.org/licenses/>.
|
|
||||||
#
|
|
||||||
# For questions and ideas, please contact the author at jens@jayfield.org
|
|
||||||
#
|
|
||||||
# ---------------------------------------------------------------------
|
|
||||||
|
|
||||||
arg = $*
|
|
||||||
rom_filename = arg[0].to_s
|
|
||||||
tpl_filename = arg[1].to_s
|
|
||||||
|
|
||||||
subst_pattern = "ROM_INSERT_HERE"
|
|
||||||
|
|
||||||
# --------------------------------------------------------
|
|
||||||
# Open file
|
|
||||||
# --------------------------------------------------------
|
|
||||||
romfile = File.open(rom_filename, "r")
|
|
||||||
tplfile = File.open(tpl_filename, "r")
|
|
||||||
re = Regexp.new(subst_pattern)
|
|
||||||
|
|
||||||
while (line = tplfile.gets)
|
|
||||||
puts line
|
|
||||||
line.scan(re).each do |word|
|
|
||||||
romfile.each do |raw_line|
|
|
||||||
puts raw_line
|
|
||||||
end
|
|
||||||
end
|
|
||||||
end
|
|
||||||
@@ -1,29 +0,0 @@
|
|||||||
-------------------------------------------------------------------------
|
|
||||||
-- Project: JIPS, a portable 32-bit RISC CPU written in VHDL
|
|
||||||
-- This file: The ROM file for use in your VHDL design
|
|
||||||
--
|
|
||||||
-- Copyright (C) 2008 J. Ahrensfeld
|
|
||||||
--
|
|
||||||
-- This program is free software: you can redistribute it and/or modify
|
|
||||||
-- it under the terms of the GNU General Public License as published by
|
|
||||||
-- the Free Software Foundation, either version 3 of the License, or
|
|
||||||
-- (at your option) any later version.
|
|
||||||
--
|
|
||||||
-- This program is distributed in the hope that it will be useful,
|
|
||||||
-- but WITHOUT ANY WARRANTY; without even the implied warranty of
|
|
||||||
-- MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
|
||||||
-- GNU General Public License for more details.
|
|
||||||
--
|
|
||||||
-- You should have received a copy of the GNU General Public License
|
|
||||||
-- along with this program. If not, see <http://www.gnu.org/licenses/>.
|
|
||||||
--
|
|
||||||
-- For questions and ideas, please contact the author at jens@jayfield.org
|
|
||||||
--
|
|
||||||
--------------------------------------------------------------------------
|
|
||||||
|
|
||||||
LIBRARY ieee;
|
|
||||||
use IEEE.STD_LOGIC_1164.ALL;
|
|
||||||
USE ieee.numeric_std.ALL;
|
|
||||||
|
|
||||||
-- ROM_INSERT_HERE
|
|
||||||
|
|
||||||
@@ -1,147 +0,0 @@
|
|||||||
-------------------------------------------------------------------------
|
|
||||||
-- Project: JIPS, a portable 32-bit RISC CPU written in VHDL
|
|
||||||
-- This file: loadable ROM
|
|
||||||
--
|
|
||||||
-- Copyright (C) 2008 J. Ahrensfeld
|
|
||||||
--
|
|
||||||
-- This program is free software: you can redistribute it and/or modify
|
|
||||||
-- it under the terms of the GNU General Public License as published by
|
|
||||||
-- the Free Software Foundation, either version 3 of the License, or
|
|
||||||
-- (at your option) any later version.
|
|
||||||
--
|
|
||||||
-- This program is distributed in the hope that it will be useful,
|
|
||||||
-- but WITHOUT ANY WARRANTY; without even the implied warranty of
|
|
||||||
-- MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
|
||||||
-- GNU General Public License for more details.
|
|
||||||
--
|
|
||||||
-- You should have received a copy of the GNU General Public License
|
|
||||||
-- along with this program. If not, see <http://www.gnu.org/licenses/>.
|
|
||||||
--
|
|
||||||
-- For questions and ideas, please contact the author at jens@jayfield.org
|
|
||||||
--
|
|
||||||
--------------------------------------------------------------------------
|
|
||||||
|
|
||||||
LIBRARY ieee;
|
|
||||||
use IEEE.STD_LOGIC_1164.ALL;
|
|
||||||
USE ieee.numeric_std.ALL;
|
|
||||||
|
|
||||||
library UNISIM;
|
|
||||||
use UNISIM.VComponents.all;
|
|
||||||
|
|
||||||
ENTITY irom IS
|
|
||||||
Port (
|
|
||||||
clk : in STD_LOGIC;
|
|
||||||
addr : in inst_addr_t;
|
|
||||||
dout : out inst_t
|
|
||||||
);
|
|
||||||
|
|
||||||
END irom;
|
|
||||||
|
|
||||||
ARCHITECTURE loadable OF irom IS
|
|
||||||
|
|
||||||
-- JASM_ROM_INSERT_HERE
|
|
||||||
|
|
||||||
signal jtag_ld_clk : STD_LOGIC;
|
|
||||||
signal jtag_ld_we : STD_LOGIC;
|
|
||||||
signal jtag_ld_addr : unsigned (15 downto 0);
|
|
||||||
signal jtag_ld_dout : unsigned (31 downto 0);
|
|
||||||
signal jtag_ld_din : unsigned (31 downto 0);
|
|
||||||
signal bs_rst, bs_sel, bs_shift, bs_tdi, bs_tdo : std_logic;
|
|
||||||
signal bs_capture, bs_clk0, bs_clk1, bs_update0, bs_update1 : std_logic;
|
|
||||||
signal user_regi, user_rego : unsigned (47 downto 0);
|
|
||||||
constant id : unsigned (47 downto 0) := X"DEAD" & X"BEEF" & "X"BABE";
|
|
||||||
|
|
||||||
begin
|
|
||||||
|
|
||||||
--------------------------------------------------------------------------
|
|
||||||
-- Virtex-4: JTAG Loader
|
|
||||||
--------------------------------------------------------------------------
|
|
||||||
i00_BUFG : BUFG
|
|
||||||
port map
|
|
||||||
(
|
|
||||||
O => bs_clk1,
|
|
||||||
I => bs_clk0
|
|
||||||
);
|
|
||||||
|
|
||||||
i01_BUFG : BUFG
|
|
||||||
port map
|
|
||||||
(
|
|
||||||
O => bs_update1,
|
|
||||||
I => bs_update0
|
|
||||||
);
|
|
||||||
|
|
||||||
BSCAN_VIRTEX4_inst1 : BSCAN_VIRTEX4
|
|
||||||
generic map
|
|
||||||
(
|
|
||||||
JTAG_CHAIN => 1 -- Value to set BSCAN site of device. Possible values: (1,2,3 or 4)
|
|
||||||
)
|
|
||||||
port map
|
|
||||||
(
|
|
||||||
CAPTURE => bs_capture, -- CAPTURE output from TAP controller
|
|
||||||
DRCK => bs_clk0, -- Data register output for USER functions
|
|
||||||
RESET => bs_rst, -- Reset output from TAP controller
|
|
||||||
SEL => bs_sel, -- USER active output
|
|
||||||
SHIFT => bs_shift, -- SHIFT output from TAP controller
|
|
||||||
TDI => bs_tdi, -- TDI output from TAP controller
|
|
||||||
UPDATE => bs_update0, -- UPDATE output from TAP controller
|
|
||||||
TDO => bs_tdo -- Data input for USER function
|
|
||||||
);
|
|
||||||
|
|
||||||
jtag_ld_addr <= user_regi(user_regi'left downto jtag_ld_dout'length);
|
|
||||||
jtag_ld_din <= user_regi(jtag_ld_dout'length-1 downto 0);
|
|
||||||
jtag_ld_clk <= bs_update1;
|
|
||||||
jtag_ld_we <= bs_sel;
|
|
||||||
|
|
||||||
sipo:
|
|
||||||
process (bs_rst, bs_clk1, bs_tdi, bs_shift)
|
|
||||||
begin
|
|
||||||
if bs_rst = '1' then
|
|
||||||
user_regi <= (others => '0');
|
|
||||||
elsif rising_edge(bs_clk1) then
|
|
||||||
if bs_shift = '1' then
|
|
||||||
user_regi <= bs_tdi & user_regi(user_regi'left downto 1);
|
|
||||||
end if;
|
|
||||||
end if;
|
|
||||||
end process;
|
|
||||||
|
|
||||||
piso:
|
|
||||||
process (bs_rst, bs_clk1, bs_shift, user_rego)
|
|
||||||
begin
|
|
||||||
bs_tdo <= user_rego(0);
|
|
||||||
if bs_rst = '1' then
|
|
||||||
user_rego <= (others => '0');
|
|
||||||
elsif rising_edge(bs_clk1) then
|
|
||||||
if bs_shift = '1' then
|
|
||||||
user_rego <= user_rego(0) & user_rego(user_rego'left downto 1);
|
|
||||||
else
|
|
||||||
user_rego <= (user_rego'left downto jtag_ld_dout'length => '0') & jtag_ld_dout;
|
|
||||||
-- user_rego <= id;
|
|
||||||
end if;
|
|
||||||
end if;
|
|
||||||
end process;
|
|
||||||
|
|
||||||
PROM_WRITE:
|
|
||||||
process(jtag_ld_clk, jtag_ld_we)
|
|
||||||
begin
|
|
||||||
if rising_edge(jtag_ld_clk) then
|
|
||||||
if jtag_ld_we = '1' then
|
|
||||||
imem_rom(to_integer(jtag_ld_addr)) <= jtag_ld_din;
|
|
||||||
else
|
|
||||||
jtag_ld_dout <= imem_rom(to_integer(jtag_ld_addr));
|
|
||||||
end if;
|
|
||||||
end if;
|
|
||||||
end process;
|
|
||||||
|
|
||||||
--------------------------------------------------------------------------
|
|
||||||
-- ROM Read/Write
|
|
||||||
--------------------------------------------------------------------------
|
|
||||||
PROM_READ:
|
|
||||||
process(clk)
|
|
||||||
begin
|
|
||||||
if rising_edge(clk) then
|
|
||||||
dout <= imem_rom(to_integer(addr));
|
|
||||||
end if;
|
|
||||||
end process;
|
|
||||||
|
|
||||||
--------------------------------------------------------------------------
|
|
||||||
end loadable;
|
|
||||||
@@ -1,50 +0,0 @@
|
|||||||
#!/bin/sh
|
|
||||||
|
|
||||||
# ----------------------------------------------------------------------
|
|
||||||
# Project: JCPU, a portable 8-bit RISC CPU written in VHDL
|
|
||||||
# This file: rom-file generation for cpu_core
|
|
||||||
#
|
|
||||||
# Copyright (C) 2007 J. Ahrensfeld
|
|
||||||
#
|
|
||||||
# This program is free software: you can redistribute it and/or modify
|
|
||||||
# it under the terms of the GNU General Public License as published by
|
|
||||||
# the Free Software Foundation, either version 3 of the License, or
|
|
||||||
# (at your option) any later version.
|
|
||||||
#
|
|
||||||
# This program is distributed in the hope that it will be useful,
|
|
||||||
# but WITHOUT ANY WARRANTY; without even the implied warranty of
|
|
||||||
# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
|
||||||
# GNU General Public License for more details.
|
|
||||||
#
|
|
||||||
# You should have received a copy of the GNU General Public License
|
|
||||||
# along with this program. If not, see <http://www.gnu.org/licenses/>.
|
|
||||||
#
|
|
||||||
# For questions and ideas, please contact the author at jens@jayfield.org
|
|
||||||
#
|
|
||||||
# ---------------------------------------------------------------------
|
|
||||||
|
|
||||||
TARGET=$2
|
|
||||||
DSTDIR=$1
|
|
||||||
|
|
||||||
JASM_HOME=/cygdrive/w/vhdl/lib/CPUs/JCpu/tools
|
|
||||||
|
|
||||||
$JASM_HOME/jasm.rb $TARGET.jsm
|
|
||||||
|
|
||||||
irom_tcl_snippet="$TARGET.irom.tcl.snip"
|
|
||||||
irom_vhdl_snippet="$TARGET.irom.vhdl.snip"
|
|
||||||
irom_ld_vhdl_snippet="$TARGET.irom_ld.vhdl.snip"
|
|
||||||
xrom_tcl_snippet="$TARGET.xrom.tcl.snip"
|
|
||||||
xrom_vhdl_snippet="$TARGET.xrom.vhdl.snip"
|
|
||||||
xrom_ld_vhdl_snippet="$TARGET.xrom_ld.vhdl.snip"
|
|
||||||
|
|
||||||
$JASM_HOME/insrom.rb $irom_vhdl_snippet $JASM_HOME/irom.vhd.tpl >$DSTDIR/$TARGET\_irom.vhdl
|
|
||||||
$JASM_HOME/insrom.rb $irom_ld_vhdl_snippet $JASM_HOME/irom_ld.vhd.tpl >$DSTDIR/$TARGET\_irom_ld.vhdl
|
|
||||||
|
|
||||||
$JASM_HOME/insrom.rb $xrom_vhdl_snippet $JASM_HOME/xrom.vhd.tpl >$DSTDIR/$TARGET\_xrom.vhdl
|
|
||||||
$JASM_HOME/insrom.rb $xrom_ld_vhdl_snippet $JASM_HOME/xrom_ld.vhd.tpl >$DSTDIR/$TARGET\_xrom_ld.vhdl
|
|
||||||
|
|
||||||
cat $irom_tcl_snippet > $TARGET.tcl.snip.snip
|
|
||||||
cat $xrom_tcl_snippet >> $TARGET.tcl.snip.snip
|
|
||||||
$JASM_HOME/insrom.rb $TARGET.tcl.snip.snip $JASM_HOME/rom.tcl.tpl >$TARGET.tcl
|
|
||||||
|
|
||||||
rm -f *.snip
|
|
||||||
@@ -1,51 +0,0 @@
|
|||||||
#!/bin/sh
|
|
||||||
|
|
||||||
# ----------------------------------------------------------------------
|
|
||||||
# Project: JCPU, a portable 8-bit RISC CPU written in VHDL
|
|
||||||
# This file: rom-file generation for cpu_core
|
|
||||||
#
|
|
||||||
# Copyright (C) 2007 J. Ahrensfeld
|
|
||||||
#
|
|
||||||
# This program is free software: you can redistribute it and/or modify
|
|
||||||
# it under the terms of the GNU General Public License as published by
|
|
||||||
# the Free Software Foundation, either version 3 of the License, or
|
|
||||||
# (at your option) any later version.
|
|
||||||
#
|
|
||||||
# This program is distributed in the hope that it will be useful,
|
|
||||||
# but WITHOUT ANY WARRANTY; without even the implied warranty of
|
|
||||||
# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
|
||||||
# GNU General Public License for more details.
|
|
||||||
#
|
|
||||||
# You should have received a copy of the GNU General Public License
|
|
||||||
# along with this program. If not, see <http://www.gnu.org/licenses/>.
|
|
||||||
#
|
|
||||||
# For questions and ideas, please contact the author at jens@jayfield.org
|
|
||||||
#
|
|
||||||
# ---------------------------------------------------------------------
|
|
||||||
# $Header: /tmp/cvsroot/VHDL/lib/CPUs/MIPS/tools/make.sh,v 1.1 2008-08-25 08:29:55 Jens Exp $
|
|
||||||
# ----------------------------------------------------------------------
|
|
||||||
TARGET=$2
|
|
||||||
DSTDIR=$1
|
|
||||||
|
|
||||||
JASM_HOME=/cygdrive/w/vhdl/lib/CPUs/JCpu/tools
|
|
||||||
|
|
||||||
$JASM_HOME/jasm.rb $TARGET.jsm
|
|
||||||
|
|
||||||
irom_tcl_snippet="$TARGET.irom.tcl.snip"
|
|
||||||
irom_vhdl_snippet="$TARGET.irom.vhdl.snip"
|
|
||||||
irom_ld_vhdl_snippet="$TARGET.irom_ld.vhdl.snip"
|
|
||||||
xrom_tcl_snippet="$TARGET.xrom.tcl.snip"
|
|
||||||
xrom_vhdl_snippet="$TARGET.xrom.vhdl.snip"
|
|
||||||
xrom_ld_vhdl_snippet="$TARGET.xrom_ld.vhdl.snip"
|
|
||||||
|
|
||||||
$JASM_HOME/insrom.rb $irom_vhdl_snippet $JASM_HOME/irom.vhd.tpl >$DSTDIR/$TARGET\_irom.vhdl
|
|
||||||
$JASM_HOME/insrom.rb $irom_ld_vhdl_snippet $JASM_HOME/irom_ld.vhd.tpl >$DSTDIR/$TARGET\_irom_ld.vhdl
|
|
||||||
|
|
||||||
$JASM_HOME/insrom.rb $xrom_vhdl_snippet $JASM_HOME/xrom.vhd.tpl >$DSTDIR/$TARGET\_xrom.vhdl
|
|
||||||
$JASM_HOME/insrom.rb $xrom_ld_vhdl_snippet $JASM_HOME/xrom_ld.vhd.tpl >$DSTDIR/$TARGET\_xrom_ld.vhdl
|
|
||||||
|
|
||||||
cat $irom_tcl_snippet > $TARGET.tcl.snip.snip
|
|
||||||
cat $xrom_tcl_snippet >> $TARGET.tcl.snip.snip
|
|
||||||
$JASM_HOME/insrom.rb $TARGET.tcl.snip.snip $JASM_HOME/rom.tcl.tpl >$TARGET.tcl
|
|
||||||
|
|
||||||
rm -f *.snip
|
|
||||||
@@ -1,61 +0,0 @@
|
|||||||
# ----------------------------------------------------------------------
|
|
||||||
# Project: JCPU, a portable 8-bit RISC CPU written in VHDL
|
|
||||||
# This file: The ROM file for upload to target over JTAG
|
|
||||||
#
|
|
||||||
# Copyright (C) 2007 J. Ahrensfeld
|
|
||||||
#
|
|
||||||
# This program is free software: you can redistribute it and/or modify
|
|
||||||
# it under the terms of the GNU General Public License as published by
|
|
||||||
# the Free Software Foundation, either version 3 of the License, or
|
|
||||||
# (at your option) any later version.
|
|
||||||
#
|
|
||||||
# This program is distributed in the hope that it will be useful,
|
|
||||||
# but WITHOUT ANY WARRANTY; without even the implied warranty of
|
|
||||||
# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
|
||||||
# GNU General Public License for more details.
|
|
||||||
#
|
|
||||||
# You should have received a copy of the GNU General Public License
|
|
||||||
# along with this program. If not, see <http://www.gnu.org/licenses/>.
|
|
||||||
#
|
|
||||||
# For questions and ideas, please contact the author at jens@jayfield.org
|
|
||||||
#
|
|
||||||
# ---------------------------------------------------------------------
|
|
||||||
|
|
||||||
# ---------------------------------------------------------------------
|
|
||||||
# For Chipscope 9.1
|
|
||||||
# ---------------------------------------------------------------------
|
|
||||||
# Source JTAG/TCL frame work
|
|
||||||
cd $env(CHIPSCOPE)\\bin\\nt
|
|
||||||
source csejtag.tcl
|
|
||||||
|
|
||||||
namespace import ::chipscope::*
|
|
||||||
|
|
||||||
# Platform USB Cable
|
|
||||||
set PLATFORM_USB_CABLE_ARGS [list "port=USB2" "frequency=6000000"]
|
|
||||||
# frequency="24000000 | 12000000 | 6000000 | 3000000 | 1500000 | 750000"
|
|
||||||
|
|
||||||
# Create session
|
|
||||||
set handle [::chipscope::csejtag_session create 0]
|
|
||||||
|
|
||||||
# Open JTAG and lock
|
|
||||||
set open_result [::chipscope::csejtag_target open $handle $CSEJTAG_TARGET_PLATFORMUSB 0 $PLATFORM_USB_CABLE_ARGS]
|
|
||||||
set lock_result [::chipscope::csejtag_target lock $handle 1000]
|
|
||||||
|
|
||||||
set devlist [::chipscope::csejtag_tap autodetect_chain $handle $CSEJTAG_SCAN_DEFAULT]
|
|
||||||
|
|
||||||
# Get Device ID
|
|
||||||
set devtype "Virtex-4SX"
|
|
||||||
set devid 2
|
|
||||||
set irlength [::chipscope::csejtag_tap get_irlength $handle $devid]
|
|
||||||
set idcode [::chipscope::csejtag_tap get_device_idcode $handle $devid]
|
|
||||||
|
|
||||||
set CSE_OP $CSEJTAG_SHIFT_READWRITE
|
|
||||||
set CSE_ES $CSEJTAG_RUN_TEST_IDLE
|
|
||||||
|
|
||||||
# Write Program
|
|
||||||
# JASM_ROM_INSERT_HERE
|
|
||||||
|
|
||||||
::chipscope::csejtag_target unlock $handle
|
|
||||||
::chipscope::csejtag_target close $handle
|
|
||||||
::chipscope::csejtag_session destroy $handle
|
|
||||||
exit
|
|
||||||
@@ -1,125 +0,0 @@
|
|||||||
#include <stdio.h>
|
|
||||||
#include <stdlib.h>
|
|
||||||
#include <string.h>
|
|
||||||
#include <math.h>
|
|
||||||
|
|
||||||
#define ARCH_NAME "data"
|
|
||||||
#define ENT_NAME "ram"
|
|
||||||
#define JTAG_ADDR_WIDTH 16
|
|
||||||
|
|
||||||
// --------------------------------------------------------------
|
|
||||||
void basename(char *pSrc, char *pDst)
|
|
||||||
{
|
|
||||||
int i, size;
|
|
||||||
|
|
||||||
size = strlen(pSrc);
|
|
||||||
|
|
||||||
while(pSrc[size] != '.')
|
|
||||||
size--;
|
|
||||||
|
|
||||||
for (i=0; i < size; i++)
|
|
||||||
pDst[i] = pSrc[i];
|
|
||||||
|
|
||||||
pDst[i] = 0;
|
|
||||||
|
|
||||||
}
|
|
||||||
|
|
||||||
int SaveRAM_TCL(char *pFilenameIn, char *pFilenameOut, char *pArchName, char *pEntName, int nbits_addr, int nbits_data)
|
|
||||||
{
|
|
||||||
FILE *pFileIn, *pFileOut;
|
|
||||||
long start, end;
|
|
||||||
int i, word, word_addr, filesize, romsize;
|
|
||||||
char binstr_addr[33];
|
|
||||||
char binstr_data[33];
|
|
||||||
|
|
||||||
char tpl[] = {"# ---------------------------------------------------------------------\n# For Chipscope 9.1\n# ---------------------------------------------------------------------\n# Source JTAG/TCL frame work\ncd $env(CHIPSCOPE)\\\\bin\\\\nt\nsource csejtag.tcl\n\nnamespace import ::chipscope::*\n\n# Platform USB Cable\nset PLATFORM_USB_CABLE_ARGS [list \"port=USB2\" \"frequency=6000000\"]\n# frequency=\"24000000 | 12000000 | 6000000 | 3000000 | 1500000 | 750000\"\n\n# Create session\nset handle [::chipscope::csejtag_session create 0]\n\n# Open JTAG and lock\nset open_result [::chipscope::csejtag_target open $handle $CSEJTAG_TARGET_PLATFORMUSB 0 $PLATFORM_USB_CABLE_ARGS]\nset lock_result [::chipscope::csejtag_target lock $handle 1000]\n\nset devlist [::chipscope::csejtag_tap autodetect_chain $handle $CSEJTAG_SCAN_DEFAULT]\n\n# Get Device ID\nset devtype \"Virtex-4SX\"\nset devid 2\nset irlength [::chipscope::csejtag_tap get_irlength $handle $devid]\nset idcode [::chipscope::csejtag_tap get_device_idcode $handle $devid]\n\nset CSE_OP $CSEJTAG_SHIFT_READWRITE\nset CSE_ES $CSEJTAG_RUN_TEST_IDLE\n\n# Write Program\n"};
|
|
||||||
|
|
||||||
pFileIn = fopen(pFilenameIn, "rb");
|
|
||||||
if (!pFileIn)
|
|
||||||
{
|
|
||||||
fprintf(stderr, "Error opening file %s\n", pFilenameIn);
|
|
||||||
return 1;
|
|
||||||
}
|
|
||||||
|
|
||||||
pFileOut = fopen(pFilenameOut, "wb");
|
|
||||||
if (!pFileOut)
|
|
||||||
{
|
|
||||||
fprintf(stderr, "Error opening file %s\n", pFilenameOut);
|
|
||||||
return 1;
|
|
||||||
}
|
|
||||||
|
|
||||||
fseek(pFileIn, 0, SEEK_SET);
|
|
||||||
start = ftell(pFileIn);
|
|
||||||
fseek(pFileIn, 0, SEEK_END);
|
|
||||||
end = ftell(pFileIn);
|
|
||||||
fseek(pFileIn, 0, SEEK_SET);
|
|
||||||
|
|
||||||
filesize = (end-start);
|
|
||||||
romsize = (int)pow(2, nbits_addr+2);
|
|
||||||
|
|
||||||
// -------------------------------------------------------------------------
|
|
||||||
// Header
|
|
||||||
|
|
||||||
// -------------------------------------------------------------------------
|
|
||||||
fputs(tpl, pFileOut);
|
|
||||||
|
|
||||||
// -------------------------------------------------------------------------
|
|
||||||
// ROM part
|
|
||||||
// -------------------------------------------------------------------------
|
|
||||||
fprintf(pFileOut, "# Assembled from %s\n", pFilenameIn);
|
|
||||||
fprintf(pFileOut, "# ---------------------------------------------------------------\n");
|
|
||||||
fprintf(pFileOut, "# Shift the USER2 Instruction (b1111000011) into the Instruction Register of FPGA\n");
|
|
||||||
fprintf(pFileOut, "# User 2\n");
|
|
||||||
fprintf(pFileOut, "set result [::chipscope::csejtag_tap shift_device_ir $handle $devid $CSE_OP $CSE_ES 0 $irlength \"3C3\"]\n\n");
|
|
||||||
|
|
||||||
word_addr = 0;
|
|
||||||
for (i=0; i < filesize; i += sizeof(int))
|
|
||||||
{
|
|
||||||
fread(&word, 1, sizeof(int), pFileIn);
|
|
||||||
fprintf(pFileOut, "::chipscope::csejtag_tap shift_device_dr $handle $devid $CSE_OP $CSE_ES 0 %d \"%4.4X%8.8X\"\n", nbits_data + JTAG_ADDR_WIDTH, word_addr, word);
|
|
||||||
word_addr++;
|
|
||||||
}
|
|
||||||
fprintf(pFileOut, "\n");
|
|
||||||
|
|
||||||
// -------------------------------------------------------------------------
|
|
||||||
// Trailer
|
|
||||||
// -------------------------------------------------------------------------
|
|
||||||
fprintf(pFileOut, "::chipscope::csejtag_target unlock $handle\n");
|
|
||||||
fprintf(pFileOut, "::chipscope::csejtag_target close $handle\n");
|
|
||||||
fprintf(pFileOut, "::chipscope::csejtag_session destroy $handle\n");
|
|
||||||
fprintf(pFileOut, "exit\n");
|
|
||||||
|
|
||||||
return 0;
|
|
||||||
}
|
|
||||||
|
|
||||||
int main(int argc, char *argv[])
|
|
||||||
{
|
|
||||||
char *pFilenameIn;
|
|
||||||
char name_prj[1024];
|
|
||||||
char name_rom_tcl[1024];
|
|
||||||
|
|
||||||
FILE *pFileIn;
|
|
||||||
int filesize, romsize, nbits_addr, nbits_data;
|
|
||||||
long start, end;
|
|
||||||
int word, i;
|
|
||||||
|
|
||||||
if (argc < 2)
|
|
||||||
{
|
|
||||||
fprintf(stderr, "Usage: romgen <input file> <num. word address bits>\n");
|
|
||||||
return 1;
|
|
||||||
}
|
|
||||||
|
|
||||||
pFilenameIn = argv[1];
|
|
||||||
if (argc == 3)
|
|
||||||
nbits_addr = atoi(argv[2]);
|
|
||||||
|
|
||||||
|
|
||||||
basename(pFilenameIn, name_prj);
|
|
||||||
sprintf(name_rom_tcl, "%s.tcl", name_prj);
|
|
||||||
|
|
||||||
SaveRAM_TCL(pFilenameIn, name_rom_tcl, ARCH_NAME, ENT_NAME, nbits_addr, 32);
|
|
||||||
|
|
||||||
|
|
||||||
return 0;
|
|
||||||
}
|
|
||||||
|
|
||||||
@@ -1,368 +0,0 @@
|
|||||||
#include <stdio.h>
|
|
||||||
#include <stdlib.h>
|
|
||||||
#include <string.h>
|
|
||||||
#include <math.h>
|
|
||||||
|
|
||||||
#define ARCH_NAME "data"
|
|
||||||
#define ENT_NAME "icache"
|
|
||||||
#define JTAG_ADDR_WIDTH 16
|
|
||||||
|
|
||||||
// --------------------------------------------------------------
|
|
||||||
void basename(char *pSrc, char *pDst)
|
|
||||||
{
|
|
||||||
int i, size;
|
|
||||||
|
|
||||||
size = strlen(pSrc);
|
|
||||||
|
|
||||||
while(pSrc[size] != '.')
|
|
||||||
size--;
|
|
||||||
|
|
||||||
for (i=0; i < size; i++)
|
|
||||||
pDst[i] = pSrc[i];
|
|
||||||
|
|
||||||
pDst[i] = 0;
|
|
||||||
|
|
||||||
}
|
|
||||||
|
|
||||||
int SaveROM(char *pFilenameIn, char *pFilenameOut, char *pArchName, char *pEntName, int nbits_addr, int nbits_data)
|
|
||||||
{
|
|
||||||
FILE *pFileIn, *pFileOut;
|
|
||||||
long start, end;
|
|
||||||
int i, word, filesize, romsize;
|
|
||||||
|
|
||||||
pFileIn = fopen(pFilenameIn, "rb");
|
|
||||||
if (!pFileIn)
|
|
||||||
{
|
|
||||||
fprintf(stderr, "Error opening file %s\n", pFilenameIn);
|
|
||||||
return 1;
|
|
||||||
}
|
|
||||||
|
|
||||||
pFileOut = fopen(pFilenameOut, "wb");
|
|
||||||
if (!pFileOut)
|
|
||||||
{
|
|
||||||
fprintf(stderr, "Error opening file %s\n", pFilenameOut);
|
|
||||||
return 1;
|
|
||||||
}
|
|
||||||
|
|
||||||
fseek(pFileIn, 0, SEEK_SET);
|
|
||||||
start = ftell(pFileIn);
|
|
||||||
fseek(pFileIn, 0, SEEK_END);
|
|
||||||
end = ftell(pFileIn);
|
|
||||||
fseek(pFileIn, 0, SEEK_SET);
|
|
||||||
|
|
||||||
filesize = (end-start);
|
|
||||||
romsize = (int)pow(2, nbits_addr+2);
|
|
||||||
|
|
||||||
// -------------------------------------------------------------------------
|
|
||||||
// Header
|
|
||||||
|
|
||||||
// -------------------------------------------------------------------------
|
|
||||||
fprintf(pFileOut, "LIBRARY IEEE;\n");
|
|
||||||
fprintf(pFileOut, "USE IEEE.STD_LOGIC_1164.ALL;\n");
|
|
||||||
fprintf(pFileOut, "USE IEEE.NUMERIC_STD.ALL;\n");
|
|
||||||
fprintf(pFileOut, "\n");
|
|
||||||
|
|
||||||
fprintf(pFileOut, "ENTITY %s IS\n", ENT_NAME);
|
|
||||||
fprintf(pFileOut, "\tPort\n");
|
|
||||||
fprintf(pFileOut, "\t(\n");
|
|
||||||
fprintf(pFileOut, "\t\tclk\t\t: in STD_LOGIC;\n");
|
|
||||||
fprintf(pFileOut, "\t\tce\t\t: in STD_LOGIC;\n");
|
|
||||||
fprintf(pFileOut, "\t\taddr\t\t: in unsigned(%d downto 0);\n", nbits_data-1);
|
|
||||||
fprintf(pFileOut, "\t\tdout\t\t: out unsigned(%d downto 0)\n", nbits_data-1);
|
|
||||||
fprintf(pFileOut, "\t);\n");
|
|
||||||
fprintf(pFileOut, "END %s;\n", ENT_NAME);
|
|
||||||
fprintf(pFileOut, "\n");
|
|
||||||
|
|
||||||
|
|
||||||
fprintf(pFileOut, "ARCHITECTURE %s OF %s IS\n", ARCH_NAME, ENT_NAME);
|
|
||||||
fprintf(pFileOut, "\n");
|
|
||||||
|
|
||||||
fprintf(pFileOut, "\tsubtype word_t is unsigned(%d downto 0);\n", nbits_data-1);
|
|
||||||
fprintf(pFileOut, "\ttype word_array_t is array (0 to %d) of word_t;\n", romsize/4-1);
|
|
||||||
|
|
||||||
fprintf(pFileOut, "\tconstant word_array : word_array_t :=\n");
|
|
||||||
fprintf(pFileOut, "\t(\n");
|
|
||||||
fprintf(pFileOut, "\n");
|
|
||||||
|
|
||||||
// -------------------------------------------------------------------------
|
|
||||||
// ROM part
|
|
||||||
// -------------------------------------------------------------------------
|
|
||||||
for (i=0; i < filesize; i += sizeof(int))
|
|
||||||
{
|
|
||||||
fread(&word, 1, sizeof(int), pFileIn);
|
|
||||||
fprintf(pFileOut, "\t\tX\"%8.8X\"", word);
|
|
||||||
if (i < (romsize-sizeof(int)))
|
|
||||||
fprintf(pFileOut, ", -- %8.8X\n", i);
|
|
||||||
else
|
|
||||||
fprintf(pFileOut, " -- %8.8X\n", i);
|
|
||||||
}
|
|
||||||
word = 0;
|
|
||||||
for (; i < romsize; i += sizeof(int))
|
|
||||||
{
|
|
||||||
fprintf(pFileOut, "\t\tX\"%8.8X\"", word);
|
|
||||||
if (i < (romsize-sizeof(int)))
|
|
||||||
fprintf(pFileOut, ", -- %8.8X\n", i);
|
|
||||||
else
|
|
||||||
fprintf(pFileOut, " -- %8.8X\n", i);
|
|
||||||
}
|
|
||||||
fprintf(pFileOut, "\t);\n");
|
|
||||||
fprintf(pFileOut, "\n");
|
|
||||||
|
|
||||||
// -------------------------------------------------------------------------
|
|
||||||
// Trailer
|
|
||||||
// -------------------------------------------------------------------------
|
|
||||||
fprintf(pFileOut, "begin\n", ARCH_NAME);
|
|
||||||
fprintf(pFileOut, "\n");
|
|
||||||
fprintf(pFileOut, "PROM_READ:\n", ARCH_NAME);
|
|
||||||
fprintf(pFileOut, "\tprocess(clk)\n");
|
|
||||||
fprintf(pFileOut, "\tbegin\n");
|
|
||||||
fprintf(pFileOut, "\t\tif rising_edge(clk) and ce = '1' then\n");
|
|
||||||
fprintf(pFileOut, "\t\t\tdout <= word_array(to_integer(addr(%d downto 2)));\n", nbits_addr+1);
|
|
||||||
fprintf(pFileOut, "\t\tend if;\n");
|
|
||||||
fprintf(pFileOut, "\tend process;\n");
|
|
||||||
fprintf(pFileOut, "\n");
|
|
||||||
fprintf(pFileOut, "end %s;\n", ARCH_NAME);
|
|
||||||
|
|
||||||
return 0;
|
|
||||||
}
|
|
||||||
|
|
||||||
int SaveROM_V4LD(char *pFilenameIn, char *pFilenameOut, char *pArchName, char *pEntName, int nbits_addr, int nbits_data)
|
|
||||||
{
|
|
||||||
FILE *pFileIn, *pFileOut;
|
|
||||||
long start, end;
|
|
||||||
int i, word, filesize, romsize;
|
|
||||||
|
|
||||||
char tpl[] = {"--------------------------------------------------------------------------\n-- Virtex-4: JTAG Loader\n--------------------------------------------------------------------------\n\ti00_BUFG : BUFG\n\tport map\n\t(\n\t\tO => bs_clk1,\n I => bs_clk0\n\t);\n\t\n\ti01_BUFG : BUFG\n\tport map\n\t(\n\t\tO => bs_update1,\n I => bs_update0\n\t);\n\n\tBSCAN_VIRTEX4_inst1 : BSCAN_VIRTEX4 \n\tgeneric map\n\t(\n\t\tJTAG_CHAIN => 1 -- Value to set BSCAN site of device. Possible values: (1,2,3 or 4)\n\t)\n\tport map \n\t(\n\t\tCAPTURE => bs_capture, -- CAPTURE output from TAP controller\n\t\tDRCK => bs_clk0, -- Data register output for USER functions\n\t\tRESET => bs_rst, -- Reset output from TAP controller\n\t\tSEL => bs_sel, -- USER active output\n\t\tSHIFT => bs_shift, -- SHIFT output from TAP controller\n\t\tTDI => bs_tdi, -- TDI output from TAP controller\n\t\tUPDATE => bs_update0, -- UPDATE output from TAP controller\n\t\tTDO => bs_tdo -- Data input for USER function\n\t);\n\n\tjtag_ld_addr <= user_regi(user_regi'left downto jtag_ld_dout'length);\n\tjtag_ld_din <= user_regi(jtag_ld_dout'length-1 downto 0);\n\tjtag_ld_clk <= bs_update1;\n\tjtag_ld_we <= bs_sel;\n\t\nsipo:\n\tprocess (bs_rst, bs_clk1, bs_tdi, bs_shift)\n\tbegin\n\t\tif bs_rst = '1' then\n\t\t\tuser_regi <= (others => '0');\n\t\telsif rising_edge(bs_clk1) then\n\t\t\tif bs_shift = '1' then\n\t\t\t\tuser_regi <= bs_tdi & user_regi(user_regi'left downto 1);\n\t\t\tend if;\n\t\tend if;\n\tend process;\t\n\npiso:\n\tprocess (bs_rst, bs_clk1, bs_shift, user_rego)\n\tbegin\n\t\tbs_tdo <= user_rego(0);\n\t\tif bs_rst = '1' then\n\t\t\tuser_rego <= (others => '0');\n\t\telsif rising_edge(bs_clk1) then\n\t\t\tif bs_shift = '1' then\n\t\t\t\tuser_rego <= user_rego(0) & user_rego(user_rego'left downto 1);\n\t\t\telse\n\t\t\t\tuser_rego <= (user_rego'left downto jtag_ld_dout'length => '0') & jtag_ld_dout;\t\n\t\n\t\t\tend if;\n\t\tend if;\n\tend process;\n\n"};
|
|
||||||
|
|
||||||
pFileIn = fopen(pFilenameIn, "rb");
|
|
||||||
if (!pFileIn)
|
|
||||||
{
|
|
||||||
fprintf(stderr, "Error opening file %s\n", pFilenameIn);
|
|
||||||
return 1;
|
|
||||||
}
|
|
||||||
|
|
||||||
pFileOut = fopen(pFilenameOut, "wb");
|
|
||||||
if (!pFileOut)
|
|
||||||
{
|
|
||||||
fprintf(stderr, "Error opening file %s\n", pFilenameOut);
|
|
||||||
return 1;
|
|
||||||
}
|
|
||||||
|
|
||||||
fseek(pFileIn, 0, SEEK_SET);
|
|
||||||
start = ftell(pFileIn);
|
|
||||||
fseek(pFileIn, 0, SEEK_END);
|
|
||||||
end = ftell(pFileIn);
|
|
||||||
fseek(pFileIn, 0, SEEK_SET);
|
|
||||||
|
|
||||||
filesize = (end-start);
|
|
||||||
romsize = (int)pow(2, nbits_addr+2);
|
|
||||||
|
|
||||||
// -------------------------------------------------------------------------
|
|
||||||
// Header
|
|
||||||
|
|
||||||
// -------------------------------------------------------------------------
|
|
||||||
fprintf(pFileOut, "LIBRARY IEEE;\n");
|
|
||||||
fprintf(pFileOut, "USE IEEE.STD_LOGIC_1164.ALL;\n");
|
|
||||||
fprintf(pFileOut, "USE IEEE.NUMERIC_STD.ALL;\n");
|
|
||||||
fprintf(pFileOut, "\n");
|
|
||||||
|
|
||||||
fprintf(pFileOut, "library UNISIM;\n");
|
|
||||||
fprintf(pFileOut, "use UNISIM.VComponents.all;\n");
|
|
||||||
fprintf(pFileOut, "\n");
|
|
||||||
|
|
||||||
fprintf(pFileOut, "ENTITY %s IS\n", ENT_NAME);
|
|
||||||
fprintf(pFileOut, "\tPort\n");
|
|
||||||
fprintf(pFileOut, "\t(\n");
|
|
||||||
fprintf(pFileOut, "\t\tclk\t\t: in STD_LOGIC;\n");
|
|
||||||
fprintf(pFileOut, "\t\tce\t\t: in STD_LOGIC;\n");
|
|
||||||
fprintf(pFileOut, "\t\taddr\t\t: in unsigned(%d downto 0);\n", nbits_data-1);
|
|
||||||
fprintf(pFileOut, "\t\tdout\t\t: out unsigned(%d downto 0)\n", nbits_data-1);
|
|
||||||
fprintf(pFileOut, "\t);\n");
|
|
||||||
fprintf(pFileOut, "END %s;\n", ENT_NAME);
|
|
||||||
fprintf(pFileOut, "\n");
|
|
||||||
|
|
||||||
|
|
||||||
fprintf(pFileOut, "ARCHITECTURE %s OF %s IS\n", ARCH_NAME, ENT_NAME);
|
|
||||||
fprintf(pFileOut, "\n");
|
|
||||||
|
|
||||||
fprintf(pFileOut, "\tsubtype word_t is unsigned(%d downto 0);\n", nbits_data-1);
|
|
||||||
fprintf(pFileOut, "\ttype word_array_t is array (0 to %d) of word_t;\n", romsize/4-1);
|
|
||||||
|
|
||||||
fprintf(pFileOut, "\tsignal jtag_ld_clk\t\t: STD_LOGIC;\n");
|
|
||||||
fprintf(pFileOut, "\tsignal jtag_ld_we\t\t: STD_LOGIC;\n");
|
|
||||||
fprintf(pFileOut, "\tsignal jtag_ld_addr\t\t: unsigned (%d downto 0);\n", JTAG_ADDR_WIDTH-1);
|
|
||||||
fprintf(pFileOut, "\tsignal jtag_ld_dout\t\t: unsigned (%d downto 0);\n", nbits_data-1);
|
|
||||||
fprintf(pFileOut, "\tsignal jtag_ld_din\t\t: unsigned (%d downto 0);\n", nbits_data-1);
|
|
||||||
fprintf(pFileOut, "\tsignal bs_rst, bs_sel, bs_shift, bs_tdi, bs_tdo : std_logic;\n");
|
|
||||||
fprintf(pFileOut, "\tsignal bs_capture, bs_clk0, bs_clk1, bs_update0, bs_update1 : std_logic;\n");
|
|
||||||
fprintf(pFileOut, "\tsignal user_regi, user_rego : unsigned (%d downto 0);\n", 31 + JTAG_ADDR_WIDTH);
|
|
||||||
fprintf(pFileOut, "\n");
|
|
||||||
|
|
||||||
fprintf(pFileOut, "\tsignal word_array : word_array_t :=\n");
|
|
||||||
fprintf(pFileOut, "\t(\n");
|
|
||||||
fprintf(pFileOut, "\n");
|
|
||||||
|
|
||||||
// -------------------------------------------------------------------------
|
|
||||||
// ROM part
|
|
||||||
// -------------------------------------------------------------------------
|
|
||||||
for (i=0; i < filesize; i += sizeof(int))
|
|
||||||
{
|
|
||||||
fread(&word, 1, sizeof(int), pFileIn);
|
|
||||||
fprintf(pFileOut, "\t\tX\"%8.8X\"", word);
|
|
||||||
if (i < (romsize-sizeof(int)))
|
|
||||||
fprintf(pFileOut, ", -- %8.8X\n", i);
|
|
||||||
else
|
|
||||||
fprintf(pFileOut, " -- %8.8X\n", i);
|
|
||||||
}
|
|
||||||
word = 0;
|
|
||||||
for (; i < romsize; i += sizeof(int))
|
|
||||||
{
|
|
||||||
fprintf(pFileOut, "\t\tX\"%8.8X\"", word);
|
|
||||||
if (i < (romsize-sizeof(int)))
|
|
||||||
fprintf(pFileOut, ", -- %8.8X\n", i);
|
|
||||||
else
|
|
||||||
fprintf(pFileOut, " -- %8.8X\n", i);
|
|
||||||
}
|
|
||||||
fprintf(pFileOut, "\t);\n");
|
|
||||||
fprintf(pFileOut, "\n");
|
|
||||||
|
|
||||||
fprintf(pFileOut, "begin\n", ARCH_NAME);
|
|
||||||
|
|
||||||
fprintf(pFileOut, "\n");
|
|
||||||
fprintf(pFileOut, "PROM_READ:\n", ARCH_NAME);
|
|
||||||
fprintf(pFileOut, "\tprocess(clk)\n");
|
|
||||||
fprintf(pFileOut, "\tbegin\n");
|
|
||||||
fprintf(pFileOut, "\t\tif rising_edge(clk) and ce = '1' then\n");
|
|
||||||
fprintf(pFileOut, "\t\t\tdout <= word_array(to_integer(addr(%d downto 2)));\n", nbits_addr+1);
|
|
||||||
fprintf(pFileOut, "\t\tend if;\n");
|
|
||||||
fprintf(pFileOut, "\tend process;\n");
|
|
||||||
fprintf(pFileOut, "\n");
|
|
||||||
|
|
||||||
// -------------------------------------------------------------------------
|
|
||||||
// Trailer
|
|
||||||
// -------------------------------------------------------------------------
|
|
||||||
fprintf(pFileOut, "\n");
|
|
||||||
fputs(tpl, pFileOut);
|
|
||||||
|
|
||||||
fprintf(pFileOut, "PROM_WRITE:\n", ARCH_NAME);
|
|
||||||
fprintf(pFileOut, "\tprocess(jtag_ld_clk, jtag_ld_we)\n");
|
|
||||||
fprintf(pFileOut, "\tbegin\n");
|
|
||||||
fprintf(pFileOut, "\t\tif rising_edge(jtag_ld_clk) then\n");
|
|
||||||
fprintf(pFileOut, "\t\t\tif jtag_ld_we = '1' then\n");
|
|
||||||
fprintf(pFileOut, "\t\t\t\tword_array(to_integer(jtag_ld_addr(%d downto 0))) <= jtag_ld_din;\n", nbits_addr-1);
|
|
||||||
fprintf(pFileOut, "\t\t\telse\n");
|
|
||||||
fprintf(pFileOut, "\t\t\t\tjtag_ld_dout <= word_array(to_integer(jtag_ld_addr(%d downto 0)));\n", nbits_addr-1);
|
|
||||||
fprintf(pFileOut, "\t\t\tend if;\n");
|
|
||||||
fprintf(pFileOut, "\t\tend if;\n");
|
|
||||||
fprintf(pFileOut, "\tend process;\n");
|
|
||||||
fprintf(pFileOut, "\n");
|
|
||||||
|
|
||||||
fprintf(pFileOut, "end %s;\n", ARCH_NAME);
|
|
||||||
return 0;
|
|
||||||
}
|
|
||||||
|
|
||||||
int SaveROM_TCL(char *pFilenameIn, char *pFilenameOut, char *pArchName, char *pEntName, int nbits_addr, int nbits_data)
|
|
||||||
{
|
|
||||||
FILE *pFileIn, *pFileOut;
|
|
||||||
long start, end;
|
|
||||||
int i, word, word_addr, filesize, romsize;
|
|
||||||
char binstr_addr[33];
|
|
||||||
char binstr_data[33];
|
|
||||||
|
|
||||||
char tpl[] = {"# ---------------------------------------------------------------------\n# For Chipscope 9.1\n# ---------------------------------------------------------------------\n# Source JTAG/TCL frame work\ncd $env(CHIPSCOPE)\\\\bin\\\\nt\nsource csejtag.tcl\n\nnamespace import ::chipscope::*\n\n# Platform USB Cable\nset PLATFORM_USB_CABLE_ARGS [list \"port=USB2\" \"frequency=6000000\"]\n# frequency=\"24000000 | 12000000 | 6000000 | 3000000 | 1500000 | 750000\"\n\n# Create session\nset handle [::chipscope::csejtag_session create 0]\n\n# Open JTAG and lock\nset open_result [::chipscope::csejtag_target open $handle $CSEJTAG_TARGET_PLATFORMUSB 0 $PLATFORM_USB_CABLE_ARGS]\nset lock_result [::chipscope::csejtag_target lock $handle 1000]\n\nset devlist [::chipscope::csejtag_tap autodetect_chain $handle $CSEJTAG_SCAN_DEFAULT]\n\n# Get Device ID\nset devtype \"Virtex-4SX\"\nset devid 2\nset irlength [::chipscope::csejtag_tap get_irlength $handle $devid]\nset idcode [::chipscope::csejtag_tap get_device_idcode $handle $devid]\n\nset CSE_OP $CSEJTAG_SHIFT_READWRITE\nset CSE_ES $CSEJTAG_RUN_TEST_IDLE\n\n# Write Program\n"};
|
|
||||||
|
|
||||||
pFileIn = fopen(pFilenameIn, "rb");
|
|
||||||
if (!pFileIn)
|
|
||||||
{
|
|
||||||
fprintf(stderr, "Error opening file %s\n", pFilenameIn);
|
|
||||||
return 1;
|
|
||||||
}
|
|
||||||
|
|
||||||
pFileOut = fopen(pFilenameOut, "wb");
|
|
||||||
if (!pFileOut)
|
|
||||||
{
|
|
||||||
fprintf(stderr, "Error opening file %s\n", pFilenameOut);
|
|
||||||
return 1;
|
|
||||||
}
|
|
||||||
|
|
||||||
fseek(pFileIn, 0, SEEK_SET);
|
|
||||||
start = ftell(pFileIn);
|
|
||||||
fseek(pFileIn, 0, SEEK_END);
|
|
||||||
end = ftell(pFileIn);
|
|
||||||
fseek(pFileIn, 0, SEEK_SET);
|
|
||||||
|
|
||||||
filesize = (end-start);
|
|
||||||
romsize = (int)pow(2, nbits_addr+2);
|
|
||||||
|
|
||||||
// -------------------------------------------------------------------------
|
|
||||||
// Header
|
|
||||||
|
|
||||||
// -------------------------------------------------------------------------
|
|
||||||
fputs(tpl, pFileOut);
|
|
||||||
|
|
||||||
// -------------------------------------------------------------------------
|
|
||||||
// ROM part
|
|
||||||
// -------------------------------------------------------------------------
|
|
||||||
fprintf(pFileOut, "# Assembled from %s\n", pFilenameIn);
|
|
||||||
fprintf(pFileOut, "# ---------------------------------------------------------------\n");
|
|
||||||
fprintf(pFileOut, "# Shift the USER1 Instruction (b1111000010) into the Instruction Register of FPGA\n");
|
|
||||||
fprintf(pFileOut, "# User 1\n");
|
|
||||||
fprintf(pFileOut, "set result [::chipscope::csejtag_tap shift_device_ir $handle $devid $CSE_OP $CSE_ES 0 $irlength \"3C2\"]\n\n");
|
|
||||||
|
|
||||||
word_addr = 0;
|
|
||||||
for (i=0; i < filesize; i += sizeof(int))
|
|
||||||
{
|
|
||||||
fread(&word, 1, sizeof(int), pFileIn);
|
|
||||||
fprintf(pFileOut, "::chipscope::csejtag_tap shift_device_dr $handle $devid $CSE_OP $CSE_ES 0 %d \"%4.4X%8.8X\"\n", nbits_data + JTAG_ADDR_WIDTH, word_addr, word);
|
|
||||||
word_addr++;
|
|
||||||
}
|
|
||||||
fprintf(pFileOut, "\n");
|
|
||||||
|
|
||||||
// -------------------------------------------------------------------------
|
|
||||||
// Trailer
|
|
||||||
// -------------------------------------------------------------------------
|
|
||||||
fprintf(pFileOut, "::chipscope::csejtag_target unlock $handle\n");
|
|
||||||
fprintf(pFileOut, "::chipscope::csejtag_target close $handle\n");
|
|
||||||
fprintf(pFileOut, "::chipscope::csejtag_session destroy $handle\n");
|
|
||||||
fprintf(pFileOut, "exit\n");
|
|
||||||
|
|
||||||
return 0;
|
|
||||||
}
|
|
||||||
|
|
||||||
int main(int argc, char *argv[])
|
|
||||||
{
|
|
||||||
char *pFilenameIn;
|
|
||||||
char name_prj[1024];
|
|
||||||
char name_rom[1024];
|
|
||||||
char name_rom_v4ld[1024];
|
|
||||||
char name_rom_tcl[1024];
|
|
||||||
|
|
||||||
FILE *pFileIn;
|
|
||||||
int filesize, romsize, nbits_addr, nbits_data;
|
|
||||||
long start, end;
|
|
||||||
int word, i;
|
|
||||||
|
|
||||||
if (argc < 2)
|
|
||||||
{
|
|
||||||
fprintf(stderr, "Usage: romgen <input file> <num. word address bits>\n");
|
|
||||||
return 1;
|
|
||||||
}
|
|
||||||
|
|
||||||
pFilenameIn = argv[1];
|
|
||||||
if (argc == 3)
|
|
||||||
nbits_addr = atoi(argv[2]);
|
|
||||||
|
|
||||||
|
|
||||||
basename(pFilenameIn, name_prj);
|
|
||||||
sprintf(name_rom, "%s.vhd", name_prj);
|
|
||||||
sprintf(name_rom_v4ld, "%s_ld.vhd", name_prj);
|
|
||||||
sprintf(name_rom_tcl, "%s.tcl", name_prj);
|
|
||||||
|
|
||||||
SaveROM(pFilenameIn, name_rom, ARCH_NAME, ENT_NAME, nbits_addr, 32);
|
|
||||||
SaveROM_V4LD(pFilenameIn, name_rom_v4ld, ARCH_NAME, ENT_NAME, nbits_addr, 32);
|
|
||||||
SaveROM_TCL(pFilenameIn, name_rom_tcl, ARCH_NAME, ENT_NAME, nbits_addr, 32);
|
|
||||||
|
|
||||||
|
|
||||||
return 0;
|
|
||||||
}
|
|
||||||
|
|
||||||
Reference in New Issue
Block a user