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 |
Binary file not shown.
@@ -1,8 +0,0 @@
|
|||||||
vlib simprim
|
|
||||||
|
|
||||||
set XILINX C:/Programme/Xilinx101/ISE
|
|
||||||
|
|
||||||
vcom -93 -work simprim $XILINX/vhdl/src/simprims/simprim_Vcomponents_mti.vhd
|
|
||||||
vcom -93 -work simprim $XILINX/vhdl/src/simprims/simprim_Vpackage_mti.vhd
|
|
||||||
vcom -93 -work simprim $XILINX/vhdl/src/simprims/simprim_SMODEL_mti.vhd
|
|
||||||
vcom -93 -work simprim $XILINX/vhdl/src/simprims/simprim_VITAL_mti.vhd
|
|
||||||
@@ -1,8 +0,0 @@
|
|||||||
vlib unisim
|
|
||||||
|
|
||||||
set XILINX C:/Programme/Xilinx101/ISE
|
|
||||||
|
|
||||||
vcom -93 -work unisim $XILINX/vhdl/src/unisims/unisim_vpkg.vhd
|
|
||||||
vcom -93 -work unisim $XILINX/vhdl/src/unisims/unisim_vcomp.vhd
|
|
||||||
vcom -93 -work unisim $XILINX/vhdl/src/unisims/unisim_smodel.vhd
|
|
||||||
vcom -93 -work unisim $XILINX/vhdl/src/unisims/unisim_vital.vhd
|
|
||||||
@@ -1,675 +0,0 @@
|
|||||||
#
|
|
||||||
# XILINX IS PROVIDING THIS DESIGN, CODE, OR INFORMATION "AS IS"
|
|
||||||
# SOLELY FOR USE IN DEVELOPING PROGRAMS AND SOLUTIONS FOR
|
|
||||||
# XILINX DEVICES. BY PROVIDING THIS DESIGN, CODE, OR INFORMATION
|
|
||||||
# AS ONE POSSIBLE IMPLEMENTATION OF THIS FEATURE, APPLICATION
|
|
||||||
# OR STANDARD, XILINX IS MAKING NO REPRESENTATION THAT THIS
|
|
||||||
# IMPLEMENTATION IS FREE FROM ANY CLAIMS OF INFRINGEMENT,
|
|
||||||
# AND YOU ARE RESPONSIBLE FOR OBTAINING ANY RIGHTS YOU MAY REQUIRE
|
|
||||||
# FOR YOUR IMPLEMENTATION. XILINX EXPRESSLY DISCLAIMS ANY
|
|
||||||
# WARRANTY WHATSOEVER WITH RESPECT TO THE ADEQUACY OF THE
|
|
||||||
# IMPLEMENTATION, INCLUDING BUT NOT LIMITED TO ANY WARRANTIES OR
|
|
||||||
# REPRESENTATIONS THAT THIS IMPLEMENTATION IS FREE FROM CLAIMS OF
|
|
||||||
# INFRINGEMENT, IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS
|
|
||||||
# FOR A PARTICULAR PURPOSE.
|
|
||||||
#
|
|
||||||
# (c) Copyright 2005 Xilinx, Inc.
|
|
||||||
# All rights reserved.
|
|
||||||
#
|
|
||||||
|
|
||||||
# Bus clock nets
|
|
||||||
NET "sys_clk" TNM_NET = "sys_clk";
|
|
||||||
NET "tft_clk" TNM_NET = "tft_clk";
|
|
||||||
NET sys_clk_in TNM_NET = "sys_clk_in";
|
|
||||||
TIMESPEC "TSSYSCLK" = PERIOD "sys_clk_in" 9.9 ns HIGH 50 %;
|
|
||||||
|
|
||||||
NET sys_clk_in LOC = AE14;
|
|
||||||
NET sys_clk_in IOSTANDARD = LVCMOS33;
|
|
||||||
NET sys_rst_in LOC = D6;
|
|
||||||
NET sys_rst_in PULLUP;
|
|
||||||
NET sys_rst_in TIG;
|
|
||||||
|
|
||||||
NET uart_RX LOC = W2;
|
|
||||||
NET uart_RX IOSTANDARD = LVCMOS33;
|
|
||||||
NET uart_RX TIG;
|
|
||||||
NET uart_TX LOC = W1;
|
|
||||||
NET uart_TX IOSTANDARD = LVCMOS33;
|
|
||||||
NET uart_TX TIG;
|
|
||||||
|
|
||||||
NET ext_irq TIG;
|
|
||||||
|
|
||||||
# Reset timing ignore - treat as async paths
|
|
||||||
NET sys_rst TIG;
|
|
||||||
NET opb_v20_0_OPB_Rst TIG;
|
|
||||||
NET lmb_v10_1_OPB_Rst TIG;
|
|
||||||
NET lmb_v10_0_OPB_Rst TIG;
|
|
||||||
NET opb_v20_0_Debug_SYS_Rst TIG;
|
|
||||||
NET Debug_Rst TIG;
|
|
||||||
NET plb_v34_0_PLB_Rst TIG;
|
|
||||||
NET dcm_locked TIG;
|
|
||||||
|
|
||||||
# Locate DCM/BUFG - Tools can probably figure them out automatically
|
|
||||||
# but just LOC them down to be safe
|
|
||||||
INST dcm_0/dcm_0/DCM_ADV_INST LOC = DCM_ADV_X0Y2;
|
|
||||||
INST dcm_1/dcm_1/DCM_ADV_INST LOC = DCM_ADV_X0Y4;
|
|
||||||
INST dcm_2/dcm_2/DCM_ADV_INST LOC = DCM_ADV_X0Y1;
|
|
||||||
|
|
||||||
INST dcm_0/dcm_0/CLK0_BUFG_INST LOC = BUFGCTRL_X0Y0;
|
|
||||||
INST dcm_0/dcm_0/CLK90_BUFG_INST LOC = BUFGCTRL_X0Y1;
|
|
||||||
INST dcm_0/dcm_0/CLKDV_BUFG_INST LOC = BUFGCTRL_X0Y2;
|
|
||||||
|
|
||||||
INST dcm_1/dcm_1/CLK0_BUFG_INST LOC = BUFGCTRL_X0Y31;
|
|
||||||
INST dcm_1/dcm_1/CLK90_BUFG_INST LOC = BUFGCTRL_X0Y30;
|
|
||||||
|
|
||||||
////////////////////////////////////////////////////////////////////////////
|
|
||||||
// Buttons, LEDs, and DIP Switches
|
|
||||||
////////////////////////////////////////////////////////////////////////////
|
|
||||||
|
|
||||||
# GPLED 0-3
|
|
||||||
NET gpio<0> LOC = G5; #GPLED0
|
|
||||||
NET gpio<1> LOC = G6; #GPLED1
|
|
||||||
NET gpio<2> LOC = A11; #GPLED2
|
|
||||||
NET gpio<3> LOC = A12; #GPLED3
|
|
||||||
# North-East-South-West-Center LEDs
|
|
||||||
NET gpio<4> LOC = C6; # C LED
|
|
||||||
NET gpio<5> LOC = F9; # W LED
|
|
||||||
NET gpio<6> LOC = A5; # S LED
|
|
||||||
NET gpio<7> LOC = E10; # E LED
|
|
||||||
NET gpio<8> LOC = E2; # N LED
|
|
||||||
# North-East-South-West-Center Buttons
|
|
||||||
NET gpio<9> LOC = B6; # C Button
|
|
||||||
NET gpio<10> LOC = E9; # W Button
|
|
||||||
NET gpio<11> LOC = A6; # S Button
|
|
||||||
NET gpio<12> LOC = F10; # E Button
|
|
||||||
NET gpio<13> LOC = E7; # N Button
|
|
||||||
# Dip Switches 1-8
|
|
||||||
NET gpio<14> LOC = U24; # DIP SW 8
|
|
||||||
NET gpio<15> LOC = U25; # DIP SW 7
|
|
||||||
NET gpio<16> LOC = V23; # DIP SW 6
|
|
||||||
NET gpio<17> LOC = U23; # DIP SW 5
|
|
||||||
NET gpio<18> LOC = U26; # DIP SW 4
|
|
||||||
NET gpio<19> LOC = T26; # DIP SW 3
|
|
||||||
NET gpio<20> LOC = R19; # DIP SW 2
|
|
||||||
NET gpio<21> LOC = R20; # DIP SW 1
|
|
||||||
NET gpio<14> IOSTANDARD = LVCMOS33;
|
|
||||||
NET gpio<15> IOSTANDARD = LVCMOS33;
|
|
||||||
NET gpio<16> IOSTANDARD = LVCMOS33;
|
|
||||||
NET gpio<17> IOSTANDARD = LVCMOS33;
|
|
||||||
NET gpio<18> IOSTANDARD = LVCMOS33;
|
|
||||||
NET gpio<19> IOSTANDARD = LVCMOS33;
|
|
||||||
NET gpio<20> IOSTANDARD = LVCMOS33;
|
|
||||||
NET gpio<21> IOSTANDARD = LVCMOS33;
|
|
||||||
#SMA Connectors
|
|
||||||
NET gpio<22> LOC = C12; # SMA_IN_N
|
|
||||||
NET gpio<23> LOC = C13; # SMA_IN_P
|
|
||||||
NET gpio<24> LOC = D7; # SMA_OUT_N
|
|
||||||
NET gpio<25> LOC = D8; # SMA_OUT_P
|
|
||||||
NET gpio<26> LOC = AD12;# USERCLK
|
|
||||||
NET gpio<26> IOSTANDARD = LVCMOS33;
|
|
||||||
|
|
||||||
NET "gpio<*>" PULLDOWN;
|
|
||||||
NET "gpio<*>" TIG;
|
|
||||||
NET "gpio<*>" SLEW = SLOW;
|
|
||||||
NET "gpio<*>" DRIVE = 2;
|
|
||||||
|
|
||||||
NET "gpio<22>" SLEW = FAST;
|
|
||||||
NET "gpio<22>" DRIVE = 12;
|
|
||||||
NET "gpio<23>" SLEW = FAST;
|
|
||||||
NET "gpio<23>" DRIVE = 12;
|
|
||||||
NET "gpio<24>" SLEW = FAST;
|
|
||||||
NET "gpio<24>" DRIVE = 12;
|
|
||||||
NET "gpio<25>" SLEW = FAST;
|
|
||||||
NET "gpio<25>" DRIVE = 12;
|
|
||||||
|
|
||||||
NET "gpio2_d_out<*>" TIG;
|
|
||||||
NET "gpio2_t_out<*>" TIG;
|
|
||||||
NET "gpio2_in<*>" TIG;
|
|
||||||
|
|
||||||
#------------------------------------------------------------------------------
|
|
||||||
# IO Pad Location Constraints / Properties for PS/2 Ports
|
|
||||||
#------------------------------------------------------------------------------
|
|
||||||
|
|
||||||
#Keyboard
|
|
||||||
NET ps2_keyb_clk LOC = D2;
|
|
||||||
NET ps2_keyb_clk SLEW = SLOW;
|
|
||||||
NET ps2_keyb_clk DRIVE = 2;
|
|
||||||
NET ps2_keyb_clk TIG;
|
|
||||||
NET ps2_keyb_data LOC = G9;
|
|
||||||
NET ps2_keyb_data SLEW = SLOW;
|
|
||||||
NET ps2_keyb_data DRIVE = 2;
|
|
||||||
NET ps2_keyb_data TIG;
|
|
||||||
|
|
||||||
#Mouse
|
|
||||||
NET ps2_mouse_clk LOC = B14;
|
|
||||||
NET ps2_mouse_clk SLEW = SLOW;
|
|
||||||
NET ps2_mouse_clk DRIVE = 2;
|
|
||||||
NET ps2_mouse_clk TIG;
|
|
||||||
NET ps2_mouse_data LOC = C14;
|
|
||||||
NET ps2_mouse_data SLEW = SLOW;
|
|
||||||
NET ps2_mouse_data DRIVE = 2;
|
|
||||||
NET ps2_mouse_data TIG;
|
|
||||||
|
|
||||||
#------------------------------------------------------------------------------
|
|
||||||
# IO Pad Location Constraints / Properties for IIC Controller
|
|
||||||
#------------------------------------------------------------------------------
|
|
||||||
|
|
||||||
NET iic_scl LOC = A17;
|
|
||||||
NET iic_sda LOC = B17;
|
|
||||||
NET iic_scl SLEW = SLOW;
|
|
||||||
NET iic_scl DRIVE = 6;
|
|
||||||
NET iic_scl TIG;
|
|
||||||
NET iic_sda SLEW = SLOW;
|
|
||||||
NET iic_sda DRIVE = 6;
|
|
||||||
NET iic_sda TIG;
|
|
||||||
|
|
||||||
#------------------------------------------------------------------------------
|
|
||||||
# IO Pad Location Constraints / Properties for AC97 Sound Controller
|
|
||||||
#------------------------------------------------------------------------------
|
|
||||||
|
|
||||||
NET ac97_bit_clk LOC = AE10;
|
|
||||||
NET ac97_bit_clk IOSTANDARD = LVCMOS33;
|
|
||||||
NET ac97_bit_clk PERIOD = 80;
|
|
||||||
NET ac97_sdata_in LOC = AD16;
|
|
||||||
NET ac97_sdata_in IOSTANDARD = LVCMOS33;
|
|
||||||
NET ac97_reset_n LOC = AD10;
|
|
||||||
NET ac97_reset_n IOSTANDARD = LVCMOS33;
|
|
||||||
NET ac97_reset_n TIG;
|
|
||||||
NET ac97_sdata_out LOC = C8;
|
|
||||||
NET ac97_sync LOC = D9;
|
|
||||||
|
|
||||||
#------------------------------------------------------------------------------
|
|
||||||
# IO Pad Location Constraints / Properties for System ACE MPU / USB
|
|
||||||
#------------------------------------------------------------------------------
|
|
||||||
|
|
||||||
NET sysace_clk_in LOC = AF11;
|
|
||||||
NET sysace_clk_in IOSTANDARD = LVCMOS33;
|
|
||||||
NET sysace_clk_in TNM_NET = "sysace_clk_in";
|
|
||||||
# Leave 1 ns margin
|
|
||||||
TIMESPEC "TSSYSACE" = PERIOD "sysace_clk_in" 29 ns;
|
|
||||||
|
|
||||||
NET sace_usb_a<0> LOC = U22;
|
|
||||||
NET sace_usb_a<1> LOC = Y10;
|
|
||||||
NET sace_usb_a<2> LOC = AA10;
|
|
||||||
NET sace_usb_a<3> LOC = AC7;
|
|
||||||
NET sace_usb_a<4> LOC = Y7;
|
|
||||||
NET sace_usb_a<5> LOC = AA9;
|
|
||||||
NET sace_usb_a<6> LOC = Y9;
|
|
||||||
NET sace_usb_a<*> IOSTANDARD = LVCMOS33;
|
|
||||||
NET sace_usb_a<*> SLEW = FAST;
|
|
||||||
NET sace_usb_a<*> DRIVE = 8;
|
|
||||||
NET sace_mpce LOC = AD5;
|
|
||||||
NET sace_mpce IOSTANDARD = LVCMOS33;
|
|
||||||
NET sace_mpce SLEW = FAST;
|
|
||||||
NET sace_mpce DRIVE = 8;
|
|
||||||
NET sace_usb_d<0> LOC = AB7;
|
|
||||||
NET sace_usb_d<1> LOC = AC9;
|
|
||||||
NET sace_usb_d<2> LOC = AB9;
|
|
||||||
NET sace_usb_d<3> LOC = AE6;
|
|
||||||
NET sace_usb_d<4> LOC = AD6;
|
|
||||||
NET sace_usb_d<5> LOC = AF9;
|
|
||||||
NET sace_usb_d<6> LOC = AE9;
|
|
||||||
NET sace_usb_d<7> LOC = AD8;
|
|
||||||
NET sace_usb_d<8> LOC = AC8;
|
|
||||||
NET sace_usb_d<9> LOC = AF4;
|
|
||||||
NET sace_usb_d<10> LOC = AE4;
|
|
||||||
NET sace_usb_d<11> LOC = AD3;
|
|
||||||
NET sace_usb_d<12> LOC = AC3;
|
|
||||||
NET sace_usb_d<13> LOC = AF6;
|
|
||||||
NET sace_usb_d<14> LOC = AF5;
|
|
||||||
NET sace_usb_d<15> LOC = AA7;
|
|
||||||
NET sace_usb_d<*> IOSTANDARD = LVCMOS33;
|
|
||||||
NET sace_usb_d<*> SLEW = FAST;
|
|
||||||
NET sace_usb_d<*> DRIVE = 8;
|
|
||||||
NET sace_usb_d<*> PULLDOWN;
|
|
||||||
NET sace_usb_oen LOC = AA8;
|
|
||||||
NET sace_usb_oen IOSTANDARD = LVCMOS33;
|
|
||||||
NET sace_usb_oen SLEW = FAST;
|
|
||||||
NET sace_usb_oen DRIVE = 8;
|
|
||||||
NET sace_usb_wen LOC = Y8;
|
|
||||||
NET sace_usb_wen IOSTANDARD = LVCMOS33;
|
|
||||||
NET sace_usb_wen SLEW = FAST;
|
|
||||||
NET sace_usb_wen DRIVE = 8;
|
|
||||||
NET sysace_mpirq LOC = AD4;
|
|
||||||
NET sysace_mpirq IOSTANDARD = LVCMOS33;
|
|
||||||
NET sysace_mpirq TIG;
|
|
||||||
NET sysace_mpirq PULLDOWN;
|
|
||||||
|
|
||||||
NET usb_csn LOC = AF10;
|
|
||||||
NET usb_csn IOSTANDARD = LVCMOS33;
|
|
||||||
NET usb_csn SLEW = FAST;
|
|
||||||
NET usb_csn DRIVE = 8;
|
|
||||||
NET usb_hpi_reset_n LOC = A7;
|
|
||||||
NET usb_hpi_reset_n IOSTANDARD = LVCMOS25;
|
|
||||||
NET usb_hpi_reset_n TIG;
|
|
||||||
NET usb_hpi_int LOC = V5;
|
|
||||||
NET usb_hpi_int IOSTANDARD = LVCMOS33;
|
|
||||||
NET usb_hpi_int TIG;
|
|
||||||
NET usb_hpi_int PULLDOWN;
|
|
||||||
|
|
||||||
#------------------------------------------------------------------------------
|
|
||||||
# IO Pad Location Constraints / Properties for DDR Controllers
|
|
||||||
#------------------------------------------------------------------------------
|
|
||||||
|
|
||||||
NET ddr_ad<0> LOC = C26; # DDR_A0
|
|
||||||
NET ddr_ad<1> LOC = E17; # DDR_A1
|
|
||||||
NET ddr_ad<2> LOC = D18; # DDR_A2
|
|
||||||
NET ddr_ad<3> LOC = C19; # DDR_A3
|
|
||||||
NET ddr_ad<4> LOC = F17; # DDR_A4
|
|
||||||
NET ddr_ad<5> LOC = B18; # DDR_A5
|
|
||||||
NET ddr_ad<6> LOC = B20; # DDR_A6
|
|
||||||
NET ddr_ad<7> LOC = C20; # DDR_A7
|
|
||||||
NET ddr_ad<8> LOC = D20; # DDR_A8
|
|
||||||
NET ddr_ad<9> LOC = C21; # DDR_A9
|
|
||||||
NET ddr_ad<10> LOC = A18; # DDR_A10
|
|
||||||
NET ddr_ad<11> LOC = B21; # DDR_A11
|
|
||||||
NET ddr_ad<12> LOC = A24; # DDR_A12
|
|
||||||
NET ddr_ba<0> LOC = B12; # DDR_BA0
|
|
||||||
NET ddr_ba<1> LOC = A16; # DDR_BA1
|
|
||||||
NET ddr_casb LOC = F23; # DDR_CAS_N
|
|
||||||
NET ddr_cke LOC = G22; # DDR_CKE
|
|
||||||
NET ddr_csb LOC = G21; # DDR_CS_N
|
|
||||||
NET ddr_rasb LOC = F24; # DDR_RAS_N
|
|
||||||
NET ddr_web LOC = A23; # DDR_WE_N
|
|
||||||
|
|
||||||
NET ddr_clk LOC = A10; # DDR_CK1_P
|
|
||||||
NET ddr_clk_fb LOC = B13; # DDR_CK1_P (FEEDBACK)
|
|
||||||
NET ddr_clkb LOC = B10; # DDR_CK1_N
|
|
||||||
|
|
||||||
NET ddr_dm<0> LOC = G19; # DDR_DM0
|
|
||||||
NET ddr_dm<1> LOC = G24; # DDR_DM1
|
|
||||||
NET ddr_dm<2> LOC = G20; # DDR_DM2
|
|
||||||
NET ddr_dm<3> LOC = C22; # DDR_DM3
|
|
||||||
|
|
||||||
NET ddr_dqs<0> LOC = D25; # DDR_DQS0
|
|
||||||
NET ddr_dqs<1> LOC = G18; # DDR_DQS1
|
|
||||||
NET ddr_dqs<2> LOC = G17; # DDR_DQS2
|
|
||||||
NET ddr_dqs<3> LOC = D26; # DDR_DQS3
|
|
||||||
|
|
||||||
NET ddr_dq<0> LOC = H20; # DDR_D0
|
|
||||||
NET ddr_dq<1> LOC = E23; # DDR_D1
|
|
||||||
NET ddr_dq<2> LOC = H26; # DDR_D2
|
|
||||||
NET ddr_dq<3> LOC = H22; # DDR_D3
|
|
||||||
NET ddr_dq<4> LOC = E25; # DDR_D4
|
|
||||||
NET ddr_dq<5> LOC = E26; # DDR_D5
|
|
||||||
NET ddr_dq<6> LOC = F26; # DDR_D6
|
|
||||||
NET ddr_dq<7> LOC = E24; # DDR_D7
|
|
||||||
NET ddr_dq<8> LOC = E20; # DDR_D8
|
|
||||||
NET ddr_dq<9> LOC = A22; # DDR_D9
|
|
||||||
NET ddr_dq<10> LOC = C23; # DDR_D10
|
|
||||||
NET ddr_dq<11> LOC = C24; # DDR_D11
|
|
||||||
NET ddr_dq<12> LOC = A20; # DDR_D12
|
|
||||||
NET ddr_dq<13> LOC = A21; # DDR_D13
|
|
||||||
NET ddr_dq<14> LOC = D24; # DDR_D14
|
|
||||||
NET ddr_dq<15> LOC = E18; # DDR_D15
|
|
||||||
NET ddr_dq<16> LOC = F18; # DDR_D16
|
|
||||||
NET ddr_dq<17> LOC = A19; # DDR_D17
|
|
||||||
NET ddr_dq<18> LOC = F19; # DDR_D18
|
|
||||||
NET ddr_dq<19> LOC = B23; # DDR_D19
|
|
||||||
NET ddr_dq<20> LOC = E21; # DDR_D20
|
|
||||||
NET ddr_dq<21> LOC = D22; # DDR_D21
|
|
||||||
NET ddr_dq<22> LOC = D23; # DDR_D22
|
|
||||||
NET ddr_dq<23> LOC = B24; # DDR_D23
|
|
||||||
NET ddr_dq<24> LOC = E22; # DDR_D24
|
|
||||||
NET ddr_dq<25> LOC = F20; # DDR_D25
|
|
||||||
NET ddr_dq<26> LOC = H23; # DDR_D26
|
|
||||||
NET ddr_dq<27> LOC = G25; # DDR_D27
|
|
||||||
NET ddr_dq<28> LOC = G26; # DDR_D28
|
|
||||||
NET ddr_dq<29> LOC = H25; # DDR_D29
|
|
||||||
NET ddr_dq<30> LOC = H24; # DDR_D30
|
|
||||||
NET ddr_dq<31> LOC = H21; # DDR_D31
|
|
||||||
|
|
||||||
NET ddr_ad<*> IOSTANDARD = SSTL2_I;
|
|
||||||
NET ddr_ba<*> IOSTANDARD = SSTL2_I;
|
|
||||||
NET ddr_casb IOSTANDARD = SSTL2_I;
|
|
||||||
NET ddr_cke IOSTANDARD = SSTL2_I;
|
|
||||||
NET ddr_clk IOSTANDARD = SSTL2_I;
|
|
||||||
NET ddr_clk_fb IOSTANDARD = LVCMOS25;
|
|
||||||
NET ddr_clkb IOSTANDARD = SSTL2_I;
|
|
||||||
NET ddr_casb IOSTANDARD = SSTL2_I;
|
|
||||||
NET ddr_csb IOSTANDARD = SSTL2_I;
|
|
||||||
NET ddr_rasb IOSTANDARD = SSTL2_I;
|
|
||||||
NET ddr_web IOSTANDARD = SSTL2_I;
|
|
||||||
|
|
||||||
NET ddr_dqs<*> IOSTANDARD = SSTL2_II;
|
|
||||||
NET ddr_dm<*> IOSTANDARD = SSTL2_II;
|
|
||||||
NET ddr_dq<*> IOSTANDARD = SSTL2_II;
|
|
||||||
|
|
||||||
// Timing Constraint for DDR Feedback Clock
|
|
||||||
NET "ddr_clk_fb" TNM_NET = "ddr_clk_fb";
|
|
||||||
TIMESPEC "TSDDR_FB" = PERIOD "ddr_clk_fb" 9.9 ns;
|
|
||||||
|
|
||||||
#------------------------------------------------------------------------------
|
|
||||||
# IO Pad Location Constraints / Properties for TFT VGA LCD Controller
|
|
||||||
#------------------------------------------------------------------------------
|
|
||||||
|
|
||||||
NET tft_lcd_b<0> LOC = L26; # VGA_B2
|
|
||||||
NET tft_lcd_b<0> IOSTANDARD = LVCMOS33;
|
|
||||||
NET tft_lcd_b<1> LOC = C5; # VGA_B3
|
|
||||||
NET tft_lcd_b<2> LOC = C7; # VGA_B4
|
|
||||||
NET tft_lcd_b<3> LOC = B7; # VGA_B5
|
|
||||||
NET tft_lcd_b<4> LOC = G8; # VGA_B6
|
|
||||||
NET tft_lcd_b<5> LOC = F8; # VGA_B7
|
|
||||||
NET tft_lcd_b<*> SLEW = FAST;
|
|
||||||
NET tft_lcd_b<*> DRIVE = 8;
|
|
||||||
|
|
||||||
NET tft_lcd_clk LOC = AF8;
|
|
||||||
NET tft_lcd_clk IOSTANDARD = LVDCI_33;
|
|
||||||
NET tft_lcd_clk SLEW = FAST;
|
|
||||||
NET tft_lcd_clk DRIVE = 8;
|
|
||||||
|
|
||||||
NET tft_lcd_g<0> LOC = M20; # VGA_G2
|
|
||||||
NET tft_lcd_g<0> IOSTANDARD = LVCMOS33;
|
|
||||||
NET tft_lcd_g<1> LOC = E4; # VGA_G3
|
|
||||||
NET tft_lcd_g<2> LOC = D3; # VGA_G4
|
|
||||||
NET tft_lcd_g<3> LOC = H7; # VGA_G5
|
|
||||||
NET tft_lcd_g<4> LOC = H8; # VGA_G6
|
|
||||||
NET tft_lcd_g<5> LOC = C1; # VGA_G7
|
|
||||||
NET tft_lcd_g<*> SLEW = FAST;
|
|
||||||
NET tft_lcd_g<*> DRIVE = 8;
|
|
||||||
|
|
||||||
NET tft_lcd_hsync LOC = C10;
|
|
||||||
NET tft_lcd_hsync SLEW = FAST;
|
|
||||||
NET tft_lcd_hsync DRIVE = 8;
|
|
||||||
|
|
||||||
NET tft_lcd_r<0> LOC = N25; #VGA_R2
|
|
||||||
NET tft_lcd_r<0> IOSTANDARD = LVCMOS33;
|
|
||||||
NET tft_lcd_r<1> LOC = C2; #VGA_R3
|
|
||||||
NET tft_lcd_r<2> LOC = G7; #VGA_R4
|
|
||||||
NET tft_lcd_r<3> LOC = F7; #VGA_R5
|
|
||||||
NET tft_lcd_r<4> LOC = E5; #VGA_R6
|
|
||||||
NET tft_lcd_r<5> LOC = E6; #VGA_R7
|
|
||||||
NET tft_lcd_r<*> SLEW = FAST;
|
|
||||||
NET tft_lcd_r<*> DRIVE = 8;
|
|
||||||
|
|
||||||
NET tft_lcd_vsync LOC = A8;
|
|
||||||
NET tft_lcd_vsync SLEW = FAST;
|
|
||||||
NET tft_lcd_vsync DRIVE = 8;
|
|
||||||
|
|
||||||
TIMESPEC "TSPLB_TFT" = FROM "sys_clk" TO "tft_clk" TIG;
|
|
||||||
TIMESPEC "TSTFT_PLB" = FROM "tft_clk" TO "sys_clk" TIG;
|
|
||||||
|
|
||||||
////////////////////////////////////////////////////////////////////////////
|
|
||||||
// Misc Board Signals
|
|
||||||
////////////////////////////////////////////////////////////////////////////
|
|
||||||
|
|
||||||
NET plb_error LOC = L24;
|
|
||||||
NET plb_error IOSTANDARD = LVCMOS33;
|
|
||||||
NET plb_error TIG;
|
|
||||||
NET opb_error LOC = V6;
|
|
||||||
NET opb_error IOSTANDARD = LVCMOS33;
|
|
||||||
NET opb_error TIG;
|
|
||||||
|
|
||||||
#------------------------------------------------------------------------------
|
|
||||||
# IO Pad Location Constraints / Properties for Ethernet
|
|
||||||
#------------------------------------------------------------------------------
|
|
||||||
|
|
||||||
NET phy_col LOC = E3;
|
|
||||||
NET phy_crs LOC = D5;
|
|
||||||
NET phy_dv LOC = A9;
|
|
||||||
NET phy_rx_clk LOC = B15;
|
|
||||||
NET phy_rx_data<3> LOC = C4;
|
|
||||||
NET phy_rx_data<2> LOC = D4;
|
|
||||||
NET phy_rx_data<1> LOC = E1;
|
|
||||||
NET phy_rx_data<0> LOC = F1;
|
|
||||||
|
|
||||||
NET phy_rx_er LOC = B9;
|
|
||||||
NET phy_tx_clk LOC = C15;
|
|
||||||
NET phy_mii_clk LOC = D1;
|
|
||||||
NET phy_mii_int_n LOC = H4;
|
|
||||||
NET phy_rst_n LOC = D10;
|
|
||||||
NET phy_tx_data<3> LOC = G1;
|
|
||||||
NET phy_tx_data<2> LOC = H3;
|
|
||||||
NET phy_tx_data<1> LOC = H2;
|
|
||||||
NET phy_tx_data<0> LOC = H1;
|
|
||||||
NET phy_tx_en LOC = F4;
|
|
||||||
NET phy_tx_er LOC = F3;
|
|
||||||
NET phy_mii_data LOC = G4;
|
|
||||||
|
|
||||||
NET phy_mii_int_n PULLUP;
|
|
||||||
|
|
||||||
NET phy_mii_int_n TIG;
|
|
||||||
NET phy_rst_n TIG;
|
|
||||||
|
|
||||||
# Timing Constraints (these are recommended in documentation and
|
|
||||||
# are unaltered except for the TIG)
|
|
||||||
NET "phy_rx_clk" TNM_NET = "RXCLK_GRP";
|
|
||||||
NET "phy_tx_clk" TNM_NET = "TXCLK_GRP";
|
|
||||||
TIMESPEC "TSTXOUT" = FROM "TXCLK_GRP" TO "PADS" 10 ns;
|
|
||||||
TIMESPEC "TSRXIN" = FROM "PADS" TO "RXCLK_GRP" 6 ns;
|
|
||||||
|
|
||||||
NET "phy_tx_clk" MAXSKEW= 1.0 ns;
|
|
||||||
NET "phy_rx_clk" MAXSKEW= 1.0 ns;
|
|
||||||
NET "phy_rx_clk" PERIOD = 40 ns HIGH 14 ns;
|
|
||||||
NET "phy_tx_clk" PERIOD = 40 ns HIGH 14 ns;
|
|
||||||
|
|
||||||
NET "phy_rx_data<3>" IOBDELAY=NONE;
|
|
||||||
NET "phy_rx_data<2>" IOBDELAY=NONE;
|
|
||||||
NET "phy_rx_data<1>" IOBDELAY=NONE;
|
|
||||||
NET "phy_rx_data<0>" IOBDELAY=NONE;
|
|
||||||
NET "phy_dv" IOBDELAY=NONE;
|
|
||||||
NET "phy_rx_er" IOBDELAY=NONE;
|
|
||||||
NET "phy_crs" IOBDELAY=NONE;
|
|
||||||
NET "phy_col" IOBDELAY=NONE;
|
|
||||||
|
|
||||||
# Workaround to help meet "phy_rx_clk MAXSKEW= 1.0 ns" constraint
|
|
||||||
INST "opb_ethernet_0/opb_ethernet_0/RX_FF_I0" IOB=FALSE;
|
|
||||||
INST "opb_ethernet_0/opb_ethernet_0/RX_FF_I1" IOB=FALSE;
|
|
||||||
INST "opb_ethernet_0/opb_ethernet_0/RX_FF_I2" IOB=FALSE;
|
|
||||||
INST "opb_ethernet_0/opb_ethernet_0/RX_FF_I3" IOB=FALSE;
|
|
||||||
INST "opb_ethernet_0/opb_ethernet_0/DVD_FF" IOB=FALSE;
|
|
||||||
INST "opb_ethernet_0/opb_ethernet_0/RER_FF" IOB=FALSE;
|
|
||||||
|
|
||||||
# Timing ignores (to specify unconstrained paths)
|
|
||||||
TIMESPEC "TS_PHYTX_OPB" = FROM "TXCLK_GRP" TO "sys_clk" TIG;
|
|
||||||
TIMESPEC "TS_OPB_PHYTX" = FROM "sys_clk" TO "TXCLK_GRP" TIG;
|
|
||||||
TIMESPEC "TS_PHYRX_OPB" = FROM "RXCLK_GRP" TO "sys_clk" TIG;
|
|
||||||
TIMESPEC "TS_OPB_PHYRX" = FROM "sys_clk" TO "RXCLK_GRP" TIG;
|
|
||||||
|
|
||||||
#------------------------------------------------------------------------------
|
|
||||||
# IO Pad Location Constraints / Properties for SRAM/FLASH
|
|
||||||
#------------------------------------------------------------------------------
|
|
||||||
|
|
||||||
NET sram_clk LOC = AF7;
|
|
||||||
NET sram_clk_fb LOC = AD17;
|
|
||||||
NET flash_a23 LOC = T21;
|
|
||||||
NET sram_flash_addr<22> LOC = U20;
|
|
||||||
NET sram_flash_addr<21> LOC = T19;
|
|
||||||
NET sram_flash_addr<20> LOC = AC5;
|
|
||||||
NET sram_flash_addr<19> LOC = AB5;
|
|
||||||
NET sram_flash_addr<18> LOC = AC4;
|
|
||||||
NET sram_flash_addr<17> LOC = AB4;
|
|
||||||
|
|
||||||
NET sram_flash_addr<16> LOC = AB3;
|
|
||||||
NET sram_flash_addr<15> LOC = AA4;
|
|
||||||
NET sram_flash_addr<14> LOC = AA3;
|
|
||||||
NET sram_flash_addr<13> LOC = W5;
|
|
||||||
NET sram_flash_addr<12> LOC = W6;
|
|
||||||
NET sram_flash_addr<11> LOC = W3;
|
|
||||||
NET sram_flash_addr<10> LOC = AF3;
|
|
||||||
NET sram_flash_addr<9> LOC = AE3;
|
|
||||||
NET sram_flash_addr<8> LOC = AD2;
|
|
||||||
NET sram_flash_addr<7> LOC = AD1;
|
|
||||||
NET sram_flash_addr<6> LOC = AC2;
|
|
||||||
NET sram_flash_addr<5> LOC = AC1;
|
|
||||||
NET sram_flash_addr<4> LOC = AB2;
|
|
||||||
NET sram_flash_addr<3> LOC = AB1;
|
|
||||||
NET sram_flash_addr<2> LOC = AA1;
|
|
||||||
NET sram_flash_addr<1> LOC = Y2;
|
|
||||||
NET sram_flash_addr<0> LOC = Y1;
|
|
||||||
NET sram_flash_data<31> LOC = F14;
|
|
||||||
NET sram_flash_data<30> LOC = F13;
|
|
||||||
NET sram_flash_data<29> LOC = F12;
|
|
||||||
NET sram_flash_data<28> LOC = F11;
|
|
||||||
NET sram_flash_data<27> LOC = F16;
|
|
||||||
NET sram_flash_data<26> LOC = F15;
|
|
||||||
NET sram_flash_data<25> LOC = D14;
|
|
||||||
NET sram_flash_data<24> LOC = D13;
|
|
||||||
NET sram_flash_data<23> LOC = D15;
|
|
||||||
NET sram_flash_data<22> LOC = E14;
|
|
||||||
NET sram_flash_data<21> LOC = C11;
|
|
||||||
NET sram_flash_data<20> LOC = D11;
|
|
||||||
NET sram_flash_data<19> LOC = D16;
|
|
||||||
NET sram_flash_data<18> LOC = C16;
|
|
||||||
NET sram_flash_data<17> LOC = E13;
|
|
||||||
NET sram_flash_data<16> LOC = D12;
|
|
||||||
NET sram_flash_data<15> LOC = AA14;
|
|
||||||
NET sram_flash_data<14> LOC = AB14;
|
|
||||||
NET sram_flash_data<13> LOC = AC12;
|
|
||||||
NET sram_flash_data<12> LOC = AC11;
|
|
||||||
NET sram_flash_data<11> LOC = AA16;
|
|
||||||
NET sram_flash_data<10> LOC = AA15;
|
|
||||||
NET sram_flash_data<9> LOC = AB13;
|
|
||||||
NET sram_flash_data<8> LOC = AA13;
|
|
||||||
NET sram_flash_data<7> LOC = AC14;
|
|
||||||
NET sram_flash_data<6> LOC = AD14;
|
|
||||||
NET sram_flash_data<5> LOC = AA12;
|
|
||||||
NET sram_flash_data<4> LOC = AA11;
|
|
||||||
NET sram_flash_data<3> LOC = AC16;
|
|
||||||
NET sram_flash_data<2> LOC = AC15;
|
|
||||||
NET sram_flash_data<1> LOC = AC13;
|
|
||||||
NET sram_flash_data<0> LOC = AD13;
|
|
||||||
NET sram_cen LOC = V7;
|
|
||||||
NET sram_flash_oe_n LOC = AC6;
|
|
||||||
NET sram_flash_we_n LOC = AB6;
|
|
||||||
NET sram_bw<3> LOC = Y3; #Y4;
|
|
||||||
NET sram_bw<2> LOC = Y4; #Y3;
|
|
||||||
NET sram_bw<1> LOC = Y5; #Y6;
|
|
||||||
NET sram_bw<0> LOC = Y6; #Y5;
|
|
||||||
NET flash_ce LOC = W7;
|
|
||||||
NET sram_adv_ld_n LOC = W4;
|
|
||||||
NET sram_mode LOC = V26;
|
|
||||||
|
|
||||||
NET sram_clk IOSTANDARD = LVCMOS33;
|
|
||||||
NET sram_clk DRIVE = 16;
|
|
||||||
NET sram_clk SLEW = FAST;
|
|
||||||
NET sram_clk_fb IOSTANDARD = LVCMOS33;
|
|
||||||
|
|
||||||
NET flash_a23 IOSTANDARD = LVDCI_33;
|
|
||||||
NET flash_a23 SLEW = FAST;
|
|
||||||
NET flash_a23 DRIVE = 8;
|
|
||||||
|
|
||||||
NET sram_mode IOSTANDARD = LVDCI_33;
|
|
||||||
NET sram_mode SLEW = FAST;
|
|
||||||
NET sram_mode DRIVE = 8;
|
|
||||||
|
|
||||||
NET sram_flash_addr<*> IOSTANDARD = LVDCI_33;
|
|
||||||
NET sram_flash_addr<*> SLEW = FAST;
|
|
||||||
NET sram_flash_addr<*> DRIVE = 8;
|
|
||||||
|
|
||||||
NET sram_flash_data<*> IOSTANDARD = LVCMOS33;
|
|
||||||
NET sram_flash_data<*> DRIVE = 12;
|
|
||||||
NET sram_flash_data<*> SLEW = FAST;
|
|
||||||
NET sram_flash_data<*> PULLDOWN;
|
|
||||||
|
|
||||||
NET sram_flash_oe_n IOSTANDARD = LVDCI_33;
|
|
||||||
NET sram_flash_oe_n SLEW = FAST;
|
|
||||||
NET sram_flash_oe_n DRIVE = 8;
|
|
||||||
|
|
||||||
NET sram_flash_we_n IOSTANDARD = LVDCI_33;
|
|
||||||
NET sram_flash_we_n SLEW = FAST;
|
|
||||||
NET sram_flash_we_n DRIVE = 8;
|
|
||||||
|
|
||||||
NET sram_bw<*> IOSTANDARD = LVDCI_33;
|
|
||||||
NET sram_bw<*> SLEW = FAST;
|
|
||||||
NET sram_bw<*> DRIVE = 8;
|
|
||||||
|
|
||||||
NET flash_ce IOSTANDARD = LVDCI_33;
|
|
||||||
NET flash_ce SLEW = FAST;
|
|
||||||
NET flash_ce DRIVE = 8;
|
|
||||||
|
|
||||||
NET sram_cen IOSTANDARD = LVDCI_33;
|
|
||||||
NET sram_cen SLEW = FAST;
|
|
||||||
NET sram_cen DRIVE = 8;
|
|
||||||
|
|
||||||
NET sram_adv_ld_n IOSTANDARD = LVDCI_33;
|
|
||||||
NET sram_adv_ld_n SLEW = FAST;
|
|
||||||
NET sram_adv_ld_n DRIVE = 8;
|
|
||||||
|
|
||||||
#------------------------------------------------------------------------------
|
|
||||||
# IO Pad Location Constraints / Properties for Expansion Header GPIO
|
|
||||||
#------------------------------------------------------------------------------
|
|
||||||
|
|
||||||
NET gpio_exp_hdr1<31> LOC = AF24; # HDR1_64
|
|
||||||
NET gpio_exp_hdr1<30> LOC = AE24; # HDR1_62
|
|
||||||
NET gpio_exp_hdr1<29> LOC = AD22; # HDR1_8
|
|
||||||
NET gpio_exp_hdr1<28> LOC = AB21; # HDR1_58
|
|
||||||
NET gpio_exp_hdr1<27> LOC = W20; # HDR1_44
|
|
||||||
NET gpio_exp_hdr1<26> LOC = W21; # HDR1_48
|
|
||||||
NET gpio_exp_hdr1<25> LOC = AB22; # HDR1_14
|
|
||||||
NET gpio_exp_hdr1<24> LOC = AD25; # HDR1_20
|
|
||||||
NET gpio_exp_hdr1<23> LOC = W22; # HDR1_46
|
|
||||||
NET gpio_exp_hdr1<22> LOC = V21; # HDR1_56
|
|
||||||
NET gpio_exp_hdr1<21> LOC = V22; # HDR1_54
|
|
||||||
NET gpio_exp_hdr1<20> LOC = AC22; # HDR1_16
|
|
||||||
NET gpio_exp_hdr1<19> LOC = AD26; # HDR1_18
|
|
||||||
NET gpio_exp_hdr1<18> LOC = AC26; # HDR1_34
|
|
||||||
NET gpio_exp_hdr1<17> LOC = AD23; # HDR1_6
|
|
||||||
NET gpio_exp_hdr1<16> LOC = AB25; # HDR1_30
|
|
||||||
NET gpio_exp_hdr1<15> LOC = AC23; # HDR1_4
|
|
||||||
NET gpio_exp_hdr1<14> LOC = AB26; # HDR1_24
|
|
||||||
NET gpio_exp_hdr1<13> LOC = AC21; # HDR1_60
|
|
||||||
NET gpio_exp_hdr1<12> LOC = AA23; # HDR1_10
|
|
||||||
NET gpio_exp_hdr1<11> LOC = AA26; # HDR1_22
|
|
||||||
NET gpio_exp_hdr1<10> LOC = Y25; # HDR1_40
|
|
||||||
NET gpio_exp_hdr1<9> LOC = Y26; # HDR1_38
|
|
||||||
NET gpio_exp_hdr1<8> LOC = W26; # HDR1_50
|
|
||||||
NET gpio_exp_hdr1<7> LOC = AB23; # HDR1_12
|
|
||||||
NET gpio_exp_hdr1<6> LOC = Y24; # HDR1_26
|
|
||||||
NET gpio_exp_hdr1<5> LOC = AB24; # HDR1_32
|
|
||||||
NET gpio_exp_hdr1<4> LOC = W25; # HDR1_52
|
|
||||||
NET gpio_exp_hdr1<3> LOC = AC24; # HDR1_2
|
|
||||||
NET gpio_exp_hdr1<2> LOC = AC25; # HDR1_36
|
|
||||||
NET gpio_exp_hdr1<1> LOC = V20; # HDR1_42
|
|
||||||
NET gpio_exp_hdr1<0> LOC = AA24; # HDR1_28
|
|
||||||
NET gpio_exp_hdr1<*> TIG;
|
|
||||||
NET gpio_exp_hdr1<*> PULLDOWN;
|
|
||||||
|
|
||||||
NET gpio_exp_hdr2<31> LOC = AF18; # HDR2_40
|
|
||||||
NET gpio_exp_hdr2<30> LOC = AE18; # HDR2_38
|
|
||||||
NET gpio_exp_hdr2<29> LOC = AF19; # HDR2_32
|
|
||||||
NET gpio_exp_hdr2<28> LOC = AF20; # HDR2_30
|
|
||||||
NET gpio_exp_hdr2<27> LOC = AF21; # HDR2_44
|
|
||||||
NET gpio_exp_hdr2<26> LOC = AF22; # HDR2_42
|
|
||||||
NET gpio_exp_hdr2<25> LOC = AF23; # HDR2_24
|
|
||||||
NET gpio_exp_hdr2<24> LOC = AE23; # HDR2_22
|
|
||||||
NET gpio_exp_hdr2<23> LOC = AC18; # HDR2_48
|
|
||||||
NET gpio_exp_hdr2<22> LOC = AB18; # HDR2_46
|
|
||||||
NET gpio_exp_hdr2<21> LOC = AD19; # HDR2_64
|
|
||||||
NET gpio_exp_hdr2<20> LOC = AC19; # HDR2_62
|
|
||||||
NET gpio_exp_hdr2<19> LOC = AE20; # HDR2_16
|
|
||||||
NET gpio_exp_hdr2<18> LOC = AD20; # HDR2_14
|
|
||||||
NET gpio_exp_hdr2<17> LOC = AE21; # HDR2_36
|
|
||||||
NET gpio_exp_hdr2<16> LOC = AD21; # HDR2_34
|
|
||||||
NET gpio_exp_hdr2<15> LOC = AB20; # HDR2_52
|
|
||||||
NET gpio_exp_hdr2<14> LOC = AC20; # HDR2_50
|
|
||||||
NET gpio_exp_hdr2<13> LOC = Y17; # HDR2_56
|
|
||||||
NET gpio_exp_hdr2<12> LOC = AA17; # HDR2_54
|
|
||||||
NET gpio_exp_hdr2<11> LOC = AA19; # HDR2_60
|
|
||||||
NET gpio_exp_hdr2<10> LOC = AA20; # HDR2_58
|
|
||||||
NET gpio_exp_hdr2<9> LOC = Y22; # HDR2_8
|
|
||||||
NET gpio_exp_hdr2<8> LOC = Y23; # HDR2_6
|
|
||||||
NET gpio_exp_hdr2<7> LOC = W23; # HDR2_12
|
|
||||||
NET gpio_exp_hdr2<6> LOC = W24; # HDR2_10
|
|
||||||
NET gpio_exp_hdr2<5> LOC = Y20; # HDR2_20
|
|
||||||
NET gpio_exp_hdr2<4> LOC = Y21; # HDR2_18
|
|
||||||
NET gpio_exp_hdr2<3> LOC = Y19; # HDR2_28
|
|
||||||
NET gpio_exp_hdr2<2> LOC = W19; # HDR2_26
|
|
||||||
NET gpio_exp_hdr2<1> LOC = AA18; # HDR2_4
|
|
||||||
NET gpio_exp_hdr2<0> LOC = Y18; # HDR2_2
|
|
||||||
NET gpio_exp_hdr2<*> TIG;
|
|
||||||
NET gpio_exp_hdr2<*> PULLDOWN;
|
|
||||||
|
|
||||||
#------------------------------------------------------------------------------
|
|
||||||
# IO Pad Location Constraints / Properties for Character LCD GPIO
|
|
||||||
#------------------------------------------------------------------------------
|
|
||||||
|
|
||||||
NET gpio_char_lcd<6> LOC = AE13; # LCD_E
|
|
||||||
NET gpio_char_lcd<5> LOC = AC17; # LCD_RS
|
|
||||||
NET gpio_char_lcd<4> LOC = AB17; # LCD_RW
|
|
||||||
NET gpio_char_lcd<3> LOC = AF12; # LCD_DB7
|
|
||||||
NET gpio_char_lcd<2> LOC = AE12; # LCD_DB6
|
|
||||||
NET gpio_char_lcd<1> LOC = AC10; # LCD_DB5
|
|
||||||
NET gpio_char_lcd<0> LOC = AB10; # LCD_DB4
|
|
||||||
NET gpio_char_lcd<*> IOSTANDARD = LVCMOS33;
|
|
||||||
NET gpio_char_lcd<*> TIG;
|
|
||||||
NET gpio_char_lcd<*> PULLDOWN;
|
|
||||||
@@ -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
|
||||||
|
|||||||
@@ -68,19 +68,13 @@ proc_reg_write:
|
|||||||
reg_cmem_high <= (others => '0');
|
reg_cmem_high <= (others => '0');
|
||||||
reg_bank_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_bank_sel(bank_sel_t'range) <= din(bank_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" =>
|
||||||
@@ -103,7 +97,7 @@ proc_reg_read:
|
|||||||
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,7 +214,6 @@ 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;
|
||||||
|
|||||||
@@ -49,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;
|
||||||
@@ -100,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
|
||||||
@@ -133,9 +132,6 @@ 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
|
||||||
@@ -334,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
|
||||||
@@ -435,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;
|
||||||
@@ -446,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;
|
||||||
@@ -457,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;
|
||||||
@@ -513,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;
|
||||||
@@ -524,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;
|
||||||
@@ -855,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;
|
||||||
@@ -867,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,87 +0,0 @@
|
|||||||
/************************************************************************/
|
|
||||||
/* Ein Programm zur Berechnung der Bessel-Koeffizienten Jn
|
|
||||||
/* Dateiname : Bessel.cpp
|
|
||||||
/* Autoren : T. Burr, J. Ahrensfeld
|
|
||||||
/* Datum : 28.10.1999
|
|
||||||
/* letzte Änderung : 28.01.2000
|
|
||||||
/* Version : 1.0
|
|
||||||
/************************************************************************/
|
|
||||||
|
|
||||||
#include "stdio.h"
|
|
||||||
#include "math.h"
|
|
||||||
#include "stdlib.h"
|
|
||||||
|
|
||||||
|
|
||||||
#define MAX_SUM 25
|
|
||||||
#define VERSION "1.0"
|
|
||||||
|
|
||||||
/************************************************************************/
|
|
||||||
/* Funktionsdeklarationen */
|
|
||||||
/************************************************************************/
|
|
||||||
// Fakultätsberechnung
|
|
||||||
double fak (int N)
|
|
||||||
{
|
|
||||||
int index;
|
|
||||||
double erg=1;
|
|
||||||
|
|
||||||
for (index = 1; index <= N; index++)
|
|
||||||
erg = erg * index;
|
|
||||||
|
|
||||||
return erg;
|
|
||||||
}
|
|
||||||
|
|
||||||
// Bessel()
|
|
||||||
// Berechnung von Jn von mfm
|
|
||||||
double bessel(int n, double mfm)
|
|
||||||
{
|
|
||||||
int m;
|
|
||||||
double Jn=0;
|
|
||||||
|
|
||||||
for (m=0; m < MAX_SUM; m++)
|
|
||||||
{
|
|
||||||
Jn = Jn + (pow(-1.0,m)/(fak(m)*fak(m+n))*pow(mfm/2.0,(2*m+n)));
|
|
||||||
}
|
|
||||||
return Jn;
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
/************************************************************************/
|
|
||||||
/* Das Hauptprogramm
|
|
||||||
/************************************************************************/
|
|
||||||
void main()
|
|
||||||
{
|
|
||||||
|
|
||||||
int N, Nmax;
|
|
||||||
double erg;
|
|
||||||
float mfm;
|
|
||||||
|
|
||||||
printf("\n\t Besselfunktion Version %s",VERSION);
|
|
||||||
printf("\n\t ~~~~~~~~~~~~~~~~~~~~~~~~~~\n");
|
|
||||||
printf("\n\tCopyright by J. Ahrensfeld & T. Burr\n\n");
|
|
||||||
|
|
||||||
// ---------------------------------------------------------------------------------
|
|
||||||
// Benutzereingaben
|
|
||||||
printf("\nBerechnungen fuer J = 0...");
|
|
||||||
if(scanf("%d",&Nmax)==0)
|
|
||||||
exit (-1);
|
|
||||||
|
|
||||||
printf("Bitte Modulationsindex eingeben : ");
|
|
||||||
if(scanf("%f",&mfm)==0)
|
|
||||||
exit(-1);
|
|
||||||
|
|
||||||
printf("\n");
|
|
||||||
|
|
||||||
// ---------------------------------------------------------------------------------
|
|
||||||
// Berechnung
|
|
||||||
for (N=0; N <= Nmax; N++)
|
|
||||||
{
|
|
||||||
erg = bessel(N,(double)mfm);
|
|
||||||
printf("J(%d) = %10.8f\n",N,erg);
|
|
||||||
}
|
|
||||||
|
|
||||||
printf("FERTIG.\n");
|
|
||||||
|
|
||||||
}
|
|
||||||
|
|
||||||
/************************************************************************/
|
|
||||||
|
|
||||||
@@ -1,134 +0,0 @@
|
|||||||
TOOLS_DIR=../../tools
|
|
||||||
|
|
||||||
CFLAGS=-msoft-float -O2 -march=r3000 -I.
|
|
||||||
LFLAGS=-M -T link.ld
|
|
||||||
LIB_DIRS=-L . -L /usr/local/mipsel-elf/lib -L /usr/local/lib/gcc/mipsel-elf/4.3.2
|
|
||||||
LIBS=-lc -lm -lgcc
|
|
||||||
|
|
||||||
AS=mipsel-elf-as
|
|
||||||
AR=mipsel-elf-ar
|
|
||||||
CC=mipsel-elf-gcc
|
|
||||||
LD=mipsel-elf-ld
|
|
||||||
OBJDUMP=mipsel-elf-objdump
|
|
||||||
OBJCOPY=mipsel-elf-objcopy
|
|
||||||
FLASHGEN=$(TOOLS_DIR)/flashgen_little
|
|
||||||
|
|
||||||
PROG = hello testbench test_irq dhry queens stanford paranoia rmd160_test Bessel whet phrasen dttl richards_benchmark
|
|
||||||
|
|
||||||
all: $(PROG)
|
|
||||||
|
|
||||||
libsys: startup.S init.S kernel.S libsys.c xcpt.c irq.c
|
|
||||||
$(CC) $(CFLAGS) -G 0 -c startup.S -o startup.o
|
|
||||||
$(CC) $(CFLAGS) -G 0 -c kernel.S -o kernel.o
|
|
||||||
$(CC) $(CFLAGS) -G 0 -c init.S -o init.o
|
|
||||||
$(CC) $(CFLAGS) -G 0 -c libsys.c -o libsys.o
|
|
||||||
$(CC) $(CFLAGS) -G 0 -c xcpt.c -o xcpt.o
|
|
||||||
$(CC) $(CFLAGS) -G 0 -c irq.c -o irq.o
|
|
||||||
$(AR) -r libsys.a init.o libsys.o xcpt.o irq.o
|
|
||||||
|
|
||||||
hello: hello.c
|
|
||||||
$(CC) $(CFLAGS) -c hello.c
|
|
||||||
$(LD) $(LFLAGS) $(LIB_DIRS) hello.o -o $@.elf $(LIBS) >$@.map
|
|
||||||
$(OBJDUMP) -d $@.elf > $@.dis
|
|
||||||
$(OBJCOPY) $@.elf -O binary $@.bin
|
|
||||||
$(OBJCOPY) -O srec $@.elf $@.srec
|
|
||||||
$(FLASHGEN) $@.bin
|
|
||||||
|
|
||||||
testbench: testbench.c
|
|
||||||
$(CC) $(CFLAGS) -c testbench.c paranoia.c -DNOSIGNAL -DBATCHMODE -DNOMAIN
|
|
||||||
$(LD) $(LFLAGS) $(LIB_DIRS) paranoia.o testbench.o -o $@.elf $(LIBS) >$@.map
|
|
||||||
$(OBJDUMP) -d $@.elf > $@.dis
|
|
||||||
$(OBJCOPY) $@.elf -O binary $@.bin
|
|
||||||
$(OBJCOPY) -O srec $@.elf $@.srec
|
|
||||||
$(FLASHGEN) $@.bin
|
|
||||||
|
|
||||||
test_irq: test_irq.c
|
|
||||||
$(CC) $(CFLAGS) -c test_irq.c
|
|
||||||
$(LD) $(LFLAGS) $(LIB_DIRS) test_irq.o -o $@.elf $(LIBS) >$@.map
|
|
||||||
$(OBJDUMP) -d $@.elf > $@.dis
|
|
||||||
$(OBJCOPY) $@.elf -O binary $@.bin
|
|
||||||
$(OBJCOPY) -O srec $@.elf $@.srec
|
|
||||||
$(FLASHGEN) $@.bin
|
|
||||||
|
|
||||||
dhry: dhry_1.c dhry_2.c dhry.h
|
|
||||||
$(CC) $(CFLAGS) -DHZ=1000 -c dhry_1.c dhry_2.c
|
|
||||||
$(LD) $(LFLAGS) $(LIB_DIRS) dhry_1.o dhry_2.o -o $@.elf $(LIBS) >$@.map
|
|
||||||
$(OBJDUMP) -d $@.elf > $@.dis
|
|
||||||
$(OBJCOPY) $@.elf -O binary $@.bin
|
|
||||||
$(OBJCOPY) -O srec $@.elf $@.srec
|
|
||||||
$(FLASHGEN) $@.bin
|
|
||||||
|
|
||||||
queens: queens.c
|
|
||||||
$(CC) $(CFLAGS) -DUNIX_Old -DHZ=1000 -c queens.c
|
|
||||||
$(LD) $(LFLAGS) $(LIB_DIRS) queens.o -o $@.elf $(LIBS) >$@.map
|
|
||||||
$(OBJDUMP) -d $@.elf > $@.dis
|
|
||||||
$(OBJCOPY) $@.elf -O binary $@.bin
|
|
||||||
$(OBJCOPY) -O srec $@.elf $@.srec
|
|
||||||
$(FLASHGEN) $@.bin
|
|
||||||
|
|
||||||
stanford: stanford.c
|
|
||||||
$(CC) $(CFLAGS) -DHZ=1000 -c stanford.c
|
|
||||||
$(LD) $(LFLAGS) $(LIB_DIRS) stanford.o -o $@.elf $(LIBS) >$@.map
|
|
||||||
$(OBJDUMP) -d $@.elf > $@.dis
|
|
||||||
$(OBJCOPY) $@.elf -O binary $@.bin
|
|
||||||
$(OBJCOPY) -O srec $@.elf $@.srec
|
|
||||||
$(FLASHGEN) $@.bin
|
|
||||||
|
|
||||||
paranoia: paranoia.c
|
|
||||||
$(CC) $(CFLAGS) -DNOSIGNAL -DBATCHMODE -g -c paranoia.c
|
|
||||||
$(LD) $(LFLAGS) $(LIB_DIRS) paranoia.o -o $@.elf $(LIBS) >$@.map
|
|
||||||
$(OBJDUMP) -d $@.elf > $@.dis
|
|
||||||
$(OBJCOPY) $@.elf -O binary $@.bin
|
|
||||||
$(OBJCOPY) -O srec $@.elf $@.srec
|
|
||||||
$(FLASHGEN) $@.bin
|
|
||||||
|
|
||||||
rmd160_test: rmd160_test.c rmd160.c rmd160.h
|
|
||||||
$(CC) $(CFLAGS) -DNOSIGNAL -DBATCHMODE -g -c rmd160.c rmd160_test.c
|
|
||||||
$(LD) $(LFLAGS) $(LIB_DIRS) rmd160.o rmd160_test.o -o $@.elf $(LIBS) >$@.map
|
|
||||||
$(OBJDUMP) -d $@.elf > $@.dis
|
|
||||||
$(OBJCOPY) $@.elf -O binary $@.bin
|
|
||||||
$(OBJCOPY) -O srec $@.elf $@.srec
|
|
||||||
$(FLASHGEN) $@.bin
|
|
||||||
|
|
||||||
Bessel: Bessel.c
|
|
||||||
$(CC) $(CFLAGS) -g -c Bessel.c
|
|
||||||
$(LD) $(LFLAGS) $(LIB_DIRS) Bessel.o -o $@.elf $(LIBS) >$@.map
|
|
||||||
$(OBJDUMP) -d $@.elf > $@.dis
|
|
||||||
$(OBJCOPY) $@.elf -O binary $@.bin
|
|
||||||
$(OBJCOPY) -O srec $@.elf $@.srec
|
|
||||||
$(FLASHGEN) $@.bin
|
|
||||||
|
|
||||||
whet: whet.c
|
|
||||||
$(CC) $(CFLAGS) -c whet.c
|
|
||||||
$(LD) $(LFLAGS) $(LIB_DIRS) whet.o -o $@.elf $(LIBS) >$@.map
|
|
||||||
$(OBJDUMP) -d $@.elf > $@.dis
|
|
||||||
$(OBJCOPY) $@.elf -O binary $@.bin
|
|
||||||
$(OBJCOPY) -O srec $@.elf $@.srec
|
|
||||||
$(FLASHGEN) $@.bin
|
|
||||||
|
|
||||||
phrasen: phrasen.c
|
|
||||||
$(CC) $(CFLAGS) -g -c phrasen.c
|
|
||||||
$(LD) $(LFLAGS) $(LIB_DIRS) phrasen.o -o $@.elf $(LIBS) >$@.map
|
|
||||||
$(OBJDUMP) -d $@.elf > $@.dis
|
|
||||||
$(OBJCOPY) $@.elf -O binary $@.bin
|
|
||||||
$(OBJCOPY) -O srec $@.elf $@.srec
|
|
||||||
$(FLASHGEN) $@.bin
|
|
||||||
|
|
||||||
dttl: dttl.c random.c
|
|
||||||
$(CC) $(CFLAGS) -g -c dttl.c random.c
|
|
||||||
$(LD) $(LFLAGS) $(LIB_DIRS) random.o dttl.o -o $@.elf $(LIBS) >$@.map
|
|
||||||
$(OBJDUMP) -d $@.elf > $@.dis
|
|
||||||
$(OBJCOPY) $@.elf -O binary $@.bin
|
|
||||||
$(OBJCOPY) -O srec $@.elf $@.srec
|
|
||||||
$(FLASHGEN) $@.bin
|
|
||||||
|
|
||||||
richards_benchmark: richards_benchmark.c
|
|
||||||
$(CC) $(CFLAGS) -c richards_benchmark.c
|
|
||||||
$(LD) $(LFLAGS) $(LIB_DIRS) richards_benchmark.o -o $@.elf $(LIBS) >$@.map
|
|
||||||
$(OBJDUMP) -d $@.elf > $@.dis
|
|
||||||
$(OBJCOPY) $@.elf -O binary $@.bin
|
|
||||||
$(OBJCOPY) -O srec $@.elf $@.srec
|
|
||||||
$(FLASHGEN) $@.bin
|
|
||||||
|
|
||||||
clean:
|
|
||||||
rm -rf *.a *.o *.bin *.map *.dis *.srec *.elf $(PROG) > /dev/null
|
|
||||||
@@ -1,403 +0,0 @@
|
|||||||
#include "libsys.h"
|
|
||||||
#include "cfiflash.h"
|
|
||||||
|
|
||||||
typedef struct _ssrec_t
|
|
||||||
{
|
|
||||||
UINT32 addr;
|
|
||||||
UINT32 size;
|
|
||||||
UINT32 type;
|
|
||||||
UINT8 *data;
|
|
||||||
|
|
||||||
} srec_t;
|
|
||||||
|
|
||||||
enum srec_type
|
|
||||||
{
|
|
||||||
srec_err, srec_sob, srec_data, srec_rec, srec_eob
|
|
||||||
};
|
|
||||||
|
|
||||||
UINT8 h2i(UINT8 *c)
|
|
||||||
{
|
|
||||||
int i;
|
|
||||||
UINT8 t, b = 0;
|
|
||||||
|
|
||||||
for (i=0; i < 2; i++)
|
|
||||||
{
|
|
||||||
t = c[i];
|
|
||||||
if (t >= 'A')
|
|
||||||
t = t - 'A' + 10;
|
|
||||||
else
|
|
||||||
t -= '0';
|
|
||||||
|
|
||||||
b = (b << 4) | t;
|
|
||||||
}
|
|
||||||
return b;
|
|
||||||
}
|
|
||||||
|
|
||||||
int decode_srec(srec_t *pRec, UINT8 *pBuf, int buflen)
|
|
||||||
{
|
|
||||||
UINT8 chksum, byte;
|
|
||||||
int alen, i;
|
|
||||||
|
|
||||||
if (!buflen)
|
|
||||||
return srec_err;
|
|
||||||
|
|
||||||
pRec->type = srec_rec;
|
|
||||||
alen = 0;
|
|
||||||
if ((pBuf[1] > '0') && (pBuf[1] < '4'))
|
|
||||||
{
|
|
||||||
alen = pBuf[1] - '0' + 1;
|
|
||||||
pRec->type = srec_data;
|
|
||||||
}
|
|
||||||
else if ((pBuf[1] >= '7') && (pBuf[1] <= '9'))
|
|
||||||
{
|
|
||||||
alen = 11 - (pBuf[1] - '0');
|
|
||||||
pRec->type = srec_eob;
|
|
||||||
}
|
|
||||||
else if (pBuf[1] == '0')
|
|
||||||
{
|
|
||||||
alen = 2;
|
|
||||||
pRec->type = srec_sob;
|
|
||||||
}
|
|
||||||
|
|
||||||
byte = h2i(&pBuf[2]);
|
|
||||||
pRec->size = byte;
|
|
||||||
chksum = byte;
|
|
||||||
|
|
||||||
pRec->addr = 0;
|
|
||||||
for (i=0; i < alen; i++)
|
|
||||||
{
|
|
||||||
byte = h2i(&pBuf[4+2*i]);
|
|
||||||
pRec->addr = pRec->addr << 8 | byte;
|
|
||||||
chksum += byte;
|
|
||||||
}
|
|
||||||
pRec->size -= (alen+1);
|
|
||||||
|
|
||||||
pRec->data = (UINT8*) &pBuf[4 + 2*alen];
|
|
||||||
for (i=0; i < (int)pRec->size; i++)
|
|
||||||
{
|
|
||||||
byte = h2i(&pRec->data[2*i]);
|
|
||||||
pRec->data[i] = byte;
|
|
||||||
chksum += byte;
|
|
||||||
}
|
|
||||||
chksum = ~chksum;
|
|
||||||
byte = h2i(&pRec->data[2*i]);
|
|
||||||
if (chksum != byte)
|
|
||||||
return 0;
|
|
||||||
|
|
||||||
return pRec->type;
|
|
||||||
}
|
|
||||||
|
|
||||||
int srec_getline(UINT8 *pLine)
|
|
||||||
{
|
|
||||||
char c;
|
|
||||||
int i = 0;
|
|
||||||
|
|
||||||
do
|
|
||||||
{
|
|
||||||
c = readchar();
|
|
||||||
|
|
||||||
} while ((c != 's') && (c != 'S'));
|
|
||||||
|
|
||||||
while(((c != 0x0D) && (c != 0x0A)))
|
|
||||||
{
|
|
||||||
pLine[i++] = c;
|
|
||||||
c = readchar();
|
|
||||||
};
|
|
||||||
|
|
||||||
return i;
|
|
||||||
}
|
|
||||||
|
|
||||||
void Exec_at(void *pEntry)
|
|
||||||
{
|
|
||||||
__asm
|
|
||||||
(
|
|
||||||
".set noreorder\n"
|
|
||||||
"mfc0 $26, $12\n" // change exception vector
|
|
||||||
"li $27, 0xFFBFFFFF\n"
|
|
||||||
"and $26, $27\n"
|
|
||||||
"mtc0 $26, $12\n"
|
|
||||||
"jr $4\n" // jump entry
|
|
||||||
"rfe\n"
|
|
||||||
".set reorder\n"
|
|
||||||
|
|
||||||
);
|
|
||||||
}
|
|
||||||
|
|
||||||
void PrintCPUinfo(void)
|
|
||||||
{
|
|
||||||
int result, rev_id;
|
|
||||||
|
|
||||||
char *cpu_type_str[7] = {"invalid", "R2000", "R3000", "R6000", "R4000", "reserved", "R6000A"};
|
|
||||||
|
|
||||||
// Print Status register
|
|
||||||
result = CP0_SR_read();
|
|
||||||
|
|
||||||
sputs("Status : ");
|
|
||||||
print_word(result);
|
|
||||||
sputs("\n");
|
|
||||||
|
|
||||||
// Print Revision
|
|
||||||
result = CP0_PRID_read();
|
|
||||||
rev_id = (result >> 8) & 0xFF;
|
|
||||||
sputs("CPU type: ");
|
|
||||||
if ((rev_id > 0) && (rev_id < 0x07))
|
|
||||||
{
|
|
||||||
sputs(cpu_type_str[rev_id]);
|
|
||||||
sputs(" Rev.");
|
|
||||||
rev_id = result & 0xFF;
|
|
||||||
print_byte((char)rev_id);
|
|
||||||
}
|
|
||||||
else
|
|
||||||
sputs("Unknown");
|
|
||||||
|
|
||||||
sputs("\n");
|
|
||||||
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
#define TEST_SIZE (1024*1024) // bytes
|
|
||||||
//#define TEST_SIZE (1024) // bytes
|
|
||||||
#define SDRAM_BASE 0x40000000
|
|
||||||
#define IMAGE_OFFSET 0x01000000
|
|
||||||
#define FLASH_OFFSET 0x00700000
|
|
||||||
|
|
||||||
int main(int argc, char *argv[])
|
|
||||||
{
|
|
||||||
UINT8 buf[256];
|
|
||||||
srec_t srec;
|
|
||||||
int result, i;
|
|
||||||
UINT32 haddr, addr;
|
|
||||||
flash_t flash;
|
|
||||||
|
|
||||||
volatile UINT32 *pReg = (UINT32*)sys_led_port;
|
|
||||||
volatile UINT32 *pBtn = (UINT32*)sys_gpio0;
|
|
||||||
volatile UINT8 *pMem;
|
|
||||||
volatile UINT32 *pROM32;
|
|
||||||
volatile UINT32 *pMem32;
|
|
||||||
volatile UINT32 *pFlash = (UINT32*)sys_flash_io;
|
|
||||||
volatile UINT32 *pUSB = (UINT32*)sys_usb_data;
|
|
||||||
|
|
||||||
volatile UINT8 *ram8 = (UINT8*)SDRAM_BASE;
|
|
||||||
volatile UINT16 *ram16 = (UINT16*)SDRAM_BASE;
|
|
||||||
volatile UINT32 *ram32 = (UINT32*)SDRAM_BASE;
|
|
||||||
|
|
||||||
*pReg = 0;
|
|
||||||
haddr = 0;
|
|
||||||
/*
|
|
||||||
__asm __volatile
|
|
||||||
(
|
|
||||||
".set noreorder\n"
|
|
||||||
"li $a0, 0xA0020000\n"
|
|
||||||
"li $t0, 0x12345678\n"
|
|
||||||
"li $t1, 0x5555AAAA\n"
|
|
||||||
"sw $t0, 0($a0)\n"
|
|
||||||
// "nop\n"
|
|
||||||
"sw $t1, 4($a0)\n"
|
|
||||||
// "nop\n"
|
|
||||||
"lw $v0, 0($a0)\n"
|
|
||||||
// "nop\n"
|
|
||||||
"lw $v0, 4($a0)\n"
|
|
||||||
// "nop\n"
|
|
||||||
"sw $t0, 0($a0)\n"
|
|
||||||
// "nop\n"
|
|
||||||
"lw $v0, 4($a0)\n"
|
|
||||||
// "nop\n"
|
|
||||||
"sw $t1, 4($a0)\n"
|
|
||||||
// "nop\n"
|
|
||||||
"lw $v0, 0($a0)\n"
|
|
||||||
".set reorder\n"
|
|
||||||
);
|
|
||||||
__asm __volatile
|
|
||||||
(
|
|
||||||
".set noreorder\n"
|
|
||||||
"lui $v1, 0xA002\n"
|
|
||||||
"lui $v0,0x70\n"
|
|
||||||
"ori $v0,$v0,0x70\n"
|
|
||||||
"sw $v0,0($v1)\n"
|
|
||||||
"lui $a0,0x4002\n"
|
|
||||||
"lw $a1,0($v1)\n"
|
|
||||||
"lw $ra,12($sp)\n"
|
|
||||||
"lw $s1,8($sp)\n"
|
|
||||||
"lw $s0,4($sp)\n"
|
|
||||||
".set reorder\n"
|
|
||||||
);
|
|
||||||
|
|
||||||
*/
|
|
||||||
// PrintCPUinfo();
|
|
||||||
/*
|
|
||||||
*(pFlash+0) = 0x12345678;
|
|
||||||
*(pFlash+1) = 0xAAAA5555;
|
|
||||||
*(pFlash+2) = 0xFFFF0000;
|
|
||||||
*(pFlash+3) = 0x0000FFFF;
|
|
||||||
|
|
||||||
*pReg = *(pFlash+0);
|
|
||||||
*pReg = *(pFlash+1);
|
|
||||||
*pReg = *(pFlash+2);
|
|
||||||
*pReg = *(pFlash+3);
|
|
||||||
|
|
||||||
*(pUSB+0) = 0x12345678;
|
|
||||||
*(pUSB+1) = 0xAAAA5555;
|
|
||||||
*(pUSB+2) = 0xFFFF0000;
|
|
||||||
*(pUSB+3) = 0x0000FFFF;
|
|
||||||
|
|
||||||
*pReg = *(pUSB+0);
|
|
||||||
*pReg = *(pUSB+1);
|
|
||||||
*pReg = *(pUSB+2);
|
|
||||||
*pReg = *(pUSB+3);
|
|
||||||
sputs("BOOT ");
|
|
||||||
|
|
||||||
pMem32 = (UINT32*)0x40000000;
|
|
||||||
pROM32 = (UINT32*)0x00000000;
|
|
||||||
for (i=0; i < 0x3500; i+=4)
|
|
||||||
*pMem32++ = *pROM32++;
|
|
||||||
|
|
||||||
Exec_at((void*)0x40000000);
|
|
||||||
|
|
||||||
|
|
||||||
// Memtest BEGIN
|
|
||||||
sputs("SDRAM Memory Test\r\n");
|
|
||||||
sputs("Write (8-Bit access)...");
|
|
||||||
for (i=0; i < TEST_SIZE; i++)
|
|
||||||
ram8[i] = (UINT8)i;
|
|
||||||
|
|
||||||
sputs("done\r\n");
|
|
||||||
|
|
||||||
sputs("Verify (8-Bit access)...");
|
|
||||||
for (i=TEST_SIZE-1; i >= 0; i--)
|
|
||||||
if (ram8[i] != (UINT8)i)
|
|
||||||
break;
|
|
||||||
i++;
|
|
||||||
if (i)
|
|
||||||
sputs("failed\r\n");
|
|
||||||
else
|
|
||||||
sputs("passed\r\n");
|
|
||||||
|
|
||||||
|
|
||||||
sputs("Write (16-Bit access)...");
|
|
||||||
for (i=0; i < TEST_SIZE/2; i++)
|
|
||||||
ram16[i] = (UINT16)i;
|
|
||||||
|
|
||||||
sputs("done\r\n");
|
|
||||||
|
|
||||||
sputs("Verify (16-Bit access)...");
|
|
||||||
for (i=TEST_SIZE/2-1; i >= 0; i--)
|
|
||||||
if (ram16[i] != (UINT16)i)
|
|
||||||
break;
|
|
||||||
i++;
|
|
||||||
if (i)
|
|
||||||
sputs("failed\r\n");
|
|
||||||
else
|
|
||||||
sputs("passed\r\n");
|
|
||||||
|
|
||||||
|
|
||||||
sputs("Write (32-Bit access)...");
|
|
||||||
for (i=0; i < TEST_SIZE/4; i++)
|
|
||||||
ram32[i] = (UINT32)i;
|
|
||||||
|
|
||||||
sputs("done\r\n");
|
|
||||||
|
|
||||||
sputs("Verify (32-Bit access)...");
|
|
||||||
for (i=TEST_SIZE/4-1; i >= 0; i--)
|
|
||||||
if (ram32[i] != (UINT32)i)
|
|
||||||
break;
|
|
||||||
i++;
|
|
||||||
if (i)
|
|
||||||
sputs("failed\r\n");
|
|
||||||
else
|
|
||||||
sputs("passed\r\n");
|
|
||||||
|
|
||||||
for (i=0; i < TEST_SIZE/4; i++)
|
|
||||||
ram32[i] = 0;
|
|
||||||
|
|
||||||
// Memtest END
|
|
||||||
// ----------------------------------------------------------
|
|
||||||
*/
|
|
||||||
ram32 = (UINT32*)(SDRAM_BASE + IMAGE_OFFSET);
|
|
||||||
pFlash = (UINT32*)(sys_flash_io + FLASH_OFFSET);
|
|
||||||
print_word((UINT32)*pBtn);
|
|
||||||
if (!*pBtn)
|
|
||||||
{
|
|
||||||
sputs("Booting from flash..");
|
|
||||||
for (i=0; i < TEST_SIZE/4; i++)
|
|
||||||
ram32[i] = pFlash[i];
|
|
||||||
|
|
||||||
sputs("done");
|
|
||||||
|
|
||||||
Exec_at((void*)ram32);
|
|
||||||
}
|
|
||||||
else
|
|
||||||
{
|
|
||||||
|
|
||||||
sputs("SDRAM erase at : ");
|
|
||||||
print_word((UINT32)ram32);
|
|
||||||
sputs("\n");
|
|
||||||
for (i=0; i < TEST_SIZE/4; i++)
|
|
||||||
ram32[i] = 0;
|
|
||||||
|
|
||||||
cfi_init(&flash, sys_flash_io);
|
|
||||||
if (cfi_find(&flash) < 0)
|
|
||||||
return 1;
|
|
||||||
|
|
||||||
sputs("Found Flash at ");
|
|
||||||
print_word((UINT32)flash.pBase);
|
|
||||||
sputs("\n");
|
|
||||||
|
|
||||||
addr = FLASH_OFFSET;
|
|
||||||
sputs("Flash erase at : ");
|
|
||||||
print_word(addr);
|
|
||||||
sputs("\n");
|
|
||||||
cfi_block_erase(&flash, addr/4);
|
|
||||||
|
|
||||||
while(1)
|
|
||||||
{
|
|
||||||
sputs("BOOT ");
|
|
||||||
|
|
||||||
while(1)
|
|
||||||
{
|
|
||||||
result = srec_getline(buf);
|
|
||||||
result = decode_srec(&srec, buf, result);
|
|
||||||
*pReg = 0;
|
|
||||||
srec.addr += IMAGE_OFFSET;
|
|
||||||
switch (result)
|
|
||||||
{
|
|
||||||
case srec_data:
|
|
||||||
if ((srec.addr + srec.size) > haddr)
|
|
||||||
haddr = srec.addr + srec.size;
|
|
||||||
|
|
||||||
pMem = (UINT8*)srec.addr;
|
|
||||||
for (i=0; i < srec.size; i++)
|
|
||||||
*pMem++ = srec.data[i];
|
|
||||||
|
|
||||||
break;
|
|
||||||
|
|
||||||
case srec_eob:
|
|
||||||
*pReg = 1;
|
|
||||||
print_word(srec.addr);
|
|
||||||
sputs(" to ");
|
|
||||||
print_word(haddr-4);
|
|
||||||
sputs("\n");
|
|
||||||
|
|
||||||
addr = FLASH_OFFSET;
|
|
||||||
sputs("Program Flash at : ");
|
|
||||||
print_word(addr);
|
|
||||||
sputs("\n");
|
|
||||||
cfi_program_multi(&flash, addr/4, (UINT32*)ram32, TEST_SIZE/4);
|
|
||||||
|
|
||||||
// Exec_at((void*)srec.addr);
|
|
||||||
break;
|
|
||||||
|
|
||||||
default:
|
|
||||||
break;
|
|
||||||
}
|
|
||||||
if (result == srec_err)
|
|
||||||
{
|
|
||||||
*pReg = 0x40000000;
|
|
||||||
break;
|
|
||||||
}
|
|
||||||
|
|
||||||
};
|
|
||||||
}
|
|
||||||
}
|
|
||||||
return 0;
|
|
||||||
}
|
|
||||||
|
|
||||||
@@ -1,40 +0,0 @@
|
|||||||
ROM_WORDADDR_WIDTH=11
|
|
||||||
TOOLS_DIR=../../../tools
|
|
||||||
|
|
||||||
CFLAGS=-Os -I. -I../ -msoft-float -march=r3000
|
|
||||||
LFLAGS=-M -T bootloader.ld
|
|
||||||
LIB_DIRS=-L /usr/local/mipsel-elf/lib -L /usr/local/lib/gcc/mipsel-elf/4.3.2
|
|
||||||
LIBS=-lc -lgcc
|
|
||||||
|
|
||||||
CC=mipsel-elf-gcc
|
|
||||||
LD=mipsel-elf-ld
|
|
||||||
OBJDUMP=mipsel-elf-objdump
|
|
||||||
OBJCOPY=mipsel-elf-objcopy
|
|
||||||
|
|
||||||
all: bootloader_flash
|
|
||||||
|
|
||||||
libsys: startup_boot.S init_boot.S kernel_boot.S libsys_boot.c
|
|
||||||
$(CC) $(CFLAGS) -c startup_boot.S -o startup.o
|
|
||||||
$(CC) $(CFLAGS) -c init_boot.S -o init.o
|
|
||||||
$(CC) $(CFLAGS) -c kernel_boot.S -o kernel.o
|
|
||||||
$(CC) $(CFLAGS) -c libsys_boot.c -o libsys.o
|
|
||||||
|
|
||||||
bootloader: libsys bootloader.c
|
|
||||||
$(CC) $(CFLAGS) -g -c bootloader.c
|
|
||||||
$(LD) $(LFLAGS) $(LIB_DIRS) startup.o init.o kernel.o libsys.o bootloader.o -o bootloader.elf $(LIBS) >bootloader.map
|
|
||||||
$(OBJDUMP) -d bootloader.elf > bootloader.dis
|
|
||||||
$(OBJCOPY) bootloader.elf -O binary bootloader.ROM.bin
|
|
||||||
$(OBJCOPY) -O srec bootloader.elf bootloader.srec
|
|
||||||
$(TOOLS_DIR)/romgen bootloader.ROM.bin 10
|
|
||||||
|
|
||||||
bootloader_flash: libsys bootloader_with_flash.c
|
|
||||||
$(CC) $(CFLAGS) -g -c bootloader_with_flash.c
|
|
||||||
$(CC) $(CFLAGS) -g -c ../cfiflash.c
|
|
||||||
$(LD) $(LFLAGS) $(LIB_DIRS) startup.o init.o kernel.o libsys.o cfiflash.o bootloader_with_flash.o -o bootloader.elf $(LIBS) >bootloader.map
|
|
||||||
$(OBJDUMP) -d bootloader.elf > bootloader.dis
|
|
||||||
$(OBJCOPY) bootloader.elf -O binary bootloader.ROM.bin
|
|
||||||
$(OBJCOPY) -O srec bootloader.elf bootloader.srec
|
|
||||||
$(TOOLS_DIR)/romgen bootloader.ROM.bin 11
|
|
||||||
|
|
||||||
clean:
|
|
||||||
rm -rf *.o *.bin *.map *.dis *.srec *.elf *.vhd* *.tcl bootloader > /dev/null
|
|
||||||
@@ -1,247 +0,0 @@
|
|||||||
#include "libsys_boot.h"
|
|
||||||
|
|
||||||
typedef struct _ssrec_t
|
|
||||||
{
|
|
||||||
UINT32 addr;
|
|
||||||
UINT32 size;
|
|
||||||
UINT32 type;
|
|
||||||
UINT8 *data;
|
|
||||||
|
|
||||||
} srec_t;
|
|
||||||
|
|
||||||
enum srec_type
|
|
||||||
{
|
|
||||||
srec_err, srec_sob, srec_data, srec_rec, srec_eob
|
|
||||||
};
|
|
||||||
|
|
||||||
UINT8 h2i(UINT8 *c)
|
|
||||||
{
|
|
||||||
int i;
|
|
||||||
UINT8 t, b = 0;
|
|
||||||
|
|
||||||
for (i=0; i < 2; i++)
|
|
||||||
{
|
|
||||||
t = c[i];
|
|
||||||
if (t >= 'A')
|
|
||||||
t = t - 'A' + 10;
|
|
||||||
else
|
|
||||||
t -= '0';
|
|
||||||
|
|
||||||
b = (b << 4) | t;
|
|
||||||
}
|
|
||||||
return b;
|
|
||||||
}
|
|
||||||
|
|
||||||
int decode_srec(srec_t *pRec, UINT8 *pBuf, int buflen)
|
|
||||||
{
|
|
||||||
UINT8 chksum, byte;
|
|
||||||
int alen, i;
|
|
||||||
|
|
||||||
if (!buflen)
|
|
||||||
return srec_err;
|
|
||||||
|
|
||||||
pRec->type = srec_rec;
|
|
||||||
alen = 0;
|
|
||||||
if ((pBuf[1] > '0') && (pBuf[1] < '4'))
|
|
||||||
{
|
|
||||||
alen = pBuf[1] - '0' + 1;
|
|
||||||
pRec->type = srec_data;
|
|
||||||
}
|
|
||||||
else if ((pBuf[1] >= '7') && (pBuf[1] <= '9'))
|
|
||||||
{
|
|
||||||
alen = 11 - (pBuf[1] - '0');
|
|
||||||
pRec->type = srec_eob;
|
|
||||||
}
|
|
||||||
else if (pBuf[1] == '0')
|
|
||||||
{
|
|
||||||
alen = 2;
|
|
||||||
pRec->type = srec_sob;
|
|
||||||
}
|
|
||||||
|
|
||||||
byte = h2i(&pBuf[2]);
|
|
||||||
pRec->size = byte;
|
|
||||||
chksum = byte;
|
|
||||||
|
|
||||||
pRec->addr = 0;
|
|
||||||
for (i=0; i < alen; i++)
|
|
||||||
{
|
|
||||||
byte = h2i(&pBuf[4+2*i]);
|
|
||||||
pRec->addr = pRec->addr << 8 | byte;
|
|
||||||
chksum += byte;
|
|
||||||
}
|
|
||||||
pRec->size -= (alen+1);
|
|
||||||
|
|
||||||
pRec->data = (UINT8*) &pBuf[4 + 2*alen];
|
|
||||||
for (i=0; i < (int)pRec->size; i++)
|
|
||||||
{
|
|
||||||
byte = h2i(&pRec->data[2*i]);
|
|
||||||
pRec->data[i] = byte;
|
|
||||||
chksum += byte;
|
|
||||||
}
|
|
||||||
chksum = ~chksum;
|
|
||||||
byte = h2i(&pRec->data[2*i]);
|
|
||||||
if (chksum != byte)
|
|
||||||
return 0;
|
|
||||||
|
|
||||||
return pRec->type;
|
|
||||||
}
|
|
||||||
|
|
||||||
int srec_getline(UINT8 *pLine)
|
|
||||||
{
|
|
||||||
char c;
|
|
||||||
int i = 0;
|
|
||||||
|
|
||||||
do
|
|
||||||
{
|
|
||||||
c = readchar();
|
|
||||||
|
|
||||||
} while ((c != 's') && (c != 'S'));
|
|
||||||
|
|
||||||
while(((c != 0x0D) && (c != 0x0A)))
|
|
||||||
{
|
|
||||||
pLine[i++] = c;
|
|
||||||
c = readchar();
|
|
||||||
};
|
|
||||||
|
|
||||||
return i;
|
|
||||||
}
|
|
||||||
|
|
||||||
void Jump_to(void *pEntry)
|
|
||||||
{
|
|
||||||
__asm
|
|
||||||
(
|
|
||||||
".set noreorder\n"
|
|
||||||
);
|
|
||||||
__asm
|
|
||||||
(
|
|
||||||
"jr %[pEntry]\n" // jump entry
|
|
||||||
:
|
|
||||||
: [pEntry] "r" (pEntry)
|
|
||||||
);
|
|
||||||
__asm
|
|
||||||
(
|
|
||||||
"nop\n"
|
|
||||||
);
|
|
||||||
__asm
|
|
||||||
(
|
|
||||||
".set reorder\n"
|
|
||||||
);
|
|
||||||
}
|
|
||||||
|
|
||||||
void Exec_at(void *pEntry)
|
|
||||||
{
|
|
||||||
__asm
|
|
||||||
(
|
|
||||||
".set noreorder\n"
|
|
||||||
);
|
|
||||||
|
|
||||||
__asm
|
|
||||||
(
|
|
||||||
"mfc0 $26, $12\n" // change exception vector
|
|
||||||
"li $27, 0xFFBFFFFF\n"
|
|
||||||
"and $26, $27\n"
|
|
||||||
"mtc0 $26, $12\n"
|
|
||||||
);
|
|
||||||
|
|
||||||
__asm
|
|
||||||
(
|
|
||||||
"lw $v0, 16($sp)\n"
|
|
||||||
"nop\n"
|
|
||||||
"jr $v0\n" // jump entry
|
|
||||||
"rfe\n"
|
|
||||||
);
|
|
||||||
|
|
||||||
__asm
|
|
||||||
(
|
|
||||||
".set reorder\n"
|
|
||||||
);
|
|
||||||
}
|
|
||||||
void PrintCPUinfo(void)
|
|
||||||
{
|
|
||||||
int result, rev_id;
|
|
||||||
|
|
||||||
char *cpu_type_str[7] = {"invalid", "R2000", "R3000", "R6000", "R4000", "reserved", "R6000A"};
|
|
||||||
|
|
||||||
// Print Status register
|
|
||||||
result = CP0_SR_read();
|
|
||||||
|
|
||||||
sputs("Status : ");
|
|
||||||
print_word(result);
|
|
||||||
sputs("\n");
|
|
||||||
|
|
||||||
// Print Revision
|
|
||||||
result = CP0_PRID_read();
|
|
||||||
rev_id = (result >> 8) & 0xFF;
|
|
||||||
sputs("CPU type: ");
|
|
||||||
if ((rev_id > 0) && (rev_id < 0x07))
|
|
||||||
{
|
|
||||||
sputs(cpu_type_str[rev_id]);
|
|
||||||
sputs(" Rev.");
|
|
||||||
rev_id = result & 0xFF;
|
|
||||||
print_byte((char)rev_id);
|
|
||||||
}
|
|
||||||
else
|
|
||||||
sputs("Unknown");
|
|
||||||
|
|
||||||
sputs("\n");
|
|
||||||
|
|
||||||
}
|
|
||||||
|
|
||||||
#define MAX_IMG_SIZE (1024*1024) // bytes
|
|
||||||
|
|
||||||
int main(int argc, char *argv[])
|
|
||||||
{
|
|
||||||
UINT8 buf[256];
|
|
||||||
srec_t srec;
|
|
||||||
int result, srec_state, i;
|
|
||||||
UINT32 haddr;
|
|
||||||
volatile UINT8 *pMem;
|
|
||||||
haddr = 0;
|
|
||||||
|
|
||||||
// ----------------------------------------------------------
|
|
||||||
sputs("\n\n");
|
|
||||||
PrintCPUinfo();
|
|
||||||
sputs("Booting from UART..");
|
|
||||||
|
|
||||||
while(1)
|
|
||||||
{
|
|
||||||
sputs(".");
|
|
||||||
while(1)
|
|
||||||
{
|
|
||||||
result = srec_getline(buf);
|
|
||||||
srec_state = decode_srec(&srec, buf, result);
|
|
||||||
switch (srec_state)
|
|
||||||
{
|
|
||||||
case srec_data:
|
|
||||||
if ((srec.addr + srec.size) > haddr)
|
|
||||||
haddr = srec.addr + srec.size;
|
|
||||||
|
|
||||||
pMem = (UINT8*)srec.addr;
|
|
||||||
for (i=0; i < srec.size; i++)
|
|
||||||
*pMem++ = srec.data[i];
|
|
||||||
|
|
||||||
break;
|
|
||||||
|
|
||||||
case srec_eob:
|
|
||||||
sputs("done\n\n");
|
|
||||||
sputs("Execute program at ");
|
|
||||||
print_word(srec.addr);
|
|
||||||
sputs("\n\n");
|
|
||||||
|
|
||||||
Exec_at((void*)srec.addr);
|
|
||||||
break;
|
|
||||||
|
|
||||||
default:
|
|
||||||
result = -1;
|
|
||||||
break;
|
|
||||||
}
|
|
||||||
if (result < 0)
|
|
||||||
{
|
|
||||||
break;
|
|
||||||
}
|
|
||||||
|
|
||||||
};
|
|
||||||
}
|
|
||||||
return 0;
|
|
||||||
}
|
|
||||||
|
|
||||||
@@ -1,48 +0,0 @@
|
|||||||
MEMORY
|
|
||||||
{
|
|
||||||
rom : ORIGIN = 0xBFC00000, LENGTH = 0x00002000 /* 8K */
|
|
||||||
ram : ORIGIN = 0x40000000, LENGTH = 0x00002000 /* 8K */
|
|
||||||
}
|
|
||||||
|
|
||||||
stack_ptr = 0x7FFFEFF0;
|
|
||||||
baudrate = 0x0D;
|
|
||||||
sys_led_port = 0xA0000000;
|
|
||||||
sys_uart_data = 0xA0010000;
|
|
||||||
sys_uart_stat = 0xA0010004;
|
|
||||||
sys_uart_baud = 0xA0010008;
|
|
||||||
sys_timer_usec = 0xA000008;
|
|
||||||
sys_timer_sec = 0xA000000C;
|
|
||||||
|
|
||||||
|
|
||||||
SECTIONS
|
|
||||||
{
|
|
||||||
.stext ORIGIN(rom) :
|
|
||||||
{
|
|
||||||
start = ALIGN(4);
|
|
||||||
entry = ALIGN(4);
|
|
||||||
_entry = ALIGN(4);
|
|
||||||
__entry = ALIGN(4);
|
|
||||||
*(.stext)
|
|
||||||
} > rom
|
|
||||||
|
|
||||||
.ktext ORIGIN(rom) + 0x180 :
|
|
||||||
{
|
|
||||||
*(.ktext)
|
|
||||||
} > rom
|
|
||||||
|
|
||||||
.text . :
|
|
||||||
{
|
|
||||||
*(.text)
|
|
||||||
} > rom
|
|
||||||
|
|
||||||
.rodata . :
|
|
||||||
{
|
|
||||||
*(.rodata*)
|
|
||||||
} > rom
|
|
||||||
|
|
||||||
.data ORIGIN(ram) :
|
|
||||||
{
|
|
||||||
*(.*data) *(.*bss) *(.*common)
|
|
||||||
} > ram
|
|
||||||
|
|
||||||
}
|
|
||||||
@@ -1,360 +0,0 @@
|
|||||||
#include "libsys_boot.h"
|
|
||||||
#include "cfiflash.h"
|
|
||||||
|
|
||||||
typedef struct _ssrec_t
|
|
||||||
{
|
|
||||||
UINT32 addr;
|
|
||||||
UINT32 size;
|
|
||||||
UINT32 type;
|
|
||||||
UINT8 *data;
|
|
||||||
|
|
||||||
} srec_t;
|
|
||||||
|
|
||||||
typedef struct _sflash_img_hdr_t
|
|
||||||
{
|
|
||||||
UINT8 magic[4];
|
|
||||||
UINT32 target_addr;
|
|
||||||
UINT32 img_offset;
|
|
||||||
UINT32 img_size;
|
|
||||||
UINT32 hdr_next;
|
|
||||||
UINT8 img_name[128];
|
|
||||||
UINT8 res[108];
|
|
||||||
|
|
||||||
} flash_img_hdr_t;
|
|
||||||
|
|
||||||
enum srec_type
|
|
||||||
{
|
|
||||||
srec_err, srec_sob, srec_data, srec_rec, srec_eob
|
|
||||||
};
|
|
||||||
|
|
||||||
UINT8 h2i(UINT8 *c)
|
|
||||||
{
|
|
||||||
int i;
|
|
||||||
UINT8 t, b = 0;
|
|
||||||
|
|
||||||
for (i=0; i < 2; i++)
|
|
||||||
{
|
|
||||||
t = c[i];
|
|
||||||
if (t >= 'A')
|
|
||||||
t = t - 'A' + 10;
|
|
||||||
else
|
|
||||||
t -= '0';
|
|
||||||
|
|
||||||
b = (b << 4) | t;
|
|
||||||
}
|
|
||||||
return b;
|
|
||||||
}
|
|
||||||
|
|
||||||
int decode_srec(srec_t *pRec, UINT8 *pBuf, int buflen)
|
|
||||||
{
|
|
||||||
UINT8 chksum, byte;
|
|
||||||
int alen, i;
|
|
||||||
|
|
||||||
if (!buflen)
|
|
||||||
return srec_err;
|
|
||||||
|
|
||||||
pRec->type = srec_rec;
|
|
||||||
alen = 0;
|
|
||||||
if ((pBuf[1] > '0') && (pBuf[1] < '4'))
|
|
||||||
{
|
|
||||||
alen = pBuf[1] - '0' + 1;
|
|
||||||
pRec->type = srec_data;
|
|
||||||
}
|
|
||||||
else if ((pBuf[1] >= '7') && (pBuf[1] <= '9'))
|
|
||||||
{
|
|
||||||
alen = 11 - (pBuf[1] - '0');
|
|
||||||
pRec->type = srec_eob;
|
|
||||||
}
|
|
||||||
else if (pBuf[1] == '0')
|
|
||||||
{
|
|
||||||
alen = 2;
|
|
||||||
pRec->type = srec_sob;
|
|
||||||
}
|
|
||||||
|
|
||||||
byte = h2i(&pBuf[2]);
|
|
||||||
pRec->size = byte;
|
|
||||||
chksum = byte;
|
|
||||||
|
|
||||||
pRec->addr = 0;
|
|
||||||
for (i=0; i < alen; i++)
|
|
||||||
{
|
|
||||||
byte = h2i(&pBuf[4+2*i]);
|
|
||||||
pRec->addr = pRec->addr << 8 | byte;
|
|
||||||
chksum += byte;
|
|
||||||
}
|
|
||||||
pRec->size -= (alen+1);
|
|
||||||
|
|
||||||
pRec->data = (UINT8*) &pBuf[4 + 2*alen];
|
|
||||||
for (i=0; i < (int)pRec->size; i++)
|
|
||||||
{
|
|
||||||
byte = h2i(&pRec->data[2*i]);
|
|
||||||
pRec->data[i] = byte;
|
|
||||||
chksum += byte;
|
|
||||||
}
|
|
||||||
chksum = ~chksum;
|
|
||||||
byte = h2i(&pRec->data[2*i]);
|
|
||||||
if (chksum != byte)
|
|
||||||
return 0;
|
|
||||||
|
|
||||||
return pRec->type;
|
|
||||||
}
|
|
||||||
|
|
||||||
int srec_getline(UINT8 *pLine)
|
|
||||||
{
|
|
||||||
char c;
|
|
||||||
int i = 0;
|
|
||||||
|
|
||||||
do
|
|
||||||
{
|
|
||||||
c = readchar();
|
|
||||||
|
|
||||||
} while ((c != 's') && (c != 'S'));
|
|
||||||
|
|
||||||
while(((c != 0x0D) && (c != 0x0A)))
|
|
||||||
{
|
|
||||||
pLine[i++] = c;
|
|
||||||
c = readchar();
|
|
||||||
};
|
|
||||||
|
|
||||||
return i;
|
|
||||||
}
|
|
||||||
|
|
||||||
void Jump_to(void *pEntry)
|
|
||||||
{
|
|
||||||
__asm
|
|
||||||
(
|
|
||||||
".set noreorder\n"
|
|
||||||
);
|
|
||||||
__asm
|
|
||||||
(
|
|
||||||
"jr %[pEntry]\n" // jump entry
|
|
||||||
:
|
|
||||||
: [pEntry] "r" (pEntry)
|
|
||||||
);
|
|
||||||
__asm
|
|
||||||
(
|
|
||||||
"nop\n"
|
|
||||||
);
|
|
||||||
__asm
|
|
||||||
(
|
|
||||||
".set reorder\n"
|
|
||||||
);
|
|
||||||
}
|
|
||||||
|
|
||||||
void Exec_at(void *pEntry)
|
|
||||||
{
|
|
||||||
__asm
|
|
||||||
(
|
|
||||||
".set noreorder\n"
|
|
||||||
);
|
|
||||||
|
|
||||||
__asm
|
|
||||||
(
|
|
||||||
"mfc0 $26, $12\n" // change exception vector
|
|
||||||
"li $27, 0xFFBFFFFF\n"
|
|
||||||
"and $26, $27\n"
|
|
||||||
"mtc0 $26, $12\n"
|
|
||||||
);
|
|
||||||
|
|
||||||
__asm
|
|
||||||
(
|
|
||||||
"jr %[pEntry]\n" // jump entry
|
|
||||||
:
|
|
||||||
: [pEntry] "r" (pEntry)
|
|
||||||
);
|
|
||||||
|
|
||||||
__asm
|
|
||||||
(
|
|
||||||
"rfe\n"
|
|
||||||
);
|
|
||||||
|
|
||||||
__asm
|
|
||||||
(
|
|
||||||
".set reorder\n"
|
|
||||||
);
|
|
||||||
}
|
|
||||||
|
|
||||||
void PrintCPUinfo(void)
|
|
||||||
{
|
|
||||||
int result, rev_id;
|
|
||||||
|
|
||||||
char *cpu_type_str[7] = {"invalid", "R2000", "R3000", "R6000", "R4000", "reserved", "R6000A"};
|
|
||||||
|
|
||||||
// Print Status register
|
|
||||||
result = CP0_SR_read();
|
|
||||||
|
|
||||||
sputs("Status : ");
|
|
||||||
print_word(result);
|
|
||||||
sputs("\n");
|
|
||||||
|
|
||||||
// Print Revision
|
|
||||||
result = CP0_PRID_read();
|
|
||||||
rev_id = (result >> 8) & 0xFF;
|
|
||||||
sputs("CPU type: ");
|
|
||||||
if ((rev_id > 0) && (rev_id < 0x07))
|
|
||||||
{
|
|
||||||
sputs(cpu_type_str[rev_id]);
|
|
||||||
sputs(" Rev.");
|
|
||||||
rev_id = result & 0xFF;
|
|
||||||
print_byte((char)rev_id);
|
|
||||||
}
|
|
||||||
else
|
|
||||||
sputs("Unknown");
|
|
||||||
|
|
||||||
sputs("\n");
|
|
||||||
|
|
||||||
}
|
|
||||||
|
|
||||||
#define MAX_IMG_SIZE (1024*1024) // bytes
|
|
||||||
#define SDRAM_BASE 0x40000000
|
|
||||||
#define FLASH_OFFSET 0x00000000
|
|
||||||
|
|
||||||
int main(int argc, char *argv[])
|
|
||||||
{
|
|
||||||
UINT8 buf[256];
|
|
||||||
srec_t srec;
|
|
||||||
int result, srec_state, i;
|
|
||||||
UINT32 haddr;
|
|
||||||
flash_t flash;
|
|
||||||
flash_img_hdr_t img_hdr = {0};
|
|
||||||
flash_img_hdr_t *pImg_hdr;
|
|
||||||
UINT32 img_size;
|
|
||||||
|
|
||||||
volatile UINT32 *pReg = (UINT32*)sys_led_port;
|
|
||||||
volatile UINT32 *pBtn = (UINT32*)sys_gpio0;
|
|
||||||
volatile UINT8 *pMem;
|
|
||||||
volatile UINT32 *pROM32;
|
|
||||||
volatile UINT32 *pMem32;
|
|
||||||
volatile UINT32 *pFlash = (UINT32*)sys_flash_io;
|
|
||||||
volatile UINT32 *pUSB = (UINT32*)sys_usb_data;
|
|
||||||
|
|
||||||
volatile UINT8 *ram8 = (UINT8*)SDRAM_BASE;
|
|
||||||
volatile UINT16 *ram16 = (UINT16*)SDRAM_BASE;
|
|
||||||
volatile UINT32 *ram32 = (UINT32*)SDRAM_BASE;
|
|
||||||
|
|
||||||
*pReg = 0;
|
|
||||||
haddr = 0;
|
|
||||||
|
|
||||||
// ----------------------------------------------------------
|
|
||||||
ram32 = (UINT32*)(SDRAM_BASE);
|
|
||||||
pFlash = (UINT32*)(sys_flash_io + FLASH_OFFSET);
|
|
||||||
|
|
||||||
if (!*pBtn)
|
|
||||||
{
|
|
||||||
sputs("\n\n");
|
|
||||||
sputs("Booting from flash...");
|
|
||||||
|
|
||||||
pImg_hdr = (flash_img_hdr_t*)pFlash;
|
|
||||||
ram32 = (UINT32*)pImg_hdr->target_addr;
|
|
||||||
pFlash = (UINT32*)(sys_flash_io + pImg_hdr->img_offset);
|
|
||||||
img_size = pImg_hdr->img_size;
|
|
||||||
|
|
||||||
for (i=0; i < img_size/4; i++)
|
|
||||||
ram32[i] = pFlash[i];
|
|
||||||
|
|
||||||
sputs("done\n\n");
|
|
||||||
|
|
||||||
Exec_at((void*)ram32);
|
|
||||||
}
|
|
||||||
else
|
|
||||||
{
|
|
||||||
|
|
||||||
if (flash_find(&flash, sys_flash_io) < 0)
|
|
||||||
{
|
|
||||||
sputs("Cannot find flash device. Exit now!\n\n");
|
|
||||||
return 1;
|
|
||||||
}
|
|
||||||
|
|
||||||
// Erase SDRAM
|
|
||||||
for (i=0; i < MAX_IMG_SIZE/4; i++)
|
|
||||||
ram32[i] = 0;
|
|
||||||
|
|
||||||
sputs("\n\n");
|
|
||||||
sputs("Booting from UART..");
|
|
||||||
|
|
||||||
while(1)
|
|
||||||
{
|
|
||||||
sputs(".");
|
|
||||||
while(1)
|
|
||||||
{
|
|
||||||
result = srec_getline(buf);
|
|
||||||
srec_state = decode_srec(&srec, buf, result);
|
|
||||||
*pReg = 0;
|
|
||||||
switch (srec_state)
|
|
||||||
{
|
|
||||||
case srec_data:
|
|
||||||
if ((srec.addr + srec.size) > haddr)
|
|
||||||
haddr = srec.addr + srec.size;
|
|
||||||
|
|
||||||
pMem = (UINT8*)srec.addr;
|
|
||||||
for (i=0; i < srec.size; i++)
|
|
||||||
*pMem++ = srec.data[i];
|
|
||||||
|
|
||||||
break;
|
|
||||||
|
|
||||||
case srec_eob:
|
|
||||||
sputs("done\n\n");
|
|
||||||
|
|
||||||
img_hdr.magic[0] = 'J';
|
|
||||||
img_hdr.magic[1] = 'F';
|
|
||||||
img_hdr.magic[2] = 'I';
|
|
||||||
img_hdr.magic[3] = '1';
|
|
||||||
img_hdr.target_addr = srec.addr;
|
|
||||||
img_hdr.img_size = haddr - srec.addr;
|
|
||||||
img_hdr.img_offset = FLASH_OFFSET + sizeof(flash_img_hdr_t);
|
|
||||||
img_hdr.hdr_next = FLASH_OFFSET;
|
|
||||||
|
|
||||||
sputs("Flash erase...");
|
|
||||||
result = flash_erase(&flash, FLASH_OFFSET, img_hdr.img_size + sizeof(flash_img_hdr_t));
|
|
||||||
if (result < 0)
|
|
||||||
{
|
|
||||||
sputs("failed!\n");
|
|
||||||
break;
|
|
||||||
}
|
|
||||||
sputs("done\n");
|
|
||||||
|
|
||||||
sputs("Flash write...");
|
|
||||||
result = flash_program(&flash, FLASH_OFFSET, (UINT8*)&img_hdr, sizeof(flash_img_hdr_t));
|
|
||||||
if (result < 0)
|
|
||||||
{
|
|
||||||
sputs("failed!\n");
|
|
||||||
break;
|
|
||||||
}
|
|
||||||
result = flash_program(&flash, img_hdr.img_offset, (UINT8*)ram32, img_hdr.img_size);
|
|
||||||
if (result < 0)
|
|
||||||
{
|
|
||||||
sputs("failed!\n");
|
|
||||||
break;
|
|
||||||
}
|
|
||||||
sputs("done\n");
|
|
||||||
|
|
||||||
sputs("Flash verify...");
|
|
||||||
result = flash_verify(&flash, img_hdr.img_offset, (UINT8*)ram32, img_hdr.img_size);
|
|
||||||
if (result < 0)
|
|
||||||
{
|
|
||||||
sputs("failed!\n");
|
|
||||||
break;
|
|
||||||
}
|
|
||||||
sputs("passed\n");
|
|
||||||
Jump_to((void*)0xBFC00000);
|
|
||||||
// sputs("\nPush reset button to boot!\n");
|
|
||||||
// *pReg = 1;
|
|
||||||
|
|
||||||
break;
|
|
||||||
|
|
||||||
default:
|
|
||||||
result = -1;
|
|
||||||
break;
|
|
||||||
}
|
|
||||||
if (result < 0)
|
|
||||||
{
|
|
||||||
*pReg = 0x40000000;
|
|
||||||
break;
|
|
||||||
}
|
|
||||||
|
|
||||||
};
|
|
||||||
}
|
|
||||||
}
|
|
||||||
return 0;
|
|
||||||
}
|
|
||||||
|
|
||||||
@@ -1,208 +0,0 @@
|
|||||||
.file "init.S"
|
|
||||||
|
|
||||||
.text
|
|
||||||
.align 2
|
|
||||||
.globl _init
|
|
||||||
.extern end
|
|
||||||
|
|
||||||
_init:
|
|
||||||
.set noreorder
|
|
||||||
|
|
||||||
# set uart
|
|
||||||
la $26, sys_uart_baud
|
|
||||||
addiu $27, $0, baudrate
|
|
||||||
sb $27, 0($26)
|
|
||||||
|
|
||||||
# set stack pointer
|
|
||||||
la $sp, stack_ptr
|
|
||||||
# j $jmain
|
|
||||||
|
|
||||||
# TEST
|
|
||||||
li $26, +5
|
|
||||||
beqz $26, _terminate
|
|
||||||
li $26, -5
|
|
||||||
beqz $26, _terminate
|
|
||||||
li $26, 0
|
|
||||||
beqz $26, $_L11
|
|
||||||
nop
|
|
||||||
j _terminate
|
|
||||||
nop
|
|
||||||
$_L11:
|
|
||||||
li $26, +5
|
|
||||||
li $27, +6
|
|
||||||
beq $26, $27, _terminate
|
|
||||||
li $26, -5
|
|
||||||
beq $26, $27, _terminate
|
|
||||||
li $26, 0
|
|
||||||
beq $26, $27, _terminate
|
|
||||||
li $26, +6
|
|
||||||
beq $26, $27, $_L12
|
|
||||||
nop
|
|
||||||
j _terminate
|
|
||||||
nop
|
|
||||||
$_L12:
|
|
||||||
li $26, -5
|
|
||||||
bgez $26, _terminate
|
|
||||||
li $26, +5
|
|
||||||
bgez $26, $_L13
|
|
||||||
nop
|
|
||||||
j _terminate
|
|
||||||
$_L13: li $26, 0
|
|
||||||
bgez $26, $_L14
|
|
||||||
nop
|
|
||||||
j _terminate
|
|
||||||
$_L14:
|
|
||||||
li $26, -5
|
|
||||||
bgtz $26, _terminate
|
|
||||||
li $26, 0
|
|
||||||
bgtz $26, _terminate
|
|
||||||
li $26, +5
|
|
||||||
bgtz $26, $_L15
|
|
||||||
nop
|
|
||||||
j _terminate
|
|
||||||
|
|
||||||
$_L15:
|
|
||||||
li $26, +5
|
|
||||||
blez $26, _terminate
|
|
||||||
li $26, 0
|
|
||||||
blez $26, $_L16
|
|
||||||
nop
|
|
||||||
j _terminate
|
|
||||||
$_L16: li $26, -5
|
|
||||||
blez $26, $_L17
|
|
||||||
nop
|
|
||||||
j _terminate
|
|
||||||
|
|
||||||
$_L17:
|
|
||||||
li $26, +5
|
|
||||||
bltz $26, _terminate
|
|
||||||
li $26, 0
|
|
||||||
bltz $26, _terminate
|
|
||||||
li $26, -5
|
|
||||||
bltz $26, $_L18
|
|
||||||
nop
|
|
||||||
j _terminate
|
|
||||||
$_L18:
|
|
||||||
li $26, +5
|
|
||||||
li $27, +6
|
|
||||||
bne $26, $27, $_L19
|
|
||||||
nop
|
|
||||||
j _terminate
|
|
||||||
$_L19: li $26, -5
|
|
||||||
bne $26, $27, $_L20
|
|
||||||
nop
|
|
||||||
j _terminate
|
|
||||||
$_L20: li $26, -6
|
|
||||||
bne $26, $27, $_L21
|
|
||||||
nop
|
|
||||||
j _terminate
|
|
||||||
$_L21: li $26, 0
|
|
||||||
bne $26, $27, $_L22
|
|
||||||
nop
|
|
||||||
j _terminate
|
|
||||||
$_L22: li $26, +6
|
|
||||||
bne $26, $27, _terminate
|
|
||||||
li $26, +5
|
|
||||||
bnez $26, $_L23
|
|
||||||
nop
|
|
||||||
j _terminate
|
|
||||||
$_L23: li $26, -5
|
|
||||||
bnez $26, $_L24
|
|
||||||
nop
|
|
||||||
j _terminate
|
|
||||||
$_L24: li $26, 0
|
|
||||||
bnez $26, _terminate
|
|
||||||
|
|
||||||
$_L25:
|
|
||||||
li $27, +5
|
|
||||||
sltiu $26,$27,+6
|
|
||||||
sltiu $26,$27,-6
|
|
||||||
li $27, -5
|
|
||||||
sltiu $26,$27,+6
|
|
||||||
sltiu $26,$27,-6
|
|
||||||
li $27, +6
|
|
||||||
sltiu $26,$27,+5
|
|
||||||
sltiu $26,$27,-5
|
|
||||||
li $27, -6
|
|
||||||
sltiu $26,$27,+5
|
|
||||||
sltiu $26,$27,-5
|
|
||||||
|
|
||||||
li $27, +5
|
|
||||||
slti $26,$27,+6
|
|
||||||
slti $26,$27,-6
|
|
||||||
li $27, -5
|
|
||||||
slti $26,$27,+6
|
|
||||||
slti $26,$27,-6
|
|
||||||
li $27, +6
|
|
||||||
slti $26,$27,+5
|
|
||||||
slti $26,$27,-5
|
|
||||||
li $27, -6
|
|
||||||
slti $26,$27,+5
|
|
||||||
slti $26,$27,-5
|
|
||||||
|
|
||||||
|
|
||||||
li $26, +5
|
|
||||||
li $27, +6
|
|
||||||
sltu $26,$26,$27
|
|
||||||
li $26, +5
|
|
||||||
li $27, -6
|
|
||||||
sltu $26,$26,$27
|
|
||||||
li $26, -5
|
|
||||||
li $27, +6
|
|
||||||
sltu $26,$26,$27
|
|
||||||
li $26, -5
|
|
||||||
li $27, -6
|
|
||||||
sltu $26,$26,$27
|
|
||||||
|
|
||||||
li $26, +6
|
|
||||||
li $27, +5
|
|
||||||
sltu $26,$26,$27
|
|
||||||
li $26, +6
|
|
||||||
li $27, -5
|
|
||||||
sltu $26,$26,$27
|
|
||||||
li $26, -6
|
|
||||||
li $27, +5
|
|
||||||
sltu $26,$26,$27
|
|
||||||
li $26, -6
|
|
||||||
li $27, -5
|
|
||||||
sltu $26,$26,$27
|
|
||||||
|
|
||||||
li $26, +5
|
|
||||||
li $27, +6
|
|
||||||
slt $26,$26,$27
|
|
||||||
li $26, +5
|
|
||||||
li $27, -6
|
|
||||||
slt $26,$26,$27
|
|
||||||
li $26, -5
|
|
||||||
li $27, +6
|
|
||||||
slt $26,$26,$27
|
|
||||||
li $26, -5
|
|
||||||
li $27, -6
|
|
||||||
slt $26,$26,$27
|
|
||||||
|
|
||||||
li $26, +6
|
|
||||||
li $27, +5
|
|
||||||
slt $26,$26,$27
|
|
||||||
li $26, +6
|
|
||||||
li $27, -5
|
|
||||||
slt $26,$26,$27
|
|
||||||
li $26, -6
|
|
||||||
li $27, +5
|
|
||||||
slt $26,$26,$27
|
|
||||||
li $26, -6
|
|
||||||
li $27, -5
|
|
||||||
slt $26,$26,$27
|
|
||||||
|
|
||||||
# TEST
|
|
||||||
|
|
||||||
|
|
||||||
# jump main
|
|
||||||
$jmain: la $26, main
|
|
||||||
jalr $26
|
|
||||||
|
|
||||||
_terminate:
|
|
||||||
nop
|
|
||||||
j _terminate
|
|
||||||
nop
|
|
||||||
|
|
||||||
.set reorder
|
|
||||||
@@ -1,46 +0,0 @@
|
|||||||
.file "kernel.S"
|
|
||||||
|
|
||||||
.section .ktext,"ax"
|
|
||||||
.align 2
|
|
||||||
|
|
||||||
.macro kpush reg
|
|
||||||
addiu $sp, 4
|
|
||||||
sw \reg, 0($sp)
|
|
||||||
.endm
|
|
||||||
|
|
||||||
.macro kpop reg
|
|
||||||
lw \reg, 0($sp)
|
|
||||||
addiu $sp, -4
|
|
||||||
.endm
|
|
||||||
|
|
||||||
_exc_handler:
|
|
||||||
|
|
||||||
.set noreorder
|
|
||||||
|
|
||||||
# Set Error LED and ExcCode LEDs
|
|
||||||
# Get Cause
|
|
||||||
mfc0 $26, $13
|
|
||||||
li $27, 0xC0000000
|
|
||||||
srl $26, 2
|
|
||||||
andi $26, 0x000F
|
|
||||||
or $26, $27
|
|
||||||
la $27, sys_led_port
|
|
||||||
sw $26, 0($27)
|
|
||||||
|
|
||||||
# wait for all interrupts = 0
|
|
||||||
$w4x: mfc0 $26, $13
|
|
||||||
nop
|
|
||||||
srl $26, 8
|
|
||||||
andi $26, 0xFF
|
|
||||||
bnez $26, $w4x
|
|
||||||
nop
|
|
||||||
|
|
||||||
# Get return address
|
|
||||||
mfc0 $26, $14
|
|
||||||
|
|
||||||
# Return
|
|
||||||
nop
|
|
||||||
jr $26
|
|
||||||
rfe
|
|
||||||
.set reorder
|
|
||||||
|
|
||||||
@@ -1,142 +0,0 @@
|
|||||||
#include <sys/times.h>
|
|
||||||
#include <sys/time.h>
|
|
||||||
#include <sys/resource.h>
|
|
||||||
#include <sys/stat.h>
|
|
||||||
#include <errno.h>
|
|
||||||
#include <stdlib.h>
|
|
||||||
#include "libsys_boot.h"
|
|
||||||
|
|
||||||
// ---------------------------------------------------------------------------------
|
|
||||||
// MIPS specific
|
|
||||||
UINT32 CP0_SR_read(void)
|
|
||||||
{
|
|
||||||
UINT32 result;
|
|
||||||
|
|
||||||
__asm
|
|
||||||
(
|
|
||||||
"mfc0 %[val], $12\n"
|
|
||||||
: [val] "=r" (result)
|
|
||||||
);
|
|
||||||
|
|
||||||
return result;
|
|
||||||
}
|
|
||||||
|
|
||||||
void CP0_SR_write(UINT32 val)
|
|
||||||
{
|
|
||||||
__asm
|
|
||||||
(
|
|
||||||
"mtc0 %[val], $12\n"
|
|
||||||
: /* no output */
|
|
||||||
: [val] "r" (val)
|
|
||||||
);
|
|
||||||
}
|
|
||||||
|
|
||||||
UINT32 CP0_CR_read(void)
|
|
||||||
{
|
|
||||||
UINT32 result;
|
|
||||||
|
|
||||||
__asm
|
|
||||||
(
|
|
||||||
"mfc0 %[val], $13\n"
|
|
||||||
: [val] "=r" (result)
|
|
||||||
);
|
|
||||||
|
|
||||||
return result;
|
|
||||||
}
|
|
||||||
|
|
||||||
void CP0_CR_write(UINT32 val)
|
|
||||||
{
|
|
||||||
__asm
|
|
||||||
(
|
|
||||||
"mtc0 %[val], $13\n"
|
|
||||||
:
|
|
||||||
: [val] "r" (val)
|
|
||||||
);
|
|
||||||
}
|
|
||||||
|
|
||||||
UINT32 CP0_PRID_read(void)
|
|
||||||
{
|
|
||||||
UINT32 result;
|
|
||||||
|
|
||||||
__asm
|
|
||||||
(
|
|
||||||
"mfc0 %[val], $15\n"
|
|
||||||
: [val] "=r" (result)
|
|
||||||
);
|
|
||||||
|
|
||||||
return result;
|
|
||||||
}
|
|
||||||
|
|
||||||
// ---------------------------------------------------------------------------------
|
|
||||||
char readchar(void)
|
|
||||||
{
|
|
||||||
volatile UINT32 *pUART_stat = (UINT32*)sys_uart_stat;
|
|
||||||
volatile UINT32 *pUART_data = (UINT32*)sys_uart_data;
|
|
||||||
|
|
||||||
while(!(0x10 & *pUART_stat));
|
|
||||||
|
|
||||||
return (char)*pUART_data;
|
|
||||||
}
|
|
||||||
|
|
||||||
void writechar(char c)
|
|
||||||
{
|
|
||||||
volatile UINT32 *pUART_stat = (UINT32*)sys_uart_stat;
|
|
||||||
volatile UINT32 *pUART_data = (UINT32*)sys_uart_data;
|
|
||||||
|
|
||||||
while((0x02 & *pUART_stat) != 0);
|
|
||||||
|
|
||||||
*pUART_data = (UINT32)c;
|
|
||||||
}
|
|
||||||
|
|
||||||
void _putchar(char c)
|
|
||||||
{
|
|
||||||
if (c == 0x0A)
|
|
||||||
{
|
|
||||||
writechar(0x0D);
|
|
||||||
}
|
|
||||||
writechar(c);
|
|
||||||
}
|
|
||||||
|
|
||||||
int sputs(char *pStr)
|
|
||||||
{
|
|
||||||
char *start;
|
|
||||||
start = pStr;
|
|
||||||
|
|
||||||
while(*pStr)
|
|
||||||
_putchar(*(pStr++));
|
|
||||||
|
|
||||||
return pStr - start;
|
|
||||||
}
|
|
||||||
|
|
||||||
void print_byte(char byte)
|
|
||||||
{
|
|
||||||
int i;
|
|
||||||
unsigned char c, nibble;
|
|
||||||
|
|
||||||
for (i=0; i < 2; i++)
|
|
||||||
{
|
|
||||||
nibble = (char)((byte >> 4) & 0xF);
|
|
||||||
byte <<= 4;
|
|
||||||
|
|
||||||
if (nibble < 10)
|
|
||||||
c = nibble + '0';
|
|
||||||
else
|
|
||||||
c = nibble + 'A' - 10;
|
|
||||||
|
|
||||||
_putchar(c);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
void print_word(int word)
|
|
||||||
{
|
|
||||||
int i;
|
|
||||||
unsigned char c, nibble;
|
|
||||||
|
|
||||||
for (i=0; i < 4; i++)
|
|
||||||
{
|
|
||||||
c = (char) (word >> 24);
|
|
||||||
print_byte(c);
|
|
||||||
word <<= 8;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
@@ -1,50 +0,0 @@
|
|||||||
#ifndef LIBSYS_H
|
|
||||||
#define LIBSYS_H
|
|
||||||
|
|
||||||
// ---------------------------------------------------------
|
|
||||||
// Types
|
|
||||||
// ---------------------------------------------------------
|
|
||||||
#define INT8 char
|
|
||||||
#define INT16 short
|
|
||||||
#define INT32 long
|
|
||||||
#define UINT8 unsigned char
|
|
||||||
#define UINT16 unsigned short
|
|
||||||
#define UINT32 unsigned long
|
|
||||||
#define INT int
|
|
||||||
#define UINT unsigned int
|
|
||||||
#define FLOAT32 float
|
|
||||||
#define FLOAT64 double
|
|
||||||
|
|
||||||
|
|
||||||
#define sys_gpio0 0xA0000000
|
|
||||||
#define sys_gpio1 0xA0000004
|
|
||||||
#define sys_led_port sys_gpio0
|
|
||||||
#define sys_usb_ctrl sys_gpio1
|
|
||||||
#define sys_timer_usec 0xA0000008
|
|
||||||
#define sys_timer_sec 0xA000000C
|
|
||||||
#define sys_uart_data 0xA0010000
|
|
||||||
#define sys_uart_stat 0xA0010004
|
|
||||||
#define sys_uart_baud 0xA0010008
|
|
||||||
#define sys_usb_data 0xA0020000
|
|
||||||
#define sys_usb_mbx 0xA0020004
|
|
||||||
#define sys_usb_addr 0xA0020008
|
|
||||||
#define sys_usb_status 0xA002000C
|
|
||||||
#define sys_flash_io 0xA4000000
|
|
||||||
|
|
||||||
// MIPS specific
|
|
||||||
UINT32 CP0_SR_read(void);
|
|
||||||
void CP0_SR_write(UINT32 val);
|
|
||||||
UINT32 CP0_CR_read(void);
|
|
||||||
void CP0_CR_write(UINT32 val);
|
|
||||||
UINT32 CP0_PRID_read(void);
|
|
||||||
|
|
||||||
// General
|
|
||||||
char readchar(void);
|
|
||||||
void writechar(char c);
|
|
||||||
int write(int file, char *ptr, int len);
|
|
||||||
int sputs(char *pStr);
|
|
||||||
void print_byte(char byte);
|
|
||||||
void print_word(int word);
|
|
||||||
|
|
||||||
#endif // LIBSYS_H
|
|
||||||
|
|
||||||
@@ -1,25 +0,0 @@
|
|||||||
.file "startup.S"
|
|
||||||
|
|
||||||
.section .stext,"ax"
|
|
||||||
.extern _init
|
|
||||||
.align 2
|
|
||||||
|
|
||||||
_start:
|
|
||||||
.set noreorder
|
|
||||||
|
|
||||||
# Set Kernel mode
|
|
||||||
li $26, 0x1040000C
|
|
||||||
mtc0 $26, $12
|
|
||||||
li $26, 0x00000000
|
|
||||||
mtc0 $26, $13
|
|
||||||
|
|
||||||
mfc0 $26, $15
|
|
||||||
nop
|
|
||||||
mtc0 $26, $31
|
|
||||||
|
|
||||||
# jump init
|
|
||||||
la $26, _init
|
|
||||||
jr $26
|
|
||||||
nop
|
|
||||||
|
|
||||||
.set reorder
|
|
||||||
@@ -1,253 +0,0 @@
|
|||||||
#include <stdio.h>
|
|
||||||
#include <stdlib.h>
|
|
||||||
#include "libsys.h"
|
|
||||||
#include "cfiflash.h"
|
|
||||||
|
|
||||||
UINT32 cfi_get_status(flash_t *pObj)
|
|
||||||
{
|
|
||||||
volatile UINT32 *pF;
|
|
||||||
UINT32 status;
|
|
||||||
|
|
||||||
pF = (UINT32*)pObj->pBase;
|
|
||||||
|
|
||||||
*pF = 0x00700070;
|
|
||||||
|
|
||||||
status = *pF;
|
|
||||||
|
|
||||||
*pF = 0x00FF00FF;
|
|
||||||
|
|
||||||
return status;
|
|
||||||
|
|
||||||
}
|
|
||||||
|
|
||||||
void cfi_init(flash_t *pObj, UINT32 base_addr)
|
|
||||||
{
|
|
||||||
int i;
|
|
||||||
UINT8 *pInfo;
|
|
||||||
|
|
||||||
pObj->pBase = (void*)base_addr;
|
|
||||||
|
|
||||||
pInfo = (UINT8*)&pObj->info;
|
|
||||||
for (i=0; i < sizeof(flash_info_t); i++)
|
|
||||||
{
|
|
||||||
pInfo[i] = 0;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
UINT32 cfi_find(flash_t *pObj)
|
|
||||||
{
|
|
||||||
int i;
|
|
||||||
volatile UINT32 *pF;
|
|
||||||
volatile UINT16 *pF16;
|
|
||||||
UINT8 qry_ref[12] = {0x51, 0x00, 0x51, 0x00, 0x52, 0x00, 0x52, 0x00, 0x59, 0x00, 0x59, 0x00};
|
|
||||||
UINT32 size;
|
|
||||||
|
|
||||||
pF = (UINT32*)pObj->pBase;
|
|
||||||
pF16 = (UINT16*)pObj->pBase;
|
|
||||||
|
|
||||||
// Look for flash
|
|
||||||
*pF = 0x00980098;
|
|
||||||
for (i=0; i < sizeof(qry_ref); i++)
|
|
||||||
if (((UINT8*)(&pF[0x10]))[i] != qry_ref[i])
|
|
||||||
return (UINT32)-1;
|
|
||||||
|
|
||||||
*pF = 0x00FF00FF;
|
|
||||||
*pF = 0x00900090;
|
|
||||||
|
|
||||||
/*
|
|
||||||
printf("ManID : %8.8X\n", (UINT32)pF[0]);
|
|
||||||
printf("Device code : %8.8X\n", (UINT32)pF[1]);
|
|
||||||
printf("Block info : %8.8X\n", (UINT32)pF[2]);
|
|
||||||
|
|
||||||
printf("VCC(min) : %8.8X\n", (UINT32)pF[0x1B]);
|
|
||||||
printf("VCC(max) : %8.8X\n", (UINT32)pF[0x1C]);
|
|
||||||
printf("VPP(min) : %8.8X\n", (UINT32)pF[0x1D]);
|
|
||||||
printf("VPP(max) : %8.8X\n", (UINT32)pF[0x1E]);
|
|
||||||
printf("Device Layout : %8.8X\n", (UINT32)pF[0x27]);
|
|
||||||
printf("Interface type : %8.8X %8.8X\n", (UINT32)pF[0x28], (UINT32)pF[0x29]);
|
|
||||||
printf("Write buffer size : %8.8X %8.8X\n", (UINT32)pF[0x2A], (UINT32)pF[0x2B]);
|
|
||||||
printf("Num. erase blocks : %8.8X\n", (UINT32)pF[0x2C]);
|
|
||||||
printf("Erase block info : %8.8X %8.8X %8.8X %8.8X\n", (UINT32)pF[0x2D], (UINT32)pF[0x2E], (UINT32)pF[0x2F], (UINT32)pF[0x30]);
|
|
||||||
*/
|
|
||||||
pObj->info.num_flash = 2;
|
|
||||||
pObj->info.if_width = 32;
|
|
||||||
size = (UINT32)pF16[2*0x27];
|
|
||||||
pObj->info.flashsize = pObj->info.num_flash;
|
|
||||||
for (i=0; i < size; i++)
|
|
||||||
pObj->info.flashsize *= 2;
|
|
||||||
|
|
||||||
size = (UINT32)(pF16[2*0x2B] << 8 | pF16[2*0x2A]);
|
|
||||||
pObj->info.wbuf_size = pObj->info.num_flash;
|
|
||||||
for (i=0; i < size; i++)
|
|
||||||
pObj->info.wbuf_size *= 2;
|
|
||||||
|
|
||||||
pObj->info.nblocks = pObj->info.num_flash * ((UINT32)(pF16[2*0x2E] << 8 | pF16[2*0x2D]) + 1);
|
|
||||||
pObj->info.blocksize = pObj->info.num_flash * ((UINT32)(pF16[2*0x30] << 8 | pF16[2*0x2F]) * 256);
|
|
||||||
|
|
||||||
*pF = 0x00FF00FF;
|
|
||||||
|
|
||||||
return 0;
|
|
||||||
}
|
|
||||||
|
|
||||||
UINT32 cfi_block_erase(flash_t *pObj, UINT32 word_index)
|
|
||||||
{
|
|
||||||
volatile UINT32 *pF;
|
|
||||||
UINT32 status, block_index, block_mask;
|
|
||||||
|
|
||||||
pF = (UINT32*)pObj->pBase;
|
|
||||||
|
|
||||||
if (word_index >= (pObj->info.flashsize/4))
|
|
||||||
return -1;
|
|
||||||
|
|
||||||
block_mask = ((pObj->info.nblocks-1) << 16);
|
|
||||||
block_index = word_index & block_mask;
|
|
||||||
|
|
||||||
pF[block_index] = 0x00200020;
|
|
||||||
pF[block_index] = 0x00D000D0;
|
|
||||||
|
|
||||||
do
|
|
||||||
{
|
|
||||||
status = pF[block_index];
|
|
||||||
|
|
||||||
} while((status & SR_BIT_ISMS) != SR_BIT_ISMS);
|
|
||||||
|
|
||||||
pF[block_index] = 0x00FF00FF;
|
|
||||||
|
|
||||||
return 0;
|
|
||||||
}
|
|
||||||
|
|
||||||
UINT32 cfi_program_single(flash_t *pObj, UINT32 word_index, UINT32 word)
|
|
||||||
{
|
|
||||||
volatile UINT32 *pF;
|
|
||||||
UINT32 status;
|
|
||||||
|
|
||||||
pF = (UINT32*)pObj->pBase;
|
|
||||||
|
|
||||||
if (word_index >= (pObj->info.flashsize/4))
|
|
||||||
return -1;
|
|
||||||
|
|
||||||
pF[word_index] = 0x00400040;
|
|
||||||
pF[word_index] = word;
|
|
||||||
|
|
||||||
do
|
|
||||||
{
|
|
||||||
status = pF[word_index];
|
|
||||||
|
|
||||||
} while((status & SR_BIT_ISMS) != SR_BIT_ISMS);
|
|
||||||
|
|
||||||
pF[word_index] = 0x00FF00FF;
|
|
||||||
|
|
||||||
return 0;
|
|
||||||
|
|
||||||
}
|
|
||||||
|
|
||||||
UINT32 cfi_program_multi(flash_t *pObj, UINT32 word_index, UINT32 *pWords, UINT32 num_words)
|
|
||||||
{
|
|
||||||
int i, j, k;
|
|
||||||
volatile UINT32 *pF;
|
|
||||||
UINT32 status, bcurr, bnext, block_mask, nblock_write, nbuf_write;
|
|
||||||
|
|
||||||
pF = (UINT32*)pObj->pBase;
|
|
||||||
|
|
||||||
if (word_index >= (pObj->info.flashsize/4))
|
|
||||||
return -1;
|
|
||||||
|
|
||||||
block_mask = ((pObj->info.nblocks-1) << 16);
|
|
||||||
|
|
||||||
k = 0;
|
|
||||||
while(num_words)
|
|
||||||
{
|
|
||||||
|
|
||||||
bcurr = word_index & block_mask;
|
|
||||||
bnext = bcurr + (1 << 16);
|
|
||||||
nblock_write = bnext - word_index;
|
|
||||||
if (nblock_write > num_words)
|
|
||||||
nblock_write = num_words;
|
|
||||||
|
|
||||||
// printf("bcurr : %8.8X\n", bcurr);
|
|
||||||
// printf("bnext : %8.8X\n", bnext);
|
|
||||||
// printf("windex : %8.8X\n", word_index);
|
|
||||||
// printf("num_words : %d\n", num_words);
|
|
||||||
// printf("nblock_write : %d\n", nblock_write);
|
|
||||||
|
|
||||||
while(nblock_write)
|
|
||||||
{
|
|
||||||
pF[bcurr] = 0x00E800E8;
|
|
||||||
do
|
|
||||||
{
|
|
||||||
status = pF[bcurr];
|
|
||||||
// printf("status : %8.8X\n", status);
|
|
||||||
|
|
||||||
} while((status & SR_BIT_ISMS) != SR_BIT_ISMS);
|
|
||||||
|
|
||||||
nbuf_write = nblock_write;
|
|
||||||
if (nblock_write > pObj->info.wbuf_size/4)
|
|
||||||
nbuf_write = pObj->info.wbuf_size/4;
|
|
||||||
|
|
||||||
// printf("nbuf_write : %d\n", nbuf_write);
|
|
||||||
|
|
||||||
pF[bcurr] = (nbuf_write-1) << 16 | (nbuf_write-1);
|
|
||||||
|
|
||||||
for (j=0; j < nbuf_write; j++)
|
|
||||||
pF[word_index+j] = pWords[k++];
|
|
||||||
|
|
||||||
word_index += j;
|
|
||||||
nblock_write -= j;
|
|
||||||
num_words -= j;
|
|
||||||
|
|
||||||
pF[bcurr] = 0x00D000D0;
|
|
||||||
do
|
|
||||||
{
|
|
||||||
status = pF[bcurr];
|
|
||||||
// printf("status : %8.8X\n", status);
|
|
||||||
|
|
||||||
} while((status & SR_BIT_ISMS) != SR_BIT_ISMS);
|
|
||||||
|
|
||||||
pF[bcurr] = 0x00FF00FF;
|
|
||||||
}
|
|
||||||
bcurr = bnext;
|
|
||||||
}
|
|
||||||
|
|
||||||
return 0;
|
|
||||||
|
|
||||||
}
|
|
||||||
|
|
||||||
UINT32 flash_find(flash_t *pObj, UINT32 base_addr)
|
|
||||||
{
|
|
||||||
cfi_init(pObj, base_addr);
|
|
||||||
return cfi_find(pObj);
|
|
||||||
}
|
|
||||||
|
|
||||||
UINT32 flash_erase(flash_t *pObj, UINT32 offset, UINT32 size)
|
|
||||||
{
|
|
||||||
int i;
|
|
||||||
UINT32 offset_end;
|
|
||||||
|
|
||||||
offset_end = offset + size;
|
|
||||||
|
|
||||||
for (i=offset; i < offset_end; i += pObj->info.blocksize)
|
|
||||||
if (cfi_block_erase(pObj, i/4) < 0)
|
|
||||||
return -1;
|
|
||||||
|
|
||||||
return 0;
|
|
||||||
|
|
||||||
}
|
|
||||||
|
|
||||||
UINT32 flash_program(flash_t *pObj, UINT32 offset, UINT8 *pData, UINT32 size)
|
|
||||||
{
|
|
||||||
return cfi_program_multi(pObj, offset/4, (UINT32*)pData, size/4);
|
|
||||||
}
|
|
||||||
|
|
||||||
UINT32 flash_verify(flash_t *pObj, UINT32 offset, UINT8 *pData, UINT32 size)
|
|
||||||
{
|
|
||||||
int i;
|
|
||||||
UINT8 *pF;
|
|
||||||
|
|
||||||
pF = (UINT8*)(pObj->pBase + offset);
|
|
||||||
|
|
||||||
for (i=0; i < size; i++)
|
|
||||||
if (pF[i] != pData[i])
|
|
||||||
return -1;
|
|
||||||
|
|
||||||
return 0;
|
|
||||||
}
|
|
||||||
@@ -1,44 +0,0 @@
|
|||||||
/************************************************************************/
|
|
||||||
#ifndef CFIFLASH_H
|
|
||||||
#define CFIFLASH_H
|
|
||||||
|
|
||||||
#include "libsys.h"
|
|
||||||
|
|
||||||
#define SR_BIT_DPS 0x00020002
|
|
||||||
#define SR_BIT_PSS 0x00040004
|
|
||||||
#define SR_BIT_VPENS 0x00080008
|
|
||||||
#define SR_BIT_PSLBS 0x00100010
|
|
||||||
#define SR_BIT_ECLBS 0x00200020
|
|
||||||
#define SR_BIT_ESS 0x00400040
|
|
||||||
#define SR_BIT_ISMS 0x00800080
|
|
||||||
|
|
||||||
typedef struct _sflash_info_t
|
|
||||||
{
|
|
||||||
UINT32 flashsize;
|
|
||||||
UINT32 blocksize;
|
|
||||||
UINT32 nblocks;
|
|
||||||
UINT32 wbuf_size;
|
|
||||||
UINT32 if_width;
|
|
||||||
UINT32 num_flash;
|
|
||||||
|
|
||||||
} flash_info_t;
|
|
||||||
|
|
||||||
typedef struct _sflash_t
|
|
||||||
{
|
|
||||||
void *pBase;
|
|
||||||
flash_info_t info;
|
|
||||||
|
|
||||||
} flash_t;
|
|
||||||
|
|
||||||
void cfi_init(flash_t *pObj, UINT32 base_addr);
|
|
||||||
UINT32 cfi_find(flash_t *pObj);
|
|
||||||
UINT32 cfi_block_erase(flash_t *pObj, UINT32 word_index);
|
|
||||||
UINT32 cfi_program_single(flash_t *pObj, UINT32 word_index, UINT32 word);
|
|
||||||
UINT32 cfi_program_multi(flash_t *pObj, UINT32 word_index, UINT32 *pWords, UINT32 num_words);
|
|
||||||
|
|
||||||
UINT32 flash_find(flash_t *pObj, UINT32 base_addr);
|
|
||||||
UINT32 flash_erase(flash_t *pObj, UINT32 offset, UINT32 size);
|
|
||||||
UINT32 flash_program(flash_t *pObj, UINT32 offset, UINT8 *pData, UINT32 size);
|
|
||||||
UINT32 flash_verify(flash_t *pObj, UINT32 offset, UINT8 *pData, UINT32 size);
|
|
||||||
|
|
||||||
#endif // CFIFLASH_H
|
|
||||||
@@ -1,430 +0,0 @@
|
|||||||
/*
|
|
||||||
****************************************************************************
|
|
||||||
*
|
|
||||||
* "DHRYSTONE" Benchmark Program
|
|
||||||
* -----------------------------
|
|
||||||
*
|
|
||||||
* Version: C, Version 2.1
|
|
||||||
*
|
|
||||||
* File: dhry.h (part 1 of 3)
|
|
||||||
*
|
|
||||||
* Date: May 25, 1988
|
|
||||||
*
|
|
||||||
* Author: Reinhold P. Weicker
|
|
||||||
* Siemens AG, E STE 35
|
|
||||||
* Postfach 3240
|
|
||||||
* 8520 Erlangen
|
|
||||||
* Germany (West)
|
|
||||||
* Phone: [xxx-49]-9131-7-20330
|
|
||||||
* (8-17 Central European Time)
|
|
||||||
* Usenet: ..!mcvax!unido!estevax!weicker
|
|
||||||
*
|
|
||||||
* Original Version (in Ada) published in
|
|
||||||
* "Communications of the ACM" vol. 27., no. 10 (Oct. 1984),
|
|
||||||
* pp. 1013 - 1030, together with the statistics
|
|
||||||
* on which the distribution of statements etc. is based.
|
|
||||||
*
|
|
||||||
* In this C version, the following C library functions are used:
|
|
||||||
* - strcpy, strcmp (inside the measurement loop)
|
|
||||||
* - printf, scanf (outside the measurement loop)
|
|
||||||
* In addition, Berkeley UNIX system calls "times ()" or "time ()"
|
|
||||||
* are used for execution time measurement. For measurements
|
|
||||||
* on other systems, these calls have to be changed.
|
|
||||||
*
|
|
||||||
* Collection of Results:
|
|
||||||
* Reinhold Weicker (address see above) and
|
|
||||||
*
|
|
||||||
* Rick Richardson
|
|
||||||
* PC Research. Inc.
|
|
||||||
* 94 Apple Orchard Drive
|
|
||||||
* Tinton Falls, NJ 07724
|
|
||||||
* Phone: (201) 389-8963 (9-17 EST)
|
|
||||||
* Usenet: ...!uunet!pcrat!rick
|
|
||||||
*
|
|
||||||
* Please send results to Rick Richardson and/or Reinhold Weicker.
|
|
||||||
* Complete information should be given on hardware and software used.
|
|
||||||
* Hardware information includes: Machine type, CPU, type and size
|
|
||||||
* of caches; for microprocessors: clock frequency, memory speed
|
|
||||||
* (number of wait states).
|
|
||||||
* Software information includes: Compiler (and runtime library)
|
|
||||||
* manufacturer and version, compilation switches, OS version.
|
|
||||||
* The Operating System version may give an indication about the
|
|
||||||
* compiler; Dhrystone itself performs no OS calls in the measurement loop.
|
|
||||||
*
|
|
||||||
* The complete output generated by the program should be mailed
|
|
||||||
* such that at least some checks for correctness can be made.
|
|
||||||
*
|
|
||||||
***************************************************************************
|
|
||||||
*
|
|
||||||
* History: This version C/2.1 has been made for two reasons:
|
|
||||||
*
|
|
||||||
* 1) There is an obvious need for a common C version of
|
|
||||||
* Dhrystone, since C is at present the most popular system
|
|
||||||
* programming language for the class of processors
|
|
||||||
* (microcomputers, minicomputers) where Dhrystone is used most.
|
|
||||||
* There should be, as far as possible, only one C version of
|
|
||||||
* Dhrystone such that results can be compared without
|
|
||||||
* restrictions. In the past, the C versions distributed
|
|
||||||
* by Rick Richardson (Version 1.1) and by Reinhold Weicker
|
|
||||||
* had small (though not significant) differences.
|
|
||||||
*
|
|
||||||
* 2) As far as it is possible without changes to the Dhrystone
|
|
||||||
* statistics, optimizing compilers should be prevented from
|
|
||||||
* removing significant statements.
|
|
||||||
*
|
|
||||||
* This C version has been developed in cooperation with
|
|
||||||
* Rick Richardson (Tinton Falls, NJ), it incorporates many
|
|
||||||
* ideas from the "Version 1.1" distributed previously by
|
|
||||||
* him over the UNIX network Usenet.
|
|
||||||
* I also thank Chaim Benedelac (National Semiconductor),
|
|
||||||
* David Ditzel (SUN), Earl Killian and John Mashey (MIPS),
|
|
||||||
* Alan Smith and Rafael Saavedra-Barrera (UC at Berkeley)
|
|
||||||
* for their help with comments on earlier versions of the
|
|
||||||
* benchmark.
|
|
||||||
*
|
|
||||||
* Changes: In the initialization part, this version follows mostly
|
|
||||||
* Rick Richardson's version distributed via Usenet, not the
|
|
||||||
* version distributed earlier via floppy disk by Reinhold Weicker.
|
|
||||||
* As a concession to older compilers, names have been made
|
|
||||||
* unique within the first 8 characters.
|
|
||||||
* Inside the measurement loop, this version follows the
|
|
||||||
* version previously distributed by Reinhold Weicker.
|
|
||||||
*
|
|
||||||
* At several places in the benchmark, code has been added,
|
|
||||||
* but within the measurement loop only in branches that
|
|
||||||
* are not executed. The intention is that optimizing compilers
|
|
||||||
* should be prevented from moving code out of the measurement
|
|
||||||
* loop, or from removing code altogether. Since the statements
|
|
||||||
* that are executed within the measurement loop have NOT been
|
|
||||||
* changed, the numbers defining the "Dhrystone distribution"
|
|
||||||
* (distribution of statements, operand types and locality)
|
|
||||||
* still hold. Except for sophisticated optimizing compilers,
|
|
||||||
* execution times for this version should be the same as
|
|
||||||
* for previous versions.
|
|
||||||
*
|
|
||||||
* Since it has proven difficult to subtract the time for the
|
|
||||||
* measurement loop overhead in a correct way, the loop check
|
|
||||||
* has been made a part of the benchmark. This does have
|
|
||||||
* an impact - though a very minor one - on the distribution
|
|
||||||
* statistics which have been updated for this version.
|
|
||||||
*
|
|
||||||
* All changes within the measurement loop are described
|
|
||||||
* and discussed in the companion paper "Rationale for
|
|
||||||
* Dhrystone version 2".
|
|
||||||
*
|
|
||||||
* Because of the self-imposed limitation that the order and
|
|
||||||
* distribution of the executed statements should not be
|
|
||||||
* changed, there are still cases where optimizing compilers
|
|
||||||
* may not generate code for some statements. To a certain
|
|
||||||
* degree, this is unavoidable for small synthetic benchmarks.
|
|
||||||
* Users of the benchmark are advised to check code listings
|
|
||||||
* whether code is generated for all statements of Dhrystone.
|
|
||||||
*
|
|
||||||
* Version 2.1 is identical to version 2.0 distributed via
|
|
||||||
* the UNIX network Usenet in March 1988 except that it corrects
|
|
||||||
* some minor deficiencies that were found by users of version 2.0.
|
|
||||||
* The only change within the measurement loop is that a
|
|
||||||
* non-executed "else" part was added to the "if" statement in
|
|
||||||
* Func_3, and a non-executed "else" part removed from Proc_3.
|
|
||||||
*
|
|
||||||
***************************************************************************
|
|
||||||
*
|
|
||||||
* Defines: The following "Defines" are possible:
|
|
||||||
* -DREG=register (default: Not defined)
|
|
||||||
* As an approximation to what an average C programmer
|
|
||||||
* might do, the "register" storage class is applied
|
|
||||||
* (if enabled by -DREG=register)
|
|
||||||
* - for local variables, if they are used (dynamically)
|
|
||||||
* five or more times
|
|
||||||
* - for parameters if they are used (dynamically)
|
|
||||||
* six or more times
|
|
||||||
* Note that an optimal "register" strategy is
|
|
||||||
* compiler-dependent, and that "register" declarations
|
|
||||||
* do not necessarily lead to faster execution.
|
|
||||||
* -DNOSTRUCTASSIGN (default: Not defined)
|
|
||||||
* Define if the C compiler does not support
|
|
||||||
* assignment of structures.
|
|
||||||
* -DNOENUMS (default: Not defined)
|
|
||||||
* Define if the C compiler does not support
|
|
||||||
* enumeration types.
|
|
||||||
* -DTIMES (default)
|
|
||||||
* -DTIME
|
|
||||||
* The "times" function of UNIX (returning process times)
|
|
||||||
* or the "time" function (returning wallclock time)
|
|
||||||
* is used for measurement.
|
|
||||||
* For single user machines, "time ()" is adequate. For
|
|
||||||
* multi-user machines where you cannot get single-user
|
|
||||||
* access, use the "times ()" function. If you have
|
|
||||||
* neither, use a stopwatch in the dead of night.
|
|
||||||
* "printf"s are provided marking the points "Start Timer"
|
|
||||||
* and "Stop Timer". DO NOT use the UNIX "time(1)"
|
|
||||||
* command, as this will measure the total time to
|
|
||||||
* run this program, which will (erroneously) include
|
|
||||||
* the time to allocate storage (malloc) and to perform
|
|
||||||
* the initialization.
|
|
||||||
* -DHZ=nnn
|
|
||||||
* In Berkeley UNIX, the function "times" returns process
|
|
||||||
* time in 1/HZ seconds, with HZ = 60 for most systems.
|
|
||||||
* CHECK YOUR SYSTEM DESCRIPTION BEFORE YOU JUST APPLY
|
|
||||||
* A VALUE.
|
|
||||||
*
|
|
||||||
***************************************************************************
|
|
||||||
*
|
|
||||||
* Compilation model and measurement (IMPORTANT):
|
|
||||||
*
|
|
||||||
* This C version of Dhrystone consists of three files:
|
|
||||||
* - dhry.h (this file, containing global definitions and comments)
|
|
||||||
* - dhry_1.c (containing the code corresponding to Ada package Pack_1)
|
|
||||||
* - dhry_2.c (containing the code corresponding to Ada package Pack_2)
|
|
||||||
*
|
|
||||||
* The following "ground rules" apply for measurements:
|
|
||||||
* - Separate compilation
|
|
||||||
* - No procedure merging
|
|
||||||
* - Otherwise, compiler optimizations are allowed but should be indicated
|
|
||||||
* - Default results are those without register declarations
|
|
||||||
* See the companion paper "Rationale for Dhrystone Version 2" for a more
|
|
||||||
* detailed discussion of these ground rules.
|
|
||||||
*
|
|
||||||
* For 16-Bit processors (e.g. 80186, 80286), times for all compilation
|
|
||||||
* models ("small", "medium", "large" etc.) should be given if possible,
|
|
||||||
* together with a definition of these models for the compiler system used.
|
|
||||||
*
|
|
||||||
**************************************************************************
|
|
||||||
*
|
|
||||||
* Dhrystone (C version) statistics:
|
|
||||||
*
|
|
||||||
* [Comment from the first distribution, updated for version 2.
|
|
||||||
* Note that because of language differences, the numbers are slightly
|
|
||||||
* different from the Ada version.]
|
|
||||||
*
|
|
||||||
* The following program contains statements of a high level programming
|
|
||||||
* language (here: C) in a distribution considered representative:
|
|
||||||
*
|
|
||||||
* assignments 52 (51.0 %)
|
|
||||||
* control statements 33 (32.4 %)
|
|
||||||
* procedure, function calls 17 (16.7 %)
|
|
||||||
*
|
|
||||||
* 103 statements are dynamically executed. The program is balanced with
|
|
||||||
* respect to the three aspects:
|
|
||||||
*
|
|
||||||
* - statement type
|
|
||||||
* - operand type
|
|
||||||
* - operand locality
|
|
||||||
* operand global, local, parameter, or constant.
|
|
||||||
*
|
|
||||||
* The combination of these three aspects is balanced only approximately.
|
|
||||||
*
|
|
||||||
* 1. Statement Type:
|
|
||||||
* ----------------- number
|
|
||||||
*
|
|
||||||
* V1 = V2 9
|
|
||||||
* (incl. V1 = F(..)
|
|
||||||
* V = Constant 12
|
|
||||||
* Assignment, 7
|
|
||||||
* with array element
|
|
||||||
* Assignment, 6
|
|
||||||
* with record component
|
|
||||||
* --
|
|
||||||
* 34 34
|
|
||||||
*
|
|
||||||
* X = Y +|-|"&&"|"|" Z 5
|
|
||||||
* X = Y +|-|"==" Constant 6
|
|
||||||
* X = X +|- 1 3
|
|
||||||
* X = Y *|/ Z 2
|
|
||||||
* X = Expression, 1
|
|
||||||
* two operators
|
|
||||||
* X = Expression, 1
|
|
||||||
* three operators
|
|
||||||
* --
|
|
||||||
* 18 18
|
|
||||||
*
|
|
||||||
* if .... 14
|
|
||||||
* with "else" 7
|
|
||||||
* without "else" 7
|
|
||||||
* executed 3
|
|
||||||
* not executed 4
|
|
||||||
* for ... 7 | counted every time
|
|
||||||
* while ... 4 | the loop condition
|
|
||||||
* do ... while 1 | is evaluated
|
|
||||||
* switch ... 1
|
|
||||||
* break 1
|
|
||||||
* declaration with 1
|
|
||||||
* initialization
|
|
||||||
* --
|
|
||||||
* 34 34
|
|
||||||
*
|
|
||||||
* P (...) procedure call 11
|
|
||||||
* user procedure 10
|
|
||||||
* library procedure 1
|
|
||||||
* X = F (...)
|
|
||||||
* function call 6
|
|
||||||
* user function 5
|
|
||||||
* library function 1
|
|
||||||
* --
|
|
||||||
* 17 17
|
|
||||||
* ---
|
|
||||||
* 103
|
|
||||||
*
|
|
||||||
* The average number of parameters in procedure or function calls
|
|
||||||
* is 1.82 (not counting the function values aX *
|
|
||||||
*
|
|
||||||
* 2. Operators
|
|
||||||
* ------------
|
|
||||||
* number approximate
|
|
||||||
* percentage
|
|
||||||
*
|
|
||||||
* Arithmetic 32 50.8
|
|
||||||
*
|
|
||||||
* + 21 33.3
|
|
||||||
* - 7 11.1
|
|
||||||
* * 3 4.8
|
|
||||||
* / (int div) 1 1.6
|
|
||||||
*
|
|
||||||
* Comparison 27 42.8
|
|
||||||
*
|
|
||||||
* == 9 14.3
|
|
||||||
* /= 4 6.3
|
|
||||||
* > 1 1.6
|
|
||||||
* < 3 4.8
|
|
||||||
* >= 1 1.6
|
|
||||||
* <= 9 14.3
|
|
||||||
*
|
|
||||||
* Logic 4 6.3
|
|
||||||
*
|
|
||||||
* && (AND-THEN) 1 1.6
|
|
||||||
* | (OR) 1 1.6
|
|
||||||
* ! (NOT) 2 3.2
|
|
||||||
*
|
|
||||||
* -- -----
|
|
||||||
* 63 100.1
|
|
||||||
*
|
|
||||||
*
|
|
||||||
* 3. Operand Type (counted once per operand reference):
|
|
||||||
* ---------------
|
|
||||||
* number approximate
|
|
||||||
* percentage
|
|
||||||
*
|
|
||||||
* Integer 175 72.3 %
|
|
||||||
* Character 45 18.6 %
|
|
||||||
* Pointer 12 5.0 %
|
|
||||||
* String30 6 2.5 %
|
|
||||||
* Array 2 0.8 %
|
|
||||||
* Record 2 0.8 %
|
|
||||||
* --- -------
|
|
||||||
* 242 100.0 %
|
|
||||||
*
|
|
||||||
* When there is an access path leading to the final operand (e.g. a record
|
|
||||||
* component), only the final data type on the access path is counted.
|
|
||||||
*
|
|
||||||
*
|
|
||||||
* 4. Operand Locality:
|
|
||||||
* -------------------
|
|
||||||
* number approximate
|
|
||||||
* percentage
|
|
||||||
*
|
|
||||||
* local variable 114 47.1 %
|
|
||||||
* global variable 22 9.1 %
|
|
||||||
* parameter 45 18.6 %
|
|
||||||
* value 23 9.5 %
|
|
||||||
* reference 22 9.1 %
|
|
||||||
* function result 6 2.5 %
|
|
||||||
* constant 55 22.7 %
|
|
||||||
* --- -------
|
|
||||||
* 242 100.0 %
|
|
||||||
*
|
|
||||||
*
|
|
||||||
* The program does not compute anything meaningful, but it is syntactically
|
|
||||||
* and semantically correct. All variables have a value assigned to them
|
|
||||||
* before they are used as a source operand.
|
|
||||||
*
|
|
||||||
* There has been no explicit effort to account for the effects of a
|
|
||||||
* cache, or to balance the use of long or short displacements for code or
|
|
||||||
* data.
|
|
||||||
*
|
|
||||||
***************************************************************************
|
|
||||||
*/
|
|
||||||
|
|
||||||
/* Compiler and system dependent definitions: */
|
|
||||||
|
|
||||||
#ifndef TIME
|
|
||||||
#undef TIMES
|
|
||||||
#define TIMES
|
|
||||||
#endif
|
|
||||||
/* Use times(2) time function unless */
|
|
||||||
/* explicitly defined otherwise */
|
|
||||||
#ifdef MSC_CLOCK
|
|
||||||
#undef HZ
|
|
||||||
#undef TIMES
|
|
||||||
#include <time.h>
|
|
||||||
#define HZ CLK_TCK
|
|
||||||
#endif
|
|
||||||
/* Use Microsoft C hi-res clock */
|
|
||||||
|
|
||||||
#ifdef TIMES
|
|
||||||
#include <sys/types.h>
|
|
||||||
#include <sys/times.h>
|
|
||||||
/* for "times" */
|
|
||||||
#endif
|
|
||||||
|
|
||||||
#define Mic_secs_Per_Second 1000000.0
|
|
||||||
/* Berkeley UNIX C returns process times in seconds/HZ */
|
|
||||||
|
|
||||||
#ifdef NOSTRUCTASSIGN
|
|
||||||
#define structassign(d, s) memcpy(&(d), &(s), sizeof(d))
|
|
||||||
#else
|
|
||||||
#define structassign(d, s) d = s
|
|
||||||
#endif
|
|
||||||
|
|
||||||
#ifdef NOENUM
|
|
||||||
#define Ident_1 0
|
|
||||||
#define Ident_2 1
|
|
||||||
#define Ident_3 2
|
|
||||||
#define Ident_4 3
|
|
||||||
#define Ident_5 4
|
|
||||||
typedef int Enumeration;
|
|
||||||
#else
|
|
||||||
typedef enum {Ident_1, Ident_2, Ident_3, Ident_4, Ident_5}
|
|
||||||
Enumeration;
|
|
||||||
#endif
|
|
||||||
/* for boolean and enumeration types in Ada, Pascal */
|
|
||||||
|
|
||||||
/* General definitions: */
|
|
||||||
|
|
||||||
#include <stdio.h>
|
|
||||||
/* for strcpy, strcmp */
|
|
||||||
|
|
||||||
#define Null 0
|
|
||||||
/* Value of a Null pointer */
|
|
||||||
#define true 1
|
|
||||||
#define false 0
|
|
||||||
|
|
||||||
typedef int One_Thirty;
|
|
||||||
typedef int One_Fifty;
|
|
||||||
typedef char Capital_Letter;
|
|
||||||
typedef int Boolean;
|
|
||||||
typedef char Str_30 [31];
|
|
||||||
typedef int Arr_1_Dim [50];
|
|
||||||
typedef int Arr_2_Dim [50] [50];
|
|
||||||
|
|
||||||
typedef struct record
|
|
||||||
{
|
|
||||||
struct record *Ptr_Comp;
|
|
||||||
Enumeration Discr;
|
|
||||||
union {
|
|
||||||
struct {
|
|
||||||
Enumeration Enum_Comp;
|
|
||||||
int Int_Comp;
|
|
||||||
char Str_Comp [31];
|
|
||||||
} var_1;
|
|
||||||
struct {
|
|
||||||
Enumeration E_Comp_2;
|
|
||||||
char Str_2_Comp [31];
|
|
||||||
} var_2;
|
|
||||||
struct {
|
|
||||||
char Ch_1_Comp;
|
|
||||||
char Ch_2_Comp;
|
|
||||||
} var_3;
|
|
||||||
} variant;
|
|
||||||
} Rec_Type, *Rec_Pointer;
|
|
||||||
|
|
||||||
|
|
||||||
@@ -1,402 +0,0 @@
|
|||||||
/*
|
|
||||||
****************************************************************************
|
|
||||||
*
|
|
||||||
* "DHRYSTONE" Benchmark Program
|
|
||||||
* -----------------------------
|
|
||||||
*
|
|
||||||
* Version: C, Version 2.1
|
|
||||||
*
|
|
||||||
* File: dhry_1.c (part 2 of 3)
|
|
||||||
*
|
|
||||||
* Date: May 25, 1988
|
|
||||||
*
|
|
||||||
* Author: Reinhold P. Weicker
|
|
||||||
*
|
|
||||||
****************************************************************************
|
|
||||||
*/
|
|
||||||
|
|
||||||
#include "dhry.h"
|
|
||||||
|
|
||||||
/* Global Variables: */
|
|
||||||
|
|
||||||
Rec_Pointer Ptr_Glob,
|
|
||||||
Next_Ptr_Glob;
|
|
||||||
int Int_Glob;
|
|
||||||
Boolean Bool_Glob;
|
|
||||||
char Ch_1_Glob,
|
|
||||||
Ch_2_Glob;
|
|
||||||
int Arr_1_Glob [50];
|
|
||||||
int Arr_2_Glob [50] [50];
|
|
||||||
|
|
||||||
extern char *malloc ();
|
|
||||||
Enumeration Func_1 ();
|
|
||||||
/* forward declaration necessary since Enumeration may not simply be int */
|
|
||||||
|
|
||||||
#ifndef REG
|
|
||||||
Boolean Reg = false;
|
|
||||||
#define REG
|
|
||||||
/* REG becomes defined as empty */
|
|
||||||
/* i.e. no register variables */
|
|
||||||
#else
|
|
||||||
Boolean Reg = true;
|
|
||||||
#endif
|
|
||||||
|
|
||||||
/* variables for time measurement: */
|
|
||||||
|
|
||||||
#ifdef TIMES
|
|
||||||
struct tms time_info;
|
|
||||||
/* see library function "times" */
|
|
||||||
#define Too_Small_Time (2*HZ)
|
|
||||||
/* Measurements should last at least about 2 seconds */
|
|
||||||
#endif
|
|
||||||
#ifdef TIME
|
|
||||||
extern long time();
|
|
||||||
/* see library function "time" */
|
|
||||||
#define Too_Small_Time 2
|
|
||||||
/* Measurements should last at least 2 seconds */
|
|
||||||
#endif
|
|
||||||
#ifdef MSC_CLOCK
|
|
||||||
extern clock_t clock();
|
|
||||||
#define Too_Small_Time (2*HZ)
|
|
||||||
#endif
|
|
||||||
|
|
||||||
long Begin_Time,
|
|
||||||
End_Time,
|
|
||||||
User_Time;
|
|
||||||
float Microseconds,
|
|
||||||
Dhrystones_Per_Second;
|
|
||||||
|
|
||||||
/* end of variables for time measurement */
|
|
||||||
|
|
||||||
|
|
||||||
main ()
|
|
||||||
/*****/
|
|
||||||
|
|
||||||
/* main program, corresponds to procedures */
|
|
||||||
/* Main and Proc_0 in the Ada version */
|
|
||||||
{
|
|
||||||
One_Fifty Int_1_Loc;
|
|
||||||
REG One_Fifty Int_2_Loc;
|
|
||||||
One_Fifty Int_3_Loc;
|
|
||||||
REG char Ch_Index;
|
|
||||||
Enumeration Enum_Loc;
|
|
||||||
Str_30 Str_1_Loc;
|
|
||||||
Str_30 Str_2_Loc;
|
|
||||||
REG int Run_Index;
|
|
||||||
REG int Number_Of_Runs;
|
|
||||||
|
|
||||||
/* Initializations */
|
|
||||||
|
|
||||||
Next_Ptr_Glob = (Rec_Pointer) malloc (sizeof (Rec_Type));
|
|
||||||
Ptr_Glob = (Rec_Pointer) malloc (sizeof (Rec_Type));
|
|
||||||
|
|
||||||
Ptr_Glob->Ptr_Comp = Next_Ptr_Glob;
|
|
||||||
Ptr_Glob->Discr = Ident_1;
|
|
||||||
Ptr_Glob->variant.var_1.Enum_Comp = Ident_3;
|
|
||||||
Ptr_Glob->variant.var_1.Int_Comp = 40;
|
|
||||||
strcpy (Ptr_Glob->variant.var_1.Str_Comp,
|
|
||||||
"DHRYSTONE PROGRAM, SOME STRING");
|
|
||||||
strcpy (Str_1_Loc, "DHRYSTONE PROGRAM, 1'ST STRING");
|
|
||||||
|
|
||||||
Arr_2_Glob [8][7] = 10;
|
|
||||||
/* Was missing in published program. Without this statement, */
|
|
||||||
/* Arr_2_Glob [8][7] would have an undefined value. */
|
|
||||||
/* Warning: With 16-Bit processors and Number_Of_Runs > 32000, */
|
|
||||||
/* overflow may occur for this array element. */
|
|
||||||
|
|
||||||
/*
|
|
||||||
printf ("\n");
|
|
||||||
printf ("Dhrystone Benchmark, Version 2.1 (Language: C)\n");
|
|
||||||
printf ("\n");
|
|
||||||
if (Reg)
|
|
||||||
{
|
|
||||||
printf ("Program compiled with 'register' attribute\n");
|
|
||||||
printf ("\n");
|
|
||||||
}
|
|
||||||
else
|
|
||||||
{
|
|
||||||
printf ("Program compiled without 'register' attribute\n");
|
|
||||||
printf ("\n");
|
|
||||||
}
|
|
||||||
printf ("Please give the number of runs through the benchmark: ");
|
|
||||||
{
|
|
||||||
int n;
|
|
||||||
scanf ("%d", &n);
|
|
||||||
Number_Of_Runs = n;
|
|
||||||
}
|
|
||||||
printf ("\n");
|
|
||||||
*/
|
|
||||||
#ifdef NRUNS
|
|
||||||
Number_Of_Runs = NRUNS;
|
|
||||||
#else
|
|
||||||
Number_Of_Runs = 2000000;
|
|
||||||
#endif
|
|
||||||
printf ("Execution starts, %d runs through Dhrystone\n", Number_Of_Runs);
|
|
||||||
|
|
||||||
/***************/
|
|
||||||
/* Start timer */
|
|
||||||
/***************/
|
|
||||||
|
|
||||||
#ifdef TIMES
|
|
||||||
times (&time_info);
|
|
||||||
Begin_Time = (long) time_info.tms_utime;
|
|
||||||
#endif
|
|
||||||
#ifdef TIME
|
|
||||||
Begin_Time = time ( (long *) 0);
|
|
||||||
#endif
|
|
||||||
#ifdef MSC_CLOCK
|
|
||||||
Begin_Time = clock();
|
|
||||||
#endif
|
|
||||||
|
|
||||||
for (Run_Index = 1; Run_Index <= Number_Of_Runs; ++Run_Index)
|
|
||||||
{
|
|
||||||
|
|
||||||
Proc_5();
|
|
||||||
Proc_4();
|
|
||||||
/* Ch_1_Glob == 'A', Ch_2_Glob == 'B', Bool_Glob == true */
|
|
||||||
Int_1_Loc = 2;
|
|
||||||
Int_2_Loc = 3;
|
|
||||||
strcpy (Str_2_Loc, "DHRYSTONE PROGRAM, 2'ND STRING");
|
|
||||||
Enum_Loc = Ident_2;
|
|
||||||
Bool_Glob = ! Func_2 (Str_1_Loc, Str_2_Loc);
|
|
||||||
/* Bool_Glob == 1 */
|
|
||||||
while (Int_1_Loc < Int_2_Loc) /* loop body executed once */
|
|
||||||
{
|
|
||||||
Int_3_Loc = 5 * Int_1_Loc - Int_2_Loc;
|
|
||||||
/* Int_3_Loc == 7 */
|
|
||||||
Proc_7 (Int_1_Loc, Int_2_Loc, &Int_3_Loc);
|
|
||||||
/* Int_3_Loc == 7 */
|
|
||||||
Int_1_Loc += 1;
|
|
||||||
} /* while */
|
|
||||||
/* Int_1_Loc == 3, Int_2_Loc == 3, Int_3_Loc == 7 */
|
|
||||||
Proc_8 (Arr_1_Glob, Arr_2_Glob, Int_1_Loc, Int_3_Loc);
|
|
||||||
/* Int_Glob == 5 */
|
|
||||||
Proc_1 (Ptr_Glob);
|
|
||||||
for (Ch_Index = 'A'; Ch_Index <= Ch_2_Glob; ++Ch_Index)
|
|
||||||
/* loop body executed twice */
|
|
||||||
{
|
|
||||||
if (Enum_Loc == Func_1 (Ch_Index, 'C'))
|
|
||||||
/* then, not executed */
|
|
||||||
{
|
|
||||||
Proc_6 (Ident_1, &Enum_Loc);
|
|
||||||
strcpy (Str_2_Loc, "DHRYSTONE PROGRAM, 3'RD STRING");
|
|
||||||
Int_2_Loc = Run_Index;
|
|
||||||
Int_Glob = Run_Index;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
/* Int_1_Loc == 3, Int_2_Loc == 3, Int_3_Loc == 7 */
|
|
||||||
Int_2_Loc = Int_2_Loc * Int_1_Loc;
|
|
||||||
Int_1_Loc = Int_2_Loc / Int_3_Loc;
|
|
||||||
Int_2_Loc = 7 * (Int_2_Loc - Int_3_Loc) - Int_1_Loc;
|
|
||||||
/* Int_1_Loc == 1, Int_2_Loc == 13, Int_3_Loc == 7 */
|
|
||||||
Proc_2 (&Int_1_Loc);
|
|
||||||
/* Int_1_Loc == 5 */
|
|
||||||
|
|
||||||
} /* loop "for Run_Index" */
|
|
||||||
|
|
||||||
/**************/
|
|
||||||
/* Stop timer */
|
|
||||||
/**************/
|
|
||||||
|
|
||||||
#ifdef TIMES
|
|
||||||
times (&time_info);
|
|
||||||
End_Time = (long) time_info.tms_utime;
|
|
||||||
#endif
|
|
||||||
#ifdef TIME
|
|
||||||
End_Time = time ( (long *) 0);
|
|
||||||
#endif
|
|
||||||
#ifdef MSC_CLOCK
|
|
||||||
End_Time = clock();
|
|
||||||
#endif
|
|
||||||
/*
|
|
||||||
printf ("Execution ends\n");
|
|
||||||
printf ("\n");
|
|
||||||
printf ("Final values of the variables used in the benchmark:\n");
|
|
||||||
printf ("\n");
|
|
||||||
printf ("Int_Glob: %d\n", Int_Glob);
|
|
||||||
printf (" should be: %d\n", 5);
|
|
||||||
printf ("Bool_Glob: %d\n", Bool_Glob);
|
|
||||||
printf (" should be: %d\n", 1);
|
|
||||||
printf ("Ch_1_Glob: %c\n", Ch_1_Glob);
|
|
||||||
printf (" should be: %c\n", 'A');
|
|
||||||
printf ("Ch_2_Glob: %c\n", Ch_2_Glob);
|
|
||||||
printf (" should be: %c\n", 'B');
|
|
||||||
printf ("Arr_1_Glob[8]: %d\n", Arr_1_Glob[8]);
|
|
||||||
printf (" should be: %d\n", 7);
|
|
||||||
printf ("Arr_2_Glob[8][7]: %d\n", Arr_2_Glob[8][7]);
|
|
||||||
printf (" should be: Number_Of_Runs + 10\n");
|
|
||||||
printf ("Ptr_Glob->\n");
|
|
||||||
printf (" Ptr_Comp: %d\n", (int) Ptr_Glob->Ptr_Comp);
|
|
||||||
printf (" should be: (implementation-dependent)\n");
|
|
||||||
printf (" Discr: %d\n", Ptr_Glob->Discr);
|
|
||||||
printf (" should be: %d\n", 0);
|
|
||||||
printf (" Enum_Comp: %d\n", Ptr_Glob->variant.var_1.Enum_Comp);
|
|
||||||
printf (" should be: %d\n", 2);
|
|
||||||
printf (" Int_Comp: %d\n", Ptr_Glob->variant.var_1.Int_Comp);
|
|
||||||
printf (" should be: %d\n", 17);
|
|
||||||
printf (" Str_Comp: %s\n", Ptr_Glob->variant.var_1.Str_Comp);
|
|
||||||
printf (" should be: DHRYSTONE PROGRAM, SOME STRING\n");
|
|
||||||
printf ("Next_Ptr_Glob->\n");
|
|
||||||
printf (" Ptr_Comp: %d\n", (int) Next_Ptr_Glob->Ptr_Comp);
|
|
||||||
printf (" should be: (implementation-dependent), same as above\n");
|
|
||||||
printf (" Discr: %d\n", Next_Ptr_Glob->Discr);
|
|
||||||
printf (" should be: %d\n", 0);
|
|
||||||
printf (" Enum_Comp: %d\n", Next_Ptr_Glob->variant.var_1.Enum_Comp);
|
|
||||||
printf (" should be: %d\n", 1);
|
|
||||||
printf (" Int_Comp: %d\n", Next_Ptr_Glob->variant.var_1.Int_Comp);
|
|
||||||
printf (" should be: %d\n", 18);
|
|
||||||
printf (" Str_Comp: %s\n",
|
|
||||||
Next_Ptr_Glob->variant.var_1.Str_Comp);
|
|
||||||
printf (" should be: DHRYSTONE PROGRAM, SOME STRING\n");
|
|
||||||
printf ("Int_1_Loc: %d\n", Int_1_Loc);
|
|
||||||
printf (" should be: %d\n", 5);
|
|
||||||
printf ("Int_2_Loc: %d\n", Int_2_Loc);
|
|
||||||
printf (" should be: %d\n", 13);
|
|
||||||
printf ("Int_3_Loc: %d\n", Int_3_Loc);
|
|
||||||
printf (" should be: %d\n", 7);
|
|
||||||
printf ("Enum_Loc: %d\n", Enum_Loc);
|
|
||||||
printf (" should be: %d\n", 1);
|
|
||||||
printf ("Str_1_Loc: %s\n", Str_1_Loc);
|
|
||||||
printf (" should be: DHRYSTONE PROGRAM, 1'ST STRING\n");
|
|
||||||
printf ("Str_2_Loc: %s\n", Str_2_Loc);
|
|
||||||
printf (" should be: DHRYSTONE PROGRAM, 2'ND STRING\n");
|
|
||||||
printf ("\n");
|
|
||||||
|
|
||||||
*/
|
|
||||||
User_Time = End_Time - Begin_Time;
|
|
||||||
|
|
||||||
if (User_Time < Too_Small_Time)
|
|
||||||
{
|
|
||||||
printf ("Measured time too small to obtain meaningful results\n");
|
|
||||||
printf ("Please increase number of runs\n");
|
|
||||||
printf ("\n");
|
|
||||||
}
|
|
||||||
else
|
|
||||||
{
|
|
||||||
#ifdef TIME
|
|
||||||
Microseconds = (float) User_Time * Mic_secs_Per_Second
|
|
||||||
/ (float) Number_Of_Runs;
|
|
||||||
Dhrystones_Per_Second = (float) Number_Of_Runs / (float) User_Time;
|
|
||||||
#else
|
|
||||||
Microseconds = (float) User_Time * Mic_secs_Per_Second
|
|
||||||
/ ((float) HZ * ((float) Number_Of_Runs));
|
|
||||||
Dhrystones_Per_Second = ((float) HZ * (float) Number_Of_Runs)
|
|
||||||
/ (float) User_Time;
|
|
||||||
#endif
|
|
||||||
printf ("Microseconds for one run through Dhrystone: ");
|
|
||||||
printf ("%6.1f \n", Microseconds);
|
|
||||||
printf ("Dhrystones per Second: ");
|
|
||||||
printf ("%6.1f \n", Dhrystones_Per_Second);
|
|
||||||
printf ("\n");
|
|
||||||
printf ("This equals to %6.1f DMIPS\n", Dhrystones_Per_Second/1757);
|
|
||||||
}
|
|
||||||
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
Proc_1 (Ptr_Val_Par)
|
|
||||||
/******************/
|
|
||||||
|
|
||||||
REG Rec_Pointer Ptr_Val_Par;
|
|
||||||
/* executed once */
|
|
||||||
{
|
|
||||||
REG Rec_Pointer Next_Record = Ptr_Val_Par->Ptr_Comp;
|
|
||||||
/* == Ptr_Glob_Next */
|
|
||||||
/* Local variable, initialized with Ptr_Val_Par->Ptr_Comp, */
|
|
||||||
/* corresponds to "rename" in Ada, "with" in Pascal */
|
|
||||||
|
|
||||||
structassign (*Ptr_Val_Par->Ptr_Comp, *Ptr_Glob);
|
|
||||||
Ptr_Val_Par->variant.var_1.Int_Comp = 5;
|
|
||||||
Next_Record->variant.var_1.Int_Comp
|
|
||||||
= Ptr_Val_Par->variant.var_1.Int_Comp;
|
|
||||||
Next_Record->Ptr_Comp = Ptr_Val_Par->Ptr_Comp;
|
|
||||||
Proc_3 (&Next_Record->Ptr_Comp);
|
|
||||||
/* Ptr_Val_Par->Ptr_Comp->Ptr_Comp
|
|
||||||
== Ptr_Glob->Ptr_Comp */
|
|
||||||
if (Next_Record->Discr == Ident_1)
|
|
||||||
/* then, executed */
|
|
||||||
{
|
|
||||||
Next_Record->variant.var_1.Int_Comp = 6;
|
|
||||||
Proc_6 (Ptr_Val_Par->variant.var_1.Enum_Comp,
|
|
||||||
&Next_Record->variant.var_1.Enum_Comp);
|
|
||||||
Next_Record->Ptr_Comp = Ptr_Glob->Ptr_Comp;
|
|
||||||
Proc_7 (Next_Record->variant.var_1.Int_Comp, 10,
|
|
||||||
&Next_Record->variant.var_1.Int_Comp);
|
|
||||||
}
|
|
||||||
else /* not executed */
|
|
||||||
structassign (*Ptr_Val_Par, *Ptr_Val_Par->Ptr_Comp);
|
|
||||||
} /* Proc_1 */
|
|
||||||
|
|
||||||
|
|
||||||
Proc_2 (Int_Par_Ref)
|
|
||||||
/******************/
|
|
||||||
/* executed once */
|
|
||||||
/* *Int_Par_Ref == 1, becomes 4 */
|
|
||||||
|
|
||||||
One_Fifty *Int_Par_Ref;
|
|
||||||
{
|
|
||||||
One_Fifty Int_Loc;
|
|
||||||
Enumeration Enum_Loc;
|
|
||||||
|
|
||||||
Int_Loc = *Int_Par_Ref + 10;
|
|
||||||
do /* executed once */
|
|
||||||
if (Ch_1_Glob == 'A')
|
|
||||||
/* then, executed */
|
|
||||||
{
|
|
||||||
Int_Loc -= 1;
|
|
||||||
*Int_Par_Ref = Int_Loc - Int_Glob;
|
|
||||||
Enum_Loc = Ident_1;
|
|
||||||
} /* if */
|
|
||||||
while (Enum_Loc != Ident_1); /* true */
|
|
||||||
} /* Proc_2 */
|
|
||||||
|
|
||||||
|
|
||||||
Proc_3 (Ptr_Ref_Par)
|
|
||||||
/******************/
|
|
||||||
/* executed once */
|
|
||||||
/* Ptr_Ref_Par becomes Ptr_Glob */
|
|
||||||
|
|
||||||
Rec_Pointer *Ptr_Ref_Par;
|
|
||||||
|
|
||||||
{
|
|
||||||
if (Ptr_Glob != Null)
|
|
||||||
/* then, executed */
|
|
||||||
*Ptr_Ref_Par = Ptr_Glob->Ptr_Comp;
|
|
||||||
Proc_7 (10, Int_Glob, &Ptr_Glob->variant.var_1.Int_Comp);
|
|
||||||
} /* Proc_3 */
|
|
||||||
|
|
||||||
|
|
||||||
Proc_4 () /* without parameters */
|
|
||||||
/*******/
|
|
||||||
/* executed once */
|
|
||||||
{
|
|
||||||
Boolean Bool_Loc;
|
|
||||||
|
|
||||||
Bool_Loc = Ch_1_Glob == 'A';
|
|
||||||
Bool_Glob = Bool_Loc | Bool_Glob;
|
|
||||||
Ch_2_Glob = 'B';
|
|
||||||
} /* Proc_4 */
|
|
||||||
|
|
||||||
|
|
||||||
Proc_5 () /* without parameters */
|
|
||||||
/*******/
|
|
||||||
/* executed once */
|
|
||||||
{
|
|
||||||
Ch_1_Glob = 'A';
|
|
||||||
Bool_Glob = false;
|
|
||||||
} /* Proc_5 */
|
|
||||||
|
|
||||||
|
|
||||||
/* Procedure for the assignment of structures, */
|
|
||||||
/* if the C compiler doesn't support this feature */
|
|
||||||
#ifdef NOSTRUCTASSIGN
|
|
||||||
memcpy (d, s, l)
|
|
||||||
register char *d;
|
|
||||||
register char *s;
|
|
||||||
register int l;
|
|
||||||
{
|
|
||||||
while (l--) *d++ = *s++;
|
|
||||||
}
|
|
||||||
#endif
|
|
||||||
|
|
||||||
|
|
||||||
@@ -1,192 +0,0 @@
|
|||||||
/*
|
|
||||||
****************************************************************************
|
|
||||||
*
|
|
||||||
* "DHRYSTONE" Benchmark Program
|
|
||||||
* -----------------------------
|
|
||||||
*
|
|
||||||
* Version: C, Version 2.1
|
|
||||||
*
|
|
||||||
* File: dhry_2.c (part 3 of 3)
|
|
||||||
*
|
|
||||||
* Date: May 25, 1988
|
|
||||||
*
|
|
||||||
* Author: Reinhold P. Weicker
|
|
||||||
*
|
|
||||||
****************************************************************************
|
|
||||||
*/
|
|
||||||
|
|
||||||
#include "dhry.h"
|
|
||||||
|
|
||||||
#ifndef REG
|
|
||||||
#define REG
|
|
||||||
/* REG becomes defined as empty */
|
|
||||||
/* i.e. no register variables */
|
|
||||||
#endif
|
|
||||||
|
|
||||||
extern int Int_Glob;
|
|
||||||
extern char Ch_1_Glob;
|
|
||||||
|
|
||||||
|
|
||||||
Proc_6 (Enum_Val_Par, Enum_Ref_Par)
|
|
||||||
/*********************************/
|
|
||||||
/* executed once */
|
|
||||||
/* Enum_Val_Par == Ident_3, Enum_Ref_Par becomes Ident_2 */
|
|
||||||
|
|
||||||
Enumeration Enum_Val_Par;
|
|
||||||
Enumeration *Enum_Ref_Par;
|
|
||||||
{
|
|
||||||
*Enum_Ref_Par = Enum_Val_Par;
|
|
||||||
if (! Func_3 (Enum_Val_Par))
|
|
||||||
/* then, not executed */
|
|
||||||
*Enum_Ref_Par = Ident_4;
|
|
||||||
switch (Enum_Val_Par)
|
|
||||||
{
|
|
||||||
case Ident_1:
|
|
||||||
*Enum_Ref_Par = Ident_1;
|
|
||||||
break;
|
|
||||||
case Ident_2:
|
|
||||||
if (Int_Glob > 100)
|
|
||||||
/* then */
|
|
||||||
*Enum_Ref_Par = Ident_1;
|
|
||||||
else *Enum_Ref_Par = Ident_4;
|
|
||||||
break;
|
|
||||||
case Ident_3: /* executed */
|
|
||||||
*Enum_Ref_Par = Ident_2;
|
|
||||||
break;
|
|
||||||
case Ident_4: break;
|
|
||||||
case Ident_5:
|
|
||||||
*Enum_Ref_Par = Ident_3;
|
|
||||||
break;
|
|
||||||
} /* switch */
|
|
||||||
} /* Proc_6 */
|
|
||||||
|
|
||||||
|
|
||||||
Proc_7 (Int_1_Par_Val, Int_2_Par_Val, Int_Par_Ref)
|
|
||||||
/**********************************************/
|
|
||||||
/* executed three times */
|
|
||||||
/* first call: Int_1_Par_Val == 2, Int_2_Par_Val == 3, */
|
|
||||||
/* Int_Par_Ref becomes 7 */
|
|
||||||
/* second call: Int_1_Par_Val == 10, Int_2_Par_Val == 5, */
|
|
||||||
/* Int_Par_Ref becomes 17 */
|
|
||||||
/* third call: Int_1_Par_Val == 6, Int_2_Par_Val == 10, */
|
|
||||||
/* Int_Par_Ref becomes 18 */
|
|
||||||
One_Fifty Int_1_Par_Val;
|
|
||||||
One_Fifty Int_2_Par_Val;
|
|
||||||
One_Fifty *Int_Par_Ref;
|
|
||||||
{
|
|
||||||
One_Fifty Int_Loc;
|
|
||||||
|
|
||||||
Int_Loc = Int_1_Par_Val + 2;
|
|
||||||
*Int_Par_Ref = Int_2_Par_Val + Int_Loc;
|
|
||||||
} /* Proc_7 */
|
|
||||||
|
|
||||||
|
|
||||||
Proc_8 (Arr_1_Par_Ref, Arr_2_Par_Ref, Int_1_Par_Val, Int_2_Par_Val)
|
|
||||||
/*********************************************************************/
|
|
||||||
/* executed once */
|
|
||||||
/* Int_Par_Val_1 == 3 */
|
|
||||||
/* Int_Par_Val_2 == 7 */
|
|
||||||
Arr_1_Dim Arr_1_Par_Ref;
|
|
||||||
Arr_2_Dim Arr_2_Par_Ref;
|
|
||||||
int Int_1_Par_Val;
|
|
||||||
int Int_2_Par_Val;
|
|
||||||
{
|
|
||||||
REG One_Fifty Int_Index;
|
|
||||||
REG One_Fifty Int_Loc;
|
|
||||||
|
|
||||||
Int_Loc = Int_1_Par_Val + 5;
|
|
||||||
Arr_1_Par_Ref [Int_Loc] = Int_2_Par_Val;
|
|
||||||
Arr_1_Par_Ref [Int_Loc+1] = Arr_1_Par_Ref [Int_Loc];
|
|
||||||
Arr_1_Par_Ref [Int_Loc+30] = Int_Loc;
|
|
||||||
for (Int_Index = Int_Loc; Int_Index <= Int_Loc+1; ++Int_Index)
|
|
||||||
Arr_2_Par_Ref [Int_Loc] [Int_Index] = Int_Loc;
|
|
||||||
Arr_2_Par_Ref [Int_Loc] [Int_Loc-1] += 1;
|
|
||||||
Arr_2_Par_Ref [Int_Loc+20] [Int_Loc] = Arr_1_Par_Ref [Int_Loc];
|
|
||||||
Int_Glob = 5;
|
|
||||||
} /* Proc_8 */
|
|
||||||
|
|
||||||
|
|
||||||
Enumeration Func_1 (Ch_1_Par_Val, Ch_2_Par_Val)
|
|
||||||
/*************************************************/
|
|
||||||
/* executed three times */
|
|
||||||
/* first call: Ch_1_Par_Val == 'H', Ch_2_Par_Val == 'R' */
|
|
||||||
/* second call: Ch_1_Par_Val == 'A', Ch_2_Par_Val == 'C' */
|
|
||||||
/* third call: Ch_1_Par_Val == 'B', Ch_2_Par_Val == 'C' */
|
|
||||||
|
|
||||||
Capital_Letter Ch_1_Par_Val;
|
|
||||||
Capital_Letter Ch_2_Par_Val;
|
|
||||||
{
|
|
||||||
Capital_Letter Ch_1_Loc;
|
|
||||||
Capital_Letter Ch_2_Loc;
|
|
||||||
|
|
||||||
Ch_1_Loc = Ch_1_Par_Val;
|
|
||||||
Ch_2_Loc = Ch_1_Loc;
|
|
||||||
if (Ch_2_Loc != Ch_2_Par_Val)
|
|
||||||
/* then, executed */
|
|
||||||
return (Ident_1);
|
|
||||||
else /* not executed */
|
|
||||||
{
|
|
||||||
Ch_1_Glob = Ch_1_Loc;
|
|
||||||
return (Ident_2);
|
|
||||||
}
|
|
||||||
} /* Func_1 */
|
|
||||||
|
|
||||||
|
|
||||||
Boolean Func_2 (Str_1_Par_Ref, Str_2_Par_Ref)
|
|
||||||
/*************************************************/
|
|
||||||
/* executed once */
|
|
||||||
/* Str_1_Par_Ref == "DHRYSTONE PROGRAM, 1'ST STRING" */
|
|
||||||
/* Str_2_Par_Ref == "DHRYSTONE PROGRAM, 2'ND STRING" */
|
|
||||||
|
|
||||||
Str_30 Str_1_Par_Ref;
|
|
||||||
Str_30 Str_2_Par_Ref;
|
|
||||||
{
|
|
||||||
REG One_Thirty Int_Loc;
|
|
||||||
Capital_Letter Ch_Loc;
|
|
||||||
|
|
||||||
Int_Loc = 2;
|
|
||||||
while (Int_Loc <= 2) /* loop body executed once */
|
|
||||||
if (Func_1 (Str_1_Par_Ref[Int_Loc],
|
|
||||||
Str_2_Par_Ref[Int_Loc+1]) == Ident_1)
|
|
||||||
/* then, executed */
|
|
||||||
{
|
|
||||||
Ch_Loc = 'A';
|
|
||||||
Int_Loc += 1;
|
|
||||||
} /* if, while */
|
|
||||||
if (Ch_Loc >= 'W' && Ch_Loc < 'Z')
|
|
||||||
/* then, not executed */
|
|
||||||
Int_Loc = 7;
|
|
||||||
if (Ch_Loc == 'R')
|
|
||||||
/* then, not executed */
|
|
||||||
return (true);
|
|
||||||
else /* executed */
|
|
||||||
{
|
|
||||||
if (strcmp (Str_1_Par_Ref, Str_2_Par_Ref) > 0)
|
|
||||||
/* then, not executed */
|
|
||||||
{
|
|
||||||
Int_Loc += 7;
|
|
||||||
Int_Glob = Int_Loc;
|
|
||||||
return (true);
|
|
||||||
}
|
|
||||||
else /* executed */
|
|
||||||
return (false);
|
|
||||||
} /* if Ch_Loc */
|
|
||||||
} /* Func_2 */
|
|
||||||
|
|
||||||
|
|
||||||
Boolean Func_3 (Enum_Par_Val)
|
|
||||||
/***************************/
|
|
||||||
/* executed once */
|
|
||||||
/* Enum_Par_Val == Ident_3 */
|
|
||||||
Enumeration Enum_Par_Val;
|
|
||||||
{
|
|
||||||
Enumeration Enum_Loc;
|
|
||||||
|
|
||||||
Enum_Loc = Enum_Par_Val;
|
|
||||||
if (Enum_Loc == Ident_3)
|
|
||||||
/* then, executed */
|
|
||||||
return (true);
|
|
||||||
else /* not executed */
|
|
||||||
return (false);
|
|
||||||
} /* Func_3 */
|
|
||||||
|
|
||||||
@@ -1,261 +0,0 @@
|
|||||||
/* dttl.c -- simulation of Cassini/Huygens symbol synchronizer loop
|
|
||||||
*
|
|
||||||
* Author: Lorenzo Simone's (matlab script)
|
|
||||||
* Modifications by: Jon Hamkins (conversion to C, support routines,
|
|
||||||
* memory requirement reductions)
|
|
||||||
* Last Revised: Wed Jan 31 10:47:52 PST 2001
|
|
||||||
*/
|
|
||||||
#define M_PI 3.1415926535897932384626433832795
|
|
||||||
|
|
||||||
#include <math.h>
|
|
||||||
#include <stdio.h>
|
|
||||||
#include "random.h"
|
|
||||||
|
|
||||||
/* global variables */
|
|
||||||
int delay,
|
|
||||||
L; /* samples per symbol */
|
|
||||||
double Pt, /* transition density */
|
|
||||||
sigma; /* noise standard deviation */
|
|
||||||
long seed=-123;
|
|
||||||
|
|
||||||
/* This function simulates a large 1-dimensional array without requiring
|
|
||||||
* storage for the whole array. This is possible because the array is
|
|
||||||
* accessed in roughly increasing indices. Thus, we only need to
|
|
||||||
* store a few symbols worth of samples in the array, and we can reuse
|
|
||||||
* the array indices as time goes on. */
|
|
||||||
int drint(double v)
|
|
||||||
{
|
|
||||||
return (int)(v+0.5);
|
|
||||||
}
|
|
||||||
|
|
||||||
double
|
|
||||||
rec(int idx)
|
|
||||||
{
|
|
||||||
static int firsttime = 1,
|
|
||||||
max, /* maximum index containing data */
|
|
||||||
mod, /* length of ring buffer */
|
|
||||||
b; /* value of last transmitted bit */
|
|
||||||
static double r[2000]; /* need several symbols worth of samples */
|
|
||||||
int i,j,k;
|
|
||||||
|
|
||||||
/* First time, store samples for random delay and first few symbols */
|
|
||||||
if (firsttime==1) {
|
|
||||||
firsttime=0;
|
|
||||||
for (i=0; i<delay; i++) r[i] = 0; /* random delay */
|
|
||||||
b = (ran1(&seed)>0.5) ? 1 : -1; /* first random symbol */
|
|
||||||
for (j=0; j<3; j++) { /* 3 binary symbols with transition Pt */
|
|
||||||
b = (ran1(&seed)>Pt) ? b : -b; /* next symbol value */
|
|
||||||
for (k=0; k<L; k++) r[i++] = b + sigma*gaussian(&seed);
|
|
||||||
}
|
|
||||||
max = i-1;
|
|
||||||
mod = i;
|
|
||||||
}
|
|
||||||
if (idx>max) /* check if we need to create another sample */
|
|
||||||
{
|
|
||||||
b = (ran1(&seed)>Pt) ? b : -b; /* next symbol value */
|
|
||||||
/* generate samples for one symbol and store in ring buffer */
|
|
||||||
for (i=1; i<=L; i++) r[(int)(fmod(max+i,mod))] = b+sigma*gaussian(&seed);
|
|
||||||
max += L; /* maximum index for which samples exist */
|
|
||||||
}
|
|
||||||
/* return appropriate sample from ring buffer */
|
|
||||||
return(r[(int)(fmod(idx,mod))]);
|
|
||||||
}
|
|
||||||
|
|
||||||
main()
|
|
||||||
{
|
|
||||||
double
|
|
||||||
detout, /* detector output */
|
|
||||||
I, old_I, /* in-phase accumulations */
|
|
||||||
Q, old_Q, /* quadrature accumulations */
|
|
||||||
T, /* transition detection */
|
|
||||||
theta, /* baseband NCO output (radians) */
|
|
||||||
lambda, /* normalized timing error (symbols) */
|
|
||||||
A, alfa, Ampl, Bl, Df,
|
|
||||||
DR, Es_No, Es_No_lin, Fc1, Fc2, Fvco, Fs, Kd, Kv,
|
|
||||||
lambda_ss_sim = 0., lambda_ss_th, No, P, P_No,
|
|
||||||
sigma_lambda_sim = 0., sigma_lambda_th, SNR_sim, SNR_th, tau, Tc1, Tc2,
|
|
||||||
time, Ts, x1, Y, bit_I, bit_Q, bit;
|
|
||||||
int i, j, k, N, offset, k1, k2, EOB;
|
|
||||||
FILE *p1, *p2, *p3, *p4, *p5;
|
|
||||||
|
|
||||||
/* Data settings */
|
|
||||||
Fc1 = 48000; /* sample rate at DTTL input (F1/2 = 8.215MHz/2) */
|
|
||||||
Tc1 = 1./Fc1;
|
|
||||||
|
|
||||||
DR = 4800; /* data rate (symb/sec) */
|
|
||||||
|
|
||||||
Fc2 = DR; /* sampling rate pre-detection */
|
|
||||||
Tc2 = 1./Fc2;
|
|
||||||
|
|
||||||
L = drint(Tc2/Tc1); /* samples per symbol in the arm filters */
|
|
||||||
offset = drint(L/2.);
|
|
||||||
|
|
||||||
Es_No = 600.; /* dB */
|
|
||||||
P_No = Es_No+10.*log10(DR); /* data power-over-noise spectral density */
|
|
||||||
/* ratio (dBHz) */
|
|
||||||
|
|
||||||
N = 2500; /* number of symbols to simulate */
|
|
||||||
Pt=.5; /* Transition density */
|
|
||||||
|
|
||||||
Bl=0.01*DR; /* loop bandwidth (Hz) */
|
|
||||||
Df=0.001*DR; /* frequency offset */
|
|
||||||
Fvco=DR+Df;
|
|
||||||
|
|
||||||
tau=ran1(&seed)-.5; /* set symbol timing offset, -.5 to .5 */
|
|
||||||
delay=drint(2.*L+tau*L+1); /* channel delay */
|
|
||||||
|
|
||||||
P=1.; /* data power */
|
|
||||||
Ampl=sqrt(P);
|
|
||||||
|
|
||||||
No=10.*log10(P*Tc2)-Es_No; /* noise spectral density (dBW/Hz) */
|
|
||||||
sigma=sqrt(pow(10.,0.1*No)/(2.*Tc1));
|
|
||||||
printf("sigma=%f\n",sigma);
|
|
||||||
|
|
||||||
/* DPLL settings */
|
|
||||||
Fs=DR; /* loop sampling frequency (Hz) */
|
|
||||||
Ts=1./Fs; /* loop sampling time (s) */
|
|
||||||
|
|
||||||
/* Loop gain */
|
|
||||||
Kd=2.*Ampl*Pt; /* phase detector gain (quants/rad) */
|
|
||||||
/* @ high Es/No */
|
|
||||||
Kv=1.; /* VCO gain (rad/quants) */
|
|
||||||
|
|
||||||
/* Analog loop filter components */
|
|
||||||
alfa=4.*Bl/(Kd*Kv);
|
|
||||||
|
|
||||||
/* Digital loop filter components */
|
|
||||||
A=alfa*Ts;
|
|
||||||
|
|
||||||
/* Initial condition */
|
|
||||||
theta = 0;
|
|
||||||
old_I=1;
|
|
||||||
old_Q=1;
|
|
||||||
x1=0;
|
|
||||||
Y=0;
|
|
||||||
|
|
||||||
/* Plot data files */
|
|
||||||
// p1 = fopen("plot1.dat","w"); /* theta */
|
|
||||||
// p2 = fopen("plot2.dat","w"); /* lambda */
|
|
||||||
// p3 = fopen("plot3.dat","w"); /* detout */
|
|
||||||
// p4 = fopen("plot4.dat","w"); /* I-Data */
|
|
||||||
// p5 = fopen("plot5.dat","w"); /* Q-Data */
|
|
||||||
|
|
||||||
k1 = drint(0.5*N);
|
|
||||||
k2 = N;
|
|
||||||
|
|
||||||
printf("Data rate: %.0f symbols/sec\n",DR);
|
|
||||||
printf("Sample rate at DTTL input: %.0f samples/sec\n",Fc1);
|
|
||||||
printf("Samples per symbol: %d\n",L);
|
|
||||||
printf("Random delay set to: %f symbols (%d samples)\n",tau,delay);
|
|
||||||
printf("Transition density used in random bit generation: %f\n",Pt);
|
|
||||||
printf("Es/No: %f dB\n",Es_No);
|
|
||||||
printf("Loop bandwidth: %f Hz\n",Bl);
|
|
||||||
printf("Doppler: %f Hz\n",Df);
|
|
||||||
printf("Simulation length: %d symbols (%d samples)\n\n",N,N*L+delay);
|
|
||||||
|
|
||||||
/* Simulation Loop */
|
|
||||||
for (i=2; i<=N; i++)
|
|
||||||
{
|
|
||||||
/* loop over symbols */
|
|
||||||
/* find start of in-phase integration */
|
|
||||||
for (j=1; j < L; j++)
|
|
||||||
{
|
|
||||||
if (fmod(theta + 2*M_PI * Fvco*(j+1+(i-1)*(Fc1/DR))/Fc1, 2*M_PI)
|
|
||||||
< fmod(theta + 2*M_PI * Fvco*(j +(i-1)*(Fc1/DR))/Fc1, 2*M_PI))
|
|
||||||
break;
|
|
||||||
/* one could replace loop above with a direct calculation such as: */
|
|
||||||
/* j=ceil((1.-modulo(theta/(2*M_PI),1.))/(Fvco*Tc1))-1.; */
|
|
||||||
/* j+1 is the first index in the block */
|
|
||||||
EOB=j+(i-1)*L; /* End of Block */
|
|
||||||
}
|
|
||||||
/* In-phase integrator */
|
|
||||||
bit_I = 0.;
|
|
||||||
printf("Symbol # %d\n", i);
|
|
||||||
printf("I[%d:%d] :\n", EOB-L+1, EOB);
|
|
||||||
for (j=EOB-L+1; j<=EOB; j++)
|
|
||||||
{
|
|
||||||
bit = rec(j);
|
|
||||||
if (bit > 0)
|
|
||||||
printf("-");
|
|
||||||
else
|
|
||||||
printf("_");
|
|
||||||
|
|
||||||
bit_I += bit;
|
|
||||||
}
|
|
||||||
printf("\n");
|
|
||||||
I = bit_I;
|
|
||||||
|
|
||||||
/* Mid-Phase integrator */
|
|
||||||
bit_Q = 0.;
|
|
||||||
printf("Q[%d:%d] :\n", EOB-L+offset+1, EOB+offset);
|
|
||||||
for (j=EOB-L+offset+1; j<=EOB+offset; j++)
|
|
||||||
{
|
|
||||||
bit = rec(j);
|
|
||||||
if (bit > 0)
|
|
||||||
printf("-");
|
|
||||||
else
|
|
||||||
printf("_");
|
|
||||||
|
|
||||||
bit_Q += bit;
|
|
||||||
}
|
|
||||||
printf("\n\n");
|
|
||||||
Q = bit_Q;
|
|
||||||
|
|
||||||
Q *= 2.*M_PI/(Tc2/Tc1);
|
|
||||||
|
|
||||||
/* Transition Detector */
|
|
||||||
I = (I > 0) ? 1. : -1.; /* hard limiter */
|
|
||||||
T = 0.5*(I - old_I);
|
|
||||||
|
|
||||||
/* Detector Output */
|
|
||||||
detout = fmod(old_Q*T,2*M_PI);
|
|
||||||
|
|
||||||
/* Save accumulations for next time through loop */
|
|
||||||
old_I = I;
|
|
||||||
old_Q = Q;
|
|
||||||
if (fabs(detout)>M_PI)
|
|
||||||
detout = -detout+2*M_PI*((detout>0) ? 1. : -1.);
|
|
||||||
|
|
||||||
/* NCO */
|
|
||||||
Y += detout*A; /* Loop filter */
|
|
||||||
theta=Kv*Y; /* phase */
|
|
||||||
// lambda = theta/(2.*M_PI)+(i*Tc2*Df+tau); /* normalized error */
|
|
||||||
lambda = theta/(2.*M_PI)+(i*(Fvco/DR -1) + tau); /* normalized error */
|
|
||||||
|
|
||||||
/* error mean and variance calculation */
|
|
||||||
lambda_ss_sim += lambda; /* partial sum */
|
|
||||||
sigma_lambda_sim += lambda*lambda; /* partial sum of squares */
|
|
||||||
|
|
||||||
/* store phase and normalized error to data files */
|
|
||||||
// fprintf(p1,"%f %f\n",(double)i,theta);
|
|
||||||
// fprintf(p2,"%f %f\n",(double)i,lambda);
|
|
||||||
// fprintf(p3,"%f %f\n",(double)i,detout);
|
|
||||||
// fprintf(p4,"%f %f\n",(double)i,I);
|
|
||||||
// fprintf(p5,"%f %f\n",(double)i,Q);
|
|
||||||
}
|
|
||||||
// fclose(p1);
|
|
||||||
// fclose(p2);
|
|
||||||
// fclose(p3);
|
|
||||||
// fclose(p4);
|
|
||||||
// fclose(p5);
|
|
||||||
|
|
||||||
/* Statistics Analysis */
|
|
||||||
/* ------------------- */
|
|
||||||
/* complete the mean and variance calculation */
|
|
||||||
lambda_ss_sim /= N;
|
|
||||||
sigma_lambda_sim = sigma_lambda_sim/N - lambda_ss_sim*lambda_ss_sim;
|
|
||||||
Es_No_lin = pow(10.,0.1*Es_No);
|
|
||||||
// sigma_lambda_th = Bl*Tc2/(4.*Pt*Es_No_lin*pow(erf(sqrt(Es_No_lin)),2.));
|
|
||||||
sigma_lambda_th = Bl*Tc2/(4.*Pt*Es_No_lin*Es_No_lin);
|
|
||||||
SNR_sim = -10*log10(sigma_lambda_sim);
|
|
||||||
SNR_th = -10*log10(sigma_lambda_th);
|
|
||||||
/* Steady-State error */
|
|
||||||
lambda_ss_th=Df/(4.*Bl);
|
|
||||||
printf("Simulation: var: %f rad^2 loop SNR: %f dB ss error: %f%%\n",
|
|
||||||
sigma_lambda_sim, SNR_sim, 100.*lambda_ss_sim);
|
|
||||||
printf("Theory: var: %f rad^2 loop SNR: %f dB ss error: %f%%\n",
|
|
||||||
sigma_lambda_th, SNR_th, 100.*lambda_ss_th);
|
|
||||||
// system("gnuplot < plot1.gp");
|
|
||||||
// system("gnuplot < plot2.gp");
|
|
||||||
printf("Done.\n");
|
|
||||||
}
|
|
||||||
@@ -1,18 +0,0 @@
|
|||||||
#include "libsys.h"
|
|
||||||
|
|
||||||
|
|
||||||
int main (void)
|
|
||||||
{
|
|
||||||
UINT32 *pGPIO0 = (UINT32*)sys_gpio0;
|
|
||||||
UINT32 *pGPIO1 = (UINT32*)sys_gpio1;
|
|
||||||
|
|
||||||
*pGPIO0 = 0x55555555;
|
|
||||||
*pGPIO1 = 0x55555555;
|
|
||||||
|
|
||||||
sputs("Hello world!");
|
|
||||||
|
|
||||||
*pGPIO0 = 0xAAAAAAAA;
|
|
||||||
*pGPIO1 = 0xAAAAAAAA;
|
|
||||||
return 0;
|
|
||||||
}
|
|
||||||
|
|
||||||
@@ -1,45 +0,0 @@
|
|||||||
.file "init.S"
|
|
||||||
|
|
||||||
.text
|
|
||||||
.align 2
|
|
||||||
.globl _init
|
|
||||||
.extern end
|
|
||||||
|
|
||||||
_init:
|
|
||||||
.set noreorder
|
|
||||||
|
|
||||||
# set uart
|
|
||||||
# la $8, sys_uart_baud
|
|
||||||
# addiu $9, $0, baudrate
|
|
||||||
# sb $9, 0($8)
|
|
||||||
|
|
||||||
# set stack pointer
|
|
||||||
la $sp, stack_ptr
|
|
||||||
la $gp, _gp
|
|
||||||
|
|
||||||
# zero bss
|
|
||||||
la $8, __bss_start
|
|
||||||
la $9, end
|
|
||||||
$zeroise:
|
|
||||||
sw $0, 0($8)
|
|
||||||
bne $8, $9, $zeroise
|
|
||||||
addiu $8, 4
|
|
||||||
|
|
||||||
# zero sbss
|
|
||||||
# la $8, __sbss_start
|
|
||||||
# la $9, __sbss_end
|
|
||||||
#$szeroise:
|
|
||||||
# sw $0, 0($8)
|
|
||||||
# bne $8, $9, $szeroise
|
|
||||||
# addiu $8, 4
|
|
||||||
|
|
||||||
# jump main
|
|
||||||
la $8, main
|
|
||||||
jalr $8
|
|
||||||
|
|
||||||
_terminate:
|
|
||||||
nop
|
|
||||||
j _terminate
|
|
||||||
nop
|
|
||||||
|
|
||||||
.set reorder
|
|
||||||
@@ -1,91 +0,0 @@
|
|||||||
#include <sys/times.h>
|
|
||||||
#include <sys/time.h>
|
|
||||||
#include <sys/stat.h>
|
|
||||||
#include <errno.h>
|
|
||||||
#include <stdlib.h>
|
|
||||||
#include "libsys.h"
|
|
||||||
#include "regdef.h"
|
|
||||||
#include "xcpt.h"
|
|
||||||
#include "irq.h"
|
|
||||||
|
|
||||||
static fp_t g_irq_handler[MAX_NUM_IRQ] = {NULL};
|
|
||||||
|
|
||||||
int _irq_dispatch(struct xcptcontext * xcp)
|
|
||||||
{
|
|
||||||
int i, ip;
|
|
||||||
|
|
||||||
ip = (xcp->cr >> 8) & 0xFF;
|
|
||||||
|
|
||||||
for (i=0; i < MAX_NUM_IRQ; i++)
|
|
||||||
{
|
|
||||||
if (ip & 1)
|
|
||||||
if (g_irq_handler[i])
|
|
||||||
(g_irq_handler[i])();
|
|
||||||
|
|
||||||
ip >>= 1;
|
|
||||||
}
|
|
||||||
|
|
||||||
return 0;
|
|
||||||
}
|
|
||||||
|
|
||||||
void interrupt_register(int irq_num, fp_t fp)
|
|
||||||
{
|
|
||||||
if ((irq_num >= 0) && (irq_num < MAX_NUM_IRQ))
|
|
||||||
g_irq_handler[irq_num] = fp;
|
|
||||||
|
|
||||||
}
|
|
||||||
|
|
||||||
void interrupt_enable(int irq_num)
|
|
||||||
{
|
|
||||||
reg_t reg, im;
|
|
||||||
|
|
||||||
if ((irq_num >= 0) && (irq_num < MAX_NUM_IRQ))
|
|
||||||
{
|
|
||||||
im = 1 << irq_num;
|
|
||||||
reg = CP0_SR_read();
|
|
||||||
reg |= (SR_MASK_IM & (im << 8));
|
|
||||||
CP0_SR_write(reg);
|
|
||||||
}
|
|
||||||
|
|
||||||
}
|
|
||||||
|
|
||||||
void interrupt_disable(int irq_num)
|
|
||||||
{
|
|
||||||
reg_t reg, im;
|
|
||||||
|
|
||||||
if ((irq_num >= 0) && (irq_num < MAX_NUM_IRQ))
|
|
||||||
{
|
|
||||||
im = 1 << irq_num;
|
|
||||||
reg = CP0_SR_read();
|
|
||||||
reg &= ~(SR_MASK_IM & (im << 8));
|
|
||||||
CP0_SR_write(reg);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
void interrupt_set(int irq_num)
|
|
||||||
{
|
|
||||||
reg_t reg, ip;
|
|
||||||
|
|
||||||
if ((irq_num >= 0) && (irq_num < MAX_NUM_IRQ))
|
|
||||||
{
|
|
||||||
ip = 1 << irq_num;
|
|
||||||
reg = CP0_CR_read();
|
|
||||||
reg |= (CR_MASK_IP & (ip << 8));
|
|
||||||
CP0_CR_write(reg);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
void interrupt_clr(int irq_num)
|
|
||||||
{
|
|
||||||
reg_t reg, ip;
|
|
||||||
|
|
||||||
if ((irq_num >= 0) && (irq_num < MAX_NUM_IRQ))
|
|
||||||
{
|
|
||||||
ip = 1 << irq_num;
|
|
||||||
reg = CP0_CR_read();
|
|
||||||
reg &= ~(CR_MASK_IP & (ip << 8));
|
|
||||||
CP0_CR_write(reg);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
@@ -1,15 +0,0 @@
|
|||||||
#ifndef IRQ_H
|
|
||||||
#define IRQ_H
|
|
||||||
|
|
||||||
#include "xcpt.h"
|
|
||||||
|
|
||||||
#define MAX_NUM_IRQ 8
|
|
||||||
|
|
||||||
typedef void (*fp_t)(void);
|
|
||||||
|
|
||||||
int _irq_dispatch(struct xcptcontext * xcp);
|
|
||||||
void interrupt_register(int irq_num, fp_t fp);
|
|
||||||
void interrupt_enable(int irq_num);
|
|
||||||
void interrupt_disable(int irq_num);
|
|
||||||
|
|
||||||
#endif // IRQ_H
|
|
||||||
@@ -1,180 +0,0 @@
|
|||||||
#include <regdef.h>
|
|
||||||
#include <xcpt_asm.h>
|
|
||||||
|
|
||||||
.section .ktext,"ax"
|
|
||||||
|
|
||||||
LEAF(xcptlow_handler)
|
|
||||||
.set noreorder
|
|
||||||
.set noat
|
|
||||||
/* Note: exceptions do not save and restore registers k0 and k1.
|
|
||||||
* on entry, k1 = exception class.
|
|
||||||
*/
|
|
||||||
|
|
||||||
/* allocate exception stack frame (on 8-byte boundary) */
|
|
||||||
subu k1, sp, XCP_SIZE
|
|
||||||
srl k1, 3 /* shift right/left -> alligned on boundary */
|
|
||||||
sll k1, 3
|
|
||||||
|
|
||||||
/* save enough registers to get by */
|
|
||||||
sw AT, XCP_AT(k1)
|
|
||||||
sw v0, XCP_V0(k1)
|
|
||||||
sw v1, XCP_V1(k1)
|
|
||||||
sw a0, XCP_A0(k1)
|
|
||||||
sw a1, XCP_A1(k1)
|
|
||||||
sw a2, XCP_A2(k1)
|
|
||||||
sw a3, XCP_A3(k1)
|
|
||||||
sw sp, XCP_SP(k1)
|
|
||||||
sw ra, XCP_RA(k1)
|
|
||||||
|
|
||||||
/* get coprocessor 0 exception state */
|
|
||||||
mfc0 a0, CP0_CR
|
|
||||||
mfc0 a1, CP0_SR
|
|
||||||
mfc0 a2, CP0_BADDR
|
|
||||||
mfc0 a3, CP0_EPC
|
|
||||||
|
|
||||||
/* we can safely use AT now */
|
|
||||||
.set at
|
|
||||||
|
|
||||||
/* switch to using sp to point at exception frame */
|
|
||||||
move sp, k1
|
|
||||||
|
|
||||||
/* nothing sensible to store for k0/k1, store zero */
|
|
||||||
sw zero, XCP_K0(sp)
|
|
||||||
sw zero, XCP_K1(sp)
|
|
||||||
|
|
||||||
/* we are now interruptible: dump all remaining state
|
|
||||||
* into the exception stack frame.
|
|
||||||
*/
|
|
||||||
/* coprocessor exception state */
|
|
||||||
sw a0, XCP_CR(sp)
|
|
||||||
sw a1, XCP_SR(sp)
|
|
||||||
sw a2, XCP_BADDR(sp)
|
|
||||||
sw a3, XCP_EPC(sp)
|
|
||||||
|
|
||||||
/* mdhi and mdlo */
|
|
||||||
mfhi v0
|
|
||||||
mflo v1
|
|
||||||
sw v0, XCP_MDHI(sp)
|
|
||||||
sw v1, XCP_MDLO(sp)
|
|
||||||
|
|
||||||
/* Save all the other general registers.
|
|
||||||
* We save zero, s0-s7 and s8 as well, as instruction emulators (e.g. FP
|
|
||||||
* operations) and debuggers rely on all registers stored together in
|
|
||||||
* well-defined structure.
|
|
||||||
*/
|
|
||||||
sw zero, XCP_ZERO(sp)
|
|
||||||
sw t0, XCP_T0(sp)
|
|
||||||
sw t1, XCP_T1(sp)
|
|
||||||
sw t2, XCP_T2(sp)
|
|
||||||
sw t3, XCP_T3(sp)
|
|
||||||
sw t4, XCP_T4(sp)
|
|
||||||
sw t5, XCP_T5(sp)
|
|
||||||
sw t6, XCP_T6(sp)
|
|
||||||
sw t7, XCP_T7(sp)
|
|
||||||
sw s0, XCP_S0(sp)
|
|
||||||
sw s1, XCP_S1(sp)
|
|
||||||
sw s2, XCP_S2(sp)
|
|
||||||
sw s3, XCP_S3(sp)
|
|
||||||
sw s4, XCP_S4(sp)
|
|
||||||
sw s5, XCP_S5(sp)
|
|
||||||
sw s6, XCP_S6(sp)
|
|
||||||
sw s7, XCP_S7(sp)
|
|
||||||
sw t8, XCP_T8(sp)
|
|
||||||
sw t9, XCP_T9(sp)
|
|
||||||
sw gp, XCP_GP(sp)
|
|
||||||
sw s8, XCP_S8(sp)
|
|
||||||
|
|
||||||
/* I don't know what the following does. [rb] */
|
|
||||||
/* load our _gp pointer */
|
|
||||||
# la gp, _gp
|
|
||||||
|
|
||||||
/* and call the C exception handler */
|
|
||||||
move a0, sp # arg1 = &xcp
|
|
||||||
subu sp, 16 # (arg save area)
|
|
||||||
j _xcptcall
|
|
||||||
move ra, zero # fake return address
|
|
||||||
|
|
||||||
/* This strange call to _xcptcall with zero return address is to
|
|
||||||
* help exception-aware debuggers to trace back over the exception event.
|
|
||||||
* We are basically interposing a bogus stackframe (with a zero return
|
|
||||||
* address) between the C exception handler and the actual machine
|
|
||||||
* exception.
|
|
||||||
*/
|
|
||||||
xcptrest:
|
|
||||||
.set noat
|
|
||||||
add AT, sp, 16
|
|
||||||
|
|
||||||
/* at points to exception frame */
|
|
||||||
xcptrestother:
|
|
||||||
/* restore all state */
|
|
||||||
/* restore most general registers */
|
|
||||||
lw t0, XCP_T0(AT)
|
|
||||||
lw t1, XCP_T1(AT)
|
|
||||||
lw t2, XCP_T2(AT)
|
|
||||||
lw t3, XCP_T3(AT)
|
|
||||||
lw t4, XCP_T4(AT)
|
|
||||||
lw t5, XCP_T5(AT)
|
|
||||||
lw t6, XCP_T6(AT)
|
|
||||||
lw t7, XCP_T7(AT)
|
|
||||||
lw s0, XCP_S0(AT)
|
|
||||||
lw s1, XCP_S1(AT)
|
|
||||||
lw s2, XCP_S2(AT)
|
|
||||||
lw s3, XCP_S3(AT)
|
|
||||||
lw s4, XCP_S4(AT)
|
|
||||||
lw s5, XCP_S5(AT)
|
|
||||||
lw s6, XCP_S6(AT)
|
|
||||||
lw s7, XCP_S7(AT)
|
|
||||||
lw t8, XCP_T8(AT)
|
|
||||||
lw t9, XCP_T9(AT)
|
|
||||||
lw gp, XCP_GP(AT)
|
|
||||||
lw s8, XCP_S8(AT)
|
|
||||||
|
|
||||||
/* mdhi and mdlo */
|
|
||||||
lw v0, XCP_MDHI(AT)
|
|
||||||
lw v1, XCP_MDLO(AT)
|
|
||||||
mthi v0
|
|
||||||
mtlo v1
|
|
||||||
|
|
||||||
/* remaining general registers */
|
|
||||||
lw a0, XCP_A0(AT)
|
|
||||||
lw a1, XCP_A1(AT)
|
|
||||||
lw a2, XCP_A2(AT)
|
|
||||||
lw a3, XCP_A3(AT)
|
|
||||||
lw ra, XCP_RA(AT)
|
|
||||||
|
|
||||||
/* restore the exception-time status register */
|
|
||||||
.set noreorder
|
|
||||||
lw v0, XCP_SR(AT)
|
|
||||||
nop
|
|
||||||
mtc0 v0, CP0_SR
|
|
||||||
lw v1, XCP_V1(AT)
|
|
||||||
lw v0, XCP_V0(AT)
|
|
||||||
lw sp, XCP_SP(AT)
|
|
||||||
|
|
||||||
/* we are not uninterruptible and can use k1 safely */
|
|
||||||
lw k1, XCP_EPC(AT)
|
|
||||||
lw AT, XCP_AT(AT)
|
|
||||||
mtc0 k1, CP0_EPC
|
|
||||||
j k1
|
|
||||||
rfe
|
|
||||||
|
|
||||||
.set reorder
|
|
||||||
.set at
|
|
||||||
END(xcptlow_handler)
|
|
||||||
|
|
||||||
|
|
||||||
LEAF(_xcptcall)
|
|
||||||
/* on entry: a0 == &xcp */
|
|
||||||
subu sp, 24
|
|
||||||
sw ra, 16(sp)
|
|
||||||
|
|
||||||
/* punt out to _xcpt_deliver */
|
|
||||||
jal _xcpt_deliver
|
|
||||||
nop
|
|
||||||
lw ra, 16(sp)
|
|
||||||
addu sp, 24
|
|
||||||
beqz ra, xcptrest
|
|
||||||
nop
|
|
||||||
j ra
|
|
||||||
nop
|
|
||||||
END(_xcptcall)
|
|
||||||
@@ -1,260 +0,0 @@
|
|||||||
.file "kernel.s"
|
|
||||||
|
|
||||||
.equ stack_ptr, 0x7FFFEFFC
|
|
||||||
.equ baudrate, 0x0D
|
|
||||||
.equ sys_led_port, 0xA0000000
|
|
||||||
.equ sys_uart_baud, 0xA0000009
|
|
||||||
.equ sys_uart_stat, 0xA0000008
|
|
||||||
.equ sys_uart_data, 0xA0000004
|
|
||||||
.equ sys_timer_sec, 0xA0000014
|
|
||||||
.equ sys_timer_usec, 0xA0000010
|
|
||||||
|
|
||||||
.section .kdata,"a"
|
|
||||||
.align 2
|
|
||||||
_k_stack: .space 256, 0
|
|
||||||
_k_msg1: .asciiz "Exception at "
|
|
||||||
_k_msg2: .asciiz "EPC : "
|
|
||||||
_k_msg3: .asciiz "Cause : "
|
|
||||||
_k_msg4: .asciiz "Status : "
|
|
||||||
_k_msg5: .asciiz "BadVAddr : "
|
|
||||||
_k_crlf: .asciiz "\r\n"
|
|
||||||
_k_hextbl: .ascii "0123456789ABCDEF"
|
|
||||||
|
|
||||||
.section .ktext,"ax"
|
|
||||||
.align 2
|
|
||||||
.globl _kputs
|
|
||||||
|
|
||||||
.macro kpush reg
|
|
||||||
addiu $sp, 4
|
|
||||||
sw \reg, 0($sp)
|
|
||||||
.endm
|
|
||||||
|
|
||||||
.macro kpop reg
|
|
||||||
lw \reg, 0($sp)
|
|
||||||
addiu $sp, -4
|
|
||||||
.endm
|
|
||||||
|
|
||||||
_exc_handler:
|
|
||||||
|
|
||||||
sw $sp, _k_stack
|
|
||||||
la $sp, _k_stack
|
|
||||||
kpush $8
|
|
||||||
kpush $9
|
|
||||||
kpush $10
|
|
||||||
kpush $11
|
|
||||||
kpush $12
|
|
||||||
kpush $31
|
|
||||||
|
|
||||||
.set noreorder
|
|
||||||
# # Get BadVAddr
|
|
||||||
# mfc0 $10, $8
|
|
||||||
# kpush $10
|
|
||||||
# # Get Status
|
|
||||||
# mfc0 $10, $12
|
|
||||||
# kpush $10
|
|
||||||
# # Get Cause
|
|
||||||
# mfc0 $10, $13
|
|
||||||
# kpush $10
|
|
||||||
# srl $10, 29
|
|
||||||
# andi $11, $10, 4
|
|
||||||
# # Get EPC
|
|
||||||
# mfc0 $10, $14
|
|
||||||
# kpush $10
|
|
||||||
#
|
|
||||||
# # Get real EPC
|
|
||||||
# addu $10, $11
|
|
||||||
# kpush $10
|
|
||||||
#
|
|
||||||
# # set uart
|
|
||||||
# la $26, sys_uart_baud
|
|
||||||
# addiu $27, $0, baudrate
|
|
||||||
# sb $27, 0($26)
|
|
||||||
#
|
|
||||||
# # Print CRLF
|
|
||||||
# la $11, _k_crlf
|
|
||||||
# jal _kputs
|
|
||||||
# nop
|
|
||||||
#
|
|
||||||
# # Print real EPC
|
|
||||||
# la $11, _k_msg1
|
|
||||||
# jal _kputs
|
|
||||||
# nop
|
|
||||||
# kpop $10
|
|
||||||
# jal _kprint_word
|
|
||||||
# nop
|
|
||||||
# la $11, _k_crlf
|
|
||||||
# jal _kputs
|
|
||||||
# nop
|
|
||||||
#
|
|
||||||
# # Print EPC
|
|
||||||
# la $11, _k_msg2
|
|
||||||
# jal _kputs
|
|
||||||
# nop
|
|
||||||
# kpop $10
|
|
||||||
# jal _kprint_word
|
|
||||||
# nop
|
|
||||||
# la $11, _k_crlf
|
|
||||||
# jal _kputs
|
|
||||||
# nop
|
|
||||||
#
|
|
||||||
# # Print Cause
|
|
||||||
# la $11, _k_msg3
|
|
||||||
# jal _kputs
|
|
||||||
# nop
|
|
||||||
# kpop $10
|
|
||||||
# jal _kprint_word
|
|
||||||
# nop
|
|
||||||
# la $11, _k_crlf
|
|
||||||
# jal _kputs
|
|
||||||
# nop
|
|
||||||
#
|
|
||||||
# # Print Status
|
|
||||||
# la $11, _k_msg4
|
|
||||||
# jal _kputs
|
|
||||||
# nop
|
|
||||||
# kpop $10
|
|
||||||
# jal _kprint_word
|
|
||||||
# nop
|
|
||||||
# la $11, _k_crlf
|
|
||||||
# jal _kputs
|
|
||||||
# nop
|
|
||||||
#
|
|
||||||
# # Print BadVAddr
|
|
||||||
# la $11, _k_msg5
|
|
||||||
# jal _kputs
|
|
||||||
# nop
|
|
||||||
# kpop $10
|
|
||||||
# jal _kprint_word
|
|
||||||
# nop
|
|
||||||
# la $11, _k_crlf
|
|
||||||
# jal _kputs
|
|
||||||
# nop
|
|
||||||
#
|
|
||||||
# Set Error LED and ExcCode LEDs
|
|
||||||
# Get Cause
|
|
||||||
# mfc0 $26, $13
|
|
||||||
# la $27, sys_led_port
|
|
||||||
# srl $26, 2
|
|
||||||
# andi $26, 0x000F
|
|
||||||
# or $26, $27
|
|
||||||
# sw $26, 0($27)
|
|
||||||
|
|
||||||
# wait for all interrupts = 0
|
|
||||||
#$w4x: mfc0 $26, $13
|
|
||||||
# mfc0 $27, $12
|
|
||||||
# srl $26, 8
|
|
||||||
# srl $27, 8
|
|
||||||
# and $26, $27
|
|
||||||
# bnez $26, $w4x
|
|
||||||
|
|
||||||
# Get return address
|
|
||||||
mfc0 $26, $14
|
|
||||||
|
|
||||||
$no_int: kpop $31
|
|
||||||
kpop $12
|
|
||||||
kpop $11
|
|
||||||
kpop $10
|
|
||||||
kpop $9
|
|
||||||
kpop $8
|
|
||||||
lw $sp, _k_stack
|
|
||||||
|
|
||||||
# Return
|
|
||||||
jr $26
|
|
||||||
rfe
|
|
||||||
.set reorder
|
|
||||||
|
|
||||||
# word = $10
|
|
||||||
_kprint_word:
|
|
||||||
.set noreorder
|
|
||||||
kpush $31
|
|
||||||
kpush $10
|
|
||||||
srl $10, 16
|
|
||||||
jal _kprint_halfword
|
|
||||||
nop
|
|
||||||
kpop $10
|
|
||||||
jal _kprint_halfword
|
|
||||||
nop
|
|
||||||
kpop $31
|
|
||||||
jr $31
|
|
||||||
nop
|
|
||||||
.set noreorder
|
|
||||||
|
|
||||||
# halfword = $10
|
|
||||||
_kprint_halfword:
|
|
||||||
.set noreorder
|
|
||||||
kpush $31
|
|
||||||
kpush $10
|
|
||||||
srl $10, 8
|
|
||||||
jal _kprint_byte
|
|
||||||
nop
|
|
||||||
kpop $10
|
|
||||||
jal _kprint_byte
|
|
||||||
nop
|
|
||||||
kpop $31
|
|
||||||
jr $31
|
|
||||||
nop
|
|
||||||
.set noreorder
|
|
||||||
|
|
||||||
# byte = $10
|
|
||||||
_kprint_byte:
|
|
||||||
.set noreorder
|
|
||||||
kpush $31
|
|
||||||
kpush $10
|
|
||||||
srl $10, 4
|
|
||||||
jal _kprint_nibble
|
|
||||||
nop
|
|
||||||
kpop $10
|
|
||||||
jal _kprint_nibble
|
|
||||||
nop
|
|
||||||
kpop $31
|
|
||||||
jr $31
|
|
||||||
nop
|
|
||||||
.set noreorder
|
|
||||||
|
|
||||||
_kprint_nibble:
|
|
||||||
.set noreorder
|
|
||||||
kpush $31
|
|
||||||
kpush $10
|
|
||||||
la $12, _k_hextbl
|
|
||||||
andi $10, 0xF
|
|
||||||
addu $12, $10
|
|
||||||
lbu $10, 0($12)
|
|
||||||
jal _ksaus
|
|
||||||
nop
|
|
||||||
kpop $10
|
|
||||||
kpop $31
|
|
||||||
jr $31
|
|
||||||
nop
|
|
||||||
.set noreorder
|
|
||||||
|
|
||||||
# char = $10
|
|
||||||
_ksaus:
|
|
||||||
.set noreorder
|
|
||||||
la $8, sys_uart_stat
|
|
||||||
lbu $8, 0($8)
|
|
||||||
la $9, sys_uart_data
|
|
||||||
andi $8, 0x02
|
|
||||||
bnez $8, _ksaus
|
|
||||||
nop
|
|
||||||
j $31
|
|
||||||
sb $10, 0($9)
|
|
||||||
.set reorder
|
|
||||||
|
|
||||||
_kputs:
|
|
||||||
.set noreorder
|
|
||||||
kpush $11
|
|
||||||
kpush $31
|
|
||||||
$kpl: lbu $10, 0($11)
|
|
||||||
addiu $11, 1
|
|
||||||
blez $10, $kpex
|
|
||||||
nop
|
|
||||||
jal _ksaus
|
|
||||||
nop
|
|
||||||
j $kpl
|
|
||||||
nop
|
|
||||||
$kpex: kpop $31
|
|
||||||
kpop $11
|
|
||||||
jr $31
|
|
||||||
nop
|
|
||||||
.set reorder
|
|
||||||
|
|
||||||
@@ -1,440 +0,0 @@
|
|||||||
#include <sys/times.h>
|
|
||||||
#include <sys/time.h>
|
|
||||||
#include <sys/resource.h>
|
|
||||||
#include <sys/stat.h>
|
|
||||||
#include <errno.h>
|
|
||||||
#include <stdlib.h>
|
|
||||||
#include "libsys.h"
|
|
||||||
|
|
||||||
// ---------------------------------------------------------------------------------
|
|
||||||
// MIPS specific
|
|
||||||
UINT32 CP0_SR_read(void)
|
|
||||||
{
|
|
||||||
UINT32 result;
|
|
||||||
|
|
||||||
__asm
|
|
||||||
(
|
|
||||||
"mfc0 %[val], $12\n"
|
|
||||||
: [val] "=r" (result)
|
|
||||||
);
|
|
||||||
|
|
||||||
return result;
|
|
||||||
}
|
|
||||||
|
|
||||||
void CP0_SR_write(UINT32 val)
|
|
||||||
{
|
|
||||||
__asm
|
|
||||||
(
|
|
||||||
"mtc0 %[val], $12\n"
|
|
||||||
: /* no output */
|
|
||||||
: [val] "r" (val)
|
|
||||||
);
|
|
||||||
}
|
|
||||||
|
|
||||||
UINT32 CP0_CR_read(void)
|
|
||||||
{
|
|
||||||
UINT32 result;
|
|
||||||
|
|
||||||
__asm
|
|
||||||
(
|
|
||||||
"mfc0 %[val], $13\n"
|
|
||||||
: [val] "=r" (result)
|
|
||||||
);
|
|
||||||
|
|
||||||
return result;
|
|
||||||
}
|
|
||||||
|
|
||||||
void CP0_CR_write(UINT32 val)
|
|
||||||
{
|
|
||||||
__asm
|
|
||||||
(
|
|
||||||
"mtc0 %[val], $13\n"
|
|
||||||
:
|
|
||||||
: [val] "r" (val)
|
|
||||||
);
|
|
||||||
}
|
|
||||||
|
|
||||||
UINT32 CP0_TR_read(void)
|
|
||||||
{
|
|
||||||
UINT32 result;
|
|
||||||
|
|
||||||
__asm
|
|
||||||
(
|
|
||||||
"mfc0 %[val], $31\n"
|
|
||||||
: [val] "=r" (result)
|
|
||||||
);
|
|
||||||
|
|
||||||
return result;
|
|
||||||
}
|
|
||||||
|
|
||||||
void CP0_TR_write(UINT32 val)
|
|
||||||
{
|
|
||||||
__asm
|
|
||||||
(
|
|
||||||
"mtc0 %[val], $31\n"
|
|
||||||
:
|
|
||||||
: [val] "r" (val)
|
|
||||||
);
|
|
||||||
}
|
|
||||||
|
|
||||||
UINT32 CP0_PRID_read(void)
|
|
||||||
{
|
|
||||||
UINT32 result;
|
|
||||||
|
|
||||||
__asm
|
|
||||||
(
|
|
||||||
"mfc0 %[val], $15\n"
|
|
||||||
: [val] "=r" (result)
|
|
||||||
);
|
|
||||||
|
|
||||||
return result;
|
|
||||||
}
|
|
||||||
|
|
||||||
// ---------------------------------------------------------------------------------
|
|
||||||
char readchar(void)
|
|
||||||
{
|
|
||||||
volatile UINT32 *pUART_stat = (UINT32*)sys_uart_stat;
|
|
||||||
volatile UINT32 *pUART_data = (UINT32*)sys_uart_data;
|
|
||||||
|
|
||||||
while(!(0x10 & *pUART_stat));
|
|
||||||
|
|
||||||
return (char)*pUART_data;
|
|
||||||
}
|
|
||||||
|
|
||||||
void writechar(char c)
|
|
||||||
{
|
|
||||||
volatile UINT32 *pUART_stat = (UINT32*)sys_uart_stat;
|
|
||||||
volatile UINT32 *pUART_data = (UINT32*)sys_uart_data;
|
|
||||||
|
|
||||||
while((0x01 & *pUART_stat) != 0);
|
|
||||||
|
|
||||||
*pUART_data = (UINT32)c;
|
|
||||||
}
|
|
||||||
|
|
||||||
void _putchar(char c)
|
|
||||||
{
|
|
||||||
if (c == 0x0A)
|
|
||||||
{
|
|
||||||
writechar(0x0D);
|
|
||||||
}
|
|
||||||
writechar(c);
|
|
||||||
}
|
|
||||||
|
|
||||||
void cg_writechar(char c)
|
|
||||||
{
|
|
||||||
volatile UINT32 *pCG_data = (UINT32*)sys_vga_data;
|
|
||||||
|
|
||||||
while (!(*pCG_data & 1));
|
|
||||||
*pCG_data = (UINT32)c;
|
|
||||||
}
|
|
||||||
|
|
||||||
void cg_clr_line(void)
|
|
||||||
{
|
|
||||||
volatile UINT32 *pCG_clrline = (UINT32*)sys_vga_clrline;
|
|
||||||
|
|
||||||
while (!(*pCG_clrline & 1));
|
|
||||||
*pCG_clrline = 1;
|
|
||||||
}
|
|
||||||
|
|
||||||
void _cg_putchar(char c)
|
|
||||||
{
|
|
||||||
if (c == 0x0A)
|
|
||||||
{
|
|
||||||
cg_writechar(0x0D);
|
|
||||||
}
|
|
||||||
cg_writechar(c);
|
|
||||||
if (c == 0x0A)
|
|
||||||
cg_clr_line();
|
|
||||||
|
|
||||||
}
|
|
||||||
|
|
||||||
void _exit (int exitcode)
|
|
||||||
{
|
|
||||||
sputs("_exit(");
|
|
||||||
print_word(exitcode);
|
|
||||||
sputs(")\n");
|
|
||||||
while(1);
|
|
||||||
}
|
|
||||||
|
|
||||||
void sleep(unsigned ms)
|
|
||||||
{
|
|
||||||
unsigned stop;
|
|
||||||
struct tms t;
|
|
||||||
|
|
||||||
times(&t);
|
|
||||||
stop = t.tms_utime + ms;
|
|
||||||
|
|
||||||
do
|
|
||||||
{
|
|
||||||
times(&t);
|
|
||||||
} while (t.tms_utime < stop);
|
|
||||||
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
int getrusage(int who, struct rusage *usage)
|
|
||||||
{
|
|
||||||
volatile long *pReg_usec = (long*)sys_timer_usec;
|
|
||||||
volatile long *pReg_sec = (long*)sys_timer_sec;
|
|
||||||
|
|
||||||
// who: RUSAGE_SELF or RUSAGE_CHILDREN
|
|
||||||
usage->ru_utime.tv_usec = *pReg_usec;
|
|
||||||
usage->ru_utime.tv_sec = *pReg_sec;
|
|
||||||
usage->ru_stime.tv_usec = *pReg_usec;
|
|
||||||
usage->ru_stime.tv_sec = *pReg_sec;
|
|
||||||
}
|
|
||||||
|
|
||||||
clock_t times(struct tms *buffer)
|
|
||||||
{
|
|
||||||
volatile long *pReg_usec = (long*)sys_timer_usec;
|
|
||||||
volatile long *pReg_sec = (long*)sys_timer_sec;
|
|
||||||
long sec;
|
|
||||||
long usec;
|
|
||||||
|
|
||||||
sec = *pReg_sec;
|
|
||||||
usec = *pReg_usec;
|
|
||||||
|
|
||||||
if (buffer)
|
|
||||||
{
|
|
||||||
buffer->tms_utime = sec*1000 + usec/1000;
|
|
||||||
buffer->tms_stime = 0;
|
|
||||||
buffer->tms_cutime = 0;
|
|
||||||
buffer->tms_cstime = 0;
|
|
||||||
}
|
|
||||||
|
|
||||||
return (clock_t)sec;
|
|
||||||
}
|
|
||||||
|
|
||||||
int gettimeofday(struct timeval *tp, void *tzp)
|
|
||||||
{
|
|
||||||
volatile long *pReg_usec = (long*)sys_timer_usec;
|
|
||||||
volatile long *pReg_sec = (long*)sys_timer_sec;
|
|
||||||
|
|
||||||
if (tp)
|
|
||||||
{
|
|
||||||
tp->tv_sec = *pReg_sec;
|
|
||||||
tp->tv_usec = *pReg_usec;
|
|
||||||
}
|
|
||||||
|
|
||||||
return 0;
|
|
||||||
}
|
|
||||||
|
|
||||||
int settimeofday(const struct timeval *tp, const struct timezone *tzp)
|
|
||||||
{
|
|
||||||
volatile long *pReg_usec = (long*)sys_timer_usec;
|
|
||||||
volatile long *pReg_sec = (long*)sys_timer_sec;
|
|
||||||
div_t res;
|
|
||||||
|
|
||||||
res = div(tp->tv_usec, 1E6);
|
|
||||||
|
|
||||||
if (tp)
|
|
||||||
{
|
|
||||||
*pReg_usec = res.rem;
|
|
||||||
*pReg_sec = tp->tv_sec + res.quot;
|
|
||||||
}
|
|
||||||
|
|
||||||
return 0;
|
|
||||||
}
|
|
||||||
|
|
||||||
caddr_t sbrk(int incr)
|
|
||||||
{
|
|
||||||
extern char end;
|
|
||||||
static char *heap_end;
|
|
||||||
char *prev_heap_end;
|
|
||||||
|
|
||||||
if (heap_end == 0)
|
|
||||||
heap_end = &end;
|
|
||||||
|
|
||||||
prev_heap_end = heap_end;
|
|
||||||
// if (heap_end + incr > stack_ptr)
|
|
||||||
// {
|
|
||||||
// sputs("Heap and stack collision\r\n");
|
|
||||||
// abort();
|
|
||||||
// }
|
|
||||||
|
|
||||||
// sputs("\n");
|
|
||||||
// print_word((int)prev_heap_end);
|
|
||||||
// sputs("\n");
|
|
||||||
heap_end += incr;
|
|
||||||
return (caddr_t) prev_heap_end;
|
|
||||||
}
|
|
||||||
|
|
||||||
int fstat(int file, struct stat *st)
|
|
||||||
{
|
|
||||||
// sputs("Fstat()\n");
|
|
||||||
st->st_mode = S_IFCHR;
|
|
||||||
st->st_blksize = 0;
|
|
||||||
return 0;
|
|
||||||
}
|
|
||||||
|
|
||||||
int lseek(int file, int ptr, int dir)
|
|
||||||
{
|
|
||||||
sputs("Lseek()\n");
|
|
||||||
|
|
||||||
errno = ESPIPE;
|
|
||||||
return -1;
|
|
||||||
}
|
|
||||||
|
|
||||||
int open(const char *name, int flags, int mode)
|
|
||||||
{
|
|
||||||
sputs("Open()\n");
|
|
||||||
errno = EIO;
|
|
||||||
return -1;
|
|
||||||
}
|
|
||||||
|
|
||||||
int close(int file)
|
|
||||||
{
|
|
||||||
sputs("Close()\n");
|
|
||||||
return 0;
|
|
||||||
}
|
|
||||||
|
|
||||||
int read(int file, char *ptr, int len)
|
|
||||||
{
|
|
||||||
int i;
|
|
||||||
|
|
||||||
// sputs("Read()\n");
|
|
||||||
for (i = 0; i < len; i++)
|
|
||||||
{
|
|
||||||
ptr[i] = readchar();
|
|
||||||
if ((ptr[i] == '\n') || (ptr[i] == '\r'))
|
|
||||||
{
|
|
||||||
i++;
|
|
||||||
writechar(0x0D);
|
|
||||||
writechar(0x0A);
|
|
||||||
break;
|
|
||||||
}
|
|
||||||
writechar(ptr[i]);
|
|
||||||
}
|
|
||||||
return i;
|
|
||||||
}
|
|
||||||
|
|
||||||
int write(int file, char *ptr, int len)
|
|
||||||
{
|
|
||||||
int i;
|
|
||||||
|
|
||||||
if (file == 1)
|
|
||||||
{
|
|
||||||
for (i=0; i < len; i++)
|
|
||||||
STDOUT_FUNCTION(*ptr++);
|
|
||||||
}
|
|
||||||
if (file == 2)
|
|
||||||
{
|
|
||||||
for (i=0; i < len; i++)
|
|
||||||
STDERR_FUNCTION(*ptr++);
|
|
||||||
}
|
|
||||||
return i;
|
|
||||||
}
|
|
||||||
|
|
||||||
int isatty(int file)
|
|
||||||
{
|
|
||||||
// sputs("Isatty()\n");
|
|
||||||
return 1;
|
|
||||||
}
|
|
||||||
|
|
||||||
int sputs(char *pStr)
|
|
||||||
{
|
|
||||||
char *start;
|
|
||||||
start = pStr;
|
|
||||||
|
|
||||||
while(*pStr)
|
|
||||||
_putchar(*(pStr++));
|
|
||||||
|
|
||||||
return pStr - start;
|
|
||||||
}
|
|
||||||
|
|
||||||
void print_byte(char byte)
|
|
||||||
{
|
|
||||||
int i;
|
|
||||||
unsigned char c, nibble;
|
|
||||||
|
|
||||||
for (i=0; i < 2; i++)
|
|
||||||
{
|
|
||||||
nibble = (char)((byte >> 4) & 0xF);
|
|
||||||
byte <<= 4;
|
|
||||||
|
|
||||||
if (nibble < 10)
|
|
||||||
c = nibble + '0';
|
|
||||||
else
|
|
||||||
c = nibble + 'A' - 10;
|
|
||||||
|
|
||||||
_putchar(c);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
void print_word(int word)
|
|
||||||
{
|
|
||||||
int i;
|
|
||||||
unsigned char c, nibble;
|
|
||||||
|
|
||||||
for (i=0; i < 4; i++)
|
|
||||||
{
|
|
||||||
c = (char) (word >> 24);
|
|
||||||
print_byte(c);
|
|
||||||
word <<= 8;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
// ---------------------------------------------------------------------------------
|
|
||||||
// PrintBuffer8()
|
|
||||||
// Prints byte buffer as hex and ascii interpretation
|
|
||||||
// ---------------------------------------------------------------------------------
|
|
||||||
// _Parameters :
|
|
||||||
// pBuf: : IN: Buffer to display
|
|
||||||
// nbpr : Number of bytes per row to display
|
|
||||||
// len : Length of input buffer
|
|
||||||
// _Return: none
|
|
||||||
//
|
|
||||||
// ---------------------------------------------------------------------------
|
|
||||||
void PrintBuffer8(UINT8 *pBuf, int nbpr, int len)
|
|
||||||
{
|
|
||||||
int i, j, cnt_hex, cnt_asc;
|
|
||||||
unsigned char c;
|
|
||||||
|
|
||||||
i = j = 0;
|
|
||||||
cnt_hex = len;
|
|
||||||
cnt_asc = len;
|
|
||||||
|
|
||||||
do
|
|
||||||
{
|
|
||||||
print_word(i);
|
|
||||||
sputs(": ");
|
|
||||||
for (j=0; j < nbpr; j++)
|
|
||||||
{
|
|
||||||
if (cnt_hex)
|
|
||||||
{
|
|
||||||
print_byte(pBuf[i+j]);
|
|
||||||
sputs(" ");
|
|
||||||
cnt_hex--;
|
|
||||||
}
|
|
||||||
else
|
|
||||||
{
|
|
||||||
sputs(" ");
|
|
||||||
break;
|
|
||||||
}
|
|
||||||
|
|
||||||
}
|
|
||||||
|
|
||||||
sputs(" ");
|
|
||||||
for (j=0; j < nbpr; j++)
|
|
||||||
{
|
|
||||||
if (cnt_asc)
|
|
||||||
{
|
|
||||||
c = pBuf[i+j];
|
|
||||||
if((c < 0x20) || (c > 0x7F))
|
|
||||||
c = '.';
|
|
||||||
|
|
||||||
_putchar(c);
|
|
||||||
cnt_asc--;
|
|
||||||
}
|
|
||||||
else
|
|
||||||
{
|
|
||||||
sputs(" ");
|
|
||||||
break;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
sputs("\n");
|
|
||||||
i += nbpr;
|
|
||||||
|
|
||||||
} while (cnt_hex);
|
|
||||||
}
|
|
||||||
|
|
||||||
@@ -1,77 +0,0 @@
|
|||||||
#ifndef LIBSYS_H
|
|
||||||
#define LIBSYS_H
|
|
||||||
|
|
||||||
// ---------------------------------------------------------
|
|
||||||
// Types
|
|
||||||
// ---------------------------------------------------------
|
|
||||||
#define INT8 signed char
|
|
||||||
#define INT16 signed short
|
|
||||||
#define INT32 signed int
|
|
||||||
#define INT64 signed long long
|
|
||||||
#define UINT8 unsigned char
|
|
||||||
#define UINT16 unsigned short
|
|
||||||
#define UINT32 unsigned int
|
|
||||||
#define UINT64 unsigned long long
|
|
||||||
#define INT INT32
|
|
||||||
#define UINT UINT32
|
|
||||||
#define FLOAT32 float
|
|
||||||
#define FLOAT64 double
|
|
||||||
|
|
||||||
|
|
||||||
#define sys_gpio0 0xA0000000
|
|
||||||
#define sys_gpio1 0xA0000004
|
|
||||||
#define sys_led_port sys_gpio0
|
|
||||||
#define sys_usb_ctrl sys_gpio1
|
|
||||||
#define sys_timer_usec 0xA0000008
|
|
||||||
#define sys_timer_sec 0xA000000C
|
|
||||||
#define sys_uart_data 0xA0010000
|
|
||||||
#define sys_uart_stat 0xA0010004
|
|
||||||
#define sys_uart_baud 0xA0010008
|
|
||||||
#define sys_usb_data 0xA0020000
|
|
||||||
#define sys_usb_mbx 0xA0020004
|
|
||||||
#define sys_usb_addr 0xA0020008
|
|
||||||
#define sys_usb_status 0xA002000C
|
|
||||||
#define sys_vga_data 0xA0030004
|
|
||||||
#define sys_vga_posx 0xA0030008
|
|
||||||
#define sys_vga_posy 0xA0030010
|
|
||||||
#define sys_vga_clrscr 0xA0030020
|
|
||||||
#define sys_vga_clrline 0xA0030040
|
|
||||||
#define sys_vga_mctrl 0xA0030100
|
|
||||||
#define sys_vga_moffs 0xA0030200
|
|
||||||
#define sys_ac97_stat 0xA0040000
|
|
||||||
#define sys_ac97_ctrl 0xA0040000
|
|
||||||
#define sys_ac97_acstat 0xA0040400
|
|
||||||
#define sys_ac97_acctrl 0xA0040600
|
|
||||||
#define sys_ac97_pcm 0xA0040800
|
|
||||||
#define sys_ac97_wavin sys_ac97_pcm
|
|
||||||
#define sys_ac97_wavout sys_ac97_pcm
|
|
||||||
#define sys_flash_io 0xA4000000
|
|
||||||
#define sys_ssram_io 0xA8000000
|
|
||||||
|
|
||||||
//#define STDOUT_FUNCTION _cg_putchar // Video character
|
|
||||||
//#define STDERR_FUNCTION _putchar // Serial output
|
|
||||||
|
|
||||||
#define STDOUT_FUNCTION _putchar // Serial output
|
|
||||||
#define STDERR_FUNCTION _putchar // Serial output
|
|
||||||
|
|
||||||
UINT32 CP0_SR_read(void);
|
|
||||||
void CP0_SR_write(UINT32 val);
|
|
||||||
UINT32 CP0_CR_read(void);
|
|
||||||
void CP0_CR_write(UINT32 val);
|
|
||||||
UINT32 CP0_PRID_read(void);
|
|
||||||
UINT32 CP0_TR_read(void);
|
|
||||||
void CP0_TR_write(UINT32 val);
|
|
||||||
|
|
||||||
char readchar(void);
|
|
||||||
void writechar(char c);
|
|
||||||
int write(int file, char *ptr, int len);
|
|
||||||
int sputs(char *pStr);
|
|
||||||
void print_byte(char byte);
|
|
||||||
void print_word(int word);
|
|
||||||
void _exit (int exitcode);
|
|
||||||
void sleep(unsigned ms);
|
|
||||||
|
|
||||||
void PrintBuffer8(UINT8 *pBuf, int nbpr, int len);
|
|
||||||
|
|
||||||
#endif // LIBSYS_H
|
|
||||||
|
|
||||||
@@ -1,274 +0,0 @@
|
|||||||
/* Script for -z combreloc: combine and sort reloc sections */
|
|
||||||
OUTPUT_FORMAT("elf32-littlemips", "elf32-bigmips",
|
|
||||||
"elf32-littlemips")
|
|
||||||
OUTPUT_ARCH(mips)
|
|
||||||
ENTRY(_start)
|
|
||||||
SEARCH_DIR("/usr/local/mipsel-elf/lib");
|
|
||||||
|
|
||||||
stack_ptr = 0x7FFFEFF0;
|
|
||||||
baudrate = 0x0D;
|
|
||||||
sys_led_port = 0xA0000000;
|
|
||||||
sys_uart_data = 0xA0010000;
|
|
||||||
sys_uart_stat = 0xA0010004;
|
|
||||||
sys_uart_baud = 0xA0010008;
|
|
||||||
sys_timer_usec = 0xA000008;
|
|
||||||
sys_timer_sec = 0xA000000C;
|
|
||||||
|
|
||||||
STARTUP(startup.o)
|
|
||||||
INPUT(kernel.o)
|
|
||||||
INPUT(libsys.a)
|
|
||||||
|
|
||||||
SECTIONS
|
|
||||||
{
|
|
||||||
/* Read-only sections, merged into text segment: */
|
|
||||||
PROVIDE (__executable_start = 0x40000000); . = 0x40000000;
|
|
||||||
.etext __executable_start :
|
|
||||||
{
|
|
||||||
start = ALIGN(2);
|
|
||||||
entry = ALIGN(2);
|
|
||||||
_entry = ALIGN(2);
|
|
||||||
__entry = ALIGN(2);
|
|
||||||
*(.etext)
|
|
||||||
}
|
|
||||||
|
|
||||||
.ktext __executable_start + 0x180 :
|
|
||||||
{
|
|
||||||
*(.ktext)
|
|
||||||
}
|
|
||||||
|
|
||||||
.interp : { *(.interp) }
|
|
||||||
.reginfo : { *(.reginfo) }
|
|
||||||
.note.gnu.build-id : { *(.note.gnu.build-id) }
|
|
||||||
.dynamic : { *(.dynamic) }
|
|
||||||
.hash : { *(.hash) }
|
|
||||||
.gnu.hash : { *(.gnu.hash) }
|
|
||||||
.dynsym : { *(.dynsym) }
|
|
||||||
.dynstr : { *(.dynstr) }
|
|
||||||
.gnu.version : { *(.gnu.version) }
|
|
||||||
.gnu.version_d : { *(.gnu.version_d) }
|
|
||||||
.gnu.version_r : { *(.gnu.version_r) }
|
|
||||||
.rel.dyn :
|
|
||||||
{
|
|
||||||
*(.rel.init)
|
|
||||||
*(.rel.text .rel.text.* .rel.gnu.linkonce.t.*)
|
|
||||||
*(.rel.fini)
|
|
||||||
*(.rel.rodata .rel.rodata.* .rel.gnu.linkonce.r.*)
|
|
||||||
*(.rel.data.rel.ro* .rel.gnu.linkonce.d.rel.ro.*)
|
|
||||||
*(.rel.data .rel.data.* .rel.gnu.linkonce.d.*)
|
|
||||||
*(.rel.tdata .rel.tdata.* .rel.gnu.linkonce.td.*)
|
|
||||||
*(.rel.tbss .rel.tbss.* .rel.gnu.linkonce.tb.*)
|
|
||||||
*(.rel.ctors)
|
|
||||||
*(.rel.dtors)
|
|
||||||
*(.rel.got)
|
|
||||||
*(.rel.dyn)
|
|
||||||
*(.rel.sdata .rel.sdata.* .rel.gnu.linkonce.s.*)
|
|
||||||
*(.rel.sbss .rel.sbss.* .rel.gnu.linkonce.sb.*)
|
|
||||||
*(.rel.sdata2 .rel.sdata2.* .rel.gnu.linkonce.s2.*)
|
|
||||||
*(.rel.sbss2 .rel.sbss2.* .rel.gnu.linkonce.sb2.*)
|
|
||||||
*(.rel.bss .rel.bss.* .rel.gnu.linkonce.b.*)
|
|
||||||
}
|
|
||||||
.rela.dyn :
|
|
||||||
{
|
|
||||||
*(.rela.init)
|
|
||||||
*(.rela.text .rela.text.* .rela.gnu.linkonce.t.*)
|
|
||||||
*(.rela.fini)
|
|
||||||
*(.rela.rodata .rela.rodata.* .rela.gnu.linkonce.r.*)
|
|
||||||
*(.rela.data .rela.data.* .rela.gnu.linkonce.d.*)
|
|
||||||
*(.rela.tdata .rela.tdata.* .rela.gnu.linkonce.td.*)
|
|
||||||
*(.rela.tbss .rela.tbss.* .rela.gnu.linkonce.tb.*)
|
|
||||||
*(.rela.ctors)
|
|
||||||
*(.rela.dtors)
|
|
||||||
*(.rela.got)
|
|
||||||
*(.rela.sdata .rela.sdata.* .rela.gnu.linkonce.s.*)
|
|
||||||
*(.rela.sbss .rela.sbss.* .rela.gnu.linkonce.sb.*)
|
|
||||||
*(.rela.sdata2 .rela.sdata2.* .rela.gnu.linkonce.s2.*)
|
|
||||||
*(.rela.sbss2 .rela.sbss2.* .rela.gnu.linkonce.sb2.*)
|
|
||||||
*(.rela.bss .rela.bss.* .rela.gnu.linkonce.b.*)
|
|
||||||
}
|
|
||||||
.rel.plt : { *(.rel.plt) }
|
|
||||||
.rela.plt : { *(.rela.plt) }
|
|
||||||
.init :
|
|
||||||
{
|
|
||||||
KEEP (*(.init))
|
|
||||||
} =0
|
|
||||||
.plt : { *(.plt) }
|
|
||||||
.text :
|
|
||||||
{
|
|
||||||
_ftext = . ;
|
|
||||||
*(.text .stub .text.* .gnu.linkonce.t.*)
|
|
||||||
/* .gnu.warning sections are handled specially by elf32.em. */
|
|
||||||
*(.gnu.warning)
|
|
||||||
*(.mips16.fn.*) *(.mips16.call.*)
|
|
||||||
}
|
|
||||||
.fini :
|
|
||||||
{
|
|
||||||
KEEP (*(.fini))
|
|
||||||
} =0
|
|
||||||
PROVIDE (__etext = .);
|
|
||||||
PROVIDE (_etext = .);
|
|
||||||
PROVIDE (etext = .);
|
|
||||||
.rodata : { *(.rodata .rodata.* .gnu.linkonce.r.*) }
|
|
||||||
.rodata1 : { *(.rodata1) }
|
|
||||||
.sdata2 :
|
|
||||||
{
|
|
||||||
*(.sdata2 .sdata2.* .gnu.linkonce.s2.*)
|
|
||||||
}
|
|
||||||
.sbss2 : { *(.sbss2 .sbss2.* .gnu.linkonce.sb2.*) }
|
|
||||||
.eh_frame_hdr : { *(.eh_frame_hdr) }
|
|
||||||
.eh_frame : ONLY_IF_RO { KEEP (*(.eh_frame)) }
|
|
||||||
.gcc_except_table : ONLY_IF_RO { *(.gcc_except_table .gcc_except_table.*) }
|
|
||||||
/* Adjust the address for the data segment. We want to adjust up to
|
|
||||||
the same address within the page on the next page up. */
|
|
||||||
. = ALIGN (CONSTANT (MAXPAGESIZE)) - ((CONSTANT (MAXPAGESIZE) - .) & (CONSTANT (MAXPAGESIZE) - 1)); . = DATA_SEGMENT_ALIGN (CONSTANT (MAXPAGESIZE), CONSTANT (COMMONPAGESIZE));
|
|
||||||
/* Exception handling */
|
|
||||||
.eh_frame : ONLY_IF_RW { KEEP (*(.eh_frame)) }
|
|
||||||
.gcc_except_table : ONLY_IF_RW { *(.gcc_except_table .gcc_except_table.*) }
|
|
||||||
/* Thread Local Storage sections */
|
|
||||||
.tdata : { *(.tdata .tdata.* .gnu.linkonce.td.*) }
|
|
||||||
.tbss : { *(.tbss .tbss.* .gnu.linkonce.tb.*) *(.tcommon) }
|
|
||||||
.preinit_array :
|
|
||||||
{
|
|
||||||
PROVIDE_HIDDEN (__preinit_array_start = .);
|
|
||||||
KEEP (*(.preinit_array))
|
|
||||||
PROVIDE_HIDDEN (__preinit_array_end = .);
|
|
||||||
}
|
|
||||||
.init_array :
|
|
||||||
{
|
|
||||||
PROVIDE_HIDDEN (__init_array_start = .);
|
|
||||||
KEEP (*(SORT(.init_array.*)))
|
|
||||||
KEEP (*(.init_array))
|
|
||||||
PROVIDE_HIDDEN (__init_array_end = .);
|
|
||||||
}
|
|
||||||
.fini_array :
|
|
||||||
{
|
|
||||||
PROVIDE_HIDDEN (__fini_array_start = .);
|
|
||||||
KEEP (*(.fini_array))
|
|
||||||
KEEP (*(SORT(.fini_array.*)))
|
|
||||||
PROVIDE_HIDDEN (__fini_array_end = .);
|
|
||||||
}
|
|
||||||
.ctors :
|
|
||||||
{
|
|
||||||
/* gcc uses crtbegin.o to find the start of
|
|
||||||
the constructors, so we make sure it is
|
|
||||||
first. Because this is a wildcard, it
|
|
||||||
doesn't matter if the user does not
|
|
||||||
actually link against crtbegin.o; the
|
|
||||||
linker won't look for a file to match a
|
|
||||||
wildcard. The wildcard also means that it
|
|
||||||
doesn't matter which directory crtbegin.o
|
|
||||||
is in. */
|
|
||||||
KEEP (*crtbegin.o(.ctors))
|
|
||||||
KEEP (*crtbegin?.o(.ctors))
|
|
||||||
/* We don't want to include the .ctor section from
|
|
||||||
the crtend.o file until after the sorted ctors.
|
|
||||||
The .ctor section from the crtend file contains the
|
|
||||||
end of ctors marker and it must be last */
|
|
||||||
KEEP (*(EXCLUDE_FILE (*crtend.o *crtend?.o ) .ctors))
|
|
||||||
KEEP (*(SORT(.ctors.*)))
|
|
||||||
KEEP (*(.ctors))
|
|
||||||
}
|
|
||||||
.dtors :
|
|
||||||
{
|
|
||||||
KEEP (*crtbegin.o(.dtors))
|
|
||||||
KEEP (*crtbegin?.o(.dtors))
|
|
||||||
KEEP (*(EXCLUDE_FILE (*crtend.o *crtend?.o ) .dtors))
|
|
||||||
KEEP (*(SORT(.dtors.*)))
|
|
||||||
KEEP (*(.dtors))
|
|
||||||
}
|
|
||||||
.jcr : { KEEP (*(.jcr)) }
|
|
||||||
.data.rel.ro : { *(.data.rel.ro.local* .gnu.linkonce.d.rel.ro.local.*) *(.data.rel.ro* .gnu.linkonce.d.rel.ro.*) }
|
|
||||||
. = DATA_SEGMENT_RELRO_END (0, .);
|
|
||||||
.data :
|
|
||||||
{
|
|
||||||
_fdata = . ;
|
|
||||||
*(.data .data.* .gnu.linkonce.d.*)
|
|
||||||
SORT(CONSTRUCTORS)
|
|
||||||
}
|
|
||||||
.data1 : { *(.data1) }
|
|
||||||
.got.plt : { *(.got.plt) }
|
|
||||||
. = .;
|
|
||||||
_gp = ALIGN(16) + 0x7ff0;
|
|
||||||
.got : { *(.got) }
|
|
||||||
/* We want the small data sections together, so single-instruction offsets
|
|
||||||
can access them all, and initialized data all before uninitialized, so
|
|
||||||
we can shorten the on-disk segment size. */
|
|
||||||
.sdata :
|
|
||||||
{
|
|
||||||
*(.sdata .sdata.* .gnu.linkonce.s.*)
|
|
||||||
}
|
|
||||||
.lit8 : { *(.lit8) }
|
|
||||||
.lit4 : { *(.lit4) }
|
|
||||||
_edata = .; PROVIDE (edata = .);
|
|
||||||
__bss_start = .;
|
|
||||||
_fbss = .;
|
|
||||||
.sbss :
|
|
||||||
{
|
|
||||||
*(.dynsbss)
|
|
||||||
*(.sbss .sbss.* .gnu.linkonce.sb.*)
|
|
||||||
*(.scommon)
|
|
||||||
}
|
|
||||||
.bss :
|
|
||||||
{
|
|
||||||
*(.dynbss)
|
|
||||||
*(.bss .bss.* .gnu.linkonce.b.*)
|
|
||||||
*(COMMON)
|
|
||||||
/* Align here to ensure that the .bss section occupies space up to
|
|
||||||
_end. Align after .bss to ensure correct alignment even if the
|
|
||||||
.bss section disappears because there are no input sections.
|
|
||||||
FIXME: Why do we need it? When there is no .bss section, we don't
|
|
||||||
pad the .data section. */
|
|
||||||
. = ALIGN(. != 0 ? 32 / 8 : 1);
|
|
||||||
}
|
|
||||||
. = ALIGN(32 / 8);
|
|
||||||
. = ALIGN(32 / 8);
|
|
||||||
_end = .; PROVIDE (end = .);
|
|
||||||
. = DATA_SEGMENT_END (.);
|
|
||||||
/* Stabs debugging sections. */
|
|
||||||
.stab 0 : { *(.stab) }
|
|
||||||
.stabstr 0 : { *(.stabstr) }
|
|
||||||
.stab.excl 0 : { *(.stab.excl) }
|
|
||||||
.stab.exclstr 0 : { *(.stab.exclstr) }
|
|
||||||
.stab.index 0 : { *(.stab.index) }
|
|
||||||
.stab.indexstr 0 : { *(.stab.indexstr) }
|
|
||||||
.comment 0 : { *(.comment) }
|
|
||||||
/* DWARF debug sections.
|
|
||||||
Symbols in the DWARF debugging sections are relative to the beginning
|
|
||||||
of the section so we begin them at 0. */
|
|
||||||
/* DWARF 1 */
|
|
||||||
.debug 0 : { *(.debug) }
|
|
||||||
.line 0 : { *(.line) }
|
|
||||||
/* GNU DWARF 1 extensions */
|
|
||||||
.debug_srcinfo 0 : { *(.debug_srcinfo) }
|
|
||||||
.debug_sfnames 0 : { *(.debug_sfnames) }
|
|
||||||
/* DWARF 1.1 and DWARF 2 */
|
|
||||||
.debug_aranges 0 : { *(.debug_aranges) }
|
|
||||||
.debug_pubnames 0 : { *(.debug_pubnames) }
|
|
||||||
/* DWARF 2 */
|
|
||||||
.debug_info 0 : { *(.debug_info .gnu.linkonce.wi.*) }
|
|
||||||
.debug_abbrev 0 : { *(.debug_abbrev) }
|
|
||||||
.debug_line 0 : { *(.debug_line) }
|
|
||||||
.debug_frame 0 : { *(.debug_frame) }
|
|
||||||
.debug_str 0 : { *(.debug_str) }
|
|
||||||
.debug_loc 0 : { *(.debug_loc) }
|
|
||||||
.debug_macinfo 0 : { *(.debug_macinfo) }
|
|
||||||
/* SGI/MIPS DWARF 2 extensions */
|
|
||||||
.debug_weaknames 0 : { *(.debug_weaknames) }
|
|
||||||
.debug_funcnames 0 : { *(.debug_funcnames) }
|
|
||||||
.debug_typenames 0 : { *(.debug_typenames) }
|
|
||||||
.debug_varnames 0 : { *(.debug_varnames) }
|
|
||||||
/* DWARF 3 */
|
|
||||||
.debug_pubtypes 0 : { *(.debug_pubtypes) }
|
|
||||||
.debug_ranges 0 : { *(.debug_ranges) }
|
|
||||||
.gnu.attributes 0 : { KEEP (*(.gnu.attributes)) }
|
|
||||||
.gptab.sdata : { *(.gptab.data) *(.gptab.sdata) }
|
|
||||||
.gptab.sbss : { *(.gptab.bss) *(.gptab.sbss) }
|
|
||||||
.mdebug.abi32 : { KEEP(*(.mdebug.abi32)) }
|
|
||||||
.mdebug.abiN32 : { KEEP(*(.mdebug.abiN32)) }
|
|
||||||
.mdebug.abi64 : { KEEP(*(.mdebug.abi64)) }
|
|
||||||
.mdebug.abiO64 : { KEEP(*(.mdebug.abiO64)) }
|
|
||||||
.mdebug.eabi32 : { KEEP(*(.mdebug.eabi32)) }
|
|
||||||
.mdebug.eabi64 : { KEEP(*(.mdebug.eabi64)) }
|
|
||||||
.gcc_compiled_long32 : { KEEP(*(.gcc_compiled_long32)) }
|
|
||||||
.gcc_compiled_long64 : { KEEP(*(.gcc_compiled_long64)) }
|
|
||||||
/DISCARD/ : { *(.note.GNU-stack) *(.gnu_debuglink) }
|
|
||||||
}
|
|
||||||
File diff suppressed because it is too large
Load Diff
@@ -1,298 +0,0 @@
|
|||||||
#include <stdio.h>
|
|
||||||
#include <stdlib.h>
|
|
||||||
#include "libsys.h"
|
|
||||||
|
|
||||||
struct substantive
|
|
||||||
{
|
|
||||||
char *subst;
|
|
||||||
int sex;
|
|
||||||
};
|
|
||||||
|
|
||||||
struct verben
|
|
||||||
{
|
|
||||||
char *verb_k;
|
|
||||||
char *verb_gr;
|
|
||||||
int art;
|
|
||||||
};
|
|
||||||
|
|
||||||
struct adjektive
|
|
||||||
{
|
|
||||||
char *adj;
|
|
||||||
};
|
|
||||||
|
|
||||||
char *art[4]={"er","ie","as","en"};
|
|
||||||
|
|
||||||
char getch(void)
|
|
||||||
{
|
|
||||||
return readchar();
|
|
||||||
}
|
|
||||||
|
|
||||||
void randomize(void)
|
|
||||||
{
|
|
||||||
srand(clock());
|
|
||||||
}
|
|
||||||
|
|
||||||
struct substantive namen[]=
|
|
||||||
{
|
|
||||||
{"Gerhard Schröder",1},{"Helmut Kohl",1},{"Rudolf Scharping",1},
|
|
||||||
{"Claudia Nolte",2}, {"Johannes Rau",1},{"Wolfgang Schäuble",1},
|
|
||||||
{"Joschka Fischer",1},{"Toni Blair",1},{"Kleopatra",2},
|
|
||||||
{"Claudia Schiffer",2},{"Hannelore Kohl",2},{"Konrad Adenauer",1},
|
|
||||||
{"Michael Jackson",1},{"Karl Marx",1}, {"Helmut Kohl",1},{"Heino",1},
|
|
||||||
{"Gerhard Schröder",1},{"Donald Duck",1},{"Madonna",2},{"Jesus",1},
|
|
||||||
{"Gott",1},{"Sheryl Crow",2},{"Verona Feldbusch",2},{"Pipi Langstrumpf",2},
|
|
||||||
{"Bill Gates",1},{"Bill Clinton",1},{"Cleopatra",2},{"Winnetou",1},
|
|
||||||
{"Käpt'n Blaubär",1},{"Rita Süssmuth",2},{"Boris Becker",1},
|
|
||||||
{"Lilo Wanders",2},{"Queen Elizabeth",2},{"Lady Di",2},{"Steffi Graf",2},
|
|
||||||
{"Frank Zappa",1},{"Dolly Buster",2},{"Mao Tse Tung",1},{"Ghandi",1},
|
|
||||||
{"Dalai Lama",1},{"Teufel",1},{"Lenin",1},{"Edmund Stoiber",1},
|
|
||||||
{"Ludwig van Beethoven",1},{"Wolfgang Amadeus Mozart",1},
|
|
||||||
{"Richard Wagner",1},{"Erich Honecker",1},{"Adam Riese",1},
|
|
||||||
{"Bill Clinton",1},{"Josef Stalin",1},{"Willy Brandt",1},
|
|
||||||
{"John F. Kennedy",1},{"E.T.",1},{"Donald Duck",1},{"Lothar Matthäus",1},
|
|
||||||
{"Hans Dietrich Genscher",1},{"Franz Josef Strauss",1},{"Sting",1},
|
|
||||||
{"Hermann Hesse",1},{"Albert Einstein",1},{"Max Planck",1},
|
|
||||||
{"Tom Jones",1},{"Heidi Kabel",2},{"Homer Simpson",1},{"Zeus",1},
|
|
||||||
{"Helmut Schmidt",1},{"Antje Vollmer",2},{"Politiker",1},{"Papst",1},
|
|
||||||
{"Bundeskanzler",1},{"Arzt",1},{"Friseuse",2},{"Teufel",1},
|
|
||||||
{"Sandmännchen",3},{"Mutter",2},{"Vater",1},{"Säufer",1},{"Student",1},
|
|
||||||
{"Bauer",1},{"Leiche",2},{"Polizist",1},{"Patientin",2},{"Bäcker",1},
|
|
||||||
{"Wirt",1}, {"Schlachter",1},{"Baby",3},{"Reporter",1},{"Politiker",1},
|
|
||||||
{"Beamtin",2},{"Oma",2},{"Putzfrau",2},{"Blinde",2},{"Wahnsinnige",2},
|
|
||||||
{"Mörder",1},{"Psychiater",1},{"Prinz Charles",1},{"Onkel",1},{"Tante",2}
|
|
||||||
};
|
|
||||||
|
|
||||||
struct substantive sachen[]=
|
|
||||||
{
|
|
||||||
{"Haus",3},{"Buch",3},{"Fahrrad",3},{"Schule",2},{"Auto",3},{"Nase",2},
|
|
||||||
{"Mund",1},{"Kopf",1},{"Kaffee",1},{"Telephon",3},{"Tasse",2},{"Katze",2},
|
|
||||||
{"Hund",1},{"Maus",2},{"Stuhl",1},{"Mann",1},{"Frau",2},{"Kind",3},
|
|
||||||
{"Idiotin",2},{"Lampe",2},{"Panzer",1},{"Klavier",3},{"Gitarre",2},
|
|
||||||
{"Straße",2},{"Wasser",3},{"Luft",2},{"Feuer",3},{"Erde",2},{"Mond",1},
|
|
||||||
{"Sonne",2},{"Bild",3},{"Stadt",2},{"Land",3},{"Fluss",1},
|
|
||||||
{"Bundeskanzler",1},{"Ball",1},{"Hut",1},{"Hose",2},{"Hemd",3},{"Tod",1},
|
|
||||||
{"Geld",3},{"Tisch",1},{"Hand",2},{"Baum",1},{"Bier",3},{"Ratte",2},
|
|
||||||
{"Esel",1},{"Musik",2},{"Blech",3},{"Dose",2},{"Zahn",1},{"Humor",1},
|
|
||||||
{"Unterhose",2},{"Gift",3},{"Gesicht",3},{"Fuß",1},{"Auge",3},{"Warze",2},
|
|
||||||
{"Ohr",3},{"Kanone",2},{"Milch",2},{"Messer",3},{"Papier",3},{"Haar",3},
|
|
||||||
{"Welt",2},{"Motor",1},{"Langeweile",2},{"Grab",3},{"Schnaps",1},
|
|
||||||
{"Vogel",1},{"Fisch",1},{"Meer",3},{"Banane",2},{"Brot",3},
|
|
||||||
{"Sitzung",2},{"Labor",3},{"Kurzschluß",1},{"Lüge",2},{"Axt",2},
|
|
||||||
{"Abstimmung",2},{"Toilette",2},{"Zigarette",2},{"Winter",1},
|
|
||||||
{"Torte",2},{"Bahnhof",1},{"Sarg",1},{"Imbiss",1},{"Mund",1},{"Seife",2},
|
|
||||||
{"Fernseher",1},{"Flasche",2},{"Eimer",1},{"Uhr",2},{"Irrenhaus",3},
|
|
||||||
{"Wüste",2},{"Klumpen",1},{"Glück",3},{"Schiff",3},{"Käse",1},{"Quark",1},
|
|
||||||
{"Sommer",1},{"Witz",1},{"Idee",2},{"Nacht",2},{"Dreck",1},{"Meer",3},
|
|
||||||
{"Blut",3},{"Herz",3},{"Apfel",1},{"Banane",2},{"Mist",1},{"Atom",3},
|
|
||||||
{"Note",2},{"Gehirn",3},{"Gefühl",3},{"Bombe",2},{"Vakuum",3},
|
|
||||||
{"Zahl",2},{"Wort",3},{"Programm",3},{"Computer",1},{"Orient",1},
|
|
||||||
{"Gabelstapler",1}
|
|
||||||
};
|
|
||||||
|
|
||||||
struct adjektive ad[]=
|
|
||||||
{
|
|
||||||
{"schön"},{"doof"},{"gut"},{"schlecht"},{"gelb"},{"grün"},{"rot"},
|
|
||||||
{"blau"},{"schnell"},{"lang"},{"kurz"},{"hell"},{"düster"},{"sanft"},
|
|
||||||
{"hart"},{"langsam"},{"bitter"},{"süß"},{"kaputt"},{"nett"},{"groß"},
|
|
||||||
{"klein"},{"leicht"},{"schwer"},{"dick"},{"dünn"},{"rund"},{"eckig"},
|
|
||||||
{"heiß"},{"kalt"},{"schlau"},{"elektrisch"},{"nass"},{"trocken"},{"ratlos"},
|
|
||||||
{"abartig"},{"genial"},{"bestechlich"},{"irr"},{"steif"},{"angespannt"},
|
|
||||||
{"laut"},{"leis"},{"warm"},{"wütend"},{"sauber"},{"schmutzig"},{"arm"},
|
|
||||||
{"ätzend"},{"langweilig"},{"interessant"},{"erfahren"},{"abgewählt"},
|
|
||||||
{"durchgeknallt"},{"angenehm"},{"widerwärtig"},{"willig"},{"mutig"},
|
|
||||||
{"schwach"},{"stark"},{"nervend"},{"spießig"},{"alt"},{"neu"},{"spitz"},
|
|
||||||
{"stumpf"},{"teuflisch"},{"scharf"},{"lecker"},{"übelriechend"},{"halb"},
|
|
||||||
{"ganz"},{"bleich"},{"peinlich"},{"taktlos"},{"gewieft"},{"windig"},
|
|
||||||
{"größenwahnsinnig"},{"verrückt"},{"uralt"},{"aalglatt"},{"korrekt"},
|
|
||||||
{"kompetent"},{"einfühlsam"},{"tot"},{"schleimig"},{"gestört"},{"hohl"},
|
|
||||||
{"beknackt"},{"nackt"},{"barfüßig"},{"schwitzend"},{"laufend"},{"knackig"},
|
|
||||||
{"unverschämt"},{"schläfrig"},{"wohlgeformt"},{"kugelförmig"},{"rauh"},
|
|
||||||
{"degeneriert"},{"ekelhaft"},{"brutal"},{"gemein"},{"aggressiv"},
|
|
||||||
{"aufdringlich"},{"betroffen"},{"geliebt"},{"gehasst"},{"beharrlich"},
|
|
||||||
{"unmenschlich"},{"verblödet"},{"wichtig"},{"gigantisch"},{"winzig"},
|
|
||||||
{"witzig"},{"komisch"},{"pervers"},{"fett"},{"stinkend"},{"lausig"},
|
|
||||||
{"wendig"},{"breit"},{"locker"},{"einzigartig"},{"sterbend"},{"munter"},
|
|
||||||
{"ungepflegt"},{"eisern"},{"echt"},{"besser"},{"wild"},{"ächzend"},
|
|
||||||
{"frohlockend"},{"unscheinbar"},{"nebulös"},{"skandalös"},{"obzön"},
|
|
||||||
{"beschränkt"},{"genervt"},{"hilflos"},{"unwürdig"},{"geleckt"},
|
|
||||||
{"betrunken"},{"unwürdig"},{"bissig"},{"verkalkt"},{"senil"},
|
|
||||||
{"jungfräulich"},{"ausgeleiert"},{"beleibt"},{"nachtragend"},{"errötend"},
|
|
||||||
{"kahl"},{"würgend"},{"abwesend"},{"ruhig"},{"albern"},{"trostlos"},
|
|
||||||
{"salzig"},{"lachend"},{"merkwürdig"},{"behaart"},{"leblos"},{"aufgeblasen"},
|
|
||||||
{"frech"},{"kopflos"},{"schmierig"}
|
|
||||||
};
|
|
||||||
|
|
||||||
struct verben verb[]=
|
|
||||||
{
|
|
||||||
{"geht","gehen",6},{"steht","stehen",2},{"sitzt","sitzen",2},
|
|
||||||
{"spielt","spielen",7},{"singt","singen",2},{"trinkt","trinken",3},
|
|
||||||
{"redet","reden",2}, {"liebt","lieben",7},{"schläft","schlafen",2},
|
|
||||||
{"ißt","essen",3},{"lacht","lachen",2},{"tötet","töten",7},
|
|
||||||
{"lügt","lügen",2},{"fliegt","fliegen",2},{"überfährt","überfahren",7},
|
|
||||||
{"sieht","sehen",3},{"hört","hören",3},{"spricht","sprechen",2},
|
|
||||||
{"berechnet","rechnen",3},{"schwimmt","schwimmen",2},
|
|
||||||
{"zerschneidet","zerschnitten werden",3},{"raucht","rauchen",3},
|
|
||||||
{"spaltet","spalten",3},{"verbrennt","verbrennen",2},{"ist","sein",2},
|
|
||||||
{"hat","haben",1},{"zerbricht","zerbrechen",3},{"muss","müssen",4},
|
|
||||||
{"kann","können",4},{"darf","dürfen",4},{"will","wollen",5},
|
|
||||||
{"klaut","klauen",1},{"soll","sollen",4},{"studiert","studieren",3},
|
|
||||||
{"reibt","reiben",3},{"liest","lesen",2},{"irrt","irren",2},
|
|
||||||
{"spendiert","spendieren",1},{"schlägt","schlagen",3},{"fragt","fragen",7},
|
|
||||||
{"zerstört","zerstören",1},{"erschießt","sich erschießen",1},
|
|
||||||
{"überlegt","überlegen",2},{"trifft","treffen",7},{"leckt","lecken",1},
|
|
||||||
{"wirft","werfen",1},{"vergiftet","vergiftet werden",1},
|
|
||||||
{"öffnet","öffnen",1},{"schreit","schreien",2},{"sprengt","explodieren",3},
|
|
||||||
{"erwürgt","würgen",7},{"arbeitet","arbeiten",2},{"erlegt","erlegen",1},
|
|
||||||
{"putzt","putzen",1},{"stirbt","sterben",2}, {"kauft","kaufen",1},
|
|
||||||
{"brüllt","brüllen",2},{"versteht","es verstehen",7},
|
|
||||||
{"zertritt","zertreten werden",1},{"verendet","verenden",2},
|
|
||||||
{"labert","labern",2},{"kratzt","kratzen",1},{"wird","nichts werden",2},
|
|
||||||
{"entkleidet","sich entkleiden",7},{"verbiegt","sich verbiegen",1},
|
|
||||||
{"verschenkt","es verschenken",7},{"vergisst","es vergessen",1},
|
|
||||||
{"ergreift","greifen",1},{"baut","bauen",1},{"betet","beten",},
|
|
||||||
{"rollt","rollen",3},{"bleibt","bleiben",2},{"wäscht","sich waschen",1},
|
|
||||||
{"heiratet","heiraten",7},{"hebt","heben",1},{"denkt","nachdenken",2}
|
|
||||||
};
|
|
||||||
|
|
||||||
void end_sach_aus(void);
|
|
||||||
void nam_aus(void);
|
|
||||||
void end_nam_aus(void);
|
|
||||||
void adj_aus(void);
|
|
||||||
int verb_aus_k(void);
|
|
||||||
int verb_aus_gr(void);
|
|
||||||
int zufall(int);
|
|
||||||
|
|
||||||
int main()
|
|
||||||
{
|
|
||||||
int vindx;
|
|
||||||
int rem=0;
|
|
||||||
char end;
|
|
||||||
|
|
||||||
setbuf(stdout, NULL);
|
|
||||||
randomize();
|
|
||||||
printf("\n\t\t************************");
|
|
||||||
printf("\n\t\t* DER ELEKTRISCHE POET *");
|
|
||||||
printf("\n\t\t************************\n");
|
|
||||||
printf("\n\tCopyright by J. Ahrensfeld & T. Burr");
|
|
||||||
printf("\n\n\tFür die Texte ist Ihr Computer verantwortlich :-)\n");
|
|
||||||
printf("\n\tZum beenden des Programmes 'x' eingeben!\n");
|
|
||||||
printf("\n\tWeiter mit beliebiger Taste!\n");
|
|
||||||
end = getch();
|
|
||||||
|
|
||||||
while(end != 'x')
|
|
||||||
{
|
|
||||||
if(rem >= 10)
|
|
||||||
{
|
|
||||||
printf("\n\n\tZum beenden des Programmes 'x' eingeben!\n");
|
|
||||||
rem = 0;
|
|
||||||
if(getch() == 'x')
|
|
||||||
break;
|
|
||||||
}
|
|
||||||
printf("\n\n");
|
|
||||||
nam_aus();
|
|
||||||
|
|
||||||
vindx=verb_aus_k();
|
|
||||||
|
|
||||||
switch (vindx)
|
|
||||||
{
|
|
||||||
case 1: end_sach_aus(); break;
|
|
||||||
|
|
||||||
case 2: adj_aus(); break;
|
|
||||||
|
|
||||||
case 3: end_sach_aus(); break;
|
|
||||||
|
|
||||||
case 4: verb_aus_gr(); break;
|
|
||||||
|
|
||||||
case 5: verb_aus_gr(); break;
|
|
||||||
|
|
||||||
case 6: adj_aus(); break;
|
|
||||||
|
|
||||||
case 7: end_nam_aus(); break;
|
|
||||||
}
|
|
||||||
|
|
||||||
printf(".");
|
|
||||||
end = getch();
|
|
||||||
rem++;
|
|
||||||
|
|
||||||
}
|
|
||||||
printf("\n\n\tDas ist das Ende!");
|
|
||||||
return 0;
|
|
||||||
}
|
|
||||||
|
|
||||||
int zufall(int max)
|
|
||||||
{
|
|
||||||
|
|
||||||
return (rand()%max);
|
|
||||||
}
|
|
||||||
|
|
||||||
void adj_aus(void)
|
|
||||||
{
|
|
||||||
printf("%s", ad[zufall((sizeof(ad)/sizeof(*ad)))].adj);
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
|
|
||||||
void end_sach_aus(void)
|
|
||||||
{
|
|
||||||
int index;
|
|
||||||
|
|
||||||
index = zufall(sizeof(sachen)/sizeof(*sachen));
|
|
||||||
if (sachen[index].sex==1)
|
|
||||||
printf("d%s", art[3]);
|
|
||||||
else
|
|
||||||
printf("d%s", art[(sachen[index].sex)-1]);
|
|
||||||
printf(" ");
|
|
||||||
adj_aus();
|
|
||||||
if (sachen[index].sex==1)
|
|
||||||
printf("en %s", sachen[index].subst);
|
|
||||||
else
|
|
||||||
printf("e %s", sachen[index].subst);
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
|
|
||||||
void nam_aus(void)
|
|
||||||
{
|
|
||||||
int index;
|
|
||||||
|
|
||||||
index = zufall(sizeof(namen)/sizeof(*namen));
|
|
||||||
printf("D%s", art[(namen[index].sex)-1]);
|
|
||||||
printf(" ");
|
|
||||||
adj_aus();
|
|
||||||
printf("e %s " ,namen[index].subst);
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
|
|
||||||
void end_nam_aus(void)
|
|
||||||
{
|
|
||||||
int index;
|
|
||||||
|
|
||||||
index = zufall(sizeof(namen)/sizeof(*namen));
|
|
||||||
if (namen[index].sex==1)
|
|
||||||
printf("d%s", art[3]);
|
|
||||||
else
|
|
||||||
printf("d%s", art[(namen[index].sex)-1]);
|
|
||||||
printf(" ");
|
|
||||||
adj_aus();
|
|
||||||
if (namen[index].sex==1)
|
|
||||||
printf("en %s", namen[index].subst);
|
|
||||||
else
|
|
||||||
printf("e %s", namen[index].subst);
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
|
|
||||||
int verb_aus_k(void)
|
|
||||||
{
|
|
||||||
int index;
|
|
||||||
|
|
||||||
index = zufall(sizeof(verb)/sizeof(*verb));
|
|
||||||
printf("%s ", verb[index].verb_k);
|
|
||||||
return (verb[index].art);
|
|
||||||
}
|
|
||||||
|
|
||||||
int verb_aus_gr(void)
|
|
||||||
{
|
|
||||||
int index;
|
|
||||||
|
|
||||||
index = zufall(sizeof(verb)/sizeof(*verb));
|
|
||||||
printf("%s", verb[index].verb_gr);
|
|
||||||
return index;
|
|
||||||
}
|
|
||||||
@@ -1,856 +0,0 @@
|
|||||||
/*
|
|
||||||
** Queens.c -- Find solutions to the Eight-Queens chess problem.
|
|
||||||
** Roberto Sierra 7/25/93 Version 1.1
|
|
||||||
** 3/19/84 Version 1.0
|
|
||||||
**
|
|
||||||
** Description:
|
|
||||||
** This program finds all the possible ways that N queens can
|
|
||||||
** be placed on an NxN chessboard so that the queens cannot
|
|
||||||
** capture one another -- that is, so that no rank, file or
|
|
||||||
** diagonal is occupied by more than one queen. By default,
|
|
||||||
** the program prints the first solution it finds. You can
|
|
||||||
** use the -a option to print all solutions, or the -c option
|
|
||||||
** just to count them. The program allows the chess board
|
|
||||||
** to be from 1x1 (trivial case) to 100x100. Warning: the
|
|
||||||
** larger the chess board, the longer it typically takes to
|
|
||||||
** find each solution, even though there may be more of them.
|
|
||||||
**
|
|
||||||
** This is a terrific example of the utility of recursion. The
|
|
||||||
** algorithm uses recursion to drastically limit the number
|
|
||||||
** of board positions that are tested. The program is able
|
|
||||||
** to find all 8x8 queen solutions in a fraction of a second
|
|
||||||
** (not counting print time). The code makes no attempt to
|
|
||||||
** eliminate symmetrical solutions, so the number of solutions
|
|
||||||
** reported will always be higher than the actual number of
|
|
||||||
** distinct solutions.
|
|
||||||
**
|
|
||||||
**
|
|
||||||
** Usage:
|
|
||||||
** Queens [-ac] n
|
|
||||||
**
|
|
||||||
** n number of queens (rows and columns).
|
|
||||||
** An integer from 1 to 100.
|
|
||||||
** -a Find (and print) all solutions.
|
|
||||||
** -c Count all solutions, but do not print them.
|
|
||||||
**
|
|
||||||
** The output is sent to stdout. All errors messages are
|
|
||||||
** sent to stderr. If a problem arises, the return code is -1.
|
|
||||||
**
|
|
||||||
**
|
|
||||||
** Examples:
|
|
||||||
**
|
|
||||||
** Queens 8 ## Show an 8x8 solution
|
|
||||||
** 8 queens on a 8x8 board...
|
|
||||||
** Q - - - - - - -
|
|
||||||
** - - - - Q - - -
|
|
||||||
** - - - - - - - Q
|
|
||||||
** - - - - - Q - -
|
|
||||||
** - - Q - - - - -
|
|
||||||
** - - - - - - Q -
|
|
||||||
** - Q - - - - - -
|
|
||||||
** - - - Q - - - -
|
|
||||||
**
|
|
||||||
** Queens -c 8 ## Count all 8x8 solutions
|
|
||||||
** 8 queens on a 8x8 board...
|
|
||||||
** ...there are 92 solutions.
|
|
||||||
**
|
|
||||||
** Queens -a 4 ## Show all 4x4 solutions
|
|
||||||
** 4 queens on a 4x4 board...
|
|
||||||
**
|
|
||||||
** Solution #1:
|
|
||||||
** - Q - -
|
|
||||||
** - - - Q
|
|
||||||
** Q - - -
|
|
||||||
** - - Q -
|
|
||||||
**
|
|
||||||
** Solution #2:
|
|
||||||
** - - Q -
|
|
||||||
** Q - - -
|
|
||||||
** - - - Q
|
|
||||||
** - Q - -
|
|
||||||
**
|
|
||||||
** ...there are 2 solutions.
|
|
||||||
**
|
|
||||||
**
|
|
||||||
** Build Instructions:
|
|
||||||
** You'll need an ANSI C compiler (or the willingness to edit
|
|
||||||
** the program a bit). If you've got Gnu C, then you can
|
|
||||||
** compile and load the program as follows:
|
|
||||||
**
|
|
||||||
** gcc Queens.c -ansi -o Queens
|
|
||||||
**
|
|
||||||
** [If you're using MPW on the Mac, define '-d MPW' on the
|
|
||||||
** compile line so that background processing will occur.]
|
|
||||||
**
|
|
||||||
**
|
|
||||||
** Algorithm:
|
|
||||||
** In a 1984 Byte article, I ran across an interesting letter
|
|
||||||
** from a high school student who was attempting to solve the
|
|
||||||
** Eight Queens problem using a BASIC interpreter. He had
|
|
||||||
** developed a program which placed eight queens successively
|
|
||||||
** on all sixty-four squares, testing for conflicts at each
|
|
||||||
** iteration. Of course, such a program would require 64^8
|
|
||||||
** iterations (about 2.8x10^14 iterations). Even in C on a,
|
|
||||||
** fast CPU, this could take months or years. Byte's answer was
|
|
||||||
** to alter the loops so that the queens resided on separate
|
|
||||||
** ranks, thereby reducing the number of iterations required
|
|
||||||
** to find all solutions to 8^8 iterations (about 16 million).
|
|
||||||
** More reasonable, but still requiring a chunk of CPU time.
|
|
||||||
**
|
|
||||||
** I puzzled about this problem a bit, and came to realize that
|
|
||||||
** this was still wasting a lot of CPU cycles. Though I'm sure
|
|
||||||
** others have come up with good algorithms, I decided to come
|
|
||||||
** up with my own, with a particular eye on efficiency. The
|
|
||||||
** resulting algorithm finds all 8x8 solutions in a fraction
|
|
||||||
** of a second (there are 92 solutions, including rotations).
|
|
||||||
** On a Sun 4, it'll find all 365,596 solutions on a 14x14 board
|
|
||||||
** in a bit over 2 minutes (printing them out requires extra
|
|
||||||
** time, of course). Even Byte's solution would require 14^14
|
|
||||||
** iterations (about 10^16) which would take aeons.
|
|
||||||
**
|
|
||||||
** My algorithm works as follows:
|
|
||||||
** (1) Place a queen in the top left corner.
|
|
||||||
** (2) Place another queen immediately below.
|
|
||||||
** (3) Test for conflicts. If the second queen conflicts (it
|
|
||||||
** does at first), then move it one square to the right.
|
|
||||||
** (4) Loop step 3 until there are no conflicts. Place
|
|
||||||
** the next queen on the board and recurse.
|
|
||||||
** (5) If any queen reaches the right edge of the board,
|
|
||||||
** remove it and 'pop' to the previous recursion level.
|
|
||||||
** (6) Now repeat these steps recursively until all eight
|
|
||||||
** queens (or however many) have been placed without
|
|
||||||
** conflict -- the result is a solution to the problem,
|
|
||||||
** which is counted and optionally printed.
|
|
||||||
**
|
|
||||||
** Because conflicts are tested as the recursion proceeds,
|
|
||||||
** this has the effect of 'pruning' the recursion so that
|
|
||||||
** a large number of board positions are not even attempted.
|
|
||||||
** The result is that the algorithm runs in reasonable time.
|
|
||||||
**
|
|
||||||
** I used a few tricks to make the test-for-conflict code
|
|
||||||
** extremely efficient -- there is no 'inner' loop to search
|
|
||||||
** along ranks, files, or diagonals. A series of arrays are
|
|
||||||
** maintained instead which indicate which queen currently
|
|
||||||
** 'owns' each rank, file or diagonal. This makes the
|
|
||||||
** algorithm really fly, though the code is a little hard to
|
|
||||||
** read. Lastly, pointer arithmetic is used to reduce the
|
|
||||||
** number of implicit multiplications used in array addressing.
|
|
||||||
**
|
|
||||||
**
|
|
||||||
** Contact:
|
|
||||||
** For queries regarding this program, contact Roberto Sierra
|
|
||||||
** at any of the following addresses:
|
|
||||||
**
|
|
||||||
** Roberto Sierra
|
|
||||||
** bert@netcom.com (preferred address)
|
|
||||||
** 73557.2101@compuserve.com
|
|
||||||
**
|
|
||||||
** Tempered MicroDesigns
|
|
||||||
** P.O. Box 170638
|
|
||||||
** San Francisco, CA 94117
|
|
||||||
**
|
|
||||||
**
|
|
||||||
** Fine Print:
|
|
||||||
** This program is in the public domain and can be used for
|
|
||||||
** any purpose whatsoever, including commercial application.
|
|
||||||
** [I'd like to hear what you do with it, though.]
|
|
||||||
** Absolutely no warranty or liability is implied or extended
|
|
||||||
** by the author.
|
|
||||||
**
|
|
||||||
**
|
|
||||||
** Modification History:
|
|
||||||
** PRS 3/19/84 v1.0 -- Original version.
|
|
||||||
** PRS 7/25/93 v1.1 -- ANSIfied the code. More efficient pointers.
|
|
||||||
**
|
|
||||||
*/
|
|
||||||
|
|
||||||
/***************************************************************/
|
|
||||||
/* Timer options. You MUST uncomment one of the options below */
|
|
||||||
/* or compile, for example, with the '-DUNIX' option. */
|
|
||||||
/***************************************************************/
|
|
||||||
/* #define Amiga */
|
|
||||||
/* #define UNIX */
|
|
||||||
/* #define UNIX_Old */
|
|
||||||
/* #define VMS */
|
|
||||||
/* #define BORLAND_C */
|
|
||||||
/* #define MSC */
|
|
||||||
/* #define MAC */
|
|
||||||
/* #define IPSC */
|
|
||||||
/* #define FORTRAN_SEC */
|
|
||||||
/* #define GTODay */
|
|
||||||
/* #define CTimer */
|
|
||||||
/* #define UXPM */
|
|
||||||
/* #define MAC_TMgr */
|
|
||||||
/* #define PARIX */
|
|
||||||
/* #define POSIX */
|
|
||||||
/* #define WIN32 */
|
|
||||||
/* #define POSIX1 */
|
|
||||||
/***********************/
|
|
||||||
|
|
||||||
#include <stdio.h> /* Need standard I/O functions */
|
|
||||||
#include <stdlib.h> /* Need exit() routine interface */
|
|
||||||
#include <string.h> /* Need strcmp() interface */
|
|
||||||
#ifdef MPW /* Macintosh MPW ONLY */
|
|
||||||
#include <CursorCtl.h> /* Need cursor control interfaces */
|
|
||||||
#endif
|
|
||||||
|
|
||||||
#define MAXQUEENS 100 /* Maximum number of queens */
|
|
||||||
#define MAXRANKS MAXQUEENS /* Maximum number of ranks (rows) */
|
|
||||||
#define MAXFILES MAXQUEENS /* Maximum number of files (columns) */
|
|
||||||
#define MAXDIAGS (MAXRANKS+MAXFILES-1) /* Maximum number of diagonals */
|
|
||||||
#define EMPTY (MAXQUEENS+1) /* Marks unoccupied file or diagonal */
|
|
||||||
|
|
||||||
/* GLOBAL VARIABLES */
|
|
||||||
|
|
||||||
int queens; /* Number of queens to place */
|
|
||||||
int ranks; /* Number of ranks (rows) */
|
|
||||||
int files; /* Number of files (columns) */
|
|
||||||
int printing = 1; /* TRUE if printing positions */
|
|
||||||
int findall = 0; /* TRUE if finding all solutions */
|
|
||||||
|
|
||||||
unsigned long solutions = 0; /* Number of solutions found */
|
|
||||||
int queen[MAXRANKS]; /* File on which each queen is located */
|
|
||||||
int file[MAXFILES]; /* Which queen 'owns' each file */
|
|
||||||
int fordiag[MAXDIAGS]; /* Which queen 'owns' forward diagonals */
|
|
||||||
int bakdiag[MAXDIAGS]; /* Which queen 'owns' reverse diagonals */
|
|
||||||
char *progname = 0; /* The name of this program */
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
/***********************/
|
|
||||||
/**** ROUTINES ****/
|
|
||||||
/***********************/
|
|
||||||
|
|
||||||
/* Internal prototypes */
|
|
||||||
//void main(int argc,char **argv); /* Main program */
|
|
||||||
void find(int level); /* Algorithm to find solutions */
|
|
||||||
void pboard(void); /* Print a solution */
|
|
||||||
void run_queens(int argc,char **argv);
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
/*---------------------- main() ---------------------------
|
|
||||||
** MAIN program. The main purpose of this routine is
|
|
||||||
** to deal with decoding the command line arguments,
|
|
||||||
** initializing the various arrays, and starting the
|
|
||||||
** recursive search routine.
|
|
||||||
*/
|
|
||||||
int main(void)
|
|
||||||
{
|
|
||||||
char *args[] = {"queens", "-c", "12"};
|
|
||||||
run_queens(3, args);
|
|
||||||
}
|
|
||||||
|
|
||||||
void run_queens(int argc,char **argv)
|
|
||||||
{
|
|
||||||
register int i; /* Loop variable */
|
|
||||||
register char *p; /* Pointer to argument */
|
|
||||||
double starttime, benchtime, dtime();
|
|
||||||
|
|
||||||
#ifdef MPW /* Macintosh MPW ONLY */
|
|
||||||
InitCursorCtl(0); /* Enable cursor control */
|
|
||||||
#endif
|
|
||||||
|
|
||||||
progname = argv[0]; /* The name of the program */
|
|
||||||
|
|
||||||
/**** DECODE COMMAND LINE ARGUMENTS ****/
|
|
||||||
|
|
||||||
for (i=1; i<argc; ++i) { /* Scan through arguments */
|
|
||||||
p = argv[i]; /* Pointer to base of argument */
|
|
||||||
if (*p == '-') { /* Command line option? */
|
|
||||||
while (*++p) { /* Loop through characters */
|
|
||||||
switch (*p) { /* What is the character */
|
|
||||||
case 'a': /* '-a' option */
|
|
||||||
findall = 1; /* Set flag to find all solutions */
|
|
||||||
break;
|
|
||||||
case 'c': /* '-c' option */
|
|
||||||
printing = 0; /* Counting, not printing */
|
|
||||||
findall = 1; /* Also forces findall option */
|
|
||||||
break;
|
|
||||||
default: /* Illegal option */
|
|
||||||
fprintf(stderr,"%s: Illegal option '%s'\n",progname,argv[i]);
|
|
||||||
fprintf(stderr,"usage: %s [-ac] queens\n",progname);
|
|
||||||
exit(-1);
|
|
||||||
} /* End of switch */
|
|
||||||
} /* End of loop */
|
|
||||||
} else { /* End of option test */
|
|
||||||
if (sscanf(p,"%d",&queens) != 1) { /* Read integer argument */
|
|
||||||
fprintf(stderr,"%s: non-integer argument '%s'\n",progname,p);
|
|
||||||
exit(-1);
|
|
||||||
}
|
|
||||||
if (queens <= 0) { /* N must be positive */
|
|
||||||
fprintf(stderr,"%s: queens must be positive integer\n",progname);
|
|
||||||
exit(-1);
|
|
||||||
}
|
|
||||||
if (queens > MAXQUEENS) { /* N can't be too large */
|
|
||||||
fprintf(stderr,"%s: can't have more than %d queens\n",
|
|
||||||
progname, MAXQUEENS);
|
|
||||||
exit(-1);
|
|
||||||
}
|
|
||||||
} /* End of argument test */
|
|
||||||
} /* End of argument scan loop */
|
|
||||||
if (queens == 0) {
|
|
||||||
fprintf(stderr,"%s: missing queens argument\n",progname);
|
|
||||||
fprintf(stderr,"usage: %s [-ac] queens\n",progname);
|
|
||||||
exit(-1);
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
ranks = files = queens; /* NxN board for N queens */
|
|
||||||
printf("%d queen%s on a %dx%d board...\n",
|
|
||||||
queens, queens>1? "s" : "", ranks, files);
|
|
||||||
fflush(stdout);
|
|
||||||
|
|
||||||
starttime = dtime();
|
|
||||||
|
|
||||||
/* Initialization */
|
|
||||||
solutions = 0; /* No solutions yet */
|
|
||||||
for (i=0; i<MAXFILES; ++i) file[i] = EMPTY;
|
|
||||||
for (i=0; i<MAXDIAGS; ++i) fordiag[i] = bakdiag[i] = EMPTY;
|
|
||||||
|
|
||||||
/* Find all solutions (begin recursion) */
|
|
||||||
find(0);
|
|
||||||
if (printing && solutions) putchar('\n');
|
|
||||||
|
|
||||||
/* Report results */
|
|
||||||
if (solutions == 1) {
|
|
||||||
printf("...there is 1 solution\n");
|
|
||||||
} else {
|
|
||||||
printf("...there are %ld solutions\n", solutions);
|
|
||||||
}
|
|
||||||
|
|
||||||
benchtime = dtime() - starttime;
|
|
||||||
printf("Run Time (sec) = %9.3lf\n\n",benchtime);
|
|
||||||
|
|
||||||
|
|
||||||
exit(0); /* No errors */
|
|
||||||
} /* End of main() */
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
/*-------------------------- find() ----------------------------
|
|
||||||
** FIND is the recursive heart of the program, and finds all
|
|
||||||
** solutions given a set of level-1 fixed queen positions.
|
|
||||||
** The routine moves a single queen through all files (columns)
|
|
||||||
** at the current rank (recursion level). As the queen is moved,
|
|
||||||
** conflict tests are made. If the queen can be placed without
|
|
||||||
** conflict, then the routine recurses to the next level. When
|
|
||||||
** all queens have been placed without conflict, a solution is
|
|
||||||
** counted and reported.
|
|
||||||
*/
|
|
||||||
|
|
||||||
void find(register int level)
|
|
||||||
{
|
|
||||||
register int f; /* Indexes through files */
|
|
||||||
register int *fp,*fdp,*bdp; /* Ptrs to file/diagonal entries */
|
|
||||||
|
|
||||||
#ifdef MPW /* Macintosh MPW ONLY */
|
|
||||||
if (level & 7 == 0) { /* Periodically break for... */
|
|
||||||
SpinCursor(1); /* background processing */
|
|
||||||
}
|
|
||||||
#endif
|
|
||||||
|
|
||||||
if (level == queens) { /* Placed all queens? Stop. */
|
|
||||||
++solutions; /* Congrats, this is a solution! */
|
|
||||||
if (printing) pboard(); /* Print board if printing */
|
|
||||||
if (!findall) exit(0); /* May stop after first solution */
|
|
||||||
#ifdef MPW /* Macintosh MPW ONLY */
|
|
||||||
SpinCursor(1); /* Allow background processing */
|
|
||||||
#endif
|
|
||||||
} else { /* Not at final level yet */
|
|
||||||
|
|
||||||
for ( /* MOVE QUEEN THROUGH ALL FILES */
|
|
||||||
f = 0, /* Queen starts at left (file 0) */
|
|
||||||
fp = file, /* Ptr to base of file array */
|
|
||||||
fdp = &fordiag[level], /* Ptr to first fwd diag entry */
|
|
||||||
bdp = &bakdiag[level+files-1] /* Ptr to first bak diag entry */
|
|
||||||
;
|
|
||||||
f < files /* Loop through all files */
|
|
||||||
;
|
|
||||||
++f, /* Advance index */
|
|
||||||
++fp, ++fdp, --bdp /* Advance pointers */
|
|
||||||
) {
|
|
||||||
if (*fp >= level && /* No queen on the file? */
|
|
||||||
*fdp >= level && *bdp >= level /* No queens on diagonals? */
|
|
||||||
) {
|
|
||||||
queen[level] = f; /* Note new position of queen */
|
|
||||||
*fp = *fdp = *bdp = level; /* Place queen on file & diags */
|
|
||||||
find(level+1); /* This level OK, recurse to next */
|
|
||||||
*fp = *fdp = *bdp = EMPTY; /* Remove queen from file & diags */
|
|
||||||
} /* End of conflict test */
|
|
||||||
} /* End of file loop */
|
|
||||||
} /* End if (level == queens) */
|
|
||||||
} /* End of find() */
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
/*------------------------- pboard() -----------------------
|
|
||||||
** This routines prints the board for a particular solution.
|
|
||||||
** The output is sent to stdout.
|
|
||||||
*/
|
|
||||||
|
|
||||||
void pboard(void)
|
|
||||||
{
|
|
||||||
register int i,j; /* Rank/File indices */
|
|
||||||
|
|
||||||
if (findall) { /* Only if searching for all */
|
|
||||||
printf("\nSolution #%lu:\n",solutions); /* Print solution number */
|
|
||||||
}
|
|
||||||
for (i=0; i<ranks; ++i) { /* Loop through all ranks */
|
|
||||||
for (j=0; j<files; ++j) { /* Loop through all files */
|
|
||||||
putchar(' '); /* Output a space */
|
|
||||||
if (j==queen[i]) putchar('Q'); /* Output Q for queen... */
|
|
||||||
else putchar('-'); /* or '-' if empty */
|
|
||||||
}
|
|
||||||
putchar('\n'); /* Break line */
|
|
||||||
}
|
|
||||||
fflush(stdout); /* Flush solution to output */
|
|
||||||
} /* End of pboard() */
|
|
||||||
|
|
||||||
/*****************************************************/
|
|
||||||
/* Various timer routines. */
|
|
||||||
/* Al Aburto, aburto@nosc.mil, 18 Feb 1997 */
|
|
||||||
/* */
|
|
||||||
/* t = dtime() outputs the current time in seconds. */
|
|
||||||
/* Use CAUTION as some of these routines will mess */
|
|
||||||
/* up when timing across the hour mark!!! */
|
|
||||||
/* */
|
|
||||||
/* For timing I use the 'user' time whenever */
|
|
||||||
/* possible. Using 'user+sys' time is a separate */
|
|
||||||
/* issue. */
|
|
||||||
/* */
|
|
||||||
/* Example Usage: */
|
|
||||||
/* [timer options added here] */
|
|
||||||
/* main() */
|
|
||||||
/* { */
|
|
||||||
/* double starttime,benchtime,dtime(); */
|
|
||||||
/* */
|
|
||||||
/* starttime = dtime(); */
|
|
||||||
/* [routine to time] */
|
|
||||||
/* benchtime = dtime() - starttime; */
|
|
||||||
/* } */
|
|
||||||
/* */
|
|
||||||
/* [timer code below added here] */
|
|
||||||
/*****************************************************/
|
|
||||||
|
|
||||||
/*********************************/
|
|
||||||
/* Timer code. */
|
|
||||||
/*********************************/
|
|
||||||
/*******************/
|
|
||||||
/* Amiga dtime() */
|
|
||||||
/*******************/
|
|
||||||
#ifdef Amiga
|
|
||||||
#include <ctype.h>
|
|
||||||
#define HZ 50
|
|
||||||
|
|
||||||
double dtime()
|
|
||||||
{
|
|
||||||
double q;
|
|
||||||
|
|
||||||
struct tt
|
|
||||||
{
|
|
||||||
long days;
|
|
||||||
long minutes;
|
|
||||||
long ticks;
|
|
||||||
} tt;
|
|
||||||
|
|
||||||
DateStamp(&tt);
|
|
||||||
|
|
||||||
q = ((double)(tt.ticks + (tt.minutes * 60L * 50L))) / (double)HZ;
|
|
||||||
|
|
||||||
return q;
|
|
||||||
}
|
|
||||||
#endif
|
|
||||||
|
|
||||||
/*****************************************************/
|
|
||||||
/* UNIX dtime(). This is the preferred UNIX timer. */
|
|
||||||
/* Provided by: Markku Kolkka, mk59200@cc.tut.fi */
|
|
||||||
/* HP-UX Addition by: Bo Thide', bt@irfu.se */
|
|
||||||
/*****************************************************/
|
|
||||||
#ifdef UNIX
|
|
||||||
#include <sys/time.h>
|
|
||||||
#include <sys/resource.h>
|
|
||||||
|
|
||||||
#ifdef hpux
|
|
||||||
#include <sys/syscall.h>
|
|
||||||
#define getrusage(a,b) syscall(SYS_getrusage,a,b)
|
|
||||||
#endif
|
|
||||||
|
|
||||||
struct rusage rusage;
|
|
||||||
|
|
||||||
double dtime()
|
|
||||||
{
|
|
||||||
double q;
|
|
||||||
|
|
||||||
getrusage(RUSAGE_SELF,&rusage);
|
|
||||||
|
|
||||||
q = (double)(rusage.ru_utime.tv_sec);
|
|
||||||
q = q + (double)(rusage.ru_utime.tv_usec) * 1.0e-06;
|
|
||||||
|
|
||||||
return q;
|
|
||||||
}
|
|
||||||
#endif
|
|
||||||
|
|
||||||
/***************************************************/
|
|
||||||
/* UNIX_Old dtime(). This is the old UNIX timer. */
|
|
||||||
/* Make sure HZ is properly defined in param.h !! */
|
|
||||||
/***************************************************/
|
|
||||||
#ifdef UNIX_Old
|
|
||||||
#include <sys/types.h>
|
|
||||||
#include <sys/times.h>
|
|
||||||
#include <sys/param.h>
|
|
||||||
|
|
||||||
#ifndef HZ
|
|
||||||
#define HZ 60
|
|
||||||
#endif
|
|
||||||
|
|
||||||
struct tms tms;
|
|
||||||
|
|
||||||
double dtime()
|
|
||||||
{
|
|
||||||
double q;
|
|
||||||
|
|
||||||
times(&tms);
|
|
||||||
|
|
||||||
q = (double)(tms.tms_utime) / (double)HZ;
|
|
||||||
|
|
||||||
return q;
|
|
||||||
}
|
|
||||||
#endif
|
|
||||||
|
|
||||||
/*********************************************************/
|
|
||||||
/* VMS dtime() for VMS systems. */
|
|
||||||
/* Provided by: RAMO@uvphys.phys.UVic.CA */
|
|
||||||
/* Some people have run into problems with this timer. */
|
|
||||||
/*********************************************************/
|
|
||||||
#ifdef VMS
|
|
||||||
#include time
|
|
||||||
|
|
||||||
#ifndef HZ
|
|
||||||
#define HZ 100
|
|
||||||
#endif
|
|
||||||
|
|
||||||
struct tbuffer_t
|
|
||||||
{
|
|
||||||
int proc_user_time;
|
|
||||||
int proc_system_time;
|
|
||||||
int child_user_time;
|
|
||||||
int child_system_time;
|
|
||||||
};
|
|
||||||
|
|
||||||
struct tbuffer_t tms;
|
|
||||||
|
|
||||||
double dtime()
|
|
||||||
{
|
|
||||||
double q;
|
|
||||||
|
|
||||||
times(&tms);
|
|
||||||
|
|
||||||
q = (double)(tms.proc_user_time) / (double)HZ;
|
|
||||||
|
|
||||||
return q;
|
|
||||||
}
|
|
||||||
#endif
|
|
||||||
|
|
||||||
/******************************/
|
|
||||||
/* BORLAND C dtime() for DOS */
|
|
||||||
/******************************/
|
|
||||||
#ifdef BORLAND_C
|
|
||||||
#include <ctype.h>
|
|
||||||
#include <dos.h>
|
|
||||||
#include <time.h>
|
|
||||||
|
|
||||||
#define HZ 100
|
|
||||||
struct time tnow;
|
|
||||||
|
|
||||||
double dtime()
|
|
||||||
{
|
|
||||||
double q;
|
|
||||||
|
|
||||||
gettime(&tnow);
|
|
||||||
|
|
||||||
q = 60.0 * (double)(tnow.ti_min);
|
|
||||||
q = q + (double)(tnow.ti_sec);
|
|
||||||
q = q + (double)(tnow.ti_hund)/(double)HZ;
|
|
||||||
|
|
||||||
return q;
|
|
||||||
}
|
|
||||||
#endif
|
|
||||||
|
|
||||||
/**************************************/
|
|
||||||
/* Microsoft C (MSC) dtime() for DOS */
|
|
||||||
/**************************************/
|
|
||||||
#ifdef MSC
|
|
||||||
#include <time.h>
|
|
||||||
#include <ctype.h>
|
|
||||||
|
|
||||||
#define HZ CLOCKS_PER_SEC
|
|
||||||
clock_t tnow;
|
|
||||||
|
|
||||||
double dtime()
|
|
||||||
{
|
|
||||||
double q;
|
|
||||||
|
|
||||||
tnow = clock();
|
|
||||||
|
|
||||||
q = (double)tnow / (double)HZ;
|
|
||||||
|
|
||||||
return q;
|
|
||||||
}
|
|
||||||
#endif
|
|
||||||
|
|
||||||
/*************************************/
|
|
||||||
/* Macintosh (MAC) Think C dtime() */
|
|
||||||
/*************************************/
|
|
||||||
#ifdef MAC
|
|
||||||
#include <time.h>
|
|
||||||
|
|
||||||
#define HZ 60
|
|
||||||
|
|
||||||
double dtime()
|
|
||||||
{
|
|
||||||
double q;
|
|
||||||
|
|
||||||
q = (double)clock() / (double)HZ;
|
|
||||||
|
|
||||||
return q;
|
|
||||||
}
|
|
||||||
#endif
|
|
||||||
|
|
||||||
/************************************************************/
|
|
||||||
/* iPSC/860 (IPSC) dtime() for i860. */
|
|
||||||
/* Provided by: Dan Yergeau, yergeau@gloworm.Stanford.EDU */
|
|
||||||
/************************************************************/
|
|
||||||
#ifdef IPSC
|
|
||||||
extern double dclock();
|
|
||||||
|
|
||||||
double dtime()
|
|
||||||
{
|
|
||||||
double q;
|
|
||||||
|
|
||||||
q = dclock();
|
|
||||||
|
|
||||||
return q;
|
|
||||||
}
|
|
||||||
#endif
|
|
||||||
|
|
||||||
/**************************************************/
|
|
||||||
/* FORTRAN dtime() for Cray type systems. */
|
|
||||||
/* This is the preferred timer for Cray systems. */
|
|
||||||
/**************************************************/
|
|
||||||
#ifdef FORTRAN_SEC
|
|
||||||
|
|
||||||
fortran double second();
|
|
||||||
|
|
||||||
double dtime()
|
|
||||||
{
|
|
||||||
double q;
|
|
||||||
|
|
||||||
second(&q);
|
|
||||||
|
|
||||||
return q;
|
|
||||||
}
|
|
||||||
#endif
|
|
||||||
|
|
||||||
/***********************************************************/
|
|
||||||
/* UNICOS C dtime() for Cray UNICOS systems. Don't use */
|
|
||||||
/* unless absolutely necessary as returned time includes */
|
|
||||||
/* 'user+system' time. Provided by: R. Mike Dority, */
|
|
||||||
/* dority@craysea.cray.com */
|
|
||||||
/***********************************************************/
|
|
||||||
#ifdef CTimer
|
|
||||||
#include <time.h>
|
|
||||||
|
|
||||||
double dtime()
|
|
||||||
{
|
|
||||||
double q;
|
|
||||||
clock_t clock(void);
|
|
||||||
|
|
||||||
q = (double)clock() / (double)CLOCKS_PER_SEC;
|
|
||||||
|
|
||||||
return q;
|
|
||||||
}
|
|
||||||
#endif
|
|
||||||
|
|
||||||
/********************************************/
|
|
||||||
/* Another UNIX timer using gettimeofday(). */
|
|
||||||
/* However, getrusage() is preferred. */
|
|
||||||
/********************************************/
|
|
||||||
#ifdef GTODay
|
|
||||||
#include <sys/time.h>
|
|
||||||
|
|
||||||
struct timeval tnow;
|
|
||||||
|
|
||||||
double dtime()
|
|
||||||
{
|
|
||||||
double q;
|
|
||||||
|
|
||||||
gettimeofday(&tnow,NULL);
|
|
||||||
q = (double)tnow.tv_sec + (double)tnow.tv_usec * 1.0e-6;
|
|
||||||
|
|
||||||
return q;
|
|
||||||
}
|
|
||||||
#endif
|
|
||||||
|
|
||||||
/*****************************************************/
|
|
||||||
/* Fujitsu UXP/M timer. */
|
|
||||||
/* Provided by: Mathew Lim, ANUSF, M.Lim@anu.edu.au */
|
|
||||||
/*****************************************************/
|
|
||||||
#ifdef UXPM
|
|
||||||
#include <sys/types.h>
|
|
||||||
#include <sys/timesu.h>
|
|
||||||
struct tmsu rusage;
|
|
||||||
|
|
||||||
double dtime()
|
|
||||||
{
|
|
||||||
double q;
|
|
||||||
|
|
||||||
timesu(&rusage);
|
|
||||||
|
|
||||||
q = (double)(rusage.tms_utime) * 1.0e-06;
|
|
||||||
|
|
||||||
return q;
|
|
||||||
}
|
|
||||||
#endif
|
|
||||||
|
|
||||||
/**********************************************/
|
|
||||||
/* Macintosh (MAC_TMgr) Think C dtime() */
|
|
||||||
/* requires Think C Language Extensions or */
|
|
||||||
/* #include <MacHeaders> in the prefix */
|
|
||||||
/* provided by Francis H Schiffer 3rd (fhs) */
|
|
||||||
/* skipschiffer@genie.geis.com */
|
|
||||||
/**********************************************/
|
|
||||||
#ifdef MAC_TMgr
|
|
||||||
#include <Timer.h>
|
|
||||||
#include <stdlib.h>
|
|
||||||
|
|
||||||
static TMTask mgrTimer;
|
|
||||||
static Boolean mgrInited = false;
|
|
||||||
static double mgrClock;
|
|
||||||
|
|
||||||
#define RMV_TIMER RmvTime( (QElemPtr)&mgrTimer )
|
|
||||||
#define MAX_TIME 1800000000L
|
|
||||||
/* MAX_TIME limits time between calls to */
|
|
||||||
/* dtime( ) to no more than 30 minutes */
|
|
||||||
/* this limitation could be removed by */
|
|
||||||
/* creating a completion routine to sum */
|
|
||||||
/* 30 minute segments (fhs 1994 feb 9) */
|
|
||||||
|
|
||||||
static void Remove_timer( )
|
|
||||||
{
|
|
||||||
RMV_TIMER;
|
|
||||||
mgrInited = false;
|
|
||||||
}
|
|
||||||
|
|
||||||
double dtime( )
|
|
||||||
{
|
|
||||||
if( mgrInited ) {
|
|
||||||
RMV_TIMER;
|
|
||||||
mgrClock += (MAX_TIME + mgrTimer.tmCount)*1.0e-6;
|
|
||||||
} else {
|
|
||||||
if( _atexit( &Remove_timer ) == 0 ) mgrInited = true;
|
|
||||||
mgrClock = 0.0;
|
|
||||||
}
|
|
||||||
|
|
||||||
if ( mgrInited )
|
|
||||||
{
|
|
||||||
mgrTimer.tmAddr = NULL;
|
|
||||||
mgrTimer.tmCount = 0;
|
|
||||||
mgrTimer.tmWakeUp = 0;
|
|
||||||
mgrTimer.tmReserved = 0;
|
|
||||||
InsTime( (QElemPtr)&mgrTimer );
|
|
||||||
PrimeTime( (QElemPtr)&mgrTimer, -MAX_TIME );
|
|
||||||
}
|
|
||||||
return( mgrClock );
|
|
||||||
}
|
|
||||||
#endif
|
|
||||||
|
|
||||||
/***********************************************************/
|
|
||||||
/* Parsytec GCel timer. */
|
|
||||||
/* Provided by: Georg Wambach, gw@informatik.uni-koeln.de */
|
|
||||||
/***********************************************************/
|
|
||||||
#ifdef PARIX
|
|
||||||
#include <sys/time.h>
|
|
||||||
|
|
||||||
double dtime()
|
|
||||||
{
|
|
||||||
double q;
|
|
||||||
|
|
||||||
q = (double) (TimeNowHigh()) / (double) CLK_TCK_HIGH;
|
|
||||||
|
|
||||||
return q;
|
|
||||||
}
|
|
||||||
#endif
|
|
||||||
|
|
||||||
/************************************************/
|
|
||||||
/* Sun Solaris POSIX dtime() routine */
|
|
||||||
/* Provided by: Case Larsen, CTLarsen.lbl.gov */
|
|
||||||
/************************************************/
|
|
||||||
#ifdef POSIX
|
|
||||||
#include <sys/time.h>
|
|
||||||
#include <sys/resource.h>
|
|
||||||
#include <sys/rusage.h>
|
|
||||||
|
|
||||||
#ifdef __hpux
|
|
||||||
#include <sys/syscall.h>
|
|
||||||
#endif
|
|
||||||
|
|
||||||
struct rusage rusage;
|
|
||||||
|
|
||||||
double dtime()
|
|
||||||
{
|
|
||||||
double q;
|
|
||||||
|
|
||||||
getrusage(RUSAGE_SELF,&rusage);
|
|
||||||
|
|
||||||
q = (double)(rusage.ru_utime.tv_sec);
|
|
||||||
q = q + (double)(rusage.ru_utime.tv_nsec) * 1.0e-09;
|
|
||||||
|
|
||||||
return q;
|
|
||||||
}
|
|
||||||
#endif
|
|
||||||
|
|
||||||
|
|
||||||
/****************************************************/
|
|
||||||
/* Windows NT (32 bit) dtime() routine */
|
|
||||||
/* Provided by: Piers Haken, piersh@microsoft.com */
|
|
||||||
/****************************************************/
|
|
||||||
#ifdef WIN32
|
|
||||||
#include <windows.h>
|
|
||||||
|
|
||||||
double dtime(void)
|
|
||||||
{
|
|
||||||
double q;
|
|
||||||
|
|
||||||
q = (double)GetTickCount() * 1.0e-03;
|
|
||||||
|
|
||||||
return q;
|
|
||||||
}
|
|
||||||
#endif
|
|
||||||
|
|
||||||
/*****************************************************/
|
|
||||||
/* Time according to POSIX.1 - <J.Pelan@qub.ac.uk> */
|
|
||||||
/* Ref: "POSIX Programmer's Guide" O'Reilly & Assoc.*/
|
|
||||||
/*****************************************************/
|
|
||||||
#ifdef POSIX1
|
|
||||||
#define _POSIX_SOURCE 1
|
|
||||||
#include <unistd.h>
|
|
||||||
#include <limits.h>
|
|
||||||
#include <sys/times.h>
|
|
||||||
|
|
||||||
struct tms tms;
|
|
||||||
|
|
||||||
double dtime()
|
|
||||||
{
|
|
||||||
double q;
|
|
||||||
times(&tms);
|
|
||||||
q = (double)tms.tms_utime / (double)CLK_TCK;
|
|
||||||
return q;
|
|
||||||
}
|
|
||||||
#endif
|
|
||||||
|
|
||||||
/*-------- End of queens.c, Say goodnight Linda! --------*/
|
|
||||||
@@ -1,86 +0,0 @@
|
|||||||
/* random.c
|
|
||||||
|
|
||||||
Author: Numerical recipes (ran1, gaussian), Jon Hamkins (others)
|
|
||||||
Revised by: Jon Hamkins
|
|
||||||
Date: 4-16-98
|
|
||||||
*/
|
|
||||||
|
|
||||||
#include <math.h>
|
|
||||||
|
|
||||||
#define IA 16807
|
|
||||||
#define IM 2147483647
|
|
||||||
#define AM (1.0/IM)
|
|
||||||
#define IQ 127773
|
|
||||||
#define IR 2836
|
|
||||||
#define NTAB 32
|
|
||||||
#define NDIV (1+(IM-1)/NTAB)
|
|
||||||
#define EPS 1.2e-14
|
|
||||||
#define RNMX (1.0-EPS)
|
|
||||||
/* From Numerical Recipes, p. 280, modified from float to double */
|
|
||||||
/* returns a uniform deviate in (0,1) */
|
|
||||||
double ran1(long *idum)
|
|
||||||
{
|
|
||||||
int j;
|
|
||||||
long k;
|
|
||||||
static long iy=0;
|
|
||||||
static long iv[NTAB];
|
|
||||||
double temp;
|
|
||||||
|
|
||||||
if (*idum <=0 || !iy) {
|
|
||||||
if (-(*idum) < 1) *idum=1;
|
|
||||||
else *idum = -(*idum);
|
|
||||||
for (j=NTAB+7; j>=0; j--) {
|
|
||||||
k=(*idum)/IQ;
|
|
||||||
*idum=IA*(*idum-k*IQ)-IR*k;
|
|
||||||
if (*idum < 0) *idum += IM;
|
|
||||||
if (j < NTAB) iv[j] = *idum;
|
|
||||||
}
|
|
||||||
iy = iv[0];
|
|
||||||
}
|
|
||||||
k=(*idum)/IQ;
|
|
||||||
*idum=IA*(*idum-k*IQ)-IR*k;
|
|
||||||
if (*idum < 0) *idum += IM;
|
|
||||||
j=iy/NDIV;
|
|
||||||
iy=iv[j];
|
|
||||||
iv[j] = *idum;
|
|
||||||
if ((temp=AM*iy) > RNMX) return RNMX;
|
|
||||||
else return temp;
|
|
||||||
}
|
|
||||||
#undef IA
|
|
||||||
#undef IM
|
|
||||||
#undef AM
|
|
||||||
#undef IQ
|
|
||||||
#undef IR
|
|
||||||
#undef NTAB
|
|
||||||
#undef NDIV
|
|
||||||
#undef EPS
|
|
||||||
#undef RNMX
|
|
||||||
|
|
||||||
/* Generate a N(0,1) r.v. */
|
|
||||||
double gaussian(long *idum)
|
|
||||||
{
|
|
||||||
static int iset=0;
|
|
||||||
static double gset;
|
|
||||||
double fac,r,v1,v2;
|
|
||||||
double ran1();
|
|
||||||
if (iset == 0) {
|
|
||||||
do {
|
|
||||||
v1=2.0*ran1(idum)-1.0;
|
|
||||||
v2=2.0*ran1(idum)-1.0;
|
|
||||||
r=v1*v1+v2*v2;
|
|
||||||
} while (r >= 1.0 || r == 0.0);
|
|
||||||
fac=sqrt(-2.0*log(r)/r);
|
|
||||||
gset=v1*fac;
|
|
||||||
iset=1;
|
|
||||||
return v2*fac;
|
|
||||||
} else {
|
|
||||||
iset=0;
|
|
||||||
return gset;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
/* generate a random bit */
|
|
||||||
int random_bit(long *idum)
|
|
||||||
{
|
|
||||||
return((ran1(idum)<0.5) ? 0 : 1);
|
|
||||||
}
|
|
||||||
@@ -1,6 +0,0 @@
|
|||||||
/* random.h */
|
|
||||||
|
|
||||||
/* functions provided by random.c */
|
|
||||||
extern double ran1(long *idum);
|
|
||||||
extern double gaussian(long *idum);
|
|
||||||
extern int random_bit(long *idum);
|
|
||||||
@@ -1,81 +0,0 @@
|
|||||||
/*
|
|
||||||
* This file is subject to the terms and conditions of the GNU General Public
|
|
||||||
* License. See the file "COPYING" in the main directory of this archive
|
|
||||||
* for more details.
|
|
||||||
*
|
|
||||||
* Copyright (C) 1985 MIPS Computer Systems, Inc.
|
|
||||||
* Copyright (C) 1994, 95, 99, 2003 by Ralf Baechle
|
|
||||||
* Copyright (C) 1990 - 1992, 1999 Silicon Graphics, Inc.
|
|
||||||
*/
|
|
||||||
#ifndef _ASM_REGDEF_H
|
|
||||||
#define _ASM_REGDEF_H
|
|
||||||
|
|
||||||
/*
|
|
||||||
* Symbolic register names for 32 bit ABI
|
|
||||||
*/
|
|
||||||
#define zero $0 /* wired zero */
|
|
||||||
#define AT $1 /* assembler temp - uppercase because of ".set at" */
|
|
||||||
#define v0 $2 /* return value */
|
|
||||||
#define v1 $3
|
|
||||||
#define a0 $4 /* argument registers */
|
|
||||||
#define a1 $5
|
|
||||||
#define a2 $6
|
|
||||||
#define a3 $7
|
|
||||||
#define t0 $8 /* caller saved */
|
|
||||||
#define t1 $9
|
|
||||||
#define t2 $10
|
|
||||||
#define t3 $11
|
|
||||||
#define t4 $12
|
|
||||||
#define t5 $13
|
|
||||||
#define t6 $14
|
|
||||||
#define t7 $15
|
|
||||||
#define s0 $16 /* callee saved */
|
|
||||||
#define s1 $17
|
|
||||||
#define s2 $18
|
|
||||||
#define s3 $19
|
|
||||||
#define s4 $20
|
|
||||||
#define s5 $21
|
|
||||||
#define s6 $22
|
|
||||||
#define s7 $23
|
|
||||||
#define t8 $24 /* caller saved */
|
|
||||||
#define t9 $25
|
|
||||||
#define jp $25 /* PIC jump register */
|
|
||||||
#define k0 $26 /* kernel scratch */
|
|
||||||
#define k1 $27
|
|
||||||
#define gp $28 /* global pointer */
|
|
||||||
#define sp $29 /* stack pointer */
|
|
||||||
#define fp $30 /* frame pointer */
|
|
||||||
#define s8 $30 /* same like fp! */
|
|
||||||
#define ra $31 /* return address */
|
|
||||||
|
|
||||||
/* CP0 registers */
|
|
||||||
#define CP0_INDEX $0 /* R3000 available */
|
|
||||||
#define CP0_RANDOM $1 /* R3000 available */
|
|
||||||
#define CP0_ENTRYLO $2 /* R3000 available */
|
|
||||||
#define CP0_CONTEXT $4 /* R3000 available */
|
|
||||||
#define CP0_BADDR $8 /* R3000 available */
|
|
||||||
#define CP0_ENTRYHI $10 /* R3000 available */
|
|
||||||
#define CP0_SR $12 /* R3000 available */
|
|
||||||
#define CP0_CR $13 /* R3000 available */
|
|
||||||
#define CP0_EPC $14 /* R3000 available */
|
|
||||||
#define CP0_PRID $15 /* R3000 available */
|
|
||||||
|
|
||||||
/* Status register masks */
|
|
||||||
#define SR_MASK_IEC 0x00000001
|
|
||||||
#define SR_MASK_KUC 0x00000002
|
|
||||||
#define SR_MASK_IEP 0x00000004
|
|
||||||
#define SR_MASK_KUP 0x00000008
|
|
||||||
#define SR_MASK_IEO 0x00000010
|
|
||||||
#define SR_MASK_KUO 0x00000020
|
|
||||||
#define SR_MASK_IM 0x0000FF00
|
|
||||||
#define SR_MASK_DS 0x00FF0000
|
|
||||||
#define SR_MASK_RE 0x01000000
|
|
||||||
#define SR_MASK_CU 0xF0000000
|
|
||||||
|
|
||||||
/* Cause register masks */
|
|
||||||
#define CR_MASK_EXC 0x0000007C
|
|
||||||
#define CR_MASK_IP 0x0000FF00
|
|
||||||
#define CR_MASK_CE 0x40000000
|
|
||||||
#define CR_MASK_BD 0x80000000
|
|
||||||
|
|
||||||
#endif /* _ASM_REGDEF_H */
|
|
||||||
@@ -1,408 +0,0 @@
|
|||||||
|
|
||||||
/* C version of the systems programming language benchmark
|
|
||||||
** Author: M. J. Jordan Cambridge Computer Laboratory.
|
|
||||||
**
|
|
||||||
** Modified by: M. Richards, Nov 1996
|
|
||||||
** to be ANSI C and runnable on 64 bit machines + other minor changes
|
|
||||||
** Modified by: M. Richards, 20 Oct 1998
|
|
||||||
** made minor corrections to improve ANSI compliance (suggested
|
|
||||||
** by David Levine)
|
|
||||||
**
|
|
||||||
** Compile with, say
|
|
||||||
**
|
|
||||||
** gcc -o bench bench.c
|
|
||||||
**
|
|
||||||
** or
|
|
||||||
**
|
|
||||||
** gcc -o bench100 -Dbench100 bench.c (for a version that obeys
|
|
||||||
** the main loop 100x more often)
|
|
||||||
*/
|
|
||||||
|
|
||||||
#include <stdio.h>
|
|
||||||
#include <stdlib.h>
|
|
||||||
|
|
||||||
#ifdef SMALL_PROBLEM_SIZE
|
|
||||||
#define Count 1000*1000
|
|
||||||
#define Qpktcountval 2326389
|
|
||||||
#define Holdcountval 930555
|
|
||||||
#else
|
|
||||||
#define Count 10000*1000
|
|
||||||
#define Qpktcountval 23263894
|
|
||||||
#define Holdcountval 9305557
|
|
||||||
#endif
|
|
||||||
|
|
||||||
|
|
||||||
#define TRUE 1
|
|
||||||
#define FALSE 0
|
|
||||||
#define MAXINT 32767
|
|
||||||
|
|
||||||
#define BUFSIZE 3
|
|
||||||
#define I_IDLE 1
|
|
||||||
#define I_WORK 2
|
|
||||||
#define I_HANDLERA 3
|
|
||||||
#define I_HANDLERB 4
|
|
||||||
#define I_DEVA 5
|
|
||||||
#define I_DEVB 6
|
|
||||||
#define PKTBIT 1
|
|
||||||
#define WAITBIT 2
|
|
||||||
#define HOLDBIT 4
|
|
||||||
#define NOTPKTBIT !1
|
|
||||||
#define NOTWAITBIT !2
|
|
||||||
#define NOTHOLDBIT 0XFFFB
|
|
||||||
|
|
||||||
#define S_RUN 0
|
|
||||||
#define S_RUNPKT 1
|
|
||||||
#define S_WAIT 2
|
|
||||||
#define S_WAITPKT 3
|
|
||||||
#define S_HOLD 4
|
|
||||||
#define S_HOLDPKT 5
|
|
||||||
#define S_HOLDWAIT 6
|
|
||||||
#define S_HOLDWAITPKT 7
|
|
||||||
|
|
||||||
#define K_DEV 1000
|
|
||||||
#define K_WORK 1001
|
|
||||||
|
|
||||||
struct packet
|
|
||||||
{
|
|
||||||
struct packet *p_link;
|
|
||||||
int p_id;
|
|
||||||
int p_kind;
|
|
||||||
int p_a1;
|
|
||||||
char p_a2[4];
|
|
||||||
};
|
|
||||||
|
|
||||||
struct task
|
|
||||||
{
|
|
||||||
struct task *t_link;
|
|
||||||
int t_id;
|
|
||||||
int t_pri;
|
|
||||||
struct packet *t_wkq;
|
|
||||||
int t_state;
|
|
||||||
struct task *(*t_fn)(struct packet *);
|
|
||||||
long t_v1;
|
|
||||||
long t_v2;
|
|
||||||
};
|
|
||||||
|
|
||||||
char alphabet[28] = "0ABCDEFGHIJKLMNOPQRSTUVWXYZ";
|
|
||||||
struct task *tasktab[11] = {0,0,0,0,0,0,0,0,0,0,0};
|
|
||||||
struct task *tasklist = 0;
|
|
||||||
struct task *tcb;
|
|
||||||
long taskid;
|
|
||||||
long v1;
|
|
||||||
long v2;
|
|
||||||
int qpktcount = 0;
|
|
||||||
int holdcount = 0;
|
|
||||||
int tracing = 1;
|
|
||||||
int layout = 0;
|
|
||||||
|
|
||||||
void append(struct packet *pkt, struct packet *ptr);
|
|
||||||
|
|
||||||
void createtask(int id,
|
|
||||||
int pri,
|
|
||||||
struct packet *wkq,
|
|
||||||
int state,
|
|
||||||
struct task *(*fn)(struct packet *),
|
|
||||||
long v1,
|
|
||||||
long v2)
|
|
||||||
{
|
|
||||||
struct task *t = (struct task *)malloc(sizeof(struct task));
|
|
||||||
|
|
||||||
tasktab[id] = t;
|
|
||||||
t->t_link = tasklist;
|
|
||||||
t->t_id = id;
|
|
||||||
t->t_pri = pri;
|
|
||||||
t->t_wkq = wkq;
|
|
||||||
t->t_state = state;
|
|
||||||
t->t_fn = fn;
|
|
||||||
t->t_v1 = v1;
|
|
||||||
t->t_v2 = v2;
|
|
||||||
tasklist = t;
|
|
||||||
}
|
|
||||||
|
|
||||||
struct packet *pkt(struct packet *link, int id, int kind)
|
|
||||||
{
|
|
||||||
int i;
|
|
||||||
struct packet *p = (struct packet *)malloc(sizeof(struct packet));
|
|
||||||
|
|
||||||
for (i=0; i<=BUFSIZE; i++)
|
|
||||||
p->p_a2[i] = 0;
|
|
||||||
|
|
||||||
p->p_link = link;
|
|
||||||
p->p_id = id;
|
|
||||||
p->p_kind = kind;
|
|
||||||
p->p_a1 = 0;
|
|
||||||
|
|
||||||
return (p);
|
|
||||||
}
|
|
||||||
|
|
||||||
void trace(char a)
|
|
||||||
{
|
|
||||||
if ( --layout <= 0 )
|
|
||||||
{
|
|
||||||
printf("\n");
|
|
||||||
layout = 50;
|
|
||||||
}
|
|
||||||
|
|
||||||
printf("%c", a);
|
|
||||||
}
|
|
||||||
|
|
||||||
void schedule()
|
|
||||||
{
|
|
||||||
while ( tcb != 0 )
|
|
||||||
{
|
|
||||||
struct packet *pkt;
|
|
||||||
struct task *newtcb;
|
|
||||||
|
|
||||||
pkt=0;
|
|
||||||
|
|
||||||
switch ( tcb->t_state )
|
|
||||||
{
|
|
||||||
case S_WAITPKT:
|
|
||||||
pkt = tcb->t_wkq;
|
|
||||||
tcb->t_wkq = pkt->p_link;
|
|
||||||
tcb->t_state = tcb->t_wkq == 0 ? S_RUN : S_RUNPKT;
|
|
||||||
|
|
||||||
case S_RUN:
|
|
||||||
case S_RUNPKT:
|
|
||||||
taskid = tcb->t_id;
|
|
||||||
v1 = tcb->t_v1;
|
|
||||||
v2 = tcb->t_v2;
|
|
||||||
if (tracing==TRUE) trace(taskid+'0');
|
|
||||||
|
|
||||||
newtcb = (*(tcb->t_fn))(pkt);
|
|
||||||
tcb->t_v1 = v1;
|
|
||||||
tcb->t_v2 = v2;
|
|
||||||
tcb = newtcb;
|
|
||||||
break;
|
|
||||||
|
|
||||||
case S_WAIT:
|
|
||||||
case S_HOLD:
|
|
||||||
case S_HOLDPKT:
|
|
||||||
case S_HOLDWAIT:
|
|
||||||
case S_HOLDWAITPKT:
|
|
||||||
tcb = tcb->t_link;
|
|
||||||
break;
|
|
||||||
|
|
||||||
default:
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
struct task *Wait(void)
|
|
||||||
{
|
|
||||||
tcb->t_state |= WAITBIT;
|
|
||||||
return (tcb);
|
|
||||||
}
|
|
||||||
|
|
||||||
struct task *holdself(void)
|
|
||||||
{
|
|
||||||
++holdcount;
|
|
||||||
tcb->t_state |= HOLDBIT;
|
|
||||||
return (tcb->t_link) ;
|
|
||||||
}
|
|
||||||
|
|
||||||
struct task *findtcb(int id)
|
|
||||||
{
|
|
||||||
struct task *t = 0;
|
|
||||||
|
|
||||||
if (1<=id && id<=(long)10)
|
|
||||||
t = tasktab[id];
|
|
||||||
if (t==0) printf("\nBad task id %d\n", id);
|
|
||||||
return(t);
|
|
||||||
}
|
|
||||||
|
|
||||||
struct task *release(int id)
|
|
||||||
{
|
|
||||||
struct task *t;
|
|
||||||
|
|
||||||
t = findtcb(id);
|
|
||||||
if ( t==0 ) return (0);
|
|
||||||
|
|
||||||
t->t_state &= NOTHOLDBIT;
|
|
||||||
if ( t->t_pri > tcb->t_pri ) return (t);
|
|
||||||
|
|
||||||
return (tcb) ;
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
struct task *qpkt(struct packet *pkt)
|
|
||||||
{
|
|
||||||
struct task *t;
|
|
||||||
|
|
||||||
t = findtcb(pkt->p_id);
|
|
||||||
if (t==0) return (t);
|
|
||||||
|
|
||||||
qpktcount++;
|
|
||||||
|
|
||||||
pkt->p_link = 0;
|
|
||||||
pkt->p_id = taskid;
|
|
||||||
|
|
||||||
if (t->t_wkq==0)
|
|
||||||
{
|
|
||||||
t->t_wkq = pkt;
|
|
||||||
t->t_state |= PKTBIT;
|
|
||||||
if (t->t_pri > tcb->t_pri) return (t);
|
|
||||||
}
|
|
||||||
else
|
|
||||||
{
|
|
||||||
append(pkt, (struct packet *)&(t->t_wkq));
|
|
||||||
}
|
|
||||||
|
|
||||||
return (tcb);
|
|
||||||
}
|
|
||||||
|
|
||||||
struct task *idlefn(struct packet *pkt)
|
|
||||||
{
|
|
||||||
--v2;
|
|
||||||
if ( v2==0 ) return ( holdself() );
|
|
||||||
|
|
||||||
if ( (v1&1) == 0 )
|
|
||||||
{
|
|
||||||
v1 = ( v1>>1) & MAXINT;
|
|
||||||
return ( release(I_DEVA) );
|
|
||||||
}
|
|
||||||
else
|
|
||||||
{
|
|
||||||
v1 = ( (v1>>1) & MAXINT) ^ 0XD008;
|
|
||||||
return ( release(I_DEVB) );
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
struct task *workfn(struct packet *pkt)
|
|
||||||
{
|
|
||||||
if ( pkt==0 ) return ( Wait() );
|
|
||||||
else
|
|
||||||
{
|
|
||||||
int i;
|
|
||||||
|
|
||||||
v1 = I_HANDLERA + I_HANDLERB - v1;
|
|
||||||
pkt->p_id = v1;
|
|
||||||
|
|
||||||
pkt->p_a1 = 0;
|
|
||||||
for (i=0; i<=BUFSIZE; i++)
|
|
||||||
{
|
|
||||||
v2++;
|
|
||||||
if ( v2 > 26 ) v2 = 1;
|
|
||||||
(pkt->p_a2)[i] = alphabet[v2];
|
|
||||||
}
|
|
||||||
return ( qpkt(pkt) );
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
struct task *handlerfn(struct packet *pkt)
|
|
||||||
{
|
|
||||||
if ( pkt!=0) append(pkt,
|
|
||||||
(struct packet *)(pkt->p_kind==K_WORK ? &v1 : &v2));
|
|
||||||
|
|
||||||
if ( v1!=0 )
|
|
||||||
{
|
|
||||||
int count;
|
|
||||||
struct packet *workpkt = (struct packet *)v1;
|
|
||||||
count = workpkt->p_a1;
|
|
||||||
|
|
||||||
if ( count > BUFSIZE )
|
|
||||||
{
|
|
||||||
v1 = (long)(((struct packet *)v1)->p_link);
|
|
||||||
return ( qpkt(workpkt) );
|
|
||||||
}
|
|
||||||
|
|
||||||
if ( v2!=0 )
|
|
||||||
{
|
|
||||||
struct packet *devpkt;
|
|
||||||
|
|
||||||
devpkt = (struct packet *)v2;
|
|
||||||
v2 = (long)(((struct packet *)v2)->p_link);
|
|
||||||
devpkt->p_a1 = workpkt->p_a2[count];
|
|
||||||
workpkt->p_a1 = count+1;
|
|
||||||
return( qpkt(devpkt) );
|
|
||||||
}
|
|
||||||
}
|
|
||||||
return ( Wait() );
|
|
||||||
}
|
|
||||||
|
|
||||||
struct task *devfn(struct packet *pkt)
|
|
||||||
{
|
|
||||||
if ( pkt==0 )
|
|
||||||
{
|
|
||||||
if ( v1==0 ) return ( Wait() );
|
|
||||||
pkt = (struct packet *)v1;
|
|
||||||
v1 = 0;
|
|
||||||
return ( qpkt(pkt) );
|
|
||||||
}
|
|
||||||
else
|
|
||||||
{
|
|
||||||
v1 = (long)pkt;
|
|
||||||
if (tracing==TRUE) trace(pkt->p_a1);
|
|
||||||
return ( holdself() );
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
void append(struct packet *pkt, struct packet *ptr)
|
|
||||||
{
|
|
||||||
pkt->p_link = 0;
|
|
||||||
|
|
||||||
while ( ptr->p_link ) ptr = ptr->p_link;
|
|
||||||
|
|
||||||
ptr->p_link = pkt;
|
|
||||||
}
|
|
||||||
|
|
||||||
int main()
|
|
||||||
{
|
|
||||||
struct packet *wkq = 0;
|
|
||||||
int retval;
|
|
||||||
|
|
||||||
printf("Bench mark starting\n");
|
|
||||||
|
|
||||||
createtask(I_IDLE, 0, wkq, S_RUN, idlefn, 1, Count);
|
|
||||||
|
|
||||||
wkq = pkt(0, 0, K_WORK);
|
|
||||||
wkq = pkt(wkq, 0, K_WORK);
|
|
||||||
|
|
||||||
createtask(I_WORK, 1000, wkq, S_WAITPKT, workfn, I_HANDLERA, 0);
|
|
||||||
|
|
||||||
wkq = pkt(0, I_DEVA, K_DEV);
|
|
||||||
wkq = pkt(wkq, I_DEVA, K_DEV);
|
|
||||||
wkq = pkt(wkq, I_DEVA, K_DEV);
|
|
||||||
|
|
||||||
createtask(I_HANDLERA, 2000, wkq, S_WAITPKT, handlerfn, 0, 0);
|
|
||||||
|
|
||||||
wkq = pkt(0, I_DEVB, K_DEV);
|
|
||||||
wkq = pkt(wkq, I_DEVB, K_DEV);
|
|
||||||
wkq = pkt(wkq, I_DEVB, K_DEV);
|
|
||||||
|
|
||||||
createtask(I_HANDLERB, 3000, wkq, S_WAITPKT, handlerfn, 0, 0);
|
|
||||||
|
|
||||||
wkq = 0;
|
|
||||||
createtask(I_DEVA, 4000, wkq, S_WAIT, devfn, 0, 0);
|
|
||||||
createtask(I_DEVB, 5000, wkq, S_WAIT, devfn, 0, 0);
|
|
||||||
|
|
||||||
tcb = tasklist;
|
|
||||||
|
|
||||||
qpktcount = holdcount = 0;
|
|
||||||
|
|
||||||
printf("Starting\n");
|
|
||||||
|
|
||||||
tracing = FALSE;
|
|
||||||
layout = 0;
|
|
||||||
|
|
||||||
schedule();
|
|
||||||
|
|
||||||
printf("finished\n");
|
|
||||||
|
|
||||||
printf("qpkt count = %d holdcount = %d\n",
|
|
||||||
qpktcount, holdcount);
|
|
||||||
|
|
||||||
printf("These results are ");
|
|
||||||
if (qpktcount == Qpktcountval && holdcount == Holdcountval) {
|
|
||||||
printf("correct");
|
|
||||||
retval = 0;
|
|
||||||
} else {
|
|
||||||
printf("incorrect");
|
|
||||||
retval = 1;
|
|
||||||
}
|
|
||||||
|
|
||||||
printf("\nend of run\n");
|
|
||||||
return retval;
|
|
||||||
}
|
|
||||||
|
|
||||||
@@ -1,294 +0,0 @@
|
|||||||
/********************************************************************\
|
|
||||||
*
|
|
||||||
* FILE: rmd160.c
|
|
||||||
*
|
|
||||||
* CONTENTS: A sample C-implementation of the RIPEMD-160
|
|
||||||
* hash-function.
|
|
||||||
* TARGET: any computer with an ANSI C compiler
|
|
||||||
*
|
|
||||||
* AUTHOR: Antoon Bosselaers, ESAT-COSIC
|
|
||||||
* DATE: 1 March 1996
|
|
||||||
* VERSION: 1.0
|
|
||||||
*
|
|
||||||
* Copyright (c) Katholieke Universiteit Leuven
|
|
||||||
* 1996, All Rights Reserved
|
|
||||||
*
|
|
||||||
* Conditions for use of the RIPEMD-160 Software
|
|
||||||
*
|
|
||||||
* The RIPEMD-160 software is freely available for use under the terms and
|
|
||||||
* conditions described hereunder, which shall be deemed to be accepted by
|
|
||||||
* any user of the software and applicable on any use of the software:
|
|
||||||
*
|
|
||||||
* 1. K.U.Leuven Department of Electrical Engineering-ESAT/COSIC shall for
|
|
||||||
* all purposes be considered the owner of the RIPEMD-160 software and of
|
|
||||||
* all copyright, trade secret, patent or other intellectual property
|
|
||||||
* rights therein.
|
|
||||||
* 2. The RIPEMD-160 software is provided on an "as is" basis without
|
|
||||||
* warranty of any sort, express or implied. K.U.Leuven makes no
|
|
||||||
* representation that the use of the software will not infringe any
|
|
||||||
* patent or proprietary right of third parties. User will indemnify
|
|
||||||
* K.U.Leuven and hold K.U.Leuven harmless from any claims or liabilities
|
|
||||||
* which may arise as a result of its use of the software. In no
|
|
||||||
* circumstances K.U.Leuven R&D will be held liable for any deficiency,
|
|
||||||
* fault or other mishappening with regard to the use or performance of
|
|
||||||
* the software.
|
|
||||||
* 3. User agrees to give due credit to K.U.Leuven in scientific publications
|
|
||||||
* or communications in relation with the use of the RIPEMD-160 software
|
|
||||||
* as follows: RIPEMD-160 software written by Antoon Bosselaers,
|
|
||||||
* available at http://www.esat.kuleuven.be/~cosicart/ps/AB-9601/.
|
|
||||||
*
|
|
||||||
\********************************************************************/
|
|
||||||
|
|
||||||
/* header files */
|
|
||||||
#include <stdio.h>
|
|
||||||
#include <stdlib.h>
|
|
||||||
#include <string.h>
|
|
||||||
#include "rmd160.h"
|
|
||||||
|
|
||||||
/********************************************************************/
|
|
||||||
|
|
||||||
void MDinit(dword *MDbuf)
|
|
||||||
{
|
|
||||||
MDbuf[0] = 0x67452301UL;
|
|
||||||
MDbuf[1] = 0xefcdab89UL;
|
|
||||||
MDbuf[2] = 0x98badcfeUL;
|
|
||||||
MDbuf[3] = 0x10325476UL;
|
|
||||||
MDbuf[4] = 0xc3d2e1f0UL;
|
|
||||||
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
|
|
||||||
/********************************************************************/
|
|
||||||
|
|
||||||
void compress(dword *MDbuf, dword *X)
|
|
||||||
{
|
|
||||||
dword aa = MDbuf[0], bb = MDbuf[1], cc = MDbuf[2],
|
|
||||||
dd = MDbuf[3], ee = MDbuf[4];
|
|
||||||
dword aaa = MDbuf[0], bbb = MDbuf[1], ccc = MDbuf[2],
|
|
||||||
ddd = MDbuf[3], eee = MDbuf[4];
|
|
||||||
|
|
||||||
/* round 1 */
|
|
||||||
FF(aa, bb, cc, dd, ee, X[ 0], 11);
|
|
||||||
FF(ee, aa, bb, cc, dd, X[ 1], 14);
|
|
||||||
FF(dd, ee, aa, bb, cc, X[ 2], 15);
|
|
||||||
FF(cc, dd, ee, aa, bb, X[ 3], 12);
|
|
||||||
FF(bb, cc, dd, ee, aa, X[ 4], 5);
|
|
||||||
FF(aa, bb, cc, dd, ee, X[ 5], 8);
|
|
||||||
FF(ee, aa, bb, cc, dd, X[ 6], 7);
|
|
||||||
FF(dd, ee, aa, bb, cc, X[ 7], 9);
|
|
||||||
FF(cc, dd, ee, aa, bb, X[ 8], 11);
|
|
||||||
FF(bb, cc, dd, ee, aa, X[ 9], 13);
|
|
||||||
FF(aa, bb, cc, dd, ee, X[10], 14);
|
|
||||||
FF(ee, aa, bb, cc, dd, X[11], 15);
|
|
||||||
FF(dd, ee, aa, bb, cc, X[12], 6);
|
|
||||||
FF(cc, dd, ee, aa, bb, X[13], 7);
|
|
||||||
FF(bb, cc, dd, ee, aa, X[14], 9);
|
|
||||||
FF(aa, bb, cc, dd, ee, X[15], 8);
|
|
||||||
|
|
||||||
/* round 2 */
|
|
||||||
GG(ee, aa, bb, cc, dd, X[ 7], 7);
|
|
||||||
GG(dd, ee, aa, bb, cc, X[ 4], 6);
|
|
||||||
GG(cc, dd, ee, aa, bb, X[13], 8);
|
|
||||||
GG(bb, cc, dd, ee, aa, X[ 1], 13);
|
|
||||||
GG(aa, bb, cc, dd, ee, X[10], 11);
|
|
||||||
GG(ee, aa, bb, cc, dd, X[ 6], 9);
|
|
||||||
GG(dd, ee, aa, bb, cc, X[15], 7);
|
|
||||||
GG(cc, dd, ee, aa, bb, X[ 3], 15);
|
|
||||||
GG(bb, cc, dd, ee, aa, X[12], 7);
|
|
||||||
GG(aa, bb, cc, dd, ee, X[ 0], 12);
|
|
||||||
GG(ee, aa, bb, cc, dd, X[ 9], 15);
|
|
||||||
GG(dd, ee, aa, bb, cc, X[ 5], 9);
|
|
||||||
GG(cc, dd, ee, aa, bb, X[ 2], 11);
|
|
||||||
GG(bb, cc, dd, ee, aa, X[14], 7);
|
|
||||||
GG(aa, bb, cc, dd, ee, X[11], 13);
|
|
||||||
GG(ee, aa, bb, cc, dd, X[ 8], 12);
|
|
||||||
|
|
||||||
/* round 3 */
|
|
||||||
HH(dd, ee, aa, bb, cc, X[ 3], 11);
|
|
||||||
HH(cc, dd, ee, aa, bb, X[10], 13);
|
|
||||||
HH(bb, cc, dd, ee, aa, X[14], 6);
|
|
||||||
HH(aa, bb, cc, dd, ee, X[ 4], 7);
|
|
||||||
HH(ee, aa, bb, cc, dd, X[ 9], 14);
|
|
||||||
HH(dd, ee, aa, bb, cc, X[15], 9);
|
|
||||||
HH(cc, dd, ee, aa, bb, X[ 8], 13);
|
|
||||||
HH(bb, cc, dd, ee, aa, X[ 1], 15);
|
|
||||||
HH(aa, bb, cc, dd, ee, X[ 2], 14);
|
|
||||||
HH(ee, aa, bb, cc, dd, X[ 7], 8);
|
|
||||||
HH(dd, ee, aa, bb, cc, X[ 0], 13);
|
|
||||||
HH(cc, dd, ee, aa, bb, X[ 6], 6);
|
|
||||||
HH(bb, cc, dd, ee, aa, X[13], 5);
|
|
||||||
HH(aa, bb, cc, dd, ee, X[11], 12);
|
|
||||||
HH(ee, aa, bb, cc, dd, X[ 5], 7);
|
|
||||||
HH(dd, ee, aa, bb, cc, X[12], 5);
|
|
||||||
|
|
||||||
/* round 4 */
|
|
||||||
II(cc, dd, ee, aa, bb, X[ 1], 11);
|
|
||||||
II(bb, cc, dd, ee, aa, X[ 9], 12);
|
|
||||||
II(aa, bb, cc, dd, ee, X[11], 14);
|
|
||||||
II(ee, aa, bb, cc, dd, X[10], 15);
|
|
||||||
II(dd, ee, aa, bb, cc, X[ 0], 14);
|
|
||||||
II(cc, dd, ee, aa, bb, X[ 8], 15);
|
|
||||||
II(bb, cc, dd, ee, aa, X[12], 9);
|
|
||||||
II(aa, bb, cc, dd, ee, X[ 4], 8);
|
|
||||||
II(ee, aa, bb, cc, dd, X[13], 9);
|
|
||||||
II(dd, ee, aa, bb, cc, X[ 3], 14);
|
|
||||||
II(cc, dd, ee, aa, bb, X[ 7], 5);
|
|
||||||
II(bb, cc, dd, ee, aa, X[15], 6);
|
|
||||||
II(aa, bb, cc, dd, ee, X[14], 8);
|
|
||||||
II(ee, aa, bb, cc, dd, X[ 5], 6);
|
|
||||||
II(dd, ee, aa, bb, cc, X[ 6], 5);
|
|
||||||
II(cc, dd, ee, aa, bb, X[ 2], 12);
|
|
||||||
|
|
||||||
/* round 5 */
|
|
||||||
JJ(bb, cc, dd, ee, aa, X[ 4], 9);
|
|
||||||
JJ(aa, bb, cc, dd, ee, X[ 0], 15);
|
|
||||||
JJ(ee, aa, bb, cc, dd, X[ 5], 5);
|
|
||||||
JJ(dd, ee, aa, bb, cc, X[ 9], 11);
|
|
||||||
JJ(cc, dd, ee, aa, bb, X[ 7], 6);
|
|
||||||
JJ(bb, cc, dd, ee, aa, X[12], 8);
|
|
||||||
JJ(aa, bb, cc, dd, ee, X[ 2], 13);
|
|
||||||
JJ(ee, aa, bb, cc, dd, X[10], 12);
|
|
||||||
JJ(dd, ee, aa, bb, cc, X[14], 5);
|
|
||||||
JJ(cc, dd, ee, aa, bb, X[ 1], 12);
|
|
||||||
JJ(bb, cc, dd, ee, aa, X[ 3], 13);
|
|
||||||
JJ(aa, bb, cc, dd, ee, X[ 8], 14);
|
|
||||||
JJ(ee, aa, bb, cc, dd, X[11], 11);
|
|
||||||
JJ(dd, ee, aa, bb, cc, X[ 6], 8);
|
|
||||||
JJ(cc, dd, ee, aa, bb, X[15], 5);
|
|
||||||
JJ(bb, cc, dd, ee, aa, X[13], 6);
|
|
||||||
|
|
||||||
/* parallel round 1 */
|
|
||||||
JJJ(aaa, bbb, ccc, ddd, eee, X[ 5], 8);
|
|
||||||
JJJ(eee, aaa, bbb, ccc, ddd, X[14], 9);
|
|
||||||
JJJ(ddd, eee, aaa, bbb, ccc, X[ 7], 9);
|
|
||||||
JJJ(ccc, ddd, eee, aaa, bbb, X[ 0], 11);
|
|
||||||
JJJ(bbb, ccc, ddd, eee, aaa, X[ 9], 13);
|
|
||||||
JJJ(aaa, bbb, ccc, ddd, eee, X[ 2], 15);
|
|
||||||
JJJ(eee, aaa, bbb, ccc, ddd, X[11], 15);
|
|
||||||
JJJ(ddd, eee, aaa, bbb, ccc, X[ 4], 5);
|
|
||||||
JJJ(ccc, ddd, eee, aaa, bbb, X[13], 7);
|
|
||||||
JJJ(bbb, ccc, ddd, eee, aaa, X[ 6], 7);
|
|
||||||
JJJ(aaa, bbb, ccc, ddd, eee, X[15], 8);
|
|
||||||
JJJ(eee, aaa, bbb, ccc, ddd, X[ 8], 11);
|
|
||||||
JJJ(ddd, eee, aaa, bbb, ccc, X[ 1], 14);
|
|
||||||
JJJ(ccc, ddd, eee, aaa, bbb, X[10], 14);
|
|
||||||
JJJ(bbb, ccc, ddd, eee, aaa, X[ 3], 12);
|
|
||||||
JJJ(aaa, bbb, ccc, ddd, eee, X[12], 6);
|
|
||||||
|
|
||||||
/* parallel round 2 */
|
|
||||||
III(eee, aaa, bbb, ccc, ddd, X[ 6], 9);
|
|
||||||
III(ddd, eee, aaa, bbb, ccc, X[11], 13);
|
|
||||||
III(ccc, ddd, eee, aaa, bbb, X[ 3], 15);
|
|
||||||
III(bbb, ccc, ddd, eee, aaa, X[ 7], 7);
|
|
||||||
III(aaa, bbb, ccc, ddd, eee, X[ 0], 12);
|
|
||||||
III(eee, aaa, bbb, ccc, ddd, X[13], 8);
|
|
||||||
III(ddd, eee, aaa, bbb, ccc, X[ 5], 9);
|
|
||||||
III(ccc, ddd, eee, aaa, bbb, X[10], 11);
|
|
||||||
III(bbb, ccc, ddd, eee, aaa, X[14], 7);
|
|
||||||
III(aaa, bbb, ccc, ddd, eee, X[15], 7);
|
|
||||||
III(eee, aaa, bbb, ccc, ddd, X[ 8], 12);
|
|
||||||
III(ddd, eee, aaa, bbb, ccc, X[12], 7);
|
|
||||||
III(ccc, ddd, eee, aaa, bbb, X[ 4], 6);
|
|
||||||
III(bbb, ccc, ddd, eee, aaa, X[ 9], 15);
|
|
||||||
III(aaa, bbb, ccc, ddd, eee, X[ 1], 13);
|
|
||||||
III(eee, aaa, bbb, ccc, ddd, X[ 2], 11);
|
|
||||||
|
|
||||||
/* parallel round 3 */
|
|
||||||
HHH(ddd, eee, aaa, bbb, ccc, X[15], 9);
|
|
||||||
HHH(ccc, ddd, eee, aaa, bbb, X[ 5], 7);
|
|
||||||
HHH(bbb, ccc, ddd, eee, aaa, X[ 1], 15);
|
|
||||||
HHH(aaa, bbb, ccc, ddd, eee, X[ 3], 11);
|
|
||||||
HHH(eee, aaa, bbb, ccc, ddd, X[ 7], 8);
|
|
||||||
HHH(ddd, eee, aaa, bbb, ccc, X[14], 6);
|
|
||||||
HHH(ccc, ddd, eee, aaa, bbb, X[ 6], 6);
|
|
||||||
HHH(bbb, ccc, ddd, eee, aaa, X[ 9], 14);
|
|
||||||
HHH(aaa, bbb, ccc, ddd, eee, X[11], 12);
|
|
||||||
HHH(eee, aaa, bbb, ccc, ddd, X[ 8], 13);
|
|
||||||
HHH(ddd, eee, aaa, bbb, ccc, X[12], 5);
|
|
||||||
HHH(ccc, ddd, eee, aaa, bbb, X[ 2], 14);
|
|
||||||
HHH(bbb, ccc, ddd, eee, aaa, X[10], 13);
|
|
||||||
HHH(aaa, bbb, ccc, ddd, eee, X[ 0], 13);
|
|
||||||
HHH(eee, aaa, bbb, ccc, ddd, X[ 4], 7);
|
|
||||||
HHH(ddd, eee, aaa, bbb, ccc, X[13], 5);
|
|
||||||
|
|
||||||
/* parallel round 4 */
|
|
||||||
GGG(ccc, ddd, eee, aaa, bbb, X[ 8], 15);
|
|
||||||
GGG(bbb, ccc, ddd, eee, aaa, X[ 6], 5);
|
|
||||||
GGG(aaa, bbb, ccc, ddd, eee, X[ 4], 8);
|
|
||||||
GGG(eee, aaa, bbb, ccc, ddd, X[ 1], 11);
|
|
||||||
GGG(ddd, eee, aaa, bbb, ccc, X[ 3], 14);
|
|
||||||
GGG(ccc, ddd, eee, aaa, bbb, X[11], 14);
|
|
||||||
GGG(bbb, ccc, ddd, eee, aaa, X[15], 6);
|
|
||||||
GGG(aaa, bbb, ccc, ddd, eee, X[ 0], 14);
|
|
||||||
GGG(eee, aaa, bbb, ccc, ddd, X[ 5], 6);
|
|
||||||
GGG(ddd, eee, aaa, bbb, ccc, X[12], 9);
|
|
||||||
GGG(ccc, ddd, eee, aaa, bbb, X[ 2], 12);
|
|
||||||
GGG(bbb, ccc, ddd, eee, aaa, X[13], 9);
|
|
||||||
GGG(aaa, bbb, ccc, ddd, eee, X[ 9], 12);
|
|
||||||
GGG(eee, aaa, bbb, ccc, ddd, X[ 7], 5);
|
|
||||||
GGG(ddd, eee, aaa, bbb, ccc, X[10], 15);
|
|
||||||
GGG(ccc, ddd, eee, aaa, bbb, X[14], 8);
|
|
||||||
|
|
||||||
/* parallel round 5 */
|
|
||||||
FFF(bbb, ccc, ddd, eee, aaa, X[12] , 8);
|
|
||||||
FFF(aaa, bbb, ccc, ddd, eee, X[15] , 5);
|
|
||||||
FFF(eee, aaa, bbb, ccc, ddd, X[10] , 12);
|
|
||||||
FFF(ddd, eee, aaa, bbb, ccc, X[ 4] , 9);
|
|
||||||
FFF(ccc, ddd, eee, aaa, bbb, X[ 1] , 12);
|
|
||||||
FFF(bbb, ccc, ddd, eee, aaa, X[ 5] , 5);
|
|
||||||
FFF(aaa, bbb, ccc, ddd, eee, X[ 8] , 14);
|
|
||||||
FFF(eee, aaa, bbb, ccc, ddd, X[ 7] , 6);
|
|
||||||
FFF(ddd, eee, aaa, bbb, ccc, X[ 6] , 8);
|
|
||||||
FFF(ccc, ddd, eee, aaa, bbb, X[ 2] , 13);
|
|
||||||
FFF(bbb, ccc, ddd, eee, aaa, X[13] , 6);
|
|
||||||
FFF(aaa, bbb, ccc, ddd, eee, X[14] , 5);
|
|
||||||
FFF(eee, aaa, bbb, ccc, ddd, X[ 0] , 15);
|
|
||||||
FFF(ddd, eee, aaa, bbb, ccc, X[ 3] , 13);
|
|
||||||
FFF(ccc, ddd, eee, aaa, bbb, X[ 9] , 11);
|
|
||||||
FFF(bbb, ccc, ddd, eee, aaa, X[11] , 11);
|
|
||||||
|
|
||||||
/* combine results */
|
|
||||||
ddd += cc + MDbuf[1]; /* final result for MDbuf[0] */
|
|
||||||
MDbuf[1] = MDbuf[2] + dd + eee;
|
|
||||||
MDbuf[2] = MDbuf[3] + ee + aaa;
|
|
||||||
MDbuf[3] = MDbuf[4] + aa + bbb;
|
|
||||||
MDbuf[4] = MDbuf[0] + bb + ccc;
|
|
||||||
MDbuf[0] = ddd;
|
|
||||||
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
|
|
||||||
/********************************************************************/
|
|
||||||
|
|
||||||
void MDfinish(dword *MDbuf, byte *strptr, dword lswlen, dword mswlen)
|
|
||||||
{
|
|
||||||
unsigned int i; /* counter */
|
|
||||||
dword X[16]; /* message words */
|
|
||||||
|
|
||||||
memset(X, 0, 16*sizeof(dword));
|
|
||||||
|
|
||||||
/* put bytes from strptr into X */
|
|
||||||
for (i=0; i<(lswlen&63); i++) {
|
|
||||||
/* byte i goes into word X[i div 4] at pos. 8*(i mod 4) */
|
|
||||||
X[i>>2] ^= (dword) *strptr++ << (8 * (i&3));
|
|
||||||
}
|
|
||||||
|
|
||||||
/* append the bit m_n == 1 */
|
|
||||||
X[(lswlen>>2)&15] ^= (dword)1 << (8*(lswlen&3) + 7);
|
|
||||||
|
|
||||||
if ((lswlen & 63) > 55) {
|
|
||||||
/* length goes to next block */
|
|
||||||
compress(MDbuf, X);
|
|
||||||
memset(X, 0, 16*sizeof(dword));
|
|
||||||
}
|
|
||||||
|
|
||||||
/* append length in bits*/
|
|
||||||
X[14] = lswlen << 3;
|
|
||||||
X[15] = (lswlen >> 29) | (mswlen << 3);
|
|
||||||
compress(MDbuf, X);
|
|
||||||
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
|
|
||||||
/************************ end of file rmd160.c **********************/
|
|
||||||
|
|
||||||
@@ -1,154 +0,0 @@
|
|||||||
/********************************************************************\
|
|
||||||
*
|
|
||||||
* FILE: rmd160.h
|
|
||||||
*
|
|
||||||
* CONTENTS: Header file for a sample C-implementation of the
|
|
||||||
* RIPEMD-160 hash-function.
|
|
||||||
* TARGET: any computer with an ANSI C compiler
|
|
||||||
*
|
|
||||||
* AUTHOR: Antoon Bosselaers, ESAT-COSIC
|
|
||||||
* DATE: 1 March 1996
|
|
||||||
* VERSION: 1.0
|
|
||||||
*
|
|
||||||
* Copyright (c) Katholieke Universiteit Leuven
|
|
||||||
* 1996, All Rights Reserved
|
|
||||||
*
|
|
||||||
* Conditions for use of the RIPEMD-160 Software
|
|
||||||
*
|
|
||||||
* The RIPEMD-160 software is freely available for use under the terms and
|
|
||||||
* conditions described hereunder, which shall be deemed to be accepted by
|
|
||||||
* any user of the software and applicable on any use of the software:
|
|
||||||
*
|
|
||||||
* 1. K.U.Leuven Department of Electrical Engineering-ESAT/COSIC shall for
|
|
||||||
* all purposes be considered the owner of the RIPEMD-160 software and of
|
|
||||||
* all copyright, trade secret, patent or other intellectual property
|
|
||||||
* rights therein.
|
|
||||||
* 2. The RIPEMD-160 software is provided on an "as is" basis without
|
|
||||||
* warranty of any sort, express or implied. K.U.Leuven makes no
|
|
||||||
* representation that the use of the software will not infringe any
|
|
||||||
* patent or proprietary right of third parties. User will indemnify
|
|
||||||
* K.U.Leuven and hold K.U.Leuven harmless from any claims or liabilities
|
|
||||||
* which may arise as a result of its use of the software. In no
|
|
||||||
* circumstances K.U.Leuven R&D will be held liable for any deficiency,
|
|
||||||
* fault or other mishappening with regard to the use or performance of
|
|
||||||
* the software.
|
|
||||||
* 3. User agrees to give due credit to K.U.Leuven in scientific publications
|
|
||||||
* or communications in relation with the use of the RIPEMD-160 software
|
|
||||||
* as follows: RIPEMD-160 software written by Antoon Bosselaers,
|
|
||||||
* available at http://www.esat.kuleuven.be/~cosicart/ps/AB-9601/.
|
|
||||||
*
|
|
||||||
\********************************************************************/
|
|
||||||
|
|
||||||
#ifndef RMD160H /* make sure this file is read only once */
|
|
||||||
#define RMD160H
|
|
||||||
|
|
||||||
/********************************************************************/
|
|
||||||
|
|
||||||
/* typedef 8 and 32 bit types, resp. */
|
|
||||||
/* adapt these, if necessary,
|
|
||||||
for your operating system and compiler */
|
|
||||||
typedef unsigned char byte;
|
|
||||||
typedef unsigned long dword;
|
|
||||||
|
|
||||||
|
|
||||||
/********************************************************************/
|
|
||||||
|
|
||||||
/* macro definitions */
|
|
||||||
|
|
||||||
/* collect four bytes into one word: */
|
|
||||||
#define BYTES_TO_DWORD(strptr) \
|
|
||||||
(((dword) *((strptr)+3) << 24) | \
|
|
||||||
((dword) *((strptr)+2) << 16) | \
|
|
||||||
((dword) *((strptr)+1) << 8) | \
|
|
||||||
((dword) *(strptr)))
|
|
||||||
|
|
||||||
/* ROL(x, n) cyclically rotates x over n bits to the left */
|
|
||||||
/* x must be of an unsigned 32 bits type and 0 <= n < 32. */
|
|
||||||
#define ROL(x, n) (((x) << (n)) | ((x) >> (32-(n))))
|
|
||||||
|
|
||||||
/* the five basic functions F(), G() and H() */
|
|
||||||
#define F(x, y, z) ((x) ^ (y) ^ (z))
|
|
||||||
#define G(x, y, z) (((x) & (y)) | (~(x) & (z)))
|
|
||||||
#define H(x, y, z) (((x) | ~(y)) ^ (z))
|
|
||||||
#define I(x, y, z) (((x) & (z)) | ((y) & ~(z)))
|
|
||||||
#define J(x, y, z) ((x) ^ ((y) | ~(z)))
|
|
||||||
|
|
||||||
/* the ten basic operations FF() through III() */
|
|
||||||
#define FF(a, b, c, d, e, x, s) {\
|
|
||||||
(a) += F((b), (c), (d)) + (x);\
|
|
||||||
(a) = ROL((a), (s)) + (e);\
|
|
||||||
(c) = ROL((c), 10);\
|
|
||||||
}
|
|
||||||
#define GG(a, b, c, d, e, x, s) {\
|
|
||||||
(a) += G((b), (c), (d)) + (x) + 0x5a827999UL;\
|
|
||||||
(a) = ROL((a), (s)) + (e);\
|
|
||||||
(c) = ROL((c), 10);\
|
|
||||||
}
|
|
||||||
#define HH(a, b, c, d, e, x, s) {\
|
|
||||||
(a) += H((b), (c), (d)) + (x) + 0x6ed9eba1UL;\
|
|
||||||
(a) = ROL((a), (s)) + (e);\
|
|
||||||
(c) = ROL((c), 10);\
|
|
||||||
}
|
|
||||||
#define II(a, b, c, d, e, x, s) {\
|
|
||||||
(a) += I((b), (c), (d)) + (x) + 0x8f1bbcdcUL;\
|
|
||||||
(a) = ROL((a), (s)) + (e);\
|
|
||||||
(c) = ROL((c), 10);\
|
|
||||||
}
|
|
||||||
#define JJ(a, b, c, d, e, x, s) {\
|
|
||||||
(a) += J((b), (c), (d)) + (x) + 0xa953fd4eUL;\
|
|
||||||
(a) = ROL((a), (s)) + (e);\
|
|
||||||
(c) = ROL((c), 10);\
|
|
||||||
}
|
|
||||||
#define FFF(a, b, c, d, e, x, s) {\
|
|
||||||
(a) += F((b), (c), (d)) + (x);\
|
|
||||||
(a) = ROL((a), (s)) + (e);\
|
|
||||||
(c) = ROL((c), 10);\
|
|
||||||
}
|
|
||||||
#define GGG(a, b, c, d, e, x, s) {\
|
|
||||||
(a) += G((b), (c), (d)) + (x) + 0x7a6d76e9UL;\
|
|
||||||
(a) = ROL((a), (s)) + (e);\
|
|
||||||
(c) = ROL((c), 10);\
|
|
||||||
}
|
|
||||||
#define HHH(a, b, c, d, e, x, s) {\
|
|
||||||
(a) += H((b), (c), (d)) + (x) + 0x6d703ef3UL;\
|
|
||||||
(a) = ROL((a), (s)) + (e);\
|
|
||||||
(c) = ROL((c), 10);\
|
|
||||||
}
|
|
||||||
#define III(a, b, c, d, e, x, s) {\
|
|
||||||
(a) += I((b), (c), (d)) + (x) + 0x5c4dd124UL;\
|
|
||||||
(a) = ROL((a), (s)) + (e);\
|
|
||||||
(c) = ROL((c), 10);\
|
|
||||||
}
|
|
||||||
#define JJJ(a, b, c, d, e, x, s) {\
|
|
||||||
(a) += J((b), (c), (d)) + (x) + 0x50a28be6UL;\
|
|
||||||
(a) = ROL((a), (s)) + (e);\
|
|
||||||
(c) = ROL((c), 10);\
|
|
||||||
}
|
|
||||||
|
|
||||||
/********************************************************************/
|
|
||||||
|
|
||||||
/* function prototypes */
|
|
||||||
|
|
||||||
void MDinit(dword *MDbuf);
|
|
||||||
/*
|
|
||||||
* initializes MDbuffer to "magic constants"
|
|
||||||
*/
|
|
||||||
|
|
||||||
void compress(dword *MDbuf, dword *X);
|
|
||||||
/*
|
|
||||||
* the compression function.
|
|
||||||
* transforms MDbuf using message bytes X[0] through X[15]
|
|
||||||
*/
|
|
||||||
|
|
||||||
void MDfinish(dword *MDbuf, byte *strptr, dword lswlen, dword mswlen);
|
|
||||||
/*
|
|
||||||
* puts bytes from strptr into X and pad out; appends length
|
|
||||||
* and finally, compresses the last block(s)
|
|
||||||
* note: length in bits == 8 * (lswlen + 2^32 mswlen).
|
|
||||||
* note: there are (lswlen mod 64) bytes left in strptr.
|
|
||||||
*/
|
|
||||||
|
|
||||||
#endif /* RMD160H */
|
|
||||||
|
|
||||||
/*********************** end of file rmd160.h ***********************/
|
|
||||||
|
|
||||||
@@ -1,95 +0,0 @@
|
|||||||
#include <stdio.h>
|
|
||||||
#include <stdlib.h>
|
|
||||||
#include <string.h>
|
|
||||||
#include "libsys.h"
|
|
||||||
|
|
||||||
#include "rmd160.h"
|
|
||||||
|
|
||||||
#ifndef RMDsize
|
|
||||||
#define RMDsize 160
|
|
||||||
#endif
|
|
||||||
|
|
||||||
byte *RMD(byte *message)
|
|
||||||
/*
|
|
||||||
* returns RMD(message)
|
|
||||||
* message should be a string terminated by '\0'
|
|
||||||
*/
|
|
||||||
{
|
|
||||||
dword MDbuf[RMDsize/32]; /* contains (A, B, C, D(, E)) */
|
|
||||||
static byte hashcode[RMDsize/8]; /* for final hash-value */
|
|
||||||
dword X[16]; /* current 16-word chunk */
|
|
||||||
unsigned int i; /* counter */
|
|
||||||
dword length; /* length in bytes of message */
|
|
||||||
dword nbytes; /* # of bytes not yet processed */
|
|
||||||
|
|
||||||
/* initialize */
|
|
||||||
MDinit(MDbuf);
|
|
||||||
length = (dword)strlen((char *)message);
|
|
||||||
|
|
||||||
/* process message in 16-word chunks */
|
|
||||||
for (nbytes=length; nbytes > 63; nbytes-=64) {
|
|
||||||
for (i=0; i<16; i++) {
|
|
||||||
X[i] = BYTES_TO_DWORD(message);
|
|
||||||
message += 4;
|
|
||||||
}
|
|
||||||
compress(MDbuf, X);
|
|
||||||
} /* length mod 64 bytes left */
|
|
||||||
|
|
||||||
/* finish: */
|
|
||||||
MDfinish(MDbuf, message, length, 0);
|
|
||||||
|
|
||||||
for (i=0; i<RMDsize/8; i+=4) {
|
|
||||||
hashcode[i] = MDbuf[i>>2]; /* implicit cast to byte */
|
|
||||||
hashcode[i+1] = (MDbuf[i>>2] >> 8); /* extracts the 8 least */
|
|
||||||
hashcode[i+2] = (MDbuf[i>>2] >> 16); /* significant bits. */
|
|
||||||
hashcode[i+3] = (MDbuf[i>>2] >> 24);
|
|
||||||
}
|
|
||||||
|
|
||||||
return (byte *)hashcode;
|
|
||||||
}
|
|
||||||
|
|
||||||
#define MSG_SIZE 1024*1024 // Bit
|
|
||||||
int main (void)
|
|
||||||
{
|
|
||||||
int result, i, j, cnt;
|
|
||||||
byte *hashcode;
|
|
||||||
byte hashref[] = {0xFC,0x20,0x7B,0x84,0x40,0x1C,0x49,0x0B,0x8D,0x69,0x88,0xD2,0x49,0x20,0x01,0x90,0x41,0x77,0x72,0x59};
|
|
||||||
volatile int *pLED = (int*)sys_led_port;
|
|
||||||
char msg[MSG_SIZE/8];
|
|
||||||
char crlf[] = "\n";
|
|
||||||
UINT32 start, stop;
|
|
||||||
|
|
||||||
for (i=0; i < MSG_SIZE/8; i++)
|
|
||||||
msg[i] = 0x55;
|
|
||||||
|
|
||||||
msg[i] = 0;
|
|
||||||
|
|
||||||
setbuf(stdout, NULL);
|
|
||||||
|
|
||||||
cnt = 0;
|
|
||||||
start = clock();
|
|
||||||
stop = start + 1000;
|
|
||||||
while(1)
|
|
||||||
{
|
|
||||||
hashcode = RMD((byte *)msg);
|
|
||||||
start = clock();
|
|
||||||
if (memcmp(hashcode, hashref, sizeof(hashref)))
|
|
||||||
{
|
|
||||||
printf("Error RipeMD-160!\n");
|
|
||||||
return 1;
|
|
||||||
}
|
|
||||||
if (start >= stop)
|
|
||||||
{
|
|
||||||
for (i=0; i<RMDsize/8; i++)
|
|
||||||
printf("%2.2X", hashcode[i]);
|
|
||||||
printf("\n%d Hashes/s of %d Mbit message => %d Mbit/s\n\n", cnt, MSG_SIZE/(1024*1024), cnt*MSG_SIZE/(1024*1024));
|
|
||||||
start = clock();
|
|
||||||
stop = start + 1000;
|
|
||||||
cnt = 0;
|
|
||||||
}
|
|
||||||
cnt++;
|
|
||||||
}
|
|
||||||
|
|
||||||
return 0;
|
|
||||||
}
|
|
||||||
|
|
||||||
File diff suppressed because it is too large
Load Diff
@@ -1,15 +0,0 @@
|
|||||||
.file "startup.S"
|
|
||||||
|
|
||||||
.section .etext,"ax"
|
|
||||||
.extern _init
|
|
||||||
.align 2
|
|
||||||
.globl _start
|
|
||||||
_start:
|
|
||||||
.set noreorder
|
|
||||||
|
|
||||||
# jump init
|
|
||||||
la $8, _init
|
|
||||||
jr $8
|
|
||||||
nop
|
|
||||||
|
|
||||||
.set reorder
|
|
||||||
@@ -1,94 +0,0 @@
|
|||||||
/************************************************************************/
|
|
||||||
/* */
|
|
||||||
/* AMD CFI Enabled Flash Memory Drivers */
|
|
||||||
/* File name: CFIDRIVE.C */
|
|
||||||
/* Revision: 1.0 5/07/98 */
|
|
||||||
/* */
|
|
||||||
/* Copyright (c) 1998 ADVANCED MICRO DEVICES, INC. All Rights Reserved. */
|
|
||||||
/* This software is unpublished and contains the trade secrets and */
|
|
||||||
/* confidential proprietary information of AMD. Unless otherwise */
|
|
||||||
/* provided in the Software Agreement associated herewith, it is */
|
|
||||||
/* licensed in confidence "AS IS" and is not to be reproduced in whole */
|
|
||||||
/* or part by any means except for backup. Use, duplication, or */
|
|
||||||
/* disclosure by the Government is subject to the restrictions in */
|
|
||||||
/* paragraph (b) (3) (B) of the Rights in Technical Data and Computer */
|
|
||||||
/* Software clause in DFAR 52.227-7013 (a) (Oct 1988). */
|
|
||||||
/* Software owned by */
|
|
||||||
/* Advanced Micro Devices, Inc., */
|
|
||||||
/* One AMD Place, */
|
|
||||||
/* P.O. Box 3453 */
|
|
||||||
/* Sunnyvale, CA 94088-3453. */
|
|
||||||
/************************************************************************/
|
|
||||||
/* This software constitutes a basic shell of source code for */
|
|
||||||
/* programming all AMD Flash components. AMD */
|
|
||||||
/* will not be responsible for misuse or illegal use of this */
|
|
||||||
/* software for devices not supported herein. AMD is providing */
|
|
||||||
/* this source code "AS IS" and will not be responsible for */
|
|
||||||
/* issues arising from incorrect user implementation of the */
|
|
||||||
/* source code herein. It is the user's responsibility to */
|
|
||||||
/* properly design-in this source code. */
|
|
||||||
/* */
|
|
||||||
/************************************************************************/
|
|
||||||
|
|
||||||
#include <stdio.h>
|
|
||||||
#include <stdlib.h>
|
|
||||||
#include "cfiflash.h"
|
|
||||||
#include "libsys.h"
|
|
||||||
|
|
||||||
#define TEST_SIZE (1024*1024)
|
|
||||||
#define FLASH_OFFSET 0x700000
|
|
||||||
int main(void)
|
|
||||||
{
|
|
||||||
int i;
|
|
||||||
flash_t flash;
|
|
||||||
UINT8 *pFlash = (UINT8*)0xA4000000;
|
|
||||||
UINT32 result;
|
|
||||||
UINT8 *pBuf;
|
|
||||||
|
|
||||||
setbuf(stdout, NULL);
|
|
||||||
result = flash_find(&flash, 0xA4000000);
|
|
||||||
|
|
||||||
if (result < 0)
|
|
||||||
{
|
|
||||||
printf("flash_find() error!\n");
|
|
||||||
return 1;
|
|
||||||
}
|
|
||||||
|
|
||||||
printf("Found Flash at %8.8X\n", (UINT32)flash.pBase);
|
|
||||||
|
|
||||||
pBuf = (UINT8*)malloc(TEST_SIZE);
|
|
||||||
|
|
||||||
for (i=0; i < TEST_SIZE; i++)
|
|
||||||
pBuf[i] = i;
|
|
||||||
|
|
||||||
printf("Flash erase from %8.8X to %8.8X...", FLASH_OFFSET, FLASH_OFFSET+TEST_SIZE);
|
|
||||||
result = flash_erase(&flash, FLASH_OFFSET, TEST_SIZE);
|
|
||||||
if (result < 0)
|
|
||||||
{
|
|
||||||
printf("error!\n");
|
|
||||||
return 1;
|
|
||||||
}
|
|
||||||
printf("OK\n");
|
|
||||||
|
|
||||||
printf("Flash program from %8.8X to %8.8X...", FLASH_OFFSET, FLASH_OFFSET+TEST_SIZE);
|
|
||||||
result = flash_program(&flash, FLASH_OFFSET, pBuf, TEST_SIZE);
|
|
||||||
if (result < 0)
|
|
||||||
{
|
|
||||||
printf("error!\n");
|
|
||||||
return 1;
|
|
||||||
}
|
|
||||||
printf("OK\n");
|
|
||||||
|
|
||||||
printf("Flash verify from %8.8X to %8.8X...", FLASH_OFFSET, FLASH_OFFSET+TEST_SIZE);
|
|
||||||
result = flash_verify(&flash, FLASH_OFFSET, pBuf, TEST_SIZE);
|
|
||||||
if (result < 0)
|
|
||||||
{
|
|
||||||
printf("error!\n");
|
|
||||||
return 1;
|
|
||||||
}
|
|
||||||
printf("OK\n");
|
|
||||||
|
|
||||||
// PrintBuffer8((UINT8*)pFlash, 16, TEST_SIZE);
|
|
||||||
|
|
||||||
return 0;
|
|
||||||
}
|
|
||||||
@@ -1,124 +0,0 @@
|
|||||||
#include <stdio.h>
|
|
||||||
#include <stdlib.h>
|
|
||||||
#include <string.h>
|
|
||||||
#include "irq.h"
|
|
||||||
#include "libsys.h"
|
|
||||||
|
|
||||||
char buffer[16384];
|
|
||||||
char * volatile pPtr_r;
|
|
||||||
char * volatile pPtr_w;
|
|
||||||
|
|
||||||
void handler0(void)
|
|
||||||
{
|
|
||||||
printf("Interrupt 0\n");
|
|
||||||
interrupt_clr(0);
|
|
||||||
}
|
|
||||||
|
|
||||||
void handler1(void)
|
|
||||||
{
|
|
||||||
printf("Interrupt 1\n");
|
|
||||||
interrupt_clr(1);
|
|
||||||
}
|
|
||||||
|
|
||||||
void handler2(void)
|
|
||||||
{
|
|
||||||
printf("Interrupt 2\n");
|
|
||||||
}
|
|
||||||
|
|
||||||
void handler3(void)
|
|
||||||
{
|
|
||||||
volatile char *pUART_stat = (char*)sys_uart_stat;
|
|
||||||
volatile char *pUART_data = (char*)sys_uart_data;
|
|
||||||
|
|
||||||
while((0x10 & *pUART_stat))
|
|
||||||
{
|
|
||||||
// sputs("w: "); print_word((int)pPtr_w); sputs("\n");
|
|
||||||
if (pPtr_w == &buffer[16383])
|
|
||||||
pPtr_w = buffer;
|
|
||||||
*(pPtr_w++) = *pUART_data;
|
|
||||||
}
|
|
||||||
|
|
||||||
}
|
|
||||||
|
|
||||||
void handler4(void)
|
|
||||||
{
|
|
||||||
printf("Interrupt 4\n");
|
|
||||||
}
|
|
||||||
|
|
||||||
void handler5(void)
|
|
||||||
{
|
|
||||||
printf("Interrupt 5\n");
|
|
||||||
}
|
|
||||||
|
|
||||||
void handler6(void)
|
|
||||||
{
|
|
||||||
printf("Interrupt 6\n");
|
|
||||||
}
|
|
||||||
|
|
||||||
void handler7(void)
|
|
||||||
{
|
|
||||||
printf("Interrupt 7\n");
|
|
||||||
}
|
|
||||||
|
|
||||||
int main(void)
|
|
||||||
{
|
|
||||||
|
|
||||||
printf("Hello\n");
|
|
||||||
memset(buffer, 0, sizeof(buffer));
|
|
||||||
pPtr_r = buffer;
|
|
||||||
pPtr_w = buffer;
|
|
||||||
interrupt_register(0, handler0);
|
|
||||||
interrupt_enable(0);
|
|
||||||
|
|
||||||
interrupt_register(1, handler1);
|
|
||||||
interrupt_enable(1);
|
|
||||||
|
|
||||||
interrupt_register(2, handler2);
|
|
||||||
interrupt_enable(2);
|
|
||||||
|
|
||||||
interrupt_register(3, handler3);
|
|
||||||
interrupt_enable(3);
|
|
||||||
|
|
||||||
interrupt_register(4, handler4);
|
|
||||||
// interrupt_enable(4);
|
|
||||||
|
|
||||||
interrupt_register(5, handler5);
|
|
||||||
interrupt_enable(5);
|
|
||||||
|
|
||||||
interrupt_register(6, handler6);
|
|
||||||
interrupt_enable(6);
|
|
||||||
|
|
||||||
interrupt_register(7, handler7);
|
|
||||||
interrupt_enable(7);
|
|
||||||
|
|
||||||
printf("Start:\n");
|
|
||||||
|
|
||||||
interrupt_set(0);
|
|
||||||
interrupt_set(1);
|
|
||||||
interrupt_set(2);
|
|
||||||
interrupt_set(3);
|
|
||||||
interrupt_set(4);
|
|
||||||
interrupt_set(5);
|
|
||||||
interrupt_set(6);
|
|
||||||
interrupt_set(7);
|
|
||||||
|
|
||||||
sputs("r: "); print_word((int)pPtr_r); sputs("\n");
|
|
||||||
sputs("w: "); print_word((int)pPtr_w); sputs("\n");
|
|
||||||
|
|
||||||
// Print Status register
|
|
||||||
sputs("Status : ");
|
|
||||||
print_word(CP0_SR_read());
|
|
||||||
sputs("\n");
|
|
||||||
|
|
||||||
while(1)
|
|
||||||
{
|
|
||||||
if(pPtr_w != pPtr_r)
|
|
||||||
{
|
|
||||||
// sputs("r: "); print_word((int)pPtr_r); sputs("\n");
|
|
||||||
if (pPtr_r == &buffer[16383])
|
|
||||||
pPtr_r = buffer;
|
|
||||||
writechar(*(pPtr_r++));
|
|
||||||
}
|
|
||||||
}
|
|
||||||
return 0;
|
|
||||||
}
|
|
||||||
@@ -1,594 +0,0 @@
|
|||||||
#include <stdio.h>
|
|
||||||
#include <stdlib.h>
|
|
||||||
#include <string.h>
|
|
||||||
#include <math.h>
|
|
||||||
#include <time.h>
|
|
||||||
#include "libsys.h"
|
|
||||||
|
|
||||||
#define NO_ERROR 0x00000000
|
|
||||||
#define ERROR 0x80000000
|
|
||||||
#define IS_ERROR(e) ((e & ERROR) == ERROR)
|
|
||||||
|
|
||||||
#define TEST10_ERROR (ERROR | 0x10)
|
|
||||||
#define TEST11_ERROR (ERROR | 0x11)
|
|
||||||
#define TEST12_ERROR (ERROR | 0x12)
|
|
||||||
|
|
||||||
char buffer[16384];
|
|
||||||
int i;
|
|
||||||
|
|
||||||
extern int paranoia(int argc, char **argv);
|
|
||||||
|
|
||||||
void handler3(void)
|
|
||||||
{
|
|
||||||
volatile UINT32 *pUART_stat = (UINT32*)sys_uart_stat;
|
|
||||||
volatile UINT32 *pUART_data = (UINT32*)sys_uart_data;
|
|
||||||
|
|
||||||
while((0x10 & *pUART_stat))
|
|
||||||
{
|
|
||||||
buffer[i] = (char)*pUART_data;
|
|
||||||
i = (i+1)%sizeof(buffer);
|
|
||||||
}
|
|
||||||
|
|
||||||
}
|
|
||||||
|
|
||||||
int fibonacci(int f0, int f1, int *pDst, int len)
|
|
||||||
{
|
|
||||||
int i;
|
|
||||||
|
|
||||||
i = 0;
|
|
||||||
|
|
||||||
pDst[i++] = f0;
|
|
||||||
pDst[i++] = f1;
|
|
||||||
|
|
||||||
for (; i < len; i++)
|
|
||||||
{
|
|
||||||
pDst[i] = pDst[i-2] + pDst[i-1];
|
|
||||||
}
|
|
||||||
|
|
||||||
return i;
|
|
||||||
}
|
|
||||||
|
|
||||||
void PrintCPUinfo(void)
|
|
||||||
{
|
|
||||||
int result, rev_id;
|
|
||||||
|
|
||||||
char *cpu_type_str[7] = {"invalid", "R2000", "R3000", "R6000", "R4000", "reserved", "R6000A"};
|
|
||||||
|
|
||||||
// Print Status register
|
|
||||||
result = CP0_SR_read();
|
|
||||||
|
|
||||||
printf("Status : %8.8X\n", result);
|
|
||||||
|
|
||||||
// Print Revision
|
|
||||||
result = CP0_PRID_read();
|
|
||||||
rev_id = (result >> 8) & 0xFF;
|
|
||||||
printf("CPU type: ");
|
|
||||||
if ((rev_id > 0) && (rev_id < 0x07))
|
|
||||||
{
|
|
||||||
printf(cpu_type_str[rev_id]);
|
|
||||||
printf(" Rev.");
|
|
||||||
rev_id = result & 0xFF;
|
|
||||||
printf("%d", rev_id);
|
|
||||||
}
|
|
||||||
else
|
|
||||||
printf("Unknown");
|
|
||||||
|
|
||||||
printf("\n");
|
|
||||||
|
|
||||||
}
|
|
||||||
|
|
||||||
int Test10_LoadStore()
|
|
||||||
{
|
|
||||||
int *buf, i, result, data, err;
|
|
||||||
volatile int *pPtr;
|
|
||||||
|
|
||||||
buf = (int*)malloc(32*sizeof(int));
|
|
||||||
// sputs("buf = ");
|
|
||||||
// print_word((int)buf);
|
|
||||||
// sputs("\n");
|
|
||||||
|
|
||||||
while(1)
|
|
||||||
{
|
|
||||||
err = TEST10_ERROR;
|
|
||||||
// Basic Load/Store
|
|
||||||
pPtr = buf;
|
|
||||||
*pPtr++ = 0x00000000;
|
|
||||||
*pPtr++ = 0x55555555;
|
|
||||||
*pPtr++ = 0xAAAAAAAA;
|
|
||||||
*pPtr++ = 0xFFFFFFFF;
|
|
||||||
pPtr = buf;
|
|
||||||
if (*pPtr++ != 0x00000000)
|
|
||||||
break;
|
|
||||||
if (*pPtr++ != 0x55555555)
|
|
||||||
break;
|
|
||||||
if (*pPtr++ != 0xAAAAAAAA)
|
|
||||||
break;
|
|
||||||
if (*pPtr++ != 0xFFFFFFFF)
|
|
||||||
break;
|
|
||||||
|
|
||||||
// Filling from left
|
|
||||||
pPtr = buf;
|
|
||||||
data = 0x00000000;
|
|
||||||
for (i=0; i < 32; i++)
|
|
||||||
{
|
|
||||||
*pPtr++ = data;
|
|
||||||
data = data >> 1 | 0x80000000;
|
|
||||||
|
|
||||||
}
|
|
||||||
pPtr = buf;
|
|
||||||
data = 0x00000000;
|
|
||||||
for (i=0; i < 32; i++)
|
|
||||||
{
|
|
||||||
|
|
||||||
if (*pPtr++ != data)
|
|
||||||
break;
|
|
||||||
|
|
||||||
data = data >> 1 | 0x80000000;
|
|
||||||
}
|
|
||||||
if (i != 32)
|
|
||||||
break;
|
|
||||||
|
|
||||||
// Filling from right
|
|
||||||
pPtr = buf;
|
|
||||||
data = 0x00000000;
|
|
||||||
for (i=0; i < 32; i++)
|
|
||||||
{
|
|
||||||
*pPtr++ = data;
|
|
||||||
data = data << 1 | 1;
|
|
||||||
|
|
||||||
}
|
|
||||||
pPtr = buf;
|
|
||||||
data = 0x00000000;
|
|
||||||
for (i=0; i < 32; i++)
|
|
||||||
{
|
|
||||||
|
|
||||||
if (*pPtr++ != data)
|
|
||||||
break;
|
|
||||||
|
|
||||||
data = data << 1 | 1;
|
|
||||||
}
|
|
||||||
if (i != 32)
|
|
||||||
break;
|
|
||||||
|
|
||||||
// Walking ones
|
|
||||||
pPtr = buf;
|
|
||||||
data = 0x00000001;
|
|
||||||
for (i=0; i < 32; i++)
|
|
||||||
{
|
|
||||||
*pPtr++ = data;
|
|
||||||
data = data << 1;
|
|
||||||
|
|
||||||
}
|
|
||||||
pPtr = buf;
|
|
||||||
data = 0x00000001;
|
|
||||||
for (i=0; i < 32; i++)
|
|
||||||
{
|
|
||||||
|
|
||||||
if (*pPtr++ != data)
|
|
||||||
break;
|
|
||||||
|
|
||||||
data = data << 1;
|
|
||||||
}
|
|
||||||
if (i != 32)
|
|
||||||
break;
|
|
||||||
|
|
||||||
// Walking zeros
|
|
||||||
pPtr = buf;
|
|
||||||
data = 0xFFFFFFFE;
|
|
||||||
for (i=0; i < 32; i++)
|
|
||||||
{
|
|
||||||
*pPtr++ = data;
|
|
||||||
data = data << 1 | 1;
|
|
||||||
|
|
||||||
}
|
|
||||||
pPtr = buf;
|
|
||||||
data = 0xFFFFFFFE;
|
|
||||||
for (i=0; i < 32; i++)
|
|
||||||
{
|
|
||||||
|
|
||||||
if (*pPtr++ != data)
|
|
||||||
break;
|
|
||||||
|
|
||||||
data = data << 1 | 1;
|
|
||||||
|
|
||||||
}
|
|
||||||
if (i != 32)
|
|
||||||
break;
|
|
||||||
|
|
||||||
err = NO_ERROR;
|
|
||||||
break;
|
|
||||||
}
|
|
||||||
free(buf);
|
|
||||||
return err;
|
|
||||||
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
#define NUM_ELEMENTS 100000
|
|
||||||
#define NUM_RUNS 3
|
|
||||||
int Test11_AddSub()
|
|
||||||
{
|
|
||||||
int buf[NUM_ELEMENTS], result, i, j, diff, fill, num_right_elements, num_right_runs;
|
|
||||||
|
|
||||||
fill = 0xAAAAAAAA;
|
|
||||||
|
|
||||||
num_right_runs = 0;
|
|
||||||
|
|
||||||
for (i=0; i < NUM_RUNS; i++)
|
|
||||||
{
|
|
||||||
for (j=0; j < NUM_ELEMENTS; j++)
|
|
||||||
{
|
|
||||||
buf[j] = fill;
|
|
||||||
fill = ((fill ^ j) - 1) << 1;
|
|
||||||
}
|
|
||||||
num_right_elements = 2;
|
|
||||||
result = fibonacci(i, i+1, buf, NUM_ELEMENTS);
|
|
||||||
for (j=2; j < NUM_ELEMENTS; j++)
|
|
||||||
{
|
|
||||||
diff = buf[j] - buf[j-1];
|
|
||||||
if (diff == buf[j-2])
|
|
||||||
num_right_elements++;
|
|
||||||
}
|
|
||||||
if (num_right_elements == NUM_ELEMENTS)
|
|
||||||
num_right_runs++;
|
|
||||||
|
|
||||||
}
|
|
||||||
|
|
||||||
if (num_right_runs != NUM_RUNS)
|
|
||||||
return TEST11_ERROR;
|
|
||||||
|
|
||||||
return NO_ERROR;
|
|
||||||
}
|
|
||||||
|
|
||||||
int Test12_MulDiv()
|
|
||||||
{
|
|
||||||
int mix, i, j;
|
|
||||||
int s1, s2, sp, st;
|
|
||||||
div_t div_res;
|
|
||||||
|
|
||||||
srand(0x19701031);
|
|
||||||
for (i=0; i < 100; i++)
|
|
||||||
{
|
|
||||||
for (j=1; j < 100; j++)
|
|
||||||
{
|
|
||||||
mix = (int)rand();
|
|
||||||
mix = (mix << 8) ^ (mix << 16);
|
|
||||||
s1 = (int)rand() ^ mix;
|
|
||||||
mix = (int)rand();
|
|
||||||
mix = (mix << 8) ^ (mix << 16);
|
|
||||||
s2 = (int)rand() ^ mix;
|
|
||||||
|
|
||||||
div_res = div(s1, s2);
|
|
||||||
|
|
||||||
sp = s2*div_res.quot;
|
|
||||||
st = div_res.rem + sp;
|
|
||||||
if (st != s1)
|
|
||||||
return TEST12_ERROR;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
return NO_ERROR;
|
|
||||||
}
|
|
||||||
|
|
||||||
#define PI_SCALE 10000
|
|
||||||
#define PI_MAXARR 2800
|
|
||||||
#define PI_ARRINIT 2000
|
|
||||||
|
|
||||||
int pi_calc()
|
|
||||||
{
|
|
||||||
int i, j;
|
|
||||||
int carry = 0;
|
|
||||||
int arr[PI_MAXARR+1];
|
|
||||||
|
|
||||||
// setbuf(stdout, NULL);
|
|
||||||
|
|
||||||
for (i = 0; i <= PI_MAXARR; ++i)
|
|
||||||
arr[i] = PI_ARRINIT;
|
|
||||||
for (i = PI_MAXARR; i; i -= 14)
|
|
||||||
{
|
|
||||||
int sum = 0;
|
|
||||||
for (j = i; j > 0; --j)
|
|
||||||
{
|
|
||||||
sum = sum*j + PI_SCALE*arr[j];
|
|
||||||
arr[j] = sum % (j*2-1);
|
|
||||||
sum /= (j*2-1);
|
|
||||||
}
|
|
||||||
printf("%04d", carry + sum/PI_SCALE);
|
|
||||||
carry = sum % PI_SCALE;
|
|
||||||
}
|
|
||||||
printf("\n");
|
|
||||||
return 0;
|
|
||||||
}
|
|
||||||
|
|
||||||
#define TEST_SIZE (32*1024*1024) // Bytes
|
|
||||||
#define SMALL_TEST_SIZE (8192) // Bytes
|
|
||||||
int main (void)
|
|
||||||
{
|
|
||||||
int result, i, j, cnt;
|
|
||||||
volatile UINT32 *pUART_baud = (UINT32*)sys_uart_baud;
|
|
||||||
volatile UINT32 *pReg = (UINT32*)sys_led_port;
|
|
||||||
volatile UINT32 *pReg_usec = (UINT32*)sys_timer_usec;
|
|
||||||
volatile UINT32 *pReg_sec = (UINT32*)sys_timer_sec;
|
|
||||||
volatile UINT32 *pSSRAM = (UINT32*)sys_ssram_io;
|
|
||||||
time_t curr_date;
|
|
||||||
struct tm *pDate, date;
|
|
||||||
UINT32 start, end;
|
|
||||||
char sel;
|
|
||||||
|
|
||||||
UINT8 *ram8 = NULL;
|
|
||||||
UINT16 *ram16 = NULL;
|
|
||||||
UINT32 *ram32 = NULL;
|
|
||||||
|
|
||||||
UINT32 *pSrc32, *pDst32;
|
|
||||||
|
|
||||||
// *pUART_baud = 1;
|
|
||||||
|
|
||||||
setbuf(stdout, NULL);
|
|
||||||
PrintCPUinfo();
|
|
||||||
|
|
||||||
i = 0;
|
|
||||||
memset(buffer, 0, sizeof(buffer));
|
|
||||||
interrupt_register(3, handler3);
|
|
||||||
|
|
||||||
// ----------------------------------------------------------
|
|
||||||
// Memtest BEGIN
|
|
||||||
/* printf("SSRAM Memory Test\r\n");
|
|
||||||
printf("Small data test\r\n");
|
|
||||||
printf("Write (32-Bit access)...");
|
|
||||||
start = clock();
|
|
||||||
for (j=0; j < TEST_SIZE/SMALL_TEST_SIZE; j++)
|
|
||||||
for (i=0; i < SMALL_TEST_SIZE/4; i++)
|
|
||||||
pSSRAM[i] = (UINT32)i;
|
|
||||||
|
|
||||||
end = clock();
|
|
||||||
printf("done (%.2f MByte/s)\n", (double)TEST_SIZE/(1000*(end-start)));
|
|
||||||
|
|
||||||
PrintBuffer8((UINT8*)pSSRAM, 16, 256);
|
|
||||||
|
|
||||||
printf("Verify (32-Bit access)...");
|
|
||||||
start = clock();
|
|
||||||
for (j=0; j < TEST_SIZE/SMALL_TEST_SIZE; j++)
|
|
||||||
for (i=SMALL_TEST_SIZE/4-1; i >= 0; i--)
|
|
||||||
if (pSSRAM[i] != (UINT32)i)
|
|
||||||
break;
|
|
||||||
|
|
||||||
end = clock();
|
|
||||||
i++;
|
|
||||||
if (i)
|
|
||||||
printf("failed\r\n");
|
|
||||||
else
|
|
||||||
printf("passed (%.2f MByte/s)\n", (double)TEST_SIZE/(1000*(end-start)));
|
|
||||||
*/
|
|
||||||
// ----------------------------------------------------------
|
|
||||||
// Memtest BEGIN
|
|
||||||
printf("SDRAM Memory Test\n");
|
|
||||||
printf("Test size %d kByte\n\n", TEST_SIZE/1024);
|
|
||||||
|
|
||||||
ram8 = (UINT8*)calloc(TEST_SIZE,sizeof(UINT8));
|
|
||||||
printf("Zeroize Memory (memset)...");
|
|
||||||
start = clock();
|
|
||||||
memset(ram8, 0, TEST_SIZE);
|
|
||||||
end = clock();
|
|
||||||
printf("done (%.2f MByte/s)\n", (double)TEST_SIZE/(1000*(end-start)));
|
|
||||||
|
|
||||||
free(ram8);
|
|
||||||
|
|
||||||
ram8 = (UINT8*)calloc(TEST_SIZE,sizeof(UINT8));
|
|
||||||
printf("Zeroize Memory (8-Bit access)...");
|
|
||||||
start = clock();
|
|
||||||
for (i=0; i < TEST_SIZE; i++)
|
|
||||||
ram8[i] = (UINT8)0;
|
|
||||||
|
|
||||||
end = clock();
|
|
||||||
printf("done (%.2f MByte/s)\n", (double)TEST_SIZE/(1000*(end-start)));
|
|
||||||
|
|
||||||
free(ram8);
|
|
||||||
|
|
||||||
ram16 = (UINT16*)calloc(TEST_SIZE/2,sizeof(UINT16));
|
|
||||||
printf("Zeroize Memory (16-Bit access)...");
|
|
||||||
start = clock();
|
|
||||||
for (i=0; i < TEST_SIZE/2; i++)
|
|
||||||
ram16[i] = (UINT16)0;
|
|
||||||
|
|
||||||
end = clock();
|
|
||||||
printf("done (%.2f MByte/s)\n", (double)TEST_SIZE/(1000*(end-start)));
|
|
||||||
|
|
||||||
free(ram16);
|
|
||||||
|
|
||||||
ram32 = (UINT32*)calloc(TEST_SIZE/4,sizeof(UINT32));
|
|
||||||
printf("Zeroize Memory (32-Bit access)...");
|
|
||||||
start = clock();
|
|
||||||
for (i=0; i < TEST_SIZE/4; i++)
|
|
||||||
ram32[i] = (UINT32)0;
|
|
||||||
|
|
||||||
end = clock();
|
|
||||||
printf("done (%.2f MByte/s)\n", (double)TEST_SIZE/(1000*(end-start)));
|
|
||||||
|
|
||||||
free(ram32);
|
|
||||||
|
|
||||||
ram8 = (UINT8*)calloc(TEST_SIZE,sizeof(UINT8));
|
|
||||||
printf("Write (8-Bit access)...");
|
|
||||||
start = clock();
|
|
||||||
for (i=0; i < TEST_SIZE; i++)
|
|
||||||
ram8[i] = (UINT8)i;
|
|
||||||
|
|
||||||
end = clock();
|
|
||||||
printf("done (%.2f MByte/s)\n", (double)TEST_SIZE/(1000*(end-start)));
|
|
||||||
|
|
||||||
printf("Verify (8-Bit access)...");
|
|
||||||
start = clock();
|
|
||||||
for (i=TEST_SIZE-1; i >= 0; i--)
|
|
||||||
if (ram8[i] != (UINT8)i)
|
|
||||||
break;
|
|
||||||
|
|
||||||
end = clock();
|
|
||||||
i++;
|
|
||||||
if (i)
|
|
||||||
printf("failed\r\n");
|
|
||||||
else
|
|
||||||
printf("passed (%.2f MByte/s)\n", (double)TEST_SIZE/(1000*(end-start)));
|
|
||||||
|
|
||||||
free(ram8);
|
|
||||||
|
|
||||||
ram16 = (UINT16*)calloc(TEST_SIZE/2,sizeof(UINT16));
|
|
||||||
printf("Write (16-Bit access)...");
|
|
||||||
start = clock();
|
|
||||||
for (i=0; i < TEST_SIZE/2; i++)
|
|
||||||
ram16[i] = (UINT16)i;
|
|
||||||
|
|
||||||
end = clock();
|
|
||||||
printf("done (%.2f MByte/s)\n", (double)TEST_SIZE/(1000*(end-start)));
|
|
||||||
|
|
||||||
printf("Verify (16-Bit access)...");
|
|
||||||
start = clock();
|
|
||||||
for (i=TEST_SIZE/2-1; i >= 0; i--)
|
|
||||||
if (ram16[i] != (UINT16)i)
|
|
||||||
break;
|
|
||||||
|
|
||||||
end = clock();
|
|
||||||
i++;
|
|
||||||
if (i)
|
|
||||||
printf("failed\r\n");
|
|
||||||
else
|
|
||||||
printf("passed (%.2f MByte/s)\n", (double)TEST_SIZE/(1000*(end-start)));
|
|
||||||
|
|
||||||
free(ram16);
|
|
||||||
|
|
||||||
ram32 = (UINT32*)calloc(TEST_SIZE/4,sizeof(UINT32));
|
|
||||||
printf("Write (32-Bit access)...");
|
|
||||||
start = clock();
|
|
||||||
for (i=0; i < TEST_SIZE/4; i++)
|
|
||||||
ram32[i] = (UINT32)i;
|
|
||||||
|
|
||||||
end = clock();
|
|
||||||
printf("done (%.2f MByte/s)\n", (double)TEST_SIZE/(1000*(end-start)));
|
|
||||||
|
|
||||||
printf("Verify (32-Bit access)...");
|
|
||||||
start = clock();
|
|
||||||
for (i=TEST_SIZE/4-1; i >= 0; i--)
|
|
||||||
if (ram32[i] != (UINT32)i)
|
|
||||||
break;
|
|
||||||
|
|
||||||
end = clock();
|
|
||||||
i++;
|
|
||||||
if (i)
|
|
||||||
printf("failed\r\n");
|
|
||||||
else
|
|
||||||
printf("passed (%.2f MByte/s)\n", (double)TEST_SIZE/(1000*(end-start)));
|
|
||||||
|
|
||||||
free(ram32);
|
|
||||||
|
|
||||||
printf("Small data test\r\n");
|
|
||||||
printf("Test size %d kByte\n\n", SMALL_TEST_SIZE/1024);
|
|
||||||
printf("Write (32-Bit access)...");
|
|
||||||
ram32 = (UINT32*)calloc(SMALL_TEST_SIZE/4,sizeof(UINT32));
|
|
||||||
start = clock();
|
|
||||||
for (j=0; j < TEST_SIZE/SMALL_TEST_SIZE; j++)
|
|
||||||
for (i=0; i < SMALL_TEST_SIZE/4; i++)
|
|
||||||
ram32[i] = (UINT32)i;
|
|
||||||
|
|
||||||
end = clock();
|
|
||||||
printf("done (%.2f MByte/s)\n", (double)TEST_SIZE/(1000*(end-start)));
|
|
||||||
|
|
||||||
printf("Verify (32-Bit access)...");
|
|
||||||
start = clock();
|
|
||||||
for (j=0; j < TEST_SIZE/SMALL_TEST_SIZE; j++)
|
|
||||||
for (i=SMALL_TEST_SIZE/4-1; i >= 0; i--)
|
|
||||||
if (ram32[i] != (UINT32)i)
|
|
||||||
break;
|
|
||||||
|
|
||||||
end = clock();
|
|
||||||
i++;
|
|
||||||
if (i)
|
|
||||||
printf("failed\r\n");
|
|
||||||
else
|
|
||||||
printf("passed (%.2f MByte/s)\n", (double)TEST_SIZE/(1000*(end-start)));
|
|
||||||
|
|
||||||
free(ram32);
|
|
||||||
|
|
||||||
printf("Memcpy() Test \n");
|
|
||||||
pSrc32 = (UINT32*)calloc(TEST_SIZE/8,sizeof(UINT32));
|
|
||||||
pDst32 = (UINT32*)calloc(TEST_SIZE/8,sizeof(UINT32));
|
|
||||||
printf("Copying %d kBytes...", TEST_SIZE/(2*1024));
|
|
||||||
start = clock();
|
|
||||||
memcpy(pDst32, pSrc32, TEST_SIZE/2);
|
|
||||||
end = clock();
|
|
||||||
printf("done (%.2f MByte/s)\n", (double)TEST_SIZE/(2*1000*(end-start)));
|
|
||||||
|
|
||||||
free(pSrc32);
|
|
||||||
free(pDst32);
|
|
||||||
|
|
||||||
// Memtest END
|
|
||||||
// ----------------------------------------------------------
|
|
||||||
sputs("\r\n");
|
|
||||||
|
|
||||||
printf("Datum und Uhrzeit setzen? [j/N]: ");
|
|
||||||
scanf("%c", &sel);
|
|
||||||
if (toupper(sel) == 'J')
|
|
||||||
{
|
|
||||||
printf("Jahr : ");
|
|
||||||
scanf("%d", &date.tm_year);
|
|
||||||
printf("Monat : ");
|
|
||||||
scanf("%d", &date.tm_mon);
|
|
||||||
printf("Tag : ");
|
|
||||||
scanf("%d", &date.tm_mday);
|
|
||||||
|
|
||||||
printf("Wir haben heute den %d. %d. %d\n", date.tm_mday, date.tm_mon, date.tm_year);
|
|
||||||
}
|
|
||||||
|
|
||||||
interrupt_enable(3);
|
|
||||||
cnt = 0;
|
|
||||||
while (1)
|
|
||||||
{
|
|
||||||
*pReg = cnt & 0x3FFFFFFF;
|
|
||||||
|
|
||||||
printf("-------------------------------------------\n");
|
|
||||||
printf("-- LoadStore ------------------------------\n");
|
|
||||||
printf("-------------------------------------------\n");
|
|
||||||
result = Test10_LoadStore();
|
|
||||||
if (IS_ERROR(result))
|
|
||||||
break;
|
|
||||||
printf("passed\n\n");
|
|
||||||
|
|
||||||
printf("-------------------------------------------\n");
|
|
||||||
printf("-- AddSub ---------------------------------\n");
|
|
||||||
printf("-------------------------------------------\n");
|
|
||||||
result = Test11_AddSub();
|
|
||||||
if (IS_ERROR(result))
|
|
||||||
break;
|
|
||||||
printf("passed\n\n");
|
|
||||||
|
|
||||||
printf("-------------------------------------------\n");
|
|
||||||
printf("-- MulDiv ---------------------------------\n");
|
|
||||||
printf("-------------------------------------------\n");
|
|
||||||
result = Test12_MulDiv();
|
|
||||||
if (IS_ERROR(result))
|
|
||||||
break;
|
|
||||||
printf("passed\n\n");
|
|
||||||
|
|
||||||
printf("-------------------------------------------\n");
|
|
||||||
printf("-- Paranoia -------------------------------\n");
|
|
||||||
printf("-------------------------------------------\n");
|
|
||||||
paranoia(1, NULL);
|
|
||||||
printf("passed\n\n");
|
|
||||||
|
|
||||||
printf("-------------------------------------------\n");
|
|
||||||
printf("-- PI calc --------------------------------\n");
|
|
||||||
printf("-------------------------------------------\n");
|
|
||||||
pi_calc();
|
|
||||||
printf("passed\n\n");
|
|
||||||
|
|
||||||
printf("Iteration %d: Passed\n", cnt);
|
|
||||||
curr_date = time(NULL);
|
|
||||||
pDate = gmtime(&curr_date);
|
|
||||||
puts(asctime(pDate));
|
|
||||||
cnt++;
|
|
||||||
|
|
||||||
// printf("V=%.17e\n", pow((double)cnt-1, (double)cnt));
|
|
||||||
}
|
|
||||||
*pReg = 0x40000000 | cnt;
|
|
||||||
printf("Failed with error %8.8X\n", result);
|
|
||||||
|
|
||||||
return 1;
|
|
||||||
|
|
||||||
}
|
|
||||||
|
|
||||||
@@ -1,265 +0,0 @@
|
|||||||
/*
|
|
||||||
* @(#)whet.c 1.1
|
|
||||||
*/
|
|
||||||
|
|
||||||
/*
|
|
||||||
* Whetstone benchmark in C. This program is a translation of the
|
|
||||||
* original Algol version in "A Synthetic Benchmark" by H.J. Curnow
|
|
||||||
* and B.A. Wichman in Computer Journal, Vol 19 #1, February 1976.
|
|
||||||
*
|
|
||||||
* Used to test compiler optimization and floating point performance.
|
|
||||||
*/
|
|
||||||
|
|
||||||
/*
|
|
||||||
* Compile with -DMEASURE_TIME for time measurement.
|
|
||||||
*
|
|
||||||
* Compile with -DPOUT to print intermediate results.
|
|
||||||
* Running this benchmark without printing the intermediate results is
|
|
||||||
* contrary to the authors' intentions! But using serial I/O can draw back
|
|
||||||
* the performance extremely when low baud rate communication is used.
|
|
||||||
*/
|
|
||||||
#define MEASURE_TIME 1
|
|
||||||
//#define POUT 1
|
|
||||||
|
|
||||||
#define ITERATIONS 10 /* 10 Million Whetstone instructions */
|
|
||||||
|
|
||||||
#include <math.h>
|
|
||||||
#include <stdio.h>
|
|
||||||
|
|
||||||
#ifdef MEASURE_TIME
|
|
||||||
#include <time.h>
|
|
||||||
unsigned long Begin_Time,End_Time,Total_Time;
|
|
||||||
double whetstones;
|
|
||||||
#endif
|
|
||||||
|
|
||||||
#define Pout(n, j, k, x1, x2, x3, x4) pout(n, j, k, x1, x2, x3, x4);
|
|
||||||
|
|
||||||
double xx1, xx2, xx3, xx4, x, y, z, t, t1, t2;
|
|
||||||
double e1[4];
|
|
||||||
unsigned int i, j, k, l, n1, n2, n3, n4, n6, n7, n8, n9, n10, n11;
|
|
||||||
|
|
||||||
main()
|
|
||||||
{
|
|
||||||
printf("\nWhetstone Benchmark\n\n");
|
|
||||||
|
|
||||||
printf( "%d iterations\n", ITERATIONS );
|
|
||||||
|
|
||||||
#ifdef MEASURE_TIME
|
|
||||||
Begin_Time = clock();
|
|
||||||
#endif
|
|
||||||
|
|
||||||
/* initialize constants */
|
|
||||||
|
|
||||||
t = 0.499975;
|
|
||||||
t1 = 0.50025;
|
|
||||||
t2 = 2.0;
|
|
||||||
|
|
||||||
/* set values of module weights */
|
|
||||||
|
|
||||||
n1 = 0 * ITERATIONS;
|
|
||||||
n2 = 12 * ITERATIONS;
|
|
||||||
n3 = 14 * ITERATIONS;
|
|
||||||
n4 = 345 * ITERATIONS;
|
|
||||||
n6 = 210 * ITERATIONS;
|
|
||||||
n7 = 32 * ITERATIONS;
|
|
||||||
n8 = 899 * ITERATIONS;
|
|
||||||
n9 = 616 * ITERATIONS;
|
|
||||||
n10 = 0 * ITERATIONS;
|
|
||||||
n11 = 93 * ITERATIONS;
|
|
||||||
|
|
||||||
/* MODULE 1: simple identifiers */
|
|
||||||
|
|
||||||
xx1 = 1.0;
|
|
||||||
xx2 = xx3 = xx4 = -1.0;
|
|
||||||
|
|
||||||
for(i = 1; i <= n1; i += 1) {
|
|
||||||
xx1 = ( xx1 + xx2 + xx3 - xx4 ) * t;
|
|
||||||
xx2 = ( xx1 + xx2 - xx3 + xx4 ) * t;
|
|
||||||
xx3 = ( xx1 - xx2 + xx3 + xx4 ) * t;
|
|
||||||
xx4 = (-xx1 + xx2 + xx3 + xx4 ) * t;
|
|
||||||
}
|
|
||||||
#ifdef POUT
|
|
||||||
Pout(n1, n1, n1, xx1, xx2, xx3, xx4);
|
|
||||||
#endif
|
|
||||||
|
|
||||||
|
|
||||||
/* MODULE 2: array elements */
|
|
||||||
|
|
||||||
e1[0] = 1.0;
|
|
||||||
e1[1] = e1[2] = e1[3] = -1.0;
|
|
||||||
|
|
||||||
for (i = 1; i <= n2; i +=1) {
|
|
||||||
e1[0] = ( e1[0] + e1[1] + e1[2] - e1[3] ) * t;
|
|
||||||
e1[1] = ( e1[0] + e1[1] - e1[2] + e1[3] ) * t;
|
|
||||||
e1[2] = ( e1[0] - e1[1] + e1[2] + e1[3] ) * t;
|
|
||||||
e1[3] = (-e1[0] + e1[1] + e1[2] + e1[3] ) * t;
|
|
||||||
}
|
|
||||||
#ifdef POUT
|
|
||||||
Pout(n2, n3, n2, e1[0], e1[1], e1[2], e1[3]);
|
|
||||||
#endif
|
|
||||||
|
|
||||||
/* MODULE 3: array as parameter */
|
|
||||||
|
|
||||||
for (i = 1; i <= n3; i += 1)
|
|
||||||
pa(e1);
|
|
||||||
#ifdef POUT
|
|
||||||
Pout(n3, n2, n2, e1[0], e1[1], e1[2], e1[3]);
|
|
||||||
#endif
|
|
||||||
|
|
||||||
/* MODULE 4: conditional jumps */
|
|
||||||
|
|
||||||
j = 1;
|
|
||||||
for (i = 1; i <= n4; i += 1) {
|
|
||||||
if (j == 1)
|
|
||||||
j = 2;
|
|
||||||
else
|
|
||||||
j = 3;
|
|
||||||
|
|
||||||
if (j > 2)
|
|
||||||
j = 0;
|
|
||||||
else
|
|
||||||
j = 1;
|
|
||||||
|
|
||||||
if (j < 1 )
|
|
||||||
j = 1;
|
|
||||||
else
|
|
||||||
j = 0;
|
|
||||||
}
|
|
||||||
#ifdef POUT
|
|
||||||
Pout(n4, j, j, xx1, xx2, xx3, xx4);
|
|
||||||
#endif
|
|
||||||
|
|
||||||
/* MODULE 5: omitted */
|
|
||||||
|
|
||||||
/* MODULE 6: integer arithmetic */
|
|
||||||
|
|
||||||
j = 1;
|
|
||||||
k = 2;
|
|
||||||
l = 3;
|
|
||||||
|
|
||||||
for (i = 1; i <= n6; i += 1) {
|
|
||||||
j = j * (k - j) * (l -k);
|
|
||||||
k = l * k - (l - j) * k;
|
|
||||||
l = (l - k) * (k + j);
|
|
||||||
|
|
||||||
e1[l - 2] = j + k + l; /* C arrays are zero based */
|
|
||||||
e1[k - 2] = j * k * l;
|
|
||||||
}
|
|
||||||
#ifdef POUT
|
|
||||||
Pout(n6, j, k, e1[0], e1[1], e1[2], e1[3]);
|
|
||||||
#endif
|
|
||||||
|
|
||||||
/* MODULE 7: trig. functions */
|
|
||||||
|
|
||||||
x = y = 0.5;
|
|
||||||
|
|
||||||
for(i = 1; i <= n7; i +=1) {
|
|
||||||
x = t * atan(t2*sin(x)*cos(x)/(cos(x+y)+cos(x-y)-1.0));
|
|
||||||
y = t * atan(t2*sin(y)*cos(y)/(cos(x+y)+cos(x-y)-1.0));
|
|
||||||
}
|
|
||||||
#ifdef POUT
|
|
||||||
Pout(n7, j, k, x, x, y, y);
|
|
||||||
#endif
|
|
||||||
|
|
||||||
/* MODULE 8: procedure calls */
|
|
||||||
|
|
||||||
x = y = z = 1.0;
|
|
||||||
|
|
||||||
for (i = 1; i <= n8; i +=1)
|
|
||||||
p3(x, y, &z);
|
|
||||||
#ifdef POUT
|
|
||||||
Pout(n8, j, k, x, y, z, z);
|
|
||||||
#endif
|
|
||||||
|
|
||||||
/* MODULE9: array references */
|
|
||||||
|
|
||||||
j = 1;
|
|
||||||
k = 2;
|
|
||||||
l = 3;
|
|
||||||
|
|
||||||
e1[0] = 1.0;
|
|
||||||
e1[1] = 2.0;
|
|
||||||
e1[2] = 3.0;
|
|
||||||
|
|
||||||
for(i = 1; i <= n9; i += 1)
|
|
||||||
p0();
|
|
||||||
#ifdef POUT
|
|
||||||
Pout(n9, j, k, e1[0], e1[1], e1[2], e1[3]);
|
|
||||||
#endif
|
|
||||||
|
|
||||||
/* MODULE10: integer arithmetic */
|
|
||||||
|
|
||||||
j = 2;
|
|
||||||
k = 3;
|
|
||||||
|
|
||||||
for(i = 1; i <= n10; i +=1) {
|
|
||||||
j = j + k;
|
|
||||||
k = j + k;
|
|
||||||
j = k - j;
|
|
||||||
k = k - j - j;
|
|
||||||
}
|
|
||||||
#ifdef POUT
|
|
||||||
Pout(n10, j, k, xx1, xx2, xx3, xx4);
|
|
||||||
#endif
|
|
||||||
|
|
||||||
/* MODULE11: standard functions */
|
|
||||||
|
|
||||||
x = 0.75;
|
|
||||||
for(i = 1; i <= n11; i +=1)
|
|
||||||
x = sqrt( exp( log(x) / t1));
|
|
||||||
|
|
||||||
#ifdef POUT
|
|
||||||
Pout(n11, j, k, x, x, x, x);
|
|
||||||
#endif
|
|
||||||
|
|
||||||
#ifdef MEASURE_TIME
|
|
||||||
End_Time = clock();
|
|
||||||
|
|
||||||
Total_Time = End_Time - Begin_Time; /* in 1/ seconds */
|
|
||||||
|
|
||||||
whetstones = (1e5 * ITERATIONS * CLOCKS_PER_SEC) / Total_Time;
|
|
||||||
printf("\nWhetstone runs in %ld clock ticks (%d). %ld Kwhets/second\n",
|
|
||||||
Total_Time, CLOCKS_PER_SEC, (long) whetstones / 1000 );
|
|
||||||
#endif
|
|
||||||
}
|
|
||||||
|
|
||||||
pa(e)
|
|
||||||
double e[4];
|
|
||||||
{
|
|
||||||
register int j;
|
|
||||||
|
|
||||||
j = 0;
|
|
||||||
lab:
|
|
||||||
e[0] = ( e[0] + e[1] + e[2] - e[3] ) * t;
|
|
||||||
e[1] = ( e[0] + e[1] - e[2] + e[3] ) * t;
|
|
||||||
e[2] = ( e[0] - e[1] + e[2] + e[3] ) * t;
|
|
||||||
e[3] = ( -e[0] + e[1] + e[2] + e[3] ) / t2;
|
|
||||||
j += 1;
|
|
||||||
if (j < 6)
|
|
||||||
goto lab;
|
|
||||||
}
|
|
||||||
|
|
||||||
p3(x, y, z)
|
|
||||||
double x, y, *z;
|
|
||||||
{
|
|
||||||
x = t * (x + y);
|
|
||||||
y = t * (x + y);
|
|
||||||
*z = (x + y) /t2;
|
|
||||||
}
|
|
||||||
|
|
||||||
p0()
|
|
||||||
{
|
|
||||||
e1[j] = e1[k];
|
|
||||||
e1[k] = e1[l];
|
|
||||||
e1[l] = e1[j];
|
|
||||||
}
|
|
||||||
|
|
||||||
#ifdef POUT
|
|
||||||
pout(n, j, k, x1, x2, x3, x4)
|
|
||||||
unsigned int n, j, k;
|
|
||||||
double x1, x2, x3, x4;
|
|
||||||
{
|
|
||||||
printf("%5u %5u %5u %11.3e %11.3e %11.3e %11.3e\n",
|
|
||||||
n, j, k, x1, x2, x3, x4);
|
|
||||||
}
|
|
||||||
#endif
|
|
||||||
@@ -1,128 +0,0 @@
|
|||||||
#include <sys/times.h>
|
|
||||||
#include <sys/time.h>
|
|
||||||
#include <sys/stat.h>
|
|
||||||
#include <errno.h>
|
|
||||||
#include <stdlib.h>
|
|
||||||
#include "libsys.h"
|
|
||||||
#include "xcpt.h"
|
|
||||||
#include "irq.h"
|
|
||||||
|
|
||||||
char *_xcpt_code_str[32] =
|
|
||||||
{
|
|
||||||
"Int", "Mod", "TLBL", "TLBS", "AdEL", "AdES", "IBE", "DBE",
|
|
||||||
"Sys", "Bp", "RI", "CpU", "Ov", "Tr", "NCD/VCEI", "MC/FPE",
|
|
||||||
"Res(16)", "Res(17)", "Res(18)", "Res(19)", "Res(20)", "Res(21)", "Res(22)", "WATCH",
|
|
||||||
"Res(24)", "Res(25)", "Res(26)", "Res(27)", "Res(28)", "Res(29)", "Res(30)", "VCED"
|
|
||||||
};
|
|
||||||
|
|
||||||
#define PRINT_REG(tag_str, reg) \
|
|
||||||
sputs(tag_str); \
|
|
||||||
print_word(reg); \
|
|
||||||
sputs("\n");
|
|
||||||
|
|
||||||
int _xcpt_default_dispatch(struct xcptcontext * xcp)
|
|
||||||
{
|
|
||||||
return 1;
|
|
||||||
}
|
|
||||||
|
|
||||||
int _xcpt_dispatch(struct xcptcontext * xcp)
|
|
||||||
{
|
|
||||||
int xcpt_code, result;
|
|
||||||
|
|
||||||
xcpt_code = ((0xFF & xcp->cr) >> 2);
|
|
||||||
|
|
||||||
switch(xcpt_code)
|
|
||||||
{
|
|
||||||
case Int:
|
|
||||||
result = _irq_dispatch(xcp);
|
|
||||||
break;
|
|
||||||
|
|
||||||
default:
|
|
||||||
result = _xcpt_default_dispatch(xcp);
|
|
||||||
break;
|
|
||||||
}
|
|
||||||
|
|
||||||
return result;
|
|
||||||
}
|
|
||||||
|
|
||||||
int _xcpt_deliver(struct xcptcontext * _xcp)
|
|
||||||
{
|
|
||||||
|
|
||||||
int exc_code;
|
|
||||||
volatile int *pInstr;
|
|
||||||
|
|
||||||
/* This function gets called by the low-level exception handler. */
|
|
||||||
if (_xcpt_dispatch(_xcp))
|
|
||||||
{
|
|
||||||
sputs("\n");
|
|
||||||
PRINT_REG("Status : ", _xcp->sr);
|
|
||||||
PRINT_REG("Cause : ", _xcp->cr);
|
|
||||||
PRINT_REG("EPC : ", _xcp->epc);
|
|
||||||
PRINT_REG("BadAddr : ", _xcp->baddr);
|
|
||||||
PRINT_REG("MDLO : ", _xcp->mdlo);
|
|
||||||
PRINT_REG("MDHI : ", _xcp->mdhi);
|
|
||||||
|
|
||||||
sputs("\n");
|
|
||||||
|
|
||||||
sputs("Registers:\n");
|
|
||||||
PRINT_REG(" 0 (zero) : ", _xcp->regs[0]);
|
|
||||||
PRINT_REG(" 1 (at) : ", _xcp->regs[1]);
|
|
||||||
PRINT_REG(" 2 (v0) : ", _xcp->regs[2]);
|
|
||||||
PRINT_REG(" 3 (v1) : ", _xcp->regs[3]);
|
|
||||||
PRINT_REG(" 4 (a0) : ", _xcp->regs[4]);
|
|
||||||
PRINT_REG(" 5 (a1) : ", _xcp->regs[5]);
|
|
||||||
PRINT_REG(" 6 (a2) : ", _xcp->regs[6]);
|
|
||||||
PRINT_REG(" 7 (a3) : ", _xcp->regs[7]);
|
|
||||||
PRINT_REG(" 8 (t0) : ", _xcp->regs[8]);
|
|
||||||
PRINT_REG(" 9 (t1) : ", _xcp->regs[9]);
|
|
||||||
PRINT_REG("10 (t2) : ", _xcp->regs[10]);
|
|
||||||
PRINT_REG("11 (t3) : ", _xcp->regs[11]);
|
|
||||||
PRINT_REG("12 (t4) : ", _xcp->regs[12]);
|
|
||||||
PRINT_REG("13 (t5) : ", _xcp->regs[13]);
|
|
||||||
PRINT_REG("14 (t6) : ", _xcp->regs[14]);
|
|
||||||
PRINT_REG("15 (t7) : ", _xcp->regs[15]);
|
|
||||||
PRINT_REG("16 (s0) : ", _xcp->regs[16]);
|
|
||||||
PRINT_REG("17 (s1) : ", _xcp->regs[17]);
|
|
||||||
PRINT_REG("18 (s2) : ", _xcp->regs[18]);
|
|
||||||
PRINT_REG("19 (s3) : ", _xcp->regs[19]);
|
|
||||||
PRINT_REG("20 (s4) : ", _xcp->regs[20]);
|
|
||||||
PRINT_REG("21 (s5) : ", _xcp->regs[21]);
|
|
||||||
PRINT_REG("22 (s6) : ", _xcp->regs[22]);
|
|
||||||
PRINT_REG("23 (s7) : ", _xcp->regs[23]);
|
|
||||||
PRINT_REG("24 (t8) : ", _xcp->regs[24]);
|
|
||||||
PRINT_REG("25 (t9) : ", _xcp->regs[25]);
|
|
||||||
PRINT_REG("26 (k0) : ", _xcp->regs[26]);
|
|
||||||
PRINT_REG("27 (k1) : ", _xcp->regs[27]);
|
|
||||||
PRINT_REG("28 (gp) : ", _xcp->regs[28]);
|
|
||||||
PRINT_REG("29 (sp) : ", _xcp->regs[29]);
|
|
||||||
PRINT_REG("30 (fp) : ", _xcp->regs[30]);
|
|
||||||
PRINT_REG("31 (ra) : ", _xcp->regs[31]);
|
|
||||||
sputs("\n");
|
|
||||||
|
|
||||||
exc_code = (_xcp->cr >> 2) & 0x1F;
|
|
||||||
|
|
||||||
sputs("Unhandled exception <");
|
|
||||||
sputs(_xcpt_code_str[exc_code]);
|
|
||||||
sputs("> at PC : ");
|
|
||||||
print_word(_xcp->epc);
|
|
||||||
sputs("\n");
|
|
||||||
|
|
||||||
if (_xcp->cr & 0x80000000)
|
|
||||||
{
|
|
||||||
pInstr = (int*)(_xcp->epc + 4);
|
|
||||||
}
|
|
||||||
else
|
|
||||||
{
|
|
||||||
pInstr = (int*)(_xcp->epc);
|
|
||||||
}
|
|
||||||
|
|
||||||
sputs("Instruction at exception address : ");
|
|
||||||
print_word(*pInstr);
|
|
||||||
sputs("\n");
|
|
||||||
|
|
||||||
sputs("Terminate.\n");
|
|
||||||
_exit(exc_code);
|
|
||||||
}
|
|
||||||
|
|
||||||
return 0;
|
|
||||||
}
|
|
||||||
@@ -1,34 +0,0 @@
|
|||||||
#ifndef XCPT_H
|
|
||||||
#define XCPT_H
|
|
||||||
|
|
||||||
typedef enum
|
|
||||||
{
|
|
||||||
Int = 0, Mod = 1, TLBL = 2, TLBS = 3, AdEL = 4, AdES = 5,
|
|
||||||
IBE = 6, DBE = 7, Syscall = 8, Bp = 9, RI = 10, CpU = 11,
|
|
||||||
Ov = 12, TRAP = 13, VCEI = 14, FPE = 15, C2E = 16, Watch = 23, VCED = 31
|
|
||||||
|
|
||||||
} EXCEPTION_CODE;
|
|
||||||
|
|
||||||
typedef unsigned int reg_t;
|
|
||||||
|
|
||||||
typedef struct xcptcontext
|
|
||||||
{
|
|
||||||
/* This is the exception context frame that is passed to the exception
|
|
||||||
handlers. It gets filled in by the low-level exception handler in
|
|
||||||
"machine.S". An assembler version of this structure can be found at the
|
|
||||||
bottom of "machine.H".*/
|
|
||||||
reg_t sr; /* Status Register */
|
|
||||||
reg_t cr; /* Cause Register */
|
|
||||||
reg_t epc; /* PC at time of exception. */
|
|
||||||
reg_t baddr;
|
|
||||||
reg_t regs[32]; /* Copy of all general purpose registers */
|
|
||||||
reg_t mdlo; /* HI/LO registers (used for memory management) */
|
|
||||||
reg_t mdhi;
|
|
||||||
reg_t count; /* Timer registers */
|
|
||||||
reg_t compare;
|
|
||||||
struct xcptcontext * prev; /* To link exceptions. (unused for now) */
|
|
||||||
unsigned xclass; /* Priority class of this exception. (unused for now). */
|
|
||||||
|
|
||||||
} EXCEPTION_CONTEXT;
|
|
||||||
|
|
||||||
#endif // XCPT_H
|
|
||||||
@@ -1,67 +0,0 @@
|
|||||||
#ifndef XCPT_ASM_H
|
|
||||||
#define XCPT_ASM_H
|
|
||||||
|
|
||||||
/* LEAF - declare leaf routine */
|
|
||||||
#define LEAF(symbol) \
|
|
||||||
.globl symbol; \
|
|
||||||
.align 2; \
|
|
||||||
.type symbol, @function; \
|
|
||||||
.ent symbol, 0; \
|
|
||||||
symbol: .frame sp, 0, ra
|
|
||||||
|
|
||||||
/* END - mark end of function */
|
|
||||||
#define END(function) \
|
|
||||||
.end function; \
|
|
||||||
.size function, .-function
|
|
||||||
|
|
||||||
/* Exception stack size */
|
|
||||||
#define XCP_SIZE 1024
|
|
||||||
|
|
||||||
/* save location for registers */
|
|
||||||
#define XCP_SR 0
|
|
||||||
#define XCP_CR 4
|
|
||||||
#define XCP_EPC 8
|
|
||||||
#define XCP_BADDR 12
|
|
||||||
#define XCP_ZERO 16
|
|
||||||
#define XCP_AT 20
|
|
||||||
#define XCP_V0 24
|
|
||||||
#define XCP_V1 28
|
|
||||||
#define XCP_A0 32
|
|
||||||
#define XCP_A1 36
|
|
||||||
#define XCP_A2 40
|
|
||||||
#define XCP_A3 44
|
|
||||||
#define XCP_T0 48
|
|
||||||
#define XCP_T1 52
|
|
||||||
#define XCP_T2 56
|
|
||||||
#define XCP_T3 60
|
|
||||||
#define XCP_T4 64
|
|
||||||
#define XCP_T5 68
|
|
||||||
#define XCP_T6 72
|
|
||||||
#define XCP_T7 76
|
|
||||||
#define XCP_S0 80
|
|
||||||
#define XCP_S1 84
|
|
||||||
#define XCP_S2 88
|
|
||||||
#define XCP_S3 92
|
|
||||||
#define XCP_S4 96
|
|
||||||
#define XCP_S5 100
|
|
||||||
#define XCP_S6 104
|
|
||||||
#define XCP_S7 108
|
|
||||||
#define XCP_T8 112
|
|
||||||
#define XCP_T9 116
|
|
||||||
#define XCP_JP 116
|
|
||||||
#define XCP_K0 120
|
|
||||||
#define XCP_K1 124
|
|
||||||
#define XCP_GP 128
|
|
||||||
#define XCP_SP 132
|
|
||||||
#define XCP_S8 136
|
|
||||||
#define XCP_FP 136
|
|
||||||
#define XCP_RA 140
|
|
||||||
#define XCP_MDLO 144
|
|
||||||
#define XCP_MDHI 148
|
|
||||||
#define XCP_COUNT 152
|
|
||||||
#define XCP_COMPARE 156
|
|
||||||
#define XCP_PREV 160
|
|
||||||
#define XCP_CLASS 164
|
|
||||||
|
|
||||||
|
|
||||||
#endif /* XCPT_ASM_H */
|
|
||||||
@@ -1,46 +0,0 @@
|
|||||||
# ---------------------------------------------------------------
|
|
||||||
# 1. Binutils bauen und installieren
|
|
||||||
# ---------------------------------------------------------------
|
|
||||||
> tar -xzf binutils-2.19.tar.gz
|
|
||||||
> mkdir binutils-2.19_build
|
|
||||||
> cd binutils-2.19_build
|
|
||||||
|
|
||||||
> ../binutils-2.19/configure --target=mipsel-elf --prefix=/usr/local
|
|
||||||
> make
|
|
||||||
> make install
|
|
||||||
|
|
||||||
# ---------------------------------------------------------------
|
|
||||||
# 2. GCC bootstrapping
|
|
||||||
# ---------------------------------------------------------------
|
|
||||||
> tar -xzf gcc-4.3.2.tar.gz
|
|
||||||
> mkdir gcc-4.3.2_build
|
|
||||||
> cd gcc-4.3.2_build
|
|
||||||
> ../gcc-4.3.2/configure --target=mipsel-elf --prefix=/usr/local --enable-languages="c,c++" --without-headers --with-newlib --with-float=soft --disable-multilib
|
|
||||||
> CFLAGS_FOR_TARGET="-mno-gpopt" make all-gcc
|
|
||||||
> make info-gcc
|
|
||||||
> make install-gcc
|
|
||||||
|
|
||||||
# ---------------------------------------------------------------
|
|
||||||
# 3. Newlib bauen und installieren
|
|
||||||
# ---------------------------------------------------------------
|
|
||||||
> tar -xzf newlib-1.16.0.tar.gz
|
|
||||||
! Bug in newlib-1.16.0/newlib/libc/machine/mips/strlen.c.
|
|
||||||
Newlib von Hand patchen (32-bit MIPS targets):
|
|
||||||
"lbu $3,0($4)\n"
|
|
||||||
"nop\n" <= nop einfügen
|
|
||||||
"bnez $3,1b\n"
|
|
||||||
|
|
||||||
> mkdir newlib-1.16.0_build
|
|
||||||
> cd newlib-1.16.0_build
|
|
||||||
> ../newlib-1.16.0/configure --target=mipsel-elf --prefix=/usr/local --with-float=soft --disable-multilib
|
|
||||||
> TARGET_CFLAGS="-mno-gpopt" make all
|
|
||||||
> make install
|
|
||||||
|
|
||||||
# ---------------------------------------------------------------
|
|
||||||
# 4. GCC bauen und installieren
|
|
||||||
# ---------------------------------------------------------------
|
|
||||||
> cd gcc-4.3.2_build
|
|
||||||
> ../gcc-4.3.2/configure --target=mipsel-elf --prefix=/usr/local --enable-languages="c,c++" --disable-shared --with-newlib --with-float=soft --disable-multilib
|
|
||||||
> CFLAGS_FOR_TARGET="-mno-gpopt" make all
|
|
||||||
> make info
|
|
||||||
> make install
|
|
||||||
@@ -1,47 +0,0 @@
|
|||||||
#!/bin/sh
|
|
||||||
TARGET=mipsel-elf
|
|
||||||
PREFIX=/usr/local
|
|
||||||
|
|
||||||
# ---------------------------------------------------------------
|
|
||||||
# 1. Binutils bauen und installieren
|
|
||||||
# ---------------------------------------------------------------
|
|
||||||
if [ ! -d ./binutils-2.19 ]; then
|
|
||||||
tar -xjf binutils-2.19.tar.bz2
|
|
||||||
fi
|
|
||||||
|
|
||||||
if [ ! -d ./binutils-2.19_build ]; then
|
|
||||||
mkdir -p binutils-2.19_build
|
|
||||||
cd binutils-2.19_build
|
|
||||||
../binutils-2.19/configure --target=$TARGET --prefix=$PREFIX
|
|
||||||
make
|
|
||||||
make install
|
|
||||||
cd ..
|
|
||||||
else
|
|
||||||
echo binutils is already built.
|
|
||||||
fi
|
|
||||||
|
|
||||||
# ---------------------------------------------------------------
|
|
||||||
# 2. GCC & newlib bauen und installieren
|
|
||||||
# ---------------------------------------------------------------
|
|
||||||
if [ ! -d ./newlib-1.16.0 ]; then
|
|
||||||
tar -xzf newlib-1.16.0.tar.gz
|
|
||||||
fi
|
|
||||||
|
|
||||||
if [ ! -d ./gcc-4.3.2 ]; then
|
|
||||||
tar -xjf gcc-4.3.2.tar.bz2
|
|
||||||
cd ./gcc-4.3.2
|
|
||||||
ln -sf ../newlib-1.16.0/newlib/ .
|
|
||||||
cd ..
|
|
||||||
fi
|
|
||||||
|
|
||||||
if [ ! -d ./gcc-4.3.2_build ]; then
|
|
||||||
mkdir -p gcc-4.3.2_build
|
|
||||||
cd gcc-4.3.2_build
|
|
||||||
../gcc-4.3.2/configure --target=$TARGET --prefix=$PREFIX --with-float=soft --with-newlib --verbose --enable-languages="c,c++"
|
|
||||||
make all
|
|
||||||
make info
|
|
||||||
make install
|
|
||||||
cd ..
|
|
||||||
else
|
|
||||||
echo GCC is already built.
|
|
||||||
fi
|
|
||||||
Vendored
-37
@@ -1,37 +0,0 @@
|
|||||||
../../../misc/dpram_2w2r.vhd
|
|
||||||
../../../misc/dpram_1w1r.vhd
|
|
||||||
../../../misc/dpram_1w1r_dist.vhd
|
|
||||||
../../../FIFO/src/fifo_ctrl_pkg.vhd
|
|
||||||
../../../FIFO/src/fifo_sync_ctrl.vhd
|
|
||||||
../../../FIFO/src/fifo_sync_dist.vhd
|
|
||||||
|
|
||||||
../../../uart/bbfifo_16x8.vhd
|
|
||||||
../../../uart/kcuart_rx.vhd
|
|
||||||
../../../uart/kcuart_tx.vhd
|
|
||||||
../../../uart/uart_rx.vhd
|
|
||||||
../../../uart/uart_tx.vhd
|
|
||||||
../../../uart/uart_wb.vhd
|
|
||||||
|
|
||||||
../../../misc/gpio_wb.vhd
|
|
||||||
../../../misc/async_types.vhd
|
|
||||||
../../../misc/async_port_wb.vhd
|
|
||||||
../src/async_defs.vhd
|
|
||||||
|
|
||||||
../src/bootloader.ROM.vhd
|
|
||||||
../../../misc/rom_wb.vhd
|
|
||||||
|
|
||||||
../src/core/mips_types.vhd
|
|
||||||
../src/core/mips_instr.vhd
|
|
||||||
../src/core/mips_idecode_rom.vhd
|
|
||||||
../src/core/mips_reg.vhd
|
|
||||||
../src/core/mips_shifter.vhd
|
|
||||||
../src/core/mips_alu.vhd
|
|
||||||
../src/core/mips_muldiv.vhd
|
|
||||||
../src/core/mips_cop.vhd
|
|
||||||
../src/core/mips_icache.vhd
|
|
||||||
../src/core/mips_dcache.vhd
|
|
||||||
../src/core/mips_biu.vhd
|
|
||||||
../src/core/mips_bcu.vhd
|
|
||||||
../src/core/mips_pipeline.vhd
|
|
||||||
../src/core/mips_top.vhd
|
|
||||||
../src/tb_mips_top.vhd
|
|
||||||
Vendored
-46
@@ -1,46 +0,0 @@
|
|||||||
#!/bin/sh
|
|
||||||
|
|
||||||
PROJECT="mips_top"
|
|
||||||
DIST_FILE="./files.dist"
|
|
||||||
DIST_DIR="./release/mips.r10a"
|
|
||||||
|
|
||||||
# ---------------------------------------------------------------
|
|
||||||
mkdir -p $DIST_DIR/src
|
|
||||||
mkdir -p $DIST_DIR/sim
|
|
||||||
mkdir -p $DIST_DIR/doc
|
|
||||||
mkdir -p $DIST_DIR/bsp
|
|
||||||
mkdir -p $DIST_DIR/tools
|
|
||||||
|
|
||||||
cp -a ../bsp/* $DIST_DIR/bsp/
|
|
||||||
cp -a ../doc/*.pdf $DIST_DIR/doc/
|
|
||||||
cp -a ../doc/*.txt $DIST_DIR/doc/
|
|
||||||
cp -a ../tools/* $DIST_DIR/tools/
|
|
||||||
|
|
||||||
cp -a ./tmpl/gpl-3.0.txt $DIST_DIR/
|
|
||||||
cp -a ./tmpl/tb_mips_top.wdo $DIST_DIR/sim/
|
|
||||||
cp -a ./tmpl/hello.flash.bin $DIST_DIR/sim/
|
|
||||||
|
|
||||||
for i in $(cat -s $DIST_FILE); do
|
|
||||||
echo $i;
|
|
||||||
cp -a $i $DIST_DIR/src/
|
|
||||||
done;
|
|
||||||
|
|
||||||
# Delete CVS directories
|
|
||||||
rm -r $(find release/ -name CVS)
|
|
||||||
|
|
||||||
# ---------------------------------------------------------------
|
|
||||||
# Generate testbench do-file
|
|
||||||
echo "vlib work" > $DIST_DIR/sim/tb_$PROJECT.fdo
|
|
||||||
|
|
||||||
for i in $(cat -s $DIST_FILE); do
|
|
||||||
echo "vcom -explicit -93 \"../src/$(basename $i)\"" >> $DIST_DIR/sim/tb_$PROJECT.fdo
|
|
||||||
done;
|
|
||||||
echo "vsim -t 1ps -lib work tb_$PROJECT" >> $DIST_DIR/sim/tb_$PROJECT.fdo
|
|
||||||
|
|
||||||
echo "do {tb_mips_top.wdo}" >> $DIST_DIR/sim/tb_$PROJECT.fdo
|
|
||||||
echo "view wave" >> $DIST_DIR/sim/tb_$PROJECT.fdo
|
|
||||||
echo "view structure" >> $DIST_DIR/sim/tb_$PROJECT.fdo
|
|
||||||
echo "view signals" >> $DIST_DIR/sim/tb_$PROJECT.fdo
|
|
||||||
echo "run 1600us" >> $DIST_DIR/sim/tb_$PROJECT.fdo
|
|
||||||
|
|
||||||
# ---------------------------------------------------------------
|
|
||||||
Vendored
-674
@@ -1,674 +0,0 @@
|
|||||||
GNU GENERAL PUBLIC LICENSE
|
|
||||||
Version 3, 29 June 2007
|
|
||||||
|
|
||||||
Copyright (C) 2007 Free Software Foundation, Inc. <http://fsf.org/>
|
|
||||||
Everyone is permitted to copy and distribute verbatim copies
|
|
||||||
of this license document, but changing it is not allowed.
|
|
||||||
|
|
||||||
Preamble
|
|
||||||
|
|
||||||
The GNU General Public License is a free, copyleft license for
|
|
||||||
software and other kinds of works.
|
|
||||||
|
|
||||||
The licenses for most software and other practical works are designed
|
|
||||||
to take away your freedom to share and change the works. By contrast,
|
|
||||||
the GNU General Public License is intended to guarantee your freedom to
|
|
||||||
share and change all versions of a program--to make sure it remains free
|
|
||||||
software for all its users. We, the Free Software Foundation, use the
|
|
||||||
GNU General Public License for most of our software; it applies also to
|
|
||||||
any other work released this way by its authors. You can apply it to
|
|
||||||
your programs, too.
|
|
||||||
|
|
||||||
When we speak of free software, we are referring to freedom, not
|
|
||||||
price. Our General Public Licenses are designed to make sure that you
|
|
||||||
have the freedom to distribute copies of free software (and charge for
|
|
||||||
them if you wish), that you receive source code or can get it if you
|
|
||||||
want it, that you can change the software or use pieces of it in new
|
|
||||||
free programs, and that you know you can do these things.
|
|
||||||
|
|
||||||
To protect your rights, we need to prevent others from denying you
|
|
||||||
these rights or asking you to surrender the rights. Therefore, you have
|
|
||||||
certain responsibilities if you distribute copies of the software, or if
|
|
||||||
you modify it: responsibilities to respect the freedom of others.
|
|
||||||
|
|
||||||
For example, if you distribute copies of such a program, whether
|
|
||||||
gratis or for a fee, you must pass on to the recipients the same
|
|
||||||
freedoms that you received. You must make sure that they, too, receive
|
|
||||||
or can get the source code. And you must show them these terms so they
|
|
||||||
know their rights.
|
|
||||||
|
|
||||||
Developers that use the GNU GPL protect your rights with two steps:
|
|
||||||
(1) assert copyright on the software, and (2) offer you this License
|
|
||||||
giving you legal permission to copy, distribute and/or modify it.
|
|
||||||
|
|
||||||
For the developers' and authors' protection, the GPL clearly explains
|
|
||||||
that there is no warranty for this free software. For both users' and
|
|
||||||
authors' sake, the GPL requires that modified versions be marked as
|
|
||||||
changed, so that their problems will not be attributed erroneously to
|
|
||||||
authors of previous versions.
|
|
||||||
|
|
||||||
Some devices are designed to deny users access to install or run
|
|
||||||
modified versions of the software inside them, although the manufacturer
|
|
||||||
can do so. This is fundamentally incompatible with the aim of
|
|
||||||
protecting users' freedom to change the software. The systematic
|
|
||||||
pattern of such abuse occurs in the area of products for individuals to
|
|
||||||
use, which is precisely where it is most unacceptable. Therefore, we
|
|
||||||
have designed this version of the GPL to prohibit the practice for those
|
|
||||||
products. If such problems arise substantially in other domains, we
|
|
||||||
stand ready to extend this provision to those domains in future versions
|
|
||||||
of the GPL, as needed to protect the freedom of users.
|
|
||||||
|
|
||||||
Finally, every program is threatened constantly by software patents.
|
|
||||||
States should not allow patents to restrict development and use of
|
|
||||||
software on general-purpose computers, but in those that do, we wish to
|
|
||||||
avoid the special danger that patents applied to a free program could
|
|
||||||
make it effectively proprietary. To prevent this, the GPL assures that
|
|
||||||
patents cannot be used to render the program non-free.
|
|
||||||
|
|
||||||
The precise terms and conditions for copying, distribution and
|
|
||||||
modification follow.
|
|
||||||
|
|
||||||
TERMS AND CONDITIONS
|
|
||||||
|
|
||||||
0. Definitions.
|
|
||||||
|
|
||||||
"This License" refers to version 3 of the GNU General Public License.
|
|
||||||
|
|
||||||
"Copyright" also means copyright-like laws that apply to other kinds of
|
|
||||||
works, such as semiconductor masks.
|
|
||||||
|
|
||||||
"The Program" refers to any copyrightable work licensed under this
|
|
||||||
License. Each licensee is addressed as "you". "Licensees" and
|
|
||||||
"recipients" may be individuals or organizations.
|
|
||||||
|
|
||||||
To "modify" a work means to copy from or adapt all or part of the work
|
|
||||||
in a fashion requiring copyright permission, other than the making of an
|
|
||||||
exact copy. The resulting work is called a "modified version" of the
|
|
||||||
earlier work or a work "based on" the earlier work.
|
|
||||||
|
|
||||||
A "covered work" means either the unmodified Program or a work based
|
|
||||||
on the Program.
|
|
||||||
|
|
||||||
To "propagate" a work means to do anything with it that, without
|
|
||||||
permission, would make you directly or secondarily liable for
|
|
||||||
infringement under applicable copyright law, except executing it on a
|
|
||||||
computer or modifying a private copy. Propagation includes copying,
|
|
||||||
distribution (with or without modification), making available to the
|
|
||||||
public, and in some countries other activities as well.
|
|
||||||
|
|
||||||
To "convey" a work means any kind of propagation that enables other
|
|
||||||
parties to make or receive copies. Mere interaction with a user through
|
|
||||||
a computer network, with no transfer of a copy, is not conveying.
|
|
||||||
|
|
||||||
An interactive user interface displays "Appropriate Legal Notices"
|
|
||||||
to the extent that it includes a convenient and prominently visible
|
|
||||||
feature that (1) displays an appropriate copyright notice, and (2)
|
|
||||||
tells the user that there is no warranty for the work (except to the
|
|
||||||
extent that warranties are provided), that licensees may convey the
|
|
||||||
work under this License, and how to view a copy of this License. If
|
|
||||||
the interface presents a list of user commands or options, such as a
|
|
||||||
menu, a prominent item in the list meets this criterion.
|
|
||||||
|
|
||||||
1. Source Code.
|
|
||||||
|
|
||||||
The "source code" for a work means the preferred form of the work
|
|
||||||
for making modifications to it. "Object code" means any non-source
|
|
||||||
form of a work.
|
|
||||||
|
|
||||||
A "Standard Interface" means an interface that either is an official
|
|
||||||
standard defined by a recognized standards body, or, in the case of
|
|
||||||
interfaces specified for a particular programming language, one that
|
|
||||||
is widely used among developers working in that language.
|
|
||||||
|
|
||||||
The "System Libraries" of an executable work include anything, other
|
|
||||||
than the work as a whole, that (a) is included in the normal form of
|
|
||||||
packaging a Major Component, but which is not part of that Major
|
|
||||||
Component, and (b) serves only to enable use of the work with that
|
|
||||||
Major Component, or to implement a Standard Interface for which an
|
|
||||||
implementation is available to the public in source code form. A
|
|
||||||
"Major Component", in this context, means a major essential component
|
|
||||||
(kernel, window system, and so on) of the specific operating system
|
|
||||||
(if any) on which the executable work runs, or a compiler used to
|
|
||||||
produce the work, or an object code interpreter used to run it.
|
|
||||||
|
|
||||||
The "Corresponding Source" for a work in object code form means all
|
|
||||||
the source code needed to generate, install, and (for an executable
|
|
||||||
work) run the object code and to modify the work, including scripts to
|
|
||||||
control those activities. However, it does not include the work's
|
|
||||||
System Libraries, or general-purpose tools or generally available free
|
|
||||||
programs which are used unmodified in performing those activities but
|
|
||||||
which are not part of the work. For example, Corresponding Source
|
|
||||||
includes interface definition files associated with source files for
|
|
||||||
the work, and the source code for shared libraries and dynamically
|
|
||||||
linked subprograms that the work is specifically designed to require,
|
|
||||||
such as by intimate data communication or control flow between those
|
|
||||||
subprograms and other parts of the work.
|
|
||||||
|
|
||||||
The Corresponding Source need not include anything that users
|
|
||||||
can regenerate automatically from other parts of the Corresponding
|
|
||||||
Source.
|
|
||||||
|
|
||||||
The Corresponding Source for a work in source code form is that
|
|
||||||
same work.
|
|
||||||
|
|
||||||
2. Basic Permissions.
|
|
||||||
|
|
||||||
All rights granted under this License are granted for the term of
|
|
||||||
copyright on the Program, and are irrevocable provided the stated
|
|
||||||
conditions are met. This License explicitly affirms your unlimited
|
|
||||||
permission to run the unmodified Program. The output from running a
|
|
||||||
covered work is covered by this License only if the output, given its
|
|
||||||
content, constitutes a covered work. This License acknowledges your
|
|
||||||
rights of fair use or other equivalent, as provided by copyright law.
|
|
||||||
|
|
||||||
You may make, run and propagate covered works that you do not
|
|
||||||
convey, without conditions so long as your license otherwise remains
|
|
||||||
in force. You may convey covered works to others for the sole purpose
|
|
||||||
of having them make modifications exclusively for you, or provide you
|
|
||||||
with facilities for running those works, provided that you comply with
|
|
||||||
the terms of this License in conveying all material for which you do
|
|
||||||
not control copyright. Those thus making or running the covered works
|
|
||||||
for you must do so exclusively on your behalf, under your direction
|
|
||||||
and control, on terms that prohibit them from making any copies of
|
|
||||||
your copyrighted material outside their relationship with you.
|
|
||||||
|
|
||||||
Conveying under any other circumstances is permitted solely under
|
|
||||||
the conditions stated below. Sublicensing is not allowed; section 10
|
|
||||||
makes it unnecessary.
|
|
||||||
|
|
||||||
3. Protecting Users' Legal Rights From Anti-Circumvention Law.
|
|
||||||
|
|
||||||
No covered work shall be deemed part of an effective technological
|
|
||||||
measure under any applicable law fulfilling obligations under article
|
|
||||||
11 of the WIPO copyright treaty adopted on 20 December 1996, or
|
|
||||||
similar laws prohibiting or restricting circumvention of such
|
|
||||||
measures.
|
|
||||||
|
|
||||||
When you convey a covered work, you waive any legal power to forbid
|
|
||||||
circumvention of technological measures to the extent such circumvention
|
|
||||||
is effected by exercising rights under this License with respect to
|
|
||||||
the covered work, and you disclaim any intention to limit operation or
|
|
||||||
modification of the work as a means of enforcing, against the work's
|
|
||||||
users, your or third parties' legal rights to forbid circumvention of
|
|
||||||
technological measures.
|
|
||||||
|
|
||||||
4. Conveying Verbatim Copies.
|
|
||||||
|
|
||||||
You may convey verbatim copies of the Program's source code as you
|
|
||||||
receive it, in any medium, provided that you conspicuously and
|
|
||||||
appropriately publish on each copy an appropriate copyright notice;
|
|
||||||
keep intact all notices stating that this License and any
|
|
||||||
non-permissive terms added in accord with section 7 apply to the code;
|
|
||||||
keep intact all notices of the absence of any warranty; and give all
|
|
||||||
recipients a copy of this License along with the Program.
|
|
||||||
|
|
||||||
You may charge any price or no price for each copy that you convey,
|
|
||||||
and you may offer support or warranty protection for a fee.
|
|
||||||
|
|
||||||
5. Conveying Modified Source Versions.
|
|
||||||
|
|
||||||
You may convey a work based on the Program, or the modifications to
|
|
||||||
produce it from the Program, in the form of source code under the
|
|
||||||
terms of section 4, provided that you also meet all of these conditions:
|
|
||||||
|
|
||||||
a) The work must carry prominent notices stating that you modified
|
|
||||||
it, and giving a relevant date.
|
|
||||||
|
|
||||||
b) The work must carry prominent notices stating that it is
|
|
||||||
released under this License and any conditions added under section
|
|
||||||
7. This requirement modifies the requirement in section 4 to
|
|
||||||
"keep intact all notices".
|
|
||||||
|
|
||||||
c) You must license the entire work, as a whole, under this
|
|
||||||
License to anyone who comes into possession of a copy. This
|
|
||||||
License will therefore apply, along with any applicable section 7
|
|
||||||
additional terms, to the whole of the work, and all its parts,
|
|
||||||
regardless of how they are packaged. This License gives no
|
|
||||||
permission to license the work in any other way, but it does not
|
|
||||||
invalidate such permission if you have separately received it.
|
|
||||||
|
|
||||||
d) If the work has interactive user interfaces, each must display
|
|
||||||
Appropriate Legal Notices; however, if the Program has interactive
|
|
||||||
interfaces that do not display Appropriate Legal Notices, your
|
|
||||||
work need not make them do so.
|
|
||||||
|
|
||||||
A compilation of a covered work with other separate and independent
|
|
||||||
works, which are not by their nature extensions of the covered work,
|
|
||||||
and which are not combined with it such as to form a larger program,
|
|
||||||
in or on a volume of a storage or distribution medium, is called an
|
|
||||||
"aggregate" if the compilation and its resulting copyright are not
|
|
||||||
used to limit the access or legal rights of the compilation's users
|
|
||||||
beyond what the individual works permit. Inclusion of a covered work
|
|
||||||
in an aggregate does not cause this License to apply to the other
|
|
||||||
parts of the aggregate.
|
|
||||||
|
|
||||||
6. Conveying Non-Source Forms.
|
|
||||||
|
|
||||||
You may convey a covered work in object code form under the terms
|
|
||||||
of sections 4 and 5, provided that you also convey the
|
|
||||||
machine-readable Corresponding Source under the terms of this License,
|
|
||||||
in one of these ways:
|
|
||||||
|
|
||||||
a) Convey the object code in, or embodied in, a physical product
|
|
||||||
(including a physical distribution medium), accompanied by the
|
|
||||||
Corresponding Source fixed on a durable physical medium
|
|
||||||
customarily used for software interchange.
|
|
||||||
|
|
||||||
b) Convey the object code in, or embodied in, a physical product
|
|
||||||
(including a physical distribution medium), accompanied by a
|
|
||||||
written offer, valid for at least three years and valid for as
|
|
||||||
long as you offer spare parts or customer support for that product
|
|
||||||
model, to give anyone who possesses the object code either (1) a
|
|
||||||
copy of the Corresponding Source for all the software in the
|
|
||||||
product that is covered by this License, on a durable physical
|
|
||||||
medium customarily used for software interchange, for a price no
|
|
||||||
more than your reasonable cost of physically performing this
|
|
||||||
conveying of source, or (2) access to copy the
|
|
||||||
Corresponding Source from a network server at no charge.
|
|
||||||
|
|
||||||
c) Convey individual copies of the object code with a copy of the
|
|
||||||
written offer to provide the Corresponding Source. This
|
|
||||||
alternative is allowed only occasionally and noncommercially, and
|
|
||||||
only if you received the object code with such an offer, in accord
|
|
||||||
with subsection 6b.
|
|
||||||
|
|
||||||
d) Convey the object code by offering access from a designated
|
|
||||||
place (gratis or for a charge), and offer equivalent access to the
|
|
||||||
Corresponding Source in the same way through the same place at no
|
|
||||||
further charge. You need not require recipients to copy the
|
|
||||||
Corresponding Source along with the object code. If the place to
|
|
||||||
copy the object code is a network server, the Corresponding Source
|
|
||||||
may be on a different server (operated by you or a third party)
|
|
||||||
that supports equivalent copying facilities, provided you maintain
|
|
||||||
clear directions next to the object code saying where to find the
|
|
||||||
Corresponding Source. Regardless of what server hosts the
|
|
||||||
Corresponding Source, you remain obligated to ensure that it is
|
|
||||||
available for as long as needed to satisfy these requirements.
|
|
||||||
|
|
||||||
e) Convey the object code using peer-to-peer transmission, provided
|
|
||||||
you inform other peers where the object code and Corresponding
|
|
||||||
Source of the work are being offered to the general public at no
|
|
||||||
charge under subsection 6d.
|
|
||||||
|
|
||||||
A separable portion of the object code, whose source code is excluded
|
|
||||||
from the Corresponding Source as a System Library, need not be
|
|
||||||
included in conveying the object code work.
|
|
||||||
|
|
||||||
A "User Product" is either (1) a "consumer product", which means any
|
|
||||||
tangible personal property which is normally used for personal, family,
|
|
||||||
or household purposes, or (2) anything designed or sold for incorporation
|
|
||||||
into a dwelling. In determining whether a product is a consumer product,
|
|
||||||
doubtful cases shall be resolved in favor of coverage. For a particular
|
|
||||||
product received by a particular user, "normally used" refers to a
|
|
||||||
typical or common use of that class of product, regardless of the status
|
|
||||||
of the particular user or of the way in which the particular user
|
|
||||||
actually uses, or expects or is expected to use, the product. A product
|
|
||||||
is a consumer product regardless of whether the product has substantial
|
|
||||||
commercial, industrial or non-consumer uses, unless such uses represent
|
|
||||||
the only significant mode of use of the product.
|
|
||||||
|
|
||||||
"Installation Information" for a User Product means any methods,
|
|
||||||
procedures, authorization keys, or other information required to install
|
|
||||||
and execute modified versions of a covered work in that User Product from
|
|
||||||
a modified version of its Corresponding Source. The information must
|
|
||||||
suffice to ensure that the continued functioning of the modified object
|
|
||||||
code is in no case prevented or interfered with solely because
|
|
||||||
modification has been made.
|
|
||||||
|
|
||||||
If you convey an object code work under this section in, or with, or
|
|
||||||
specifically for use in, a User Product, and the conveying occurs as
|
|
||||||
part of a transaction in which the right of possession and use of the
|
|
||||||
User Product is transferred to the recipient in perpetuity or for a
|
|
||||||
fixed term (regardless of how the transaction is characterized), the
|
|
||||||
Corresponding Source conveyed under this section must be accompanied
|
|
||||||
by the Installation Information. But this requirement does not apply
|
|
||||||
if neither you nor any third party retains the ability to install
|
|
||||||
modified object code on the User Product (for example, the work has
|
|
||||||
been installed in ROM).
|
|
||||||
|
|
||||||
The requirement to provide Installation Information does not include a
|
|
||||||
requirement to continue to provide support service, warranty, or updates
|
|
||||||
for a work that has been modified or installed by the recipient, or for
|
|
||||||
the User Product in which it has been modified or installed. Access to a
|
|
||||||
network may be denied when the modification itself materially and
|
|
||||||
adversely affects the operation of the network or violates the rules and
|
|
||||||
protocols for communication across the network.
|
|
||||||
|
|
||||||
Corresponding Source conveyed, and Installation Information provided,
|
|
||||||
in accord with this section must be in a format that is publicly
|
|
||||||
documented (and with an implementation available to the public in
|
|
||||||
source code form), and must require no special password or key for
|
|
||||||
unpacking, reading or copying.
|
|
||||||
|
|
||||||
7. Additional Terms.
|
|
||||||
|
|
||||||
"Additional permissions" are terms that supplement the terms of this
|
|
||||||
License by making exceptions from one or more of its conditions.
|
|
||||||
Additional permissions that are applicable to the entire Program shall
|
|
||||||
be treated as though they were included in this License, to the extent
|
|
||||||
that they are valid under applicable law. If additional permissions
|
|
||||||
apply only to part of the Program, that part may be used separately
|
|
||||||
under those permissions, but the entire Program remains governed by
|
|
||||||
this License without regard to the additional permissions.
|
|
||||||
|
|
||||||
When you convey a copy of a covered work, you may at your option
|
|
||||||
remove any additional permissions from that copy, or from any part of
|
|
||||||
it. (Additional permissions may be written to require their own
|
|
||||||
removal in certain cases when you modify the work.) You may place
|
|
||||||
additional permissions on material, added by you to a covered work,
|
|
||||||
for which you have or can give appropriate copyright permission.
|
|
||||||
|
|
||||||
Notwithstanding any other provision of this License, for material you
|
|
||||||
add to a covered work, you may (if authorized by the copyright holders of
|
|
||||||
that material) supplement the terms of this License with terms:
|
|
||||||
|
|
||||||
a) Disclaiming warranty or limiting liability differently from the
|
|
||||||
terms of sections 15 and 16 of this License; or
|
|
||||||
|
|
||||||
b) Requiring preservation of specified reasonable legal notices or
|
|
||||||
author attributions in that material or in the Appropriate Legal
|
|
||||||
Notices displayed by works containing it; or
|
|
||||||
|
|
||||||
c) Prohibiting misrepresentation of the origin of that material, or
|
|
||||||
requiring that modified versions of such material be marked in
|
|
||||||
reasonable ways as different from the original version; or
|
|
||||||
|
|
||||||
d) Limiting the use for publicity purposes of names of licensors or
|
|
||||||
authors of the material; or
|
|
||||||
|
|
||||||
e) Declining to grant rights under trademark law for use of some
|
|
||||||
trade names, trademarks, or service marks; or
|
|
||||||
|
|
||||||
f) Requiring indemnification of licensors and authors of that
|
|
||||||
material by anyone who conveys the material (or modified versions of
|
|
||||||
it) with contractual assumptions of liability to the recipient, for
|
|
||||||
any liability that these contractual assumptions directly impose on
|
|
||||||
those licensors and authors.
|
|
||||||
|
|
||||||
All other non-permissive additional terms are considered "further
|
|
||||||
restrictions" within the meaning of section 10. If the Program as you
|
|
||||||
received it, or any part of it, contains a notice stating that it is
|
|
||||||
governed by this License along with a term that is a further
|
|
||||||
restriction, you may remove that term. If a license document contains
|
|
||||||
a further restriction but permits relicensing or conveying under this
|
|
||||||
License, you may add to a covered work material governed by the terms
|
|
||||||
of that license document, provided that the further restriction does
|
|
||||||
not survive such relicensing or conveying.
|
|
||||||
|
|
||||||
If you add terms to a covered work in accord with this section, you
|
|
||||||
must place, in the relevant source files, a statement of the
|
|
||||||
additional terms that apply to those files, or a notice indicating
|
|
||||||
where to find the applicable terms.
|
|
||||||
|
|
||||||
Additional terms, permissive or non-permissive, may be stated in the
|
|
||||||
form of a separately written license, or stated as exceptions;
|
|
||||||
the above requirements apply either way.
|
|
||||||
|
|
||||||
8. Termination.
|
|
||||||
|
|
||||||
You may not propagate or modify a covered work except as expressly
|
|
||||||
provided under this License. Any attempt otherwise to propagate or
|
|
||||||
modify it is void, and will automatically terminate your rights under
|
|
||||||
this License (including any patent licenses granted under the third
|
|
||||||
paragraph of section 11).
|
|
||||||
|
|
||||||
However, if you cease all violation of this License, then your
|
|
||||||
license from a particular copyright holder is reinstated (a)
|
|
||||||
provisionally, unless and until the copyright holder explicitly and
|
|
||||||
finally terminates your license, and (b) permanently, if the copyright
|
|
||||||
holder fails to notify you of the violation by some reasonable means
|
|
||||||
prior to 60 days after the cessation.
|
|
||||||
|
|
||||||
Moreover, your license from a particular copyright holder is
|
|
||||||
reinstated permanently if the copyright holder notifies you of the
|
|
||||||
violation by some reasonable means, this is the first time you have
|
|
||||||
received notice of violation of this License (for any work) from that
|
|
||||||
copyright holder, and you cure the violation prior to 30 days after
|
|
||||||
your receipt of the notice.
|
|
||||||
|
|
||||||
Termination of your rights under this section does not terminate the
|
|
||||||
licenses of parties who have received copies or rights from you under
|
|
||||||
this License. If your rights have been terminated and not permanently
|
|
||||||
reinstated, you do not qualify to receive new licenses for the same
|
|
||||||
material under section 10.
|
|
||||||
|
|
||||||
9. Acceptance Not Required for Having Copies.
|
|
||||||
|
|
||||||
You are not required to accept this License in order to receive or
|
|
||||||
run a copy of the Program. Ancillary propagation of a covered work
|
|
||||||
occurring solely as a consequence of using peer-to-peer transmission
|
|
||||||
to receive a copy likewise does not require acceptance. However,
|
|
||||||
nothing other than this License grants you permission to propagate or
|
|
||||||
modify any covered work. These actions infringe copyright if you do
|
|
||||||
not accept this License. Therefore, by modifying or propagating a
|
|
||||||
covered work, you indicate your acceptance of this License to do so.
|
|
||||||
|
|
||||||
10. Automatic Licensing of Downstream Recipients.
|
|
||||||
|
|
||||||
Each time you convey a covered work, the recipient automatically
|
|
||||||
receives a license from the original licensors, to run, modify and
|
|
||||||
propagate that work, subject to this License. You are not responsible
|
|
||||||
for enforcing compliance by third parties with this License.
|
|
||||||
|
|
||||||
An "entity transaction" is a transaction transferring control of an
|
|
||||||
organization, or substantially all assets of one, or subdividing an
|
|
||||||
organization, or merging organizations. If propagation of a covered
|
|
||||||
work results from an entity transaction, each party to that
|
|
||||||
transaction who receives a copy of the work also receives whatever
|
|
||||||
licenses to the work the party's predecessor in interest had or could
|
|
||||||
give under the previous paragraph, plus a right to possession of the
|
|
||||||
Corresponding Source of the work from the predecessor in interest, if
|
|
||||||
the predecessor has it or can get it with reasonable efforts.
|
|
||||||
|
|
||||||
You may not impose any further restrictions on the exercise of the
|
|
||||||
rights granted or affirmed under this License. For example, you may
|
|
||||||
not impose a license fee, royalty, or other charge for exercise of
|
|
||||||
rights granted under this License, and you may not initiate litigation
|
|
||||||
(including a cross-claim or counterclaim in a lawsuit) alleging that
|
|
||||||
any patent claim is infringed by making, using, selling, offering for
|
|
||||||
sale, or importing the Program or any portion of it.
|
|
||||||
|
|
||||||
11. Patents.
|
|
||||||
|
|
||||||
A "contributor" is a copyright holder who authorizes use under this
|
|
||||||
License of the Program or a work on which the Program is based. The
|
|
||||||
work thus licensed is called the contributor's "contributor version".
|
|
||||||
|
|
||||||
A contributor's "essential patent claims" are all patent claims
|
|
||||||
owned or controlled by the contributor, whether already acquired or
|
|
||||||
hereafter acquired, that would be infringed by some manner, permitted
|
|
||||||
by this License, of making, using, or selling its contributor version,
|
|
||||||
but do not include claims that would be infringed only as a
|
|
||||||
consequence of further modification of the contributor version. For
|
|
||||||
purposes of this definition, "control" includes the right to grant
|
|
||||||
patent sublicenses in a manner consistent with the requirements of
|
|
||||||
this License.
|
|
||||||
|
|
||||||
Each contributor grants you a non-exclusive, worldwide, royalty-free
|
|
||||||
patent license under the contributor's essential patent claims, to
|
|
||||||
make, use, sell, offer for sale, import and otherwise run, modify and
|
|
||||||
propagate the contents of its contributor version.
|
|
||||||
|
|
||||||
In the following three paragraphs, a "patent license" is any express
|
|
||||||
agreement or commitment, however denominated, not to enforce a patent
|
|
||||||
(such as an express permission to practice a patent or covenant not to
|
|
||||||
sue for patent infringement). To "grant" such a patent license to a
|
|
||||||
party means to make such an agreement or commitment not to enforce a
|
|
||||||
patent against the party.
|
|
||||||
|
|
||||||
If you convey a covered work, knowingly relying on a patent license,
|
|
||||||
and the Corresponding Source of the work is not available for anyone
|
|
||||||
to copy, free of charge and under the terms of this License, through a
|
|
||||||
publicly available network server or other readily accessible means,
|
|
||||||
then you must either (1) cause the Corresponding Source to be so
|
|
||||||
available, or (2) arrange to deprive yourself of the benefit of the
|
|
||||||
patent license for this particular work, or (3) arrange, in a manner
|
|
||||||
consistent with the requirements of this License, to extend the patent
|
|
||||||
license to downstream recipients. "Knowingly relying" means you have
|
|
||||||
actual knowledge that, but for the patent license, your conveying the
|
|
||||||
covered work in a country, or your recipient's use of the covered work
|
|
||||||
in a country, would infringe one or more identifiable patents in that
|
|
||||||
country that you have reason to believe are valid.
|
|
||||||
|
|
||||||
If, pursuant to or in connection with a single transaction or
|
|
||||||
arrangement, you convey, or propagate by procuring conveyance of, a
|
|
||||||
covered work, and grant a patent license to some of the parties
|
|
||||||
receiving the covered work authorizing them to use, propagate, modify
|
|
||||||
or convey a specific copy of the covered work, then the patent license
|
|
||||||
you grant is automatically extended to all recipients of the covered
|
|
||||||
work and works based on it.
|
|
||||||
|
|
||||||
A patent license is "discriminatory" if it does not include within
|
|
||||||
the scope of its coverage, prohibits the exercise of, or is
|
|
||||||
conditioned on the non-exercise of one or more of the rights that are
|
|
||||||
specifically granted under this License. You may not convey a covered
|
|
||||||
work if you are a party to an arrangement with a third party that is
|
|
||||||
in the business of distributing software, under which you make payment
|
|
||||||
to the third party based on the extent of your activity of conveying
|
|
||||||
the work, and under which the third party grants, to any of the
|
|
||||||
parties who would receive the covered work from you, a discriminatory
|
|
||||||
patent license (a) in connection with copies of the covered work
|
|
||||||
conveyed by you (or copies made from those copies), or (b) primarily
|
|
||||||
for and in connection with specific products or compilations that
|
|
||||||
contain the covered work, unless you entered into that arrangement,
|
|
||||||
or that patent license was granted, prior to 28 March 2007.
|
|
||||||
|
|
||||||
Nothing in this License shall be construed as excluding or limiting
|
|
||||||
any implied license or other defenses to infringement that may
|
|
||||||
otherwise be available to you under applicable patent law.
|
|
||||||
|
|
||||||
12. No Surrender of Others' Freedom.
|
|
||||||
|
|
||||||
If conditions are imposed on you (whether by court order, agreement or
|
|
||||||
otherwise) that contradict the conditions of this License, they do not
|
|
||||||
excuse you from the conditions of this License. If you cannot convey a
|
|
||||||
covered work so as to satisfy simultaneously your obligations under this
|
|
||||||
License and any other pertinent obligations, then as a consequence you may
|
|
||||||
not convey it at all. For example, if you agree to terms that obligate you
|
|
||||||
to collect a royalty for further conveying from those to whom you convey
|
|
||||||
the Program, the only way you could satisfy both those terms and this
|
|
||||||
License would be to refrain entirely from conveying the Program.
|
|
||||||
|
|
||||||
13. Use with the GNU Affero General Public License.
|
|
||||||
|
|
||||||
Notwithstanding any other provision of this License, you have
|
|
||||||
permission to link or combine any covered work with a work licensed
|
|
||||||
under version 3 of the GNU Affero General Public License into a single
|
|
||||||
combined work, and to convey the resulting work. The terms of this
|
|
||||||
License will continue to apply to the part which is the covered work,
|
|
||||||
but the special requirements of the GNU Affero General Public License,
|
|
||||||
section 13, concerning interaction through a network will apply to the
|
|
||||||
combination as such.
|
|
||||||
|
|
||||||
14. Revised Versions of this License.
|
|
||||||
|
|
||||||
The Free Software Foundation may publish revised and/or new versions of
|
|
||||||
the GNU General Public License from time to time. Such new versions will
|
|
||||||
be similar in spirit to the present version, but may differ in detail to
|
|
||||||
address new problems or concerns.
|
|
||||||
|
|
||||||
Each version is given a distinguishing version number. If the
|
|
||||||
Program specifies that a certain numbered version of the GNU General
|
|
||||||
Public License "or any later version" applies to it, you have the
|
|
||||||
option of following the terms and conditions either of that numbered
|
|
||||||
version or of any later version published by the Free Software
|
|
||||||
Foundation. If the Program does not specify a version number of the
|
|
||||||
GNU General Public License, you may choose any version ever published
|
|
||||||
by the Free Software Foundation.
|
|
||||||
|
|
||||||
If the Program specifies that a proxy can decide which future
|
|
||||||
versions of the GNU General Public License can be used, that proxy's
|
|
||||||
public statement of acceptance of a version permanently authorizes you
|
|
||||||
to choose that version for the Program.
|
|
||||||
|
|
||||||
Later license versions may give you additional or different
|
|
||||||
permissions. However, no additional obligations are imposed on any
|
|
||||||
author or copyright holder as a result of your choosing to follow a
|
|
||||||
later version.
|
|
||||||
|
|
||||||
15. Disclaimer of Warranty.
|
|
||||||
|
|
||||||
THERE IS NO WARRANTY FOR THE PROGRAM, TO THE EXTENT PERMITTED BY
|
|
||||||
APPLICABLE LAW. EXCEPT WHEN OTHERWISE STATED IN WRITING THE COPYRIGHT
|
|
||||||
HOLDERS AND/OR OTHER PARTIES PROVIDE THE PROGRAM "AS IS" WITHOUT WARRANTY
|
|
||||||
OF ANY KIND, EITHER EXPRESSED OR IMPLIED, INCLUDING, BUT NOT LIMITED TO,
|
|
||||||
THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
|
|
||||||
PURPOSE. THE ENTIRE RISK AS TO THE QUALITY AND PERFORMANCE OF THE PROGRAM
|
|
||||||
IS WITH YOU. SHOULD THE PROGRAM PROVE DEFECTIVE, YOU ASSUME THE COST OF
|
|
||||||
ALL NECESSARY SERVICING, REPAIR OR CORRECTION.
|
|
||||||
|
|
||||||
16. Limitation of Liability.
|
|
||||||
|
|
||||||
IN NO EVENT UNLESS REQUIRED BY APPLICABLE LAW OR AGREED TO IN WRITING
|
|
||||||
WILL ANY COPYRIGHT HOLDER, OR ANY OTHER PARTY WHO MODIFIES AND/OR CONVEYS
|
|
||||||
THE PROGRAM AS PERMITTED ABOVE, BE LIABLE TO YOU FOR DAMAGES, INCLUDING ANY
|
|
||||||
GENERAL, SPECIAL, INCIDENTAL OR CONSEQUENTIAL DAMAGES ARISING OUT OF THE
|
|
||||||
USE OR INABILITY TO USE THE PROGRAM (INCLUDING BUT NOT LIMITED TO LOSS OF
|
|
||||||
DATA OR DATA BEING RENDERED INACCURATE OR LOSSES SUSTAINED BY YOU OR THIRD
|
|
||||||
PARTIES OR A FAILURE OF THE PROGRAM TO OPERATE WITH ANY OTHER PROGRAMS),
|
|
||||||
EVEN IF SUCH HOLDER OR OTHER PARTY HAS BEEN ADVISED OF THE POSSIBILITY OF
|
|
||||||
SUCH DAMAGES.
|
|
||||||
|
|
||||||
17. Interpretation of Sections 15 and 16.
|
|
||||||
|
|
||||||
If the disclaimer of warranty and limitation of liability provided
|
|
||||||
above cannot be given local legal effect according to their terms,
|
|
||||||
reviewing courts shall apply local law that most closely approximates
|
|
||||||
an absolute waiver of all civil liability in connection with the
|
|
||||||
Program, unless a warranty or assumption of liability accompanies a
|
|
||||||
copy of the Program in return for a fee.
|
|
||||||
|
|
||||||
END OF TERMS AND CONDITIONS
|
|
||||||
|
|
||||||
How to Apply These Terms to Your New Programs
|
|
||||||
|
|
||||||
If you develop a new program, and you want it to be of the greatest
|
|
||||||
possible use to the public, the best way to achieve this is to make it
|
|
||||||
free software which everyone can redistribute and change under these terms.
|
|
||||||
|
|
||||||
To do so, attach the following notices to the program. It is safest
|
|
||||||
to attach them to the start of each source file to most effectively
|
|
||||||
state the exclusion of warranty; and each file should have at least
|
|
||||||
the "copyright" line and a pointer to where the full notice is found.
|
|
||||||
|
|
||||||
<one line to give the program's name and a brief idea of what it does.>
|
|
||||||
Copyright (C) <year> <name of author>
|
|
||||||
|
|
||||||
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/>.
|
|
||||||
|
|
||||||
Also add information on how to contact you by electronic and paper mail.
|
|
||||||
|
|
||||||
If the program does terminal interaction, make it output a short
|
|
||||||
notice like this when it starts in an interactive mode:
|
|
||||||
|
|
||||||
<program> Copyright (C) <year> <name of author>
|
|
||||||
This program comes with ABSOLUTELY NO WARRANTY; for details type `show w'.
|
|
||||||
This is free software, and you are welcome to redistribute it
|
|
||||||
under certain conditions; type `show c' for details.
|
|
||||||
|
|
||||||
The hypothetical commands `show w' and `show c' should show the appropriate
|
|
||||||
parts of the General Public License. Of course, your program's commands
|
|
||||||
might be different; for a GUI interface, you would use an "about box".
|
|
||||||
|
|
||||||
You should also get your employer (if you work as a programmer) or school,
|
|
||||||
if any, to sign a "copyright disclaimer" for the program, if necessary.
|
|
||||||
For more information on this, and how to apply and follow the GNU GPL, see
|
|
||||||
<http://www.gnu.org/licenses/>.
|
|
||||||
|
|
||||||
The GNU General Public License does not permit incorporating your program
|
|
||||||
into proprietary programs. If your program is a subroutine library, you
|
|
||||||
may consider it more useful to permit linking proprietary applications with
|
|
||||||
the library. If this is what you want to do, use the GNU Lesser General
|
|
||||||
Public License instead of this License. But first, please read
|
|
||||||
<http://www.gnu.org/philosophy/why-not-lgpl.html>.
|
|
||||||
BIN
Binary file not shown.
-60
@@ -1,60 +0,0 @@
|
|||||||
onerror {resume}
|
|
||||||
quietly WaveActivateNextPane {} 0
|
|
||||||
add wave -noupdate -divider {MIPS top}
|
|
||||||
add wave -noupdate -format Literal /tb_mips_top/debug
|
|
||||||
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/mrdy_o
|
|
||||||
add wave -noupdate -format Logic /tb_mips_top/cyc_o
|
|
||||||
add wave -noupdate -format Literal -radix hexadecimal /tb_mips_top/addr_o
|
|
||||||
add wave -noupdate -format Literal /tb_mips_top/sel_o
|
|
||||||
add wave -noupdate -format Logic /tb_mips_top/we_o
|
|
||||||
add wave -noupdate -format Logic /tb_mips_top/stb_o
|
|
||||||
add wave -noupdate -format Logic /tb_mips_top/srdy_i
|
|
||||||
add wave -noupdate -format Logic /tb_mips_top/ack_i
|
|
||||||
add wave -noupdate -format Literal -radix hexadecimal /tb_mips_top/dat_i
|
|
||||||
add wave -noupdate -format Literal -radix hexadecimal /tb_mips_top/dat_o
|
|
||||||
add wave -noupdate -format Literal /tb_mips_top/int
|
|
||||||
add wave -noupdate -divider Flash
|
|
||||||
add wave -noupdate -format Logic /tb_mips_top/clk
|
|
||||||
add wave -noupdate -format Logic /tb_mips_top/flash_cs_n
|
|
||||||
add wave -noupdate -format Logic /tb_mips_top/flash_oe_n
|
|
||||||
add wave -noupdate -format Literal -radix hexadecimal /tb_mips_top/flash_a
|
|
||||||
add wave -noupdate -format Literal -radix hexadecimal /tb_mips_top/flash_d
|
|
||||||
add wave -noupdate -divider SRAM
|
|
||||||
add wave -noupdate -format Logic /tb_mips_top/clk
|
|
||||||
add wave -noupdate -format Logic /tb_mips_top/sram_cs_n
|
|
||||||
add wave -noupdate -format Literal /tb_mips_top/sram_wr_n
|
|
||||||
add wave -noupdate -format Logic /tb_mips_top/sram_oe_n
|
|
||||||
add wave -noupdate -format Literal -radix hexadecimal /tb_mips_top/sram_a
|
|
||||||
add wave -noupdate -format Literal -radix hexadecimal /tb_mips_top/sram_d
|
|
||||||
add wave -noupdate -divider GPIO
|
|
||||||
add wave -noupdate -format Logic /tb_mips_top/clk
|
|
||||||
add wave -noupdate -format Literal -radix hexadecimal /tb_mips_top/gpo0
|
|
||||||
add wave -noupdate -format Literal -radix hexadecimal /tb_mips_top/gpo1
|
|
||||||
add wave -noupdate -format Literal -radix hexadecimal /tb_mips_top/gpi0
|
|
||||||
add wave -noupdate -format Literal -radix hexadecimal /tb_mips_top/gpi1
|
|
||||||
add wave -noupdate -divider UART
|
|
||||||
add wave -noupdate -format Logic /tb_mips_top/clk
|
|
||||||
add wave -noupdate -format Logic /tb_mips_top/int_uart_rx
|
|
||||||
add wave -noupdate -format Logic /tb_mips_top/rx
|
|
||||||
add wave -noupdate -format Logic /tb_mips_top/tx
|
|
||||||
add wave -noupdate -divider {Memory bus}
|
|
||||||
add wave -noupdate -format Logic /tb_mips_top/clk
|
|
||||||
add wave -noupdate -format Literal /tb_mips_top/mem_area
|
|
||||||
TreeUpdate [SetDefaultTree]
|
|
||||||
WaveRestoreCursors {{Cursor 1} {222066850 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 {221809160 ps} {222394902 ps}
|
|
||||||
@@ -1,109 +0,0 @@
|
|||||||
-----------------------------------------------------------------
|
|
||||||
J-MIPS Features
|
|
||||||
-----------------------------------------------------------------
|
|
||||||
|
|
||||||
- Synchrones Design
|
|
||||||
- Portable Beschreibung in VHDL
|
|
||||||
- Kompatible zur GNU Toolchain (Binutils, GCC, Newlib)
|
|
||||||
- Befehle kompatibel mit MIPS-1 ISA (z.B. MIPS R3000)
|
|
||||||
- 5-Stufige Pipeline und Hazardvermeidung durch Forwarding
|
|
||||||
- 64Bit Multiplier (32Bit Operanden), 12 Cycles Latenz
|
|
||||||
- 64Bit Divider (32Bit Operanden), 36 Cycles Latenz
|
|
||||||
- Coprocessor 0 (COP0) für Exceptionhandling
|
|
||||||
- Direct-mapped Instruction Cache mit variabler Größe, 8-words per Line
|
|
||||||
- Direct-mapped Data Cache mit variabler Größe, 8-words per Line
|
|
||||||
- J-Bus kompatible Bus Interface Unit (J-Bus ist im wesentlichen FIFO interface mit 'wichtigen' Signalnamen)
|
|
||||||
- 1,2 DMIPS/MHz mit 16Kbyte I/D-Cache (Dhrystone 2.1, GCC 4.3)
|
|
||||||
|
|
||||||
-----------------------------------------------------------------
|
|
||||||
Known Limitations
|
|
||||||
-----------------------------------------------------------------
|
|
||||||
- keine MMU
|
|
||||||
- z.Zt. nur Little-endian.
|
|
||||||
- keine Unterstützung für Bus exceptions IBE und DBE
|
|
||||||
- kein externes Coprocessor interface (COP1..3) für z.B. FPU
|
|
||||||
- Befehle für Cop1..3 nicht implementiert:
|
|
||||||
CFCz, CTCz, COPz, MFCz, MTCz, LWCz, SWCz
|
|
||||||
Benutzung dieser Befehle führt zur Exception 'RI' (Reserved Instruction)
|
|
||||||
- nicht alle COP0 Register/Bits vorhanden.
|
|
||||||
|
|
||||||
-----------------------------------------------------------------
|
|
||||||
Known Bugs
|
|
||||||
-----------------------------------------------------------------
|
|
||||||
- Umschaltung (RE) zwischen Little/Big-Endian fehlerhaft
|
|
||||||
- es gibt bestimmt noch nicht entdeckte Bugs
|
|
||||||
|
|
||||||
-----------------------------------------------------------------
|
|
||||||
Known Optimizations
|
|
||||||
-----------------------------------------------------------------
|
|
||||||
- Area: Multiplier als technologieabhängiges Primitive instanzieren
|
|
||||||
- Area: Auf Divider verzichten
|
|
||||||
- Area: Auf Multiplier verzichten
|
|
||||||
- Area vs. Speed: Bei Hazards Pipeline-stall statt Forwarding.
|
|
||||||
Durch Stalling geringerer Befehlsdurchsatz dafür weniger Logik.
|
|
||||||
Weniger Logik bedeutet vielleicht wieder auch größere Taktfrequenz.
|
|
||||||
|
|
||||||
-----------------------------------------------------------------
|
|
||||||
Known ToDos
|
|
||||||
-----------------------------------------------------------------
|
|
||||||
- Unterstützung für Bus exceptions IBE und DBE
|
|
||||||
- Externes COP1..3 interface, fehlende COP-Befehle implementieren
|
|
||||||
- Optimierungen evaluieren und ggf. durchführen
|
|
||||||
|
|
||||||
-----------------------------------------------------------------
|
|
||||||
Synthesis results
|
|
||||||
-----------------------------------------------------------------
|
|
||||||
Virtex-4 XC4VSX35-10
|
|
||||||
|
|
||||||
Config: 16Kbyte I/D-Cache
|
|
||||||
|
|
||||||
Number of Slices 2387 15360 15%
|
|
||||||
Number of Slice Flip Flops 1784 30720 5%
|
|
||||||
Number of 4 input LUTs 3962 30720 12%
|
|
||||||
Number of FIFO16/RAMB16s 18 192 9%
|
|
||||||
|
|
||||||
Speed: 110MHz nach Synthesis
|
|
||||||
|
|
||||||
-----------------------------------------------------------------
|
|
||||||
Virtex-1 XCV1000-4
|
|
||||||
|
|
||||||
Config: 4Kbyte I/D-Cache
|
|
||||||
|
|
||||||
Number of Slices 2045 13824 16%
|
|
||||||
Number of Slice Flip Flops 1783 27648 7%
|
|
||||||
Number of 4 input LUTs 3923 27648 15%
|
|
||||||
Number of FIFO16/RAMB16s 20 32 62%
|
|
||||||
|
|
||||||
Speed: 30MHz nach Synthesis
|
|
||||||
|
|
||||||
-----------------------------------------------------------------
|
|
||||||
Performance bei 100MHz
|
|
||||||
- GCC ohne Small-data section
|
|
||||||
- MIPS Rev. 9
|
|
||||||
-----------------------------------------------------------------
|
|
||||||
I/D-Cache Dhrystone-2.1 RipeMD-160 Whetstone Stanford Queens(12x12)
|
|
||||||
1k 32 DMIPS 5 Mbit/s 345 kwhets/s 47/767 2,135s
|
|
||||||
2k 51 DMIPS 5 Mbit/s 534 kwhets/s 38/561 2,134s
|
|
||||||
4k 72 DMIPS 5 Mbit/s 623 kwhets/s 36/259 2,121s
|
|
||||||
8k 98 DMIPS 10 Mbit/s 1149 kwhets/s 31/228 1,938s
|
|
||||||
16k 115 DMIPS 17 Mbit/s 1234 kwhets/s 23/225 1,938s
|
|
||||||
32k 115 DMIPS 17 Mbit/s 1285 kwhets/s 24/218 1,938s
|
|
||||||
64k 115 DMIPS 17 Mbit/s 1285 kwhets/s 20/221 1,938s
|
|
||||||
|
|
||||||
-----------------------------------------------------------------
|
|
||||||
Performance bei 100MHz
|
|
||||||
- GCC mit Small-data section
|
|
||||||
- MIPS Rev. 9
|
|
||||||
-----------------------------------------------------------------
|
|
||||||
I/D-Cache Dhrystone-2.1 RipeMD-160 Whetstone Stanford Queens(12x12)
|
|
||||||
16k 117 DMIPS 17 Mbit/s 1236 kwhets/s 24/230 1,811s
|
|
||||||
|
|
||||||
-----------------------------------------------------------------
|
|
||||||
Performance bei 100MHz
|
|
||||||
- GCC mit Small-data section
|
|
||||||
- MIPS Rev. 10
|
|
||||||
-----------------------------------------------------------------
|
|
||||||
I/D-Cache Dhrystone-2.1 RipeMD-160 Whetstone Stanford Queens(12x12)
|
|
||||||
16k 120 DMIPS 17 Mbit/s 1242 kwhets/s 25/219 1,803s
|
|
||||||
|
|
||||||
|
|
||||||
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
@@ -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 8ms
|
|
||||||
@@ -1,78 +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/ref_hi
|
|
||||||
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/ref_result
|
|
||||||
add wave -noupdate -format Literal -radix hexadecimal /tb_mips_muldiv/md_result
|
|
||||||
add wave -noupdate -format Logic /tb_mips_muldiv/check
|
|
||||||
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} {7735999838 ps} 0} {{Cursor 2} {512321 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} {8400 us}
|
|
||||||
@@ -1,57 +0,0 @@
|
|||||||
## NOTE: Do not edit this file.
|
|
||||||
##
|
|
||||||
vlib work
|
|
||||||
|
|
||||||
# RAMS
|
|
||||||
vcom -explicit -93 "../../../misc/dpram_2w2r.vhd"
|
|
||||||
vcom -explicit -93 "../../../misc/dpram_1w1r.vhd"
|
|
||||||
vcom -explicit -93 "../../../misc/dpram_1w1r_dist.vhd"
|
|
||||||
|
|
||||||
# FIFOS
|
|
||||||
vcom -explicit -93 "../../../FIFO/src/fifo_ctrl_pkg.vhd"
|
|
||||||
vcom -explicit -93 "../../../FIFO/src/fifo_sync_ctrl.vhd"
|
|
||||||
vcom -explicit -93 "../../../FIFO/src/fifo_sync_dist.vhd"
|
|
||||||
|
|
||||||
# UART
|
|
||||||
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 "../../../uart/uart_wb.vhd"
|
|
||||||
|
|
||||||
# GPIO
|
|
||||||
vcom -explicit -93 "../../../misc/gpio_wb.vhd"
|
|
||||||
|
|
||||||
# Async port
|
|
||||||
vcom -explicit -93 "../../../misc/async_types.vhd"
|
|
||||||
vcom -explicit -93 "../../../misc/async_port_wb.vhd"
|
|
||||||
vcom -explicit -93 "../src/async_defs.vhd"
|
|
||||||
|
|
||||||
# ROM
|
|
||||||
vcom -explicit -93 "../src/bootloader.ROM.vhd"
|
|
||||||
vcom -explicit -93 "../../../misc/rom_wb.vhd"
|
|
||||||
|
|
||||||
# MIPS
|
|
||||||
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_muldiv.vhd"
|
|
||||||
vcom -explicit -93 "../src/core/mips_cop.vhd"
|
|
||||||
vcom -explicit -93 "../src/core/mips_icache.vhd"
|
|
||||||
vcom -explicit -93 "../src/core/mips_dcache.vhd"
|
|
||||||
vcom -explicit -93 "../src/core/mips_biu.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/tb_mips_top.vhd"
|
|
||||||
vsim -t 1ps -lib work tb_mips_top
|
|
||||||
do {tb_mips_top.wdo}
|
|
||||||
view wave
|
|
||||||
view structure
|
|
||||||
view signals
|
|
||||||
run 1600us
|
|
||||||
@@ -1,74 +0,0 @@
|
|||||||
onerror {resume}
|
|
||||||
quietly WaveActivateNextPane {} 0
|
|
||||||
add wave -noupdate -divider {TOP interface}
|
|
||||||
add wave -noupdate -format Logic /tb_mips_top/clk
|
|
||||||
add wave -noupdate -format Literal /tb_mips_top/debug
|
|
||||||
add wave -noupdate -format Logic /tb_mips_top/stb_o
|
|
||||||
add wave -noupdate -format Logic /tb_mips_top/ack_i
|
|
||||||
add wave -noupdate -format Logic /tb_mips_top/srdy_i
|
|
||||||
add wave -noupdate -format Literal -radix hexadecimal /tb_mips_top/addr_o
|
|
||||||
add wave -noupdate -format Literal -radix hexadecimal /tb_mips_top/dat_i
|
|
||||||
add wave -noupdate -format Literal -radix hexadecimal /tb_mips_top/dat_o
|
|
||||||
add wave -noupdate -format Logic /tb_mips_top/we_o
|
|
||||||
add wave -noupdate -format Literal /tb_mips_top/sel_o
|
|
||||||
add wave -noupdate -format Logic /tb_mips_top/cyc_o
|
|
||||||
add wave -noupdate -format Logic /tb_mips_top/mrdy_o
|
|
||||||
add wave -noupdate -format Literal /tb_mips_top/int
|
|
||||||
add wave -noupdate -divider {External components}
|
|
||||||
add wave -noupdate -format Logic /tb_mips_top/clk
|
|
||||||
add wave -noupdate -format Literal -radix hexadecimal /tb_mips_top/gpo0
|
|
||||||
add wave -noupdate -format Literal -radix hexadecimal /tb_mips_top/gpo1
|
|
||||||
add wave -noupdate -format Literal -radix hexadecimal /tb_mips_top/gpi0
|
|
||||||
add wave -noupdate -format Literal -radix hexadecimal /tb_mips_top/gpi1
|
|
||||||
add wave -noupdate -format Logic /tb_mips_top/clk
|
|
||||||
add wave -noupdate -format Logic /tb_mips_top/rx
|
|
||||||
add wave -noupdate -format Logic /tb_mips_top/tx
|
|
||||||
add wave -noupdate -format Logic /tb_mips_top/clk
|
|
||||||
add wave -noupdate -format Literal /tb_mips_top/mem_area
|
|
||||||
add wave -noupdate -format Literal -radix hexadecimal /tb_mips_top/sram_a
|
|
||||||
add wave -noupdate -format Literal -radix hexadecimal /tb_mips_top/sram_d
|
|
||||||
add wave -noupdate -format Literal -radix hexadecimal /tb_mips_top/flash_a
|
|
||||||
add wave -noupdate -format Literal -radix hexadecimal /tb_mips_top/flash_d
|
|
||||||
add wave -noupdate -format Logic /tb_mips_top/flash_cs_n
|
|
||||||
add wave -noupdate -format Logic /tb_mips_top/flash_oe_n
|
|
||||||
add wave -noupdate -format Literal /tb_mips_top/flash_be_n
|
|
||||||
add wave -noupdate -format Logic /tb_mips_top/sram_cs_n
|
|
||||||
add wave -noupdate -format Literal /tb_mips_top/sram_wr_n
|
|
||||||
add wave -noupdate -format Logic /tb_mips_top/sram_oe_n
|
|
||||||
add wave -noupdate -format Literal /tb_mips_top/sram_be_n
|
|
||||||
add wave -noupdate -divider ALU
|
|
||||||
add wave -noupdate -format Logic /tb_mips_top/clk
|
|
||||||
add wave -noupdate -format Literal /tb_mips_top/uut/inst_pipeline/hdu
|
|
||||||
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/pc
|
|
||||||
add wave -noupdate -divider PC
|
|
||||||
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 -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 -expand /tb_mips_top/uut/inst_pipeline/wb_stage
|
|
||||||
add wave -noupdate -format Logic /tb_mips_top/uut/inst_pipeline/rst
|
|
||||||
add wave -noupdate -format Logic /tb_mips_top/uut/inst_pipeline/cpu_rst
|
|
||||||
add wave -noupdate -format Logic /tb_mips_top/uut/inst_pipeline/cpu_run
|
|
||||||
add wave -noupdate -format Logic /tb_mips_top/uut/inst_pipeline/run_en
|
|
||||||
add wave -noupdate -format Literal -radix hexadecimal -expand /tb_mips_top/uut/inst_pipeline/inst_reg_dual/reg_mem
|
|
||||||
TreeUpdate [SetDefaultTree]
|
|
||||||
WaveRestoreCursors {{Cursor 1} {1375665640 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} {1680 us}
|
|
||||||
@@ -1,62 +0,0 @@
|
|||||||
-------------------------------------------------------------------------
|
|
||||||
-- Project: MIPS System controller
|
|
||||||
-- This 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;
|
|
||||||
|
|
||||||
use work.async_types.all;
|
|
||||||
|
|
||||||
package async_defs is
|
|
||||||
|
|
||||||
constant ts_flash : async_timespec_t :=
|
|
||||||
(
|
|
||||||
ncyc_access => 1,
|
|
||||||
ncyc_pulse_rd => 12,
|
|
||||||
ncyc_pulse_wr => 7,
|
|
||||||
ncyc_cs_hold => 1,
|
|
||||||
ncyc_release => 1,
|
|
||||||
ncyc_pulse_rst => 8,
|
|
||||||
pol_cs => '0',
|
|
||||||
pol_oe => '0',
|
|
||||||
pol_we => '0',
|
|
||||||
pol_be => '0',
|
|
||||||
pol_rst => '0'
|
|
||||||
);
|
|
||||||
|
|
||||||
constant ts_sram : async_timespec_t :=
|
|
||||||
(
|
|
||||||
ncyc_access => 1,
|
|
||||||
ncyc_pulse_rd => 12,
|
|
||||||
ncyc_pulse_wr => 7,
|
|
||||||
ncyc_cs_hold => 1,
|
|
||||||
ncyc_release => 1,
|
|
||||||
ncyc_pulse_rst => 8,
|
|
||||||
pol_cs => '0',
|
|
||||||
pol_oe => '0',
|
|
||||||
pol_we => '0',
|
|
||||||
pol_be => '0',
|
|
||||||
pol_rst => '0'
|
|
||||||
);
|
|
||||||
|
|
||||||
end async_defs;
|
|
||||||
File diff suppressed because it is too large
Load Diff
@@ -1,12 +0,0 @@
|
|||||||
VHDL/lib/CPUs/MIPS/src/core/dcache.vhd
|
|
||||||
VHDL/lib/CPUs/MIPS/src/core/mips_dcache.vhd
|
|
||||||
VHDL/lib/CPUs/MIPS/src/core/icache.vhd
|
|
||||||
VHDL/lib/CPUs/MIPS/src/core/mips_icache.vhd
|
|
||||||
VHDL/lib/CPUs/MIPS/src/core/mips_biu.vhd
|
|
||||||
|
|
||||||
VHDL/lib/CPUs/MIPS/src/core/mips_bui.vhd
|
|
||||||
VHDL/lib/CPUs/MIPS/src/core/mips_biu.vhd
|
|
||||||
VHDL/lib/CPUs/MIPS/src/core/mips_dcache.vhd
|
|
||||||
|
|
||||||
VHDL/lib/CPUs/MIPS/src/core/mips_icache.vhd
|
|
||||||
|
|
||||||
@@ -1,442 +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
|
|
||||||
(
|
|
||||||
RST_I : in STD_LOGIC;
|
|
||||||
CLK_I : in STD_LOGIC;
|
|
||||||
ACK_I : in STD_LOGIC;
|
|
||||||
SRDY_I : in STD_LOGIC;
|
|
||||||
ADDR_O : out word_t;
|
|
||||||
DAT_I : in word_t;
|
|
||||||
STB_O : out STD_LOGIC;
|
|
||||||
CYC_O : out STD_LOGIC;
|
|
||||||
en : in STD_LOGIC;
|
|
||||||
cpu_en : in STD_LOGIC;
|
|
||||||
cpu_we : in STD_LOGIC;
|
|
||||||
cpu_be : 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
|
|
||||||
);
|
|
||||||
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 := 1 + 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;
|
|
||||||
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.tv_p := x(3 downto 1);
|
|
||||||
result.tag := x(tag_width+3 downto 4);
|
|
||||||
|
|
||||||
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(3 downto 1) := x.tv_p;
|
|
||||||
result(tag_width+3 downto 4) := 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);
|
|
||||||
signal s, sn : cache_state_t;
|
|
||||||
|
|
||||||
signal cache_busy : std_logic;
|
|
||||||
signal cache_hit : std_logic;
|
|
||||||
signal tag_match : std_logic;
|
|
||||||
signal word_index_reg : unsigned(word_index_width-1 downto 0);
|
|
||||||
signal addr_windex_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_be_reg : unsigned(3 downto 0);
|
|
||||||
signal cpu_we_reg : std_logic;
|
|
||||||
signal ctrl_dram_en : 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 cpu_dram_en : std_logic;
|
|
||||||
signal cpu_en2 : std_logic;
|
|
||||||
signal cpu_we2 : 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_we : std_logic;
|
|
||||||
|
|
||||||
signal fill_count : natural range 0 to 2**word_index_width-1;
|
|
||||||
signal fill_count_rst : std_logic;
|
|
||||||
signal flush_index_count : natural range 0 to 2**cache_index_width-1;
|
|
||||||
signal flush_index_count_en : std_logic;
|
|
||||||
signal request_count : natural range 0 to 2**word_index_width-1;
|
|
||||||
signal request_count_en : std_logic;
|
|
||||||
signal request_count_rst : std_logic;
|
|
||||||
signal cpu_reg_en : std_logic;
|
|
||||||
signal was_miss : std_logic;
|
|
||||||
signal cache_fill : std_logic;
|
|
||||||
signal cpu_hit_we : std_logic;
|
|
||||||
signal instant_raw : std_logic;
|
|
||||||
|
|
||||||
begin
|
|
||||||
|
|
||||||
cpu_hit_we <= cpu_we2 and cache_hit;
|
|
||||||
|
|
||||||
cpu_index_register:
|
|
||||||
process(CLK_I)
|
|
||||||
begin
|
|
||||||
if rising_edge(CLK_I) then
|
|
||||||
if cache_fill = '1' then
|
|
||||||
if ACK_I = '1' then
|
|
||||||
word_index_reg <= word_index_reg + 1;
|
|
||||||
end if;
|
|
||||||
elsif cpu_reg_en = '1' and en = '1' and instant_raw = '0' then
|
|
||||||
word_index_reg <= cpu_word_index;
|
|
||||||
cache_index_reg <= cpu_cache_index;
|
|
||||||
tag_index_reg <= cpu_tag;
|
|
||||||
end if;
|
|
||||||
end if;
|
|
||||||
end process;
|
|
||||||
|
|
||||||
addr_windex_register:
|
|
||||||
process(CLK_I)
|
|
||||||
begin
|
|
||||||
if rising_edge(CLK_I) then
|
|
||||||
if request_count_en = '1' and SRDY_I = '1' then
|
|
||||||
addr_windex_reg <= addr_windex_reg + 1;
|
|
||||||
elsif cpu_reg_en = '1' and en = '1' and instant_raw = '0' then
|
|
||||||
addr_windex_reg <= cpu_word_index;
|
|
||||||
end if;
|
|
||||||
end if;
|
|
||||||
end process;
|
|
||||||
|
|
||||||
cpu_data_register:
|
|
||||||
process(CLK_I)
|
|
||||||
begin
|
|
||||||
if rising_edge(CLK_I) then
|
|
||||||
if RST_I = '1' then
|
|
||||||
cpu_we_reg <= '0';
|
|
||||||
elsif cpu_reg_en = '1' and en = '1' then
|
|
||||||
cpu_data_reg <= cpu_din;
|
|
||||||
cpu_be_reg <= cpu_be;
|
|
||||||
cpu_we_reg <= cpu_we;
|
|
||||||
end if;
|
|
||||||
end if;
|
|
||||||
end process;
|
|
||||||
|
|
||||||
cpu_was_wr_register:
|
|
||||||
process(CLK_I)
|
|
||||||
begin
|
|
||||||
if rising_edge(CLK_I) then
|
|
||||||
cpu_en2 <= '0';
|
|
||||||
cpu_we2 <= '0';
|
|
||||||
if cpu_en = '1' and en = '1' then
|
|
||||||
cpu_we2 <= cpu_we;
|
|
||||||
cpu_en2 <= '1';
|
|
||||||
cpu_dram_din <= cpu_din;
|
|
||||||
end if;
|
|
||||||
end if;
|
|
||||||
end process;
|
|
||||||
|
|
||||||
instant_raw_logic:
|
|
||||||
process(CLK_I)
|
|
||||||
begin
|
|
||||||
if rising_edge(CLK_I) then
|
|
||||||
instant_raw <= '0';
|
|
||||||
if cpu_word_index = word_index_reg then
|
|
||||||
instant_raw <= cpu_hit_we and cpu_en and en and not cpu_we;
|
|
||||||
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_I,
|
|
||||||
clkb => CLK_I,
|
|
||||||
en_a => '1',
|
|
||||||
en_b => '1',
|
|
||||||
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_I,
|
|
||||||
clk_b => CLK_I,
|
|
||||||
en_a => '1',
|
|
||||||
en_b => '1',
|
|
||||||
we_a => cpu_dram_we(i),
|
|
||||||
we_b => ctrl_dram_we(i),
|
|
||||||
addr_a => ctrl_dram_addr,
|
|
||||||
addr_b => cpu_dram_addr,
|
|
||||||
din_a => cpu_data_reg(8*(i+1)-1 downto 8*i),
|
|
||||||
din_b => DAT_I(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_I)
|
|
||||||
begin
|
|
||||||
if rising_edge(CLK_I) then
|
|
||||||
if RST_I = '1' then
|
|
||||||
s <= init;
|
|
||||||
else
|
|
||||||
s <= sn;
|
|
||||||
end if;
|
|
||||||
end if;
|
|
||||||
end process;
|
|
||||||
|
|
||||||
cpu_busy <= cache_busy or instant_raw;
|
|
||||||
cpu_dout <= cpu_dram_dout;
|
|
||||||
|
|
||||||
tag_match <= '1' when tag_index_reg = cache_entry_out.tag else '0';
|
|
||||||
cache_hit <= tag_match and cache_entry_out.valid;
|
|
||||||
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 instant_raw = '0' and cache_fill = '0') else (cache_index_reg & word_index_reg);
|
|
||||||
ADDR_O <= tag_index_reg & cache_index_reg & addr_windex_reg & "00";
|
|
||||||
ctrl_dram_addr <= cache_index_reg & word_index_reg;
|
|
||||||
ctrl_dram_we <= (others => cache_fill and ACK_I);
|
|
||||||
cpu_dram_we <= cpu_be_reg when (cpu_hit_we = '1') else (others => '0');
|
|
||||||
|
|
||||||
cache_state:
|
|
||||||
process(s, instant_raw, cache_hit, flush_index_count, fill_count, request_count, cache_index_reg, ACK_I, tag_index_reg, cpu_en, SRDY_I, cpu_en2, cpu_we_reg)
|
|
||||||
begin
|
|
||||||
cpu_reg_en <= '0';
|
|
||||||
cache_busy <= '1';
|
|
||||||
tram_we <= '0';
|
|
||||||
flush_index_count_en <= '0';
|
|
||||||
fill_count_rst <= '0';
|
|
||||||
request_count_en <= '0';
|
|
||||||
request_count_rst <= '0';
|
|
||||||
CYC_O <= '0';
|
|
||||||
STB_O <= '0';
|
|
||||||
was_miss <= '0';
|
|
||||||
cache_fill <= '0';
|
|
||||||
tram_addr_wr <= to_unsigned(flush_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 =>
|
|
||||||
cache_busy <= '0';
|
|
||||||
cpu_reg_en <= '1';
|
|
||||||
if cpu_en2 = '1' then
|
|
||||||
if cache_hit = '0' and cpu_we_reg = '0' then
|
|
||||||
sn <= mem_request;
|
|
||||||
cpu_reg_en <= '0';
|
|
||||||
cache_busy <= '1';
|
|
||||||
CYC_O <= '1';
|
|
||||||
end if;
|
|
||||||
end if;
|
|
||||||
when flush =>
|
|
||||||
flush_index_count_en <= '1';
|
|
||||||
tram_addr_wr <= to_unsigned(flush_index_count, cache_index_width);
|
|
||||||
tram_we <= '1';
|
|
||||||
cache_entry_in.valid <= '0';
|
|
||||||
cache_entry_in.tag <= (others => '0');
|
|
||||||
if flush_index_count = 0 then
|
|
||||||
sn <= ready;
|
|
||||||
if cpu_en = '1' then
|
|
||||||
cpu_reg_en <= '1';
|
|
||||||
end if;
|
|
||||||
end if;
|
|
||||||
when mem_request =>
|
|
||||||
fill_count_rst <= '1';
|
|
||||||
request_count_rst <= '1';
|
|
||||||
CYC_O <= '1';
|
|
||||||
if SRDY_I = '1' then
|
|
||||||
sn <= mem_access;
|
|
||||||
end if;
|
|
||||||
when mem_access =>
|
|
||||||
cache_fill <= '1';
|
|
||||||
request_count_en <= '1';
|
|
||||||
CYC_O <= '1';
|
|
||||||
STB_O <= '1';
|
|
||||||
if request_count = 0 then
|
|
||||||
if SRDY_I = '1' then
|
|
||||||
sn <= mem_data;
|
|
||||||
end if;
|
|
||||||
end if;
|
|
||||||
when mem_data =>
|
|
||||||
CYC_O <= '1';
|
|
||||||
cache_fill <= '1';
|
|
||||||
if fill_count = 0 then
|
|
||||||
if ACK_I = '1' then
|
|
||||||
sn <= upd_cache;
|
|
||||||
end if;
|
|
||||||
end if;
|
|
||||||
when upd_cache =>
|
|
||||||
tram_addr_wr <= cache_index_reg;
|
|
||||||
tram_we <= '1';
|
|
||||||
cache_entry_in.valid <= '1';
|
|
||||||
sn <= rd_cache;
|
|
||||||
when rd_cache =>
|
|
||||||
was_miss <= '1';
|
|
||||||
sn <= ready;
|
|
||||||
|
|
||||||
when others =>
|
|
||||||
sn <= ready;
|
|
||||||
end case;
|
|
||||||
end process;
|
|
||||||
|
|
||||||
flush_index_counter:
|
|
||||||
process(CLK_I)
|
|
||||||
begin
|
|
||||||
if rising_edge(CLK_I) then
|
|
||||||
if flush_index_count_en = '0' then
|
|
||||||
flush_index_count <= 2**cache_index_width-1;
|
|
||||||
elsif flush_index_count /= 0 then
|
|
||||||
flush_index_count <= flush_index_count - 1;
|
|
||||||
end if;
|
|
||||||
end if;
|
|
||||||
end process;
|
|
||||||
|
|
||||||
fill_counter:
|
|
||||||
process(CLK_I)
|
|
||||||
begin
|
|
||||||
if rising_edge(CLK_I) then
|
|
||||||
if fill_count_rst = '1' then
|
|
||||||
fill_count <= 2**word_index_width-1;
|
|
||||||
elsif cache_fill = '1' and ACK_I = '1' then
|
|
||||||
if fill_count /= 0 then
|
|
||||||
fill_count <= fill_count - 1;
|
|
||||||
end if;
|
|
||||||
end if;
|
|
||||||
end if;
|
|
||||||
end process;
|
|
||||||
|
|
||||||
request_counter:
|
|
||||||
process(CLK_I)
|
|
||||||
begin
|
|
||||||
if rising_edge(CLK_I) then
|
|
||||||
if request_count_rst = '1' then
|
|
||||||
request_count <= 2**word_index_width-1;
|
|
||||||
elsif request_count_en = '1' and SRDY_I = '1' then
|
|
||||||
if request_count /= 0 then
|
|
||||||
request_count <= request_count - 1;
|
|
||||||
end if;
|
|
||||||
end if;
|
|
||||||
end if;
|
|
||||||
end process;
|
|
||||||
|
|
||||||
end behavior;
|
|
||||||
@@ -1,349 +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
|
|
||||||
(
|
|
||||||
RST_I : in STD_LOGIC;
|
|
||||||
CLK_I : in STD_LOGIC;
|
|
||||||
ACK_I : in STD_LOGIC;
|
|
||||||
SRDY_I : in STD_LOGIC;
|
|
||||||
ADDR_O : out word_t;
|
|
||||||
DAT_I : in word_t;
|
|
||||||
STB_O : out STD_LOGIC;
|
|
||||||
CYC_O : out 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
|
|
||||||
);
|
|
||||||
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_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_I)
|
|
||||||
begin
|
|
||||||
if rising_edge(CLK_I) then
|
|
||||||
if RST_I = '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_I,
|
|
||||||
clkb => CLK_I,
|
|
||||||
en_a => '1',
|
|
||||||
en_b => '1',
|
|
||||||
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_I,
|
|
||||||
clkb => CLK_I,
|
|
||||||
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_I)
|
|
||||||
begin
|
|
||||||
if rising_edge(CLK_I) then
|
|
||||||
if RST_I = '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);
|
|
||||||
ADDR_O <= 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 <= DAT_I;
|
|
||||||
data_ram_we <= data_write and ACK_I;
|
|
||||||
|
|
||||||
cache_state:
|
|
||||||
process(s, cache_miss, cache_index_count, ram_index_count, mem_index_count, cache_index_reg, ACK_I, tag_index_reg, cpu_en, SRDY_I, 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';
|
|
||||||
CYC_O <= '0';
|
|
||||||
STB_O <= '0';
|
|
||||||
data_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';
|
|
||||||
CYC_O <= '1';
|
|
||||||
elsif cpu_en = '1' then
|
|
||||||
cpu_reg_en <= '1';
|
|
||||||
data_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';
|
|
||||||
end if;
|
|
||||||
end if;
|
|
||||||
when mem_request =>
|
|
||||||
ram_index_count_rst <= '1';
|
|
||||||
mem_index_count_rst <= '1';
|
|
||||||
CYC_O <= '1';
|
|
||||||
if SRDY_I = '1' then
|
|
||||||
sn <= mem_access;
|
|
||||||
end if;
|
|
||||||
when mem_access =>
|
|
||||||
mem_index_count_en <= '1';
|
|
||||||
data_write <= '1';
|
|
||||||
CYC_O <= '1';
|
|
||||||
STB_O <= '1';
|
|
||||||
if mem_index_count = 2**word_index_width-1 then
|
|
||||||
if SRDY_I = '1' then
|
|
||||||
sn <= mem_data;
|
|
||||||
end if;
|
|
||||||
end if;
|
|
||||||
when mem_data =>
|
|
||||||
CYC_O <= '1';
|
|
||||||
data_write <= '1';
|
|
||||||
if ram_index_count = 2**word_index_width-1 then
|
|
||||||
if ACK_I = '1' then
|
|
||||||
sn <= upd_cache;
|
|
||||||
end if;
|
|
||||||
end if;
|
|
||||||
when upd_cache =>
|
|
||||||
tag_ram_addr_wr <= cache_index_reg;
|
|
||||||
tag_ram_we <= '1';
|
|
||||||
cache_entry_in.valid <= '1';
|
|
||||||
sn <= rd_cache;
|
|
||||||
|
|
||||||
when rd_cache =>
|
|
||||||
data_ram_re <= '1';
|
|
||||||
was_miss <= '1';
|
|
||||||
sn <= ready;
|
|
||||||
when others =>
|
|
||||||
sn <= ready;
|
|
||||||
end case;
|
|
||||||
end process;
|
|
||||||
|
|
||||||
cache_index_counter:
|
|
||||||
process(CLK_I)
|
|
||||||
begin
|
|
||||||
if rising_edge(CLK_I) 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_I)
|
|
||||||
begin
|
|
||||||
if rising_edge(CLK_I) then
|
|
||||||
if ram_index_count_rst = '1' then
|
|
||||||
ram_index_count <= 0;
|
|
||||||
elsif data_write = '1' and ACK_I = '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_I)
|
|
||||||
begin
|
|
||||||
if rising_edge(CLK_I) then
|
|
||||||
if mem_index_count_rst = '1' then
|
|
||||||
mem_index_count <= 0;
|
|
||||||
elsif mem_index_count_en = '1' and SRDY_I = '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,52 +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.ltz <= op1_in(op1_in'left) after 1 ns;
|
|
||||||
|
|
||||||
--------------------------------------------------------------------------
|
|
||||||
end Behavioral;
|
|
||||||
@@ -1,500 +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 biu is
|
|
||||||
Generic
|
|
||||||
(
|
|
||||||
icache_size : natural := 2048; -- words
|
|
||||||
dcache_size : natural := 2048 -- words
|
|
||||||
);
|
|
||||||
Port
|
|
||||||
(
|
|
||||||
RST_I : in STD_LOGIC;
|
|
||||||
CLK_I : in STD_LOGIC;
|
|
||||||
ACK_I : in STD_LOGIC;
|
|
||||||
SRDY_I : in STD_LOGIC;
|
|
||||||
ADDR_O : out unsigned(31 downto 0);
|
|
||||||
DAT_I : in unsigned(31 downto 0);
|
|
||||||
DAT_O : out unsigned(31 downto 0);
|
|
||||||
WE_O : out STD_LOGIC;
|
|
||||||
SEL_O : out unsigned(3 downto 0);
|
|
||||||
CYC_O : out STD_LOGIC;
|
|
||||||
STB_O : out STD_LOGIC;
|
|
||||||
MRDY_O : out STD_LOGIC;
|
|
||||||
cpu_imem_err : 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_err : out STD_LOGIC;
|
|
||||||
cpu_dmem_rdy : out STD_LOGIC;
|
|
||||||
cpu_dmem_en : in STD_LOGIC;
|
|
||||||
cpu_dmem_we : in STD_LOGIC;
|
|
||||||
cpu_dmem_be : in unsigned(3 downto 0);
|
|
||||||
cpu_dmem_dout : in word_t;
|
|
||||||
cpu_dmem_din : out word_t;
|
|
||||||
cpu_dmem_addr : in word_t
|
|
||||||
);
|
|
||||||
end biu;
|
|
||||||
|
|
||||||
architecture behavior of biu is
|
|
||||||
|
|
||||||
COMPONENT icache
|
|
||||||
GENERIC
|
|
||||||
(
|
|
||||||
cache_size : natural; -- words
|
|
||||||
line_size : natural -- words
|
|
||||||
);
|
|
||||||
PORT
|
|
||||||
(
|
|
||||||
RST_I : in STD_LOGIC;
|
|
||||||
CLK_I : in STD_LOGIC;
|
|
||||||
ACK_I : in STD_LOGIC;
|
|
||||||
SRDY_I : in STD_LOGIC;
|
|
||||||
ADDR_O : out word_t;
|
|
||||||
DAT_I : in word_t;
|
|
||||||
STB_O : out STD_LOGIC;
|
|
||||||
CYC_O : out 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
|
|
||||||
);
|
|
||||||
END COMPONENT;
|
|
||||||
|
|
||||||
COMPONENT dcache
|
|
||||||
GENERIC
|
|
||||||
(
|
|
||||||
cache_size : natural; -- words
|
|
||||||
line_size : natural -- words
|
|
||||||
);
|
|
||||||
PORT
|
|
||||||
(
|
|
||||||
RST_I : in STD_LOGIC;
|
|
||||||
CLK_I : in STD_LOGIC;
|
|
||||||
ACK_I : in STD_LOGIC;
|
|
||||||
SRDY_I : in STD_LOGIC;
|
|
||||||
ADDR_O : out word_t;
|
|
||||||
DAT_I : in word_t;
|
|
||||||
STB_O : out STD_LOGIC;
|
|
||||||
CYC_O : out STD_LOGIC;
|
|
||||||
en : in STD_LOGIC;
|
|
||||||
cpu_en : in STD_LOGIC;
|
|
||||||
cpu_we : in STD_LOGIC;
|
|
||||||
cpu_be : 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
|
|
||||||
);
|
|
||||||
END COMPONENT;
|
|
||||||
|
|
||||||
type bus_state_t is (init, ready, icache_bus_access, dcache_bus_access, write_bus, read_bus, read_finish);
|
|
||||||
|
|
||||||
signal s, sn : bus_state_t;
|
|
||||||
signal bus_idle : std_logic;
|
|
||||||
signal busy : std_logic;
|
|
||||||
signal dmem_be : unsigned(3 downto 0);
|
|
||||||
signal dcache_dout : word_t;
|
|
||||||
signal dcache_mem_gnt : std_logic;
|
|
||||||
signal icache_mem_gnt : std_logic;
|
|
||||||
signal dmem_mem_wr_gnt : std_logic;
|
|
||||||
signal dmem_mem_rd_gnt : std_logic;
|
|
||||||
signal dcache_busy : std_logic;
|
|
||||||
signal icache_busy : std_logic;
|
|
||||||
signal CYC_O_icache : std_logic;
|
|
||||||
signal CYC_O_dcache : std_logic;
|
|
||||||
signal CYC_O_dmem_rd : std_logic;
|
|
||||||
signal CYC_O_dmem_wr : std_logic;
|
|
||||||
signal SRDY_I_icache : std_logic;
|
|
||||||
signal SRDY_I_dcache : std_logic;
|
|
||||||
signal ADDR_O_icache : word_t;
|
|
||||||
signal ADDR_O_dcache : word_t;
|
|
||||||
signal ADDR_O_dmem_rd : word_t;
|
|
||||||
signal ADDR_O_dmem_wr : word_t;
|
|
||||||
signal STB_O_icache : std_logic;
|
|
||||||
signal STB_O_dcache : std_logic;
|
|
||||||
signal STB_O_dmem_rd : std_logic;
|
|
||||||
signal STB_O_dmem_wr : std_logic;
|
|
||||||
signal DAT_I_dmem_rd : word_t;
|
|
||||||
signal DAT_O_dmem_wr : word_t;
|
|
||||||
signal SEL_O_dmem_wr : unsigned(3 downto 0);
|
|
||||||
signal SEL_O_dmem_rd : unsigned(3 downto 0);
|
|
||||||
signal dcached : std_logic;
|
|
||||||
signal dcache_en : std_logic;
|
|
||||||
signal uncached_access : std_logic;
|
|
||||||
|
|
||||||
type timeout_cnt_t is range 0 to 1E5-1;
|
|
||||||
signal bus_timeout_cnt : timeout_cnt_t;
|
|
||||||
signal bus_timeout : std_logic;
|
|
||||||
|
|
||||||
signal bout_fifo_din : unsigned(68 downto 0);
|
|
||||||
signal bout_fifo_dout : unsigned(68 downto 0);
|
|
||||||
signal bout_fifo_re : std_logic;
|
|
||||||
signal bout_fifo_we : std_logic;
|
|
||||||
signal bout_fifo_full : std_logic;
|
|
||||||
signal bout_fifo_empty : std_logic;
|
|
||||||
signal bout_rdy : std_logic;
|
|
||||||
|
|
||||||
alias bout_fifo_addr_in is bout_fifo_din(31 downto 0);
|
|
||||||
alias bout_fifo_data_in is bout_fifo_din(63 downto 32);
|
|
||||||
alias bout_fifo_sel_in is bout_fifo_din(67 downto 64);
|
|
||||||
alias bout_fifo_we_in is bout_fifo_din(68);
|
|
||||||
alias bout_fifo_addr_out is bout_fifo_dout(31 downto 0);
|
|
||||||
alias bout_fifo_data_out is bout_fifo_dout(63 downto 32);
|
|
||||||
alias bout_fifo_sel_out is bout_fifo_dout(67 downto 64);
|
|
||||||
alias bout_fifo_we_out is bout_fifo_dout(68);
|
|
||||||
|
|
||||||
signal write_fifo_din : unsigned(67 downto 0);
|
|
||||||
signal write_fifo_dout : unsigned(67 downto 0);
|
|
||||||
signal write_fifo_re : std_logic;
|
|
||||||
signal write_fifo_we : std_logic;
|
|
||||||
signal write_fifo_full : std_logic;
|
|
||||||
signal write_fifo_empty : std_logic;
|
|
||||||
signal write_busy : std_logic;
|
|
||||||
|
|
||||||
alias write_fifo_addr_in is write_fifo_din(31 downto 0);
|
|
||||||
alias write_fifo_data_in is write_fifo_din(63 downto 32);
|
|
||||||
alias write_fifo_sel_in is write_fifo_din(67 downto 64);
|
|
||||||
alias write_fifo_addr_out is write_fifo_dout(31 downto 0);
|
|
||||||
alias write_fifo_data_out is write_fifo_dout(63 downto 32);
|
|
||||||
alias write_fifo_sel_out is write_fifo_dout(67 downto 64);
|
|
||||||
|
|
||||||
signal read_cycle : std_logic;
|
|
||||||
|
|
||||||
begin
|
|
||||||
|
|
||||||
|
|
||||||
MRDY_O <= '1';
|
|
||||||
|
|
||||||
read_cyc_register:
|
|
||||||
process(CLK_I)
|
|
||||||
begin
|
|
||||||
if rising_edge(CLK_I) then
|
|
||||||
if RST_I = '1' then
|
|
||||||
read_cycle <= '0';
|
|
||||||
else
|
|
||||||
read_cycle <= (dmem_mem_rd_gnt and CYC_O_dmem_rd)
|
|
||||||
or (dcache_mem_gnt and CYC_O_dcache)
|
|
||||||
or (icache_mem_gnt and CYC_O_icache);
|
|
||||||
end if;
|
|
||||||
end if;
|
|
||||||
end process;
|
|
||||||
|
|
||||||
CYC_O <= not bout_fifo_empty or read_cycle;
|
|
||||||
STB_O <= not bout_fifo_empty;
|
|
||||||
ADDR_O <= bout_fifo_addr_out;
|
|
||||||
DAT_O <= bout_fifo_data_out;
|
|
||||||
SEL_O <= bout_fifo_sel_out;
|
|
||||||
WE_O <= bout_fifo_we_out;
|
|
||||||
|
|
||||||
cpu_imem_rdy <= not icache_busy after 4.5 ns;
|
|
||||||
busy <= CYC_O_dmem_rd or dcache_busy or (write_busy);
|
|
||||||
cpu_dmem_rdy <= not busy after 4.5 ns;
|
|
||||||
|
|
||||||
inst_icache : icache
|
|
||||||
GENERIC MAP
|
|
||||||
(
|
|
||||||
cache_size => icache_size, -- words
|
|
||||||
line_size => 8
|
|
||||||
)
|
|
||||||
PORT MAP
|
|
||||||
(
|
|
||||||
CLK_I => CLK_I,
|
|
||||||
RST_I => RST_I,
|
|
||||||
STB_O => STB_O_icache,
|
|
||||||
CYC_O => CYC_O_icache,
|
|
||||||
ADDR_O => ADDR_O_icache,
|
|
||||||
DAT_I => DAT_I,
|
|
||||||
ACK_I => ACK_I,
|
|
||||||
SRDY_I => SRDY_I_icache,
|
|
||||||
en => '1',
|
|
||||||
cpu_en => cpu_imem_en,
|
|
||||||
cpu_addr => cpu_imem_addr,
|
|
||||||
cpu_dout => cpu_imem_din,
|
|
||||||
cpu_busy => icache_busy
|
|
||||||
);
|
|
||||||
|
|
||||||
SRDY_I_icache <= bout_rdy and icache_mem_gnt;
|
|
||||||
|
|
||||||
inst_dcache : dcache
|
|
||||||
GENERIC MAP
|
|
||||||
(
|
|
||||||
cache_size => dcache_size, -- words
|
|
||||||
line_size => 8
|
|
||||||
)
|
|
||||||
PORT MAP
|
|
||||||
(
|
|
||||||
CLK_I => CLK_I,
|
|
||||||
RST_I => RST_I,
|
|
||||||
CYC_O => CYC_O_dcache,
|
|
||||||
STB_O => STB_O_dcache,
|
|
||||||
ADDR_O => ADDR_O_dcache,
|
|
||||||
DAT_I => DAT_I,
|
|
||||||
ACK_I => ACK_I,
|
|
||||||
SRDY_I => SRDY_I_dcache,
|
|
||||||
en => dcached,
|
|
||||||
cpu_en => dcache_en,
|
|
||||||
cpu_we => cpu_dmem_we,
|
|
||||||
cpu_be => cpu_dmem_be,
|
|
||||||
cpu_addr => cpu_dmem_addr,
|
|
||||||
cpu_din => cpu_dmem_dout,
|
|
||||||
cpu_dout => dcache_dout,
|
|
||||||
cpu_busy => dcache_busy
|
|
||||||
);
|
|
||||||
|
|
||||||
SRDY_I_dcache <= bout_rdy and dcache_mem_gnt;
|
|
||||||
|
|
||||||
dcached <= '1' when cpu_dmem_addr(31 downto 28) /= X"A" else '0';
|
|
||||||
cpu_dmem_din <= dcache_dout when uncached_access = '0' else DAT_I_dmem_rd;
|
|
||||||
dcache_en <= cpu_dmem_en and not busy;
|
|
||||||
|
|
||||||
-- Instantiate synchronous FIFO
|
|
||||||
inst_bout_fifo: entity work.fifo_sync_dist
|
|
||||||
GENERIC MAP
|
|
||||||
(
|
|
||||||
addr_width => 4,
|
|
||||||
data_width => 69
|
|
||||||
)
|
|
||||||
PORT MAP
|
|
||||||
(
|
|
||||||
rst => RST_I,
|
|
||||||
clk => CLK_I,
|
|
||||||
we => bout_fifo_we,
|
|
||||||
re => bout_fifo_re,
|
|
||||||
fifo_full => bout_fifo_full,
|
|
||||||
fifo_empty => bout_fifo_empty,
|
|
||||||
fifo_afull => open,
|
|
||||||
fifo_aempty => open,
|
|
||||||
data_w => bout_fifo_din,
|
|
||||||
data_r => bout_fifo_dout
|
|
||||||
);
|
|
||||||
bout_rdy <= not bout_fifo_full;
|
|
||||||
bout_fifo_re <= not bout_fifo_empty and SRDY_I;
|
|
||||||
|
|
||||||
bout_fifo_we <= STB_O_dmem_wr or STB_O_dmem_rd or STB_O_dcache or STB_O_icache;
|
|
||||||
|
|
||||||
bout_fifo_data_in <= DAT_O_dmem_wr when dmem_mem_wr_gnt = '1' else (others => '-');
|
|
||||||
|
|
||||||
bout_fifo_addr_in <= ADDR_O_dmem_wr when dmem_mem_wr_gnt = '1' else
|
|
||||||
ADDR_O_dmem_rd when dmem_mem_rd_gnt = '1' else
|
|
||||||
ADDR_O_dcache when dcache_mem_gnt = '1' else
|
|
||||||
ADDR_O_icache when icache_mem_gnt = '1' else (others => '-');
|
|
||||||
|
|
||||||
bout_fifo_sel_in <= SEL_O_dmem_wr when dmem_mem_wr_gnt = '1' else
|
|
||||||
SEL_O_dmem_rd when dmem_mem_rd_gnt = '1' else (others => '1');
|
|
||||||
|
|
||||||
bout_fifo_we_in <= '1' when dmem_mem_wr_gnt = '1' else '0';
|
|
||||||
|
|
||||||
-- Instantiate synchronous FIFO
|
|
||||||
inst_write_fifo: entity work.fifo_sync_dist
|
|
||||||
GENERIC MAP
|
|
||||||
(
|
|
||||||
addr_width => 4,
|
|
||||||
data_width => 68
|
|
||||||
)
|
|
||||||
PORT MAP
|
|
||||||
(
|
|
||||||
rst => RST_I,
|
|
||||||
clk => CLK_I,
|
|
||||||
we => write_fifo_we,
|
|
||||||
re => write_fifo_re,
|
|
||||||
fifo_full => write_busy,
|
|
||||||
fifo_empty => write_fifo_empty,
|
|
||||||
fifo_afull => open,
|
|
||||||
fifo_aempty => open,
|
|
||||||
data_w => write_fifo_din,
|
|
||||||
data_r => write_fifo_dout
|
|
||||||
);
|
|
||||||
|
|
||||||
CYC_O_dmem_wr <= not write_fifo_empty;
|
|
||||||
DAT_O_dmem_wr <= write_fifo_data_out;
|
|
||||||
ADDR_O_dmem_wr <= write_fifo_addr_out;
|
|
||||||
SEL_O_dmem_wr <= write_fifo_sel_out;
|
|
||||||
|
|
||||||
write_fifo_data_in <= cpu_dmem_dout;
|
|
||||||
write_fifo_addr_in <= cpu_dmem_addr;
|
|
||||||
write_fifo_sel_in <= cpu_dmem_be;
|
|
||||||
write_fifo_re <= STB_O_dmem_wr;
|
|
||||||
write_fifo_we <= cpu_dmem_en and not busy and cpu_dmem_we;
|
|
||||||
|
|
||||||
dmem_rd_flags:
|
|
||||||
process(CLK_I)
|
|
||||||
begin
|
|
||||||
if rising_edge(CLK_I) then
|
|
||||||
uncached_access <= '0';
|
|
||||||
if RST_I = '1' then
|
|
||||||
CYC_O_dmem_rd <= '0';
|
|
||||||
else
|
|
||||||
if ACK_I = '1' and dmem_mem_rd_gnt = '1' then
|
|
||||||
uncached_access <= '1';
|
|
||||||
CYC_O_dmem_rd <= '0';
|
|
||||||
end if;
|
|
||||||
if cpu_dmem_en = '1' and busy = '0' and cpu_dmem_we = '0' then
|
|
||||||
if dcached = '0' then
|
|
||||||
CYC_O_dmem_rd <= '1';
|
|
||||||
end if;
|
|
||||||
end if;
|
|
||||||
end if;
|
|
||||||
end if;
|
|
||||||
end process;
|
|
||||||
|
|
||||||
dmem_rd_data:
|
|
||||||
process(CLK_I)
|
|
||||||
begin
|
|
||||||
if rising_edge(CLK_I) then
|
|
||||||
if RST_I = '1' then
|
|
||||||
DAT_I_dmem_rd <= (others => '0');
|
|
||||||
elsif ACK_I = '1' and CYC_O_dmem_rd = '1' then
|
|
||||||
DAT_I_dmem_rd <= DAT_I;
|
|
||||||
end if;
|
|
||||||
end if;
|
|
||||||
end process;
|
|
||||||
|
|
||||||
dmem_rd_regs:
|
|
||||||
process(CLK_I)
|
|
||||||
begin
|
|
||||||
if rising_edge(CLK_I) then
|
|
||||||
if cpu_dmem_en = '1' and busy = '0' then
|
|
||||||
ADDR_O_dmem_rd <= cpu_dmem_addr;
|
|
||||||
SEL_O_dmem_rd <= cpu_dmem_be;
|
|
||||||
end if;
|
|
||||||
end if;
|
|
||||||
end process;
|
|
||||||
|
|
||||||
bus_state_next:
|
|
||||||
process(CLK_I)
|
|
||||||
begin
|
|
||||||
if rising_edge(CLK_I) then
|
|
||||||
if RST_I = '1' then
|
|
||||||
s <= init;
|
|
||||||
else
|
|
||||||
s <= sn;
|
|
||||||
end if;
|
|
||||||
end if;
|
|
||||||
end process;
|
|
||||||
|
|
||||||
bus_state:
|
|
||||||
process(s, CYC_O_icache, CYC_O_dcache, CYC_O_dmem_wr, CYC_O_dmem_rd, bout_rdy, ACK_I)
|
|
||||||
begin
|
|
||||||
|
|
||||||
icache_mem_gnt <= '0';
|
|
||||||
dcache_mem_gnt <= '0';
|
|
||||||
dmem_mem_rd_gnt <= '0';
|
|
||||||
dmem_mem_wr_gnt <= '0';
|
|
||||||
STB_O_dmem_rd <= '0';
|
|
||||||
STB_O_dmem_wr <= '0';
|
|
||||||
bus_idle <= '0';
|
|
||||||
sn <= s;
|
|
||||||
case s is
|
|
||||||
when init =>
|
|
||||||
sn <= ready;
|
|
||||||
when ready =>
|
|
||||||
bus_idle <= '1';
|
|
||||||
if CYC_O_dmem_wr = '1' then
|
|
||||||
sn <= write_bus;
|
|
||||||
elsif CYC_O_dmem_rd = '1' then
|
|
||||||
sn <= read_bus;
|
|
||||||
elsif CYC_O_icache = '1' then
|
|
||||||
sn <= icache_bus_access;
|
|
||||||
elsif CYC_O_dcache = '1' then
|
|
||||||
sn <= dcache_bus_access;
|
|
||||||
end if;
|
|
||||||
when icache_bus_access =>
|
|
||||||
icache_mem_gnt <= '1';
|
|
||||||
if CYC_O_icache = '0' then
|
|
||||||
sn <= ready;
|
|
||||||
end if;
|
|
||||||
when dcache_bus_access =>
|
|
||||||
dcache_mem_gnt <= '1';
|
|
||||||
if CYC_O_dcache = '0' then
|
|
||||||
sn <= ready;
|
|
||||||
end if;
|
|
||||||
when write_bus =>
|
|
||||||
dmem_mem_wr_gnt <= '1';
|
|
||||||
if CYC_O_dmem_wr = '1' then
|
|
||||||
if bout_rdy = '1' then
|
|
||||||
STB_O_dmem_wr <= '1';
|
|
||||||
end if;
|
|
||||||
else
|
|
||||||
sn <= ready;
|
|
||||||
end if;
|
|
||||||
when read_bus =>
|
|
||||||
dmem_mem_rd_gnt <= '1';
|
|
||||||
if bout_rdy = '1' then
|
|
||||||
STB_O_dmem_rd <= '1';
|
|
||||||
sn <= read_finish;
|
|
||||||
end if;
|
|
||||||
when read_finish =>
|
|
||||||
dmem_mem_rd_gnt <= '1';
|
|
||||||
if ACK_I = '1' then
|
|
||||||
sn <= ready;
|
|
||||||
end if;
|
|
||||||
when others =>
|
|
||||||
sn <= ready;
|
|
||||||
end case;
|
|
||||||
|
|
||||||
end process;
|
|
||||||
|
|
||||||
bus_timeout_counter:
|
|
||||||
process(CLK_I)
|
|
||||||
begin
|
|
||||||
if rising_edge(CLK_I) then
|
|
||||||
if bus_idle = '0' then
|
|
||||||
if bus_timeout_cnt /= 0 then
|
|
||||||
bus_timeout_cnt <= bus_timeout_cnt - 1;
|
|
||||||
else
|
|
||||||
bus_timeout <= '1';
|
|
||||||
end if;
|
|
||||||
else
|
|
||||||
bus_timeout_cnt <= timeout_cnt_t'high;
|
|
||||||
bus_timeout <= '0';
|
|
||||||
end if;
|
|
||||||
end if;
|
|
||||||
end process;
|
|
||||||
|
|
||||||
bus_err:
|
|
||||||
process(CLK_I)
|
|
||||||
begin
|
|
||||||
if rising_edge(CLK_I) then
|
|
||||||
if RST_I = '1' then
|
|
||||||
cpu_imem_err <= '0';
|
|
||||||
cpu_dmem_err <= '0';
|
|
||||||
elsif bus_timeout = '1' then
|
|
||||||
cpu_imem_err <= icache_mem_gnt;
|
|
||||||
cpu_dmem_err <= dcache_mem_gnt or dmem_mem_wr_gnt or dmem_mem_rd_gnt;
|
|
||||||
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 : unsigned) return STD_LOGIC is
|
|
||||||
variable result : STD_LOGIC;
|
|
||||||
begin
|
|
||||||
result := '0';
|
|
||||||
for i in ip'range loop
|
|
||||||
result := result or ip(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) 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) and im(1 downto 0);
|
|
||||||
end if;
|
|
||||||
ip(7 downto 2) <= events.Int and im(7 downto 2);
|
|
||||||
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 := (others => '-');
|
|
||||||
|
|
||||||
end case;
|
|
||||||
dout <= reg after 1 ns;
|
|
||||||
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,870 +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;
|
|
||||||
ce : in STD_LOGIC;
|
|
||||||
int : in unsigned(5 downto 0);
|
|
||||||
imem_err : in STD_LOGIC;
|
|
||||||
imem_rdy : in STD_LOGIC;
|
|
||||||
imem_en : out STD_LOGIC;
|
|
||||||
imem_addr : out word_t;
|
|
||||||
imem_data : in word_t;
|
|
||||||
dmem_err : in STD_LOGIC;
|
|
||||||
dmem_rdy : in STD_LOGIC;
|
|
||||||
dmem_en : out STD_LOGIC;
|
|
||||||
dmem_we : out STD_LOGIC;
|
|
||||||
dmem_be : 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 reg_a : word_t;
|
|
||||||
signal reg_b : word_t;
|
|
||||||
signal ctrl_lines : ctrl_lines_t;
|
|
||||||
signal branch_ce : STD_LOGIC;
|
|
||||||
signal cpu_run : 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 <= ce;
|
|
||||||
|
|
||||||
-- 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 => 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 => 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 <= pc.curr;
|
|
||||||
pc.last <= pc.curr;
|
|
||||||
else
|
|
||||||
if 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 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.eq 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;
|
|
||||||
|
|
||||||
--------------------------------------------------------------------------
|
|
||||||
-- 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 <= alu_result when EX_stage.ctrl.mul_access = '0' else mul_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
|
|
||||||
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_be <= store_be(EX_stage.pa_off, EX_stage.ctrl.dmem_en, EX_stage.ctrl.word2_en, EX_stage.ctrl.word4_en, EX_stage.ctrl.align_left, EX_stage.ctrl.shift_byp) after 1 ns;
|
|
||||||
dmem_we <= 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) and sdu.EX_stall = '0' then
|
|
||||||
bcu_op_a <= ID_stage.reg_a;
|
|
||||||
bcu_op_b <= ID_stage.reg_b;
|
|
||||||
end if;
|
|
||||||
end process;
|
|
||||||
|
|
||||||
EX_stage.alu_op1 <= EX_stage.reg_a;
|
|
||||||
|
|
||||||
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;
|
|
||||||
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 <= '1';
|
|
||||||
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,72 +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);
|
|
||||||
|
|
||||||
signal reg_mem : mem_t;
|
|
||||||
|
|
||||||
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,216 +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
|
|
||||||
Generic
|
|
||||||
(
|
|
||||||
icache_size : natural := 4096; -- words
|
|
||||||
dcache_size : natural := 4096 -- words
|
|
||||||
);
|
|
||||||
Port
|
|
||||||
(
|
|
||||||
debug : out unsigned(1 downto 0);
|
|
||||||
RST_I : in STD_LOGIC;
|
|
||||||
CLK_I : in STD_LOGIC;
|
|
||||||
ACK_I : in STD_LOGIC;
|
|
||||||
SRDY_I : in STD_LOGIC;
|
|
||||||
ADDR_O : out unsigned(31 downto 0);
|
|
||||||
DAT_I : in unsigned(31 downto 0);
|
|
||||||
DAT_O : out unsigned(31 downto 0);
|
|
||||||
WE_O : out STD_LOGIC;
|
|
||||||
SEL_O : out unsigned(3 downto 0);
|
|
||||||
CYC_O : out STD_LOGIC;
|
|
||||||
STB_O : out STD_LOGIC;
|
|
||||||
MRDY_O : out STD_LOGIC;
|
|
||||||
INT : in unsigned (5 downto 0)
|
|
||||||
);
|
|
||||||
|
|
||||||
end mips_top;
|
|
||||||
|
|
||||||
architecture rtl of mips_top is
|
|
||||||
|
|
||||||
COMPONENT pipeline is
|
|
||||||
Port
|
|
||||||
(
|
|
||||||
rst : in STD_LOGIC;
|
|
||||||
clk : in STD_LOGIC;
|
|
||||||
ce : in STD_LOGIC;
|
|
||||||
int : in unsigned (5 downto 0);
|
|
||||||
imem_err : in STD_LOGIC;
|
|
||||||
imem_rdy : in STD_LOGIC;
|
|
||||||
imem_en : out STD_LOGIC;
|
|
||||||
imem_addr : out word_t;
|
|
||||||
imem_data : in word_t;
|
|
||||||
dmem_err : in STD_LOGIC;
|
|
||||||
dmem_rdy : in STD_LOGIC;
|
|
||||||
dmem_en : out STD_LOGIC;
|
|
||||||
dmem_we : out STD_LOGIC;
|
|
||||||
dmem_be : out unsigned(3 downto 0);
|
|
||||||
dmem_addr : out word_t;
|
|
||||||
dmem_din : in word_t;
|
|
||||||
dmem_dout : out word_t
|
|
||||||
);
|
|
||||||
END COMPONENT;
|
|
||||||
signal imem_err : std_logic;
|
|
||||||
signal imem_rdy : std_logic;
|
|
||||||
signal imem_en : std_logic;
|
|
||||||
signal imem_addr : word_t;
|
|
||||||
signal imem_din : word_t;
|
|
||||||
signal dmem_err : std_logic;
|
|
||||||
signal dmem_rdy : std_logic;
|
|
||||||
signal dmem_en : std_logic;
|
|
||||||
signal dmem_we : std_logic;
|
|
||||||
signal dmem_addr : word_t;
|
|
||||||
signal dmem_dout : word_t;
|
|
||||||
signal dmem_din : word_t;
|
|
||||||
signal dmem_be : unsigned(3 downto 0);
|
|
||||||
|
|
||||||
signal cpu_rst : STD_LOGIC;
|
|
||||||
signal cpu_run : STD_LOGIC;
|
|
||||||
|
|
||||||
COMPONENT biu
|
|
||||||
GENERIC
|
|
||||||
(
|
|
||||||
icache_size : natural;
|
|
||||||
dcache_size : natural
|
|
||||||
);
|
|
||||||
PORT
|
|
||||||
(
|
|
||||||
RST_I : in STD_LOGIC;
|
|
||||||
CLK_I : in STD_LOGIC;
|
|
||||||
ACK_I : in STD_LOGIC;
|
|
||||||
SRDY_I : in STD_LOGIC;
|
|
||||||
ADDR_O : out unsigned(31 downto 0);
|
|
||||||
DAT_I : in unsigned(31 downto 0);
|
|
||||||
DAT_O : out unsigned(31 downto 0);
|
|
||||||
WE_O : out STD_LOGIC;
|
|
||||||
SEL_O : out unsigned(3 downto 0);
|
|
||||||
CYC_O : out STD_LOGIC;
|
|
||||||
STB_O : out STD_LOGIC;
|
|
||||||
MRDY_O : out STD_LOGIC;
|
|
||||||
cpu_imem_err : 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_err : out STD_LOGIC;
|
|
||||||
cpu_dmem_rdy : out STD_LOGIC;
|
|
||||||
cpu_dmem_en : in STD_LOGIC;
|
|
||||||
cpu_dmem_we : in STD_LOGIC;
|
|
||||||
cpu_dmem_be : in unsigned(3 downto 0);
|
|
||||||
cpu_dmem_dout : in word_t;
|
|
||||||
cpu_dmem_din : out word_t;
|
|
||||||
cpu_dmem_addr : in word_t
|
|
||||||
);
|
|
||||||
END COMPONENT;
|
|
||||||
|
|
||||||
begin
|
|
||||||
|
|
||||||
-------------------------------------------------------------------
|
|
||||||
debug(0) <= imem_err;
|
|
||||||
debug(1) <= dmem_err;
|
|
||||||
|
|
||||||
process(CLK_I)
|
|
||||||
variable reset_delay : unsigned (5 downto 0);
|
|
||||||
begin
|
|
||||||
if rising_edge(CLK_I) then
|
|
||||||
if RST_I = '1' then
|
|
||||||
reset_delay := (others => '1');
|
|
||||||
cpu_rst <= '1';
|
|
||||||
cpu_run <= '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
|
|
||||||
cpu_run <= '1';
|
|
||||||
end if;
|
|
||||||
end if;
|
|
||||||
end process;
|
|
||||||
|
|
||||||
inst_pipeline: pipeline
|
|
||||||
PORT MAP
|
|
||||||
(
|
|
||||||
rst => cpu_rst,
|
|
||||||
clk => CLK_I,
|
|
||||||
ce => cpu_run,
|
|
||||||
int => INT,
|
|
||||||
imem_err => imem_err,
|
|
||||||
imem_rdy => imem_rdy,
|
|
||||||
imem_en => imem_en,
|
|
||||||
imem_addr => imem_addr,
|
|
||||||
imem_data => imem_din,
|
|
||||||
dmem_err => dmem_err,
|
|
||||||
dmem_rdy => dmem_rdy,
|
|
||||||
dmem_en => dmem_en,
|
|
||||||
dmem_we => dmem_we,
|
|
||||||
dmem_be => dmem_be,
|
|
||||||
dmem_addr => dmem_addr,
|
|
||||||
dmem_din => dmem_din,
|
|
||||||
dmem_dout => dmem_dout
|
|
||||||
);
|
|
||||||
|
|
||||||
inst_biu: biu
|
|
||||||
GENERIC MAP
|
|
||||||
(
|
|
||||||
icache_size => icache_size, -- words
|
|
||||||
dcache_size => dcache_size -- words
|
|
||||||
)
|
|
||||||
PORT MAP
|
|
||||||
(
|
|
||||||
RST_I => cpu_rst,
|
|
||||||
CLK_I => CLK_I,
|
|
||||||
ACK_I => ACK_I,
|
|
||||||
SRDY_I => SRDY_I,
|
|
||||||
ADDR_O => ADDR_O,
|
|
||||||
DAT_I => DAT_I,
|
|
||||||
DAT_O => DAT_O,
|
|
||||||
WE_O => WE_O,
|
|
||||||
SEL_O => SEL_O,
|
|
||||||
CYC_O => CYC_O,
|
|
||||||
STB_O => STB_O,
|
|
||||||
MRDY_O => MRDY_O,
|
|
||||||
cpu_imem_err => imem_err,
|
|
||||||
cpu_imem_rdy => imem_rdy,
|
|
||||||
cpu_imem_en => imem_en,
|
|
||||||
cpu_imem_addr => imem_addr,
|
|
||||||
cpu_imem_din => imem_din,
|
|
||||||
cpu_dmem_err => dmem_err,
|
|
||||||
cpu_dmem_rdy => dmem_rdy,
|
|
||||||
cpu_dmem_en => dmem_en,
|
|
||||||
cpu_dmem_we => dmem_we,
|
|
||||||
cpu_dmem_be => dmem_be,
|
|
||||||
cpu_dmem_addr => dmem_addr,
|
|
||||||
cpu_dmem_din => dmem_din,
|
|
||||||
cpu_dmem_dout => dmem_dout
|
|
||||||
);
|
|
||||||
|
|
||||||
end rtl;
|
|
||||||
@@ -1,619 +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 := 10;
|
|
||||||
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
|
|
||||||
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;
|
|
||||||
|
|
||||||
--------------------------------------------------------------------------
|
|
||||||
--------------------------------------------------------------------------
|
|
||||||
@@ -1,332 +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 dout : word_t;
|
|
||||||
signal hilo_sel : std_logic := '0';
|
|
||||||
signal md_result : unsigned (2*word_t'length-1 downto 0) := (others => '0');
|
|
||||||
signal ref_result : unsigned (2*word_t'length-1 downto 0);
|
|
||||||
signal ref_hi : unsigned (word_t'length-1 downto 0);
|
|
||||||
signal rtmp : unsigned (2*word_t'length-1 downto 0);
|
|
||||||
signal tmp2 : unsigned (word_t'length-1 downto 0);
|
|
||||||
signal check : std_logic;
|
|
||||||
|
|
||||||
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
|
|
||||||
begin
|
|
||||||
if mul_divn = '0' then
|
|
||||||
wait until rising_edge(clk) and check = '1';
|
|
||||||
if s_un = '1' then
|
|
||||||
rtmp <= unsigned(signed(md_result(31 downto 0)) * signed(din_lo));
|
|
||||||
wait until rising_edge(clk);
|
|
||||||
tmp2 <= unsigned(signed(rtmp(31 downto 0)) + signed(md_result(63 downto 32)));
|
|
||||||
wait until rising_edge(clk);
|
|
||||||
ref_hi <= tmp2(31 downto 0);
|
|
||||||
else
|
|
||||||
rtmp <= md_result(31 downto 0) * din_lo;
|
|
||||||
wait until rising_edge(clk);
|
|
||||||
tmp2 <= rtmp(31 downto 0) + md_result(63 downto 32);
|
|
||||||
wait until rising_edge(clk);
|
|
||||||
ref_hi <= tmp2(31 downto 0);
|
|
||||||
end if;
|
|
||||||
wait until rising_edge(clk);
|
|
||||||
|
|
||||||
if din_lo /= X"00000000" then
|
|
||||||
if ENABLE_FAIL_REPORT then
|
|
||||||
assert din_hi = ref_hi report "Error on divison" severity failure;
|
|
||||||
end if;
|
|
||||||
end if;
|
|
||||||
else
|
|
||||||
wait until rising_edge(clk) and check = '1';
|
|
||||||
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 = md_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
|
|
||||||
check <= '0';
|
|
||||||
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';
|
|
||||||
wait until rising_edge(clk);
|
|
||||||
md_result(31 downto 0) <= dout;
|
|
||||||
wait until rising_edge(clk);
|
|
||||||
hilo_sel <= '1';
|
|
||||||
wait until rising_edge(clk);
|
|
||||||
md_result(63 downto 32) <= dout;
|
|
||||||
check <= '1';
|
|
||||||
wait until rising_edge(clk);
|
|
||||||
check <= '0';
|
|
||||||
wait for 8*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
|
|
||||||
check <= '0';
|
|
||||||
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';
|
|
||||||
wait until rising_edge(clk);
|
|
||||||
md_result(31 downto 0) <= dout;
|
|
||||||
wait until rising_edge(clk);
|
|
||||||
hilo_sel <= '1';
|
|
||||||
wait until rising_edge(clk);
|
|
||||||
md_result(63 downto 32) <= dout;
|
|
||||||
check <= '1';
|
|
||||||
wait until rising_edge(clk);
|
|
||||||
check <= '0';
|
|
||||||
wait for 8*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
|
|
||||||
check <= '0';
|
|
||||||
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';
|
|
||||||
wait until rising_edge(clk);
|
|
||||||
md_result(31 downto 0) <= dout;
|
|
||||||
wait until rising_edge(clk);
|
|
||||||
hilo_sel <= '1';
|
|
||||||
wait until rising_edge(clk);
|
|
||||||
md_result(63 downto 32) <= dout;
|
|
||||||
check <= '1';
|
|
||||||
wait until rising_edge(clk);
|
|
||||||
check <= '0';
|
|
||||||
wait for 8*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
|
|
||||||
check <= '0';
|
|
||||||
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';
|
|
||||||
wait until rising_edge(clk);
|
|
||||||
md_result(31 downto 0) <= dout;
|
|
||||||
wait until rising_edge(clk);
|
|
||||||
hilo_sel <= '1';
|
|
||||||
wait until rising_edge(clk);
|
|
||||||
md_result(63 downto 32) <= dout;
|
|
||||||
check <= '1';
|
|
||||||
wait until rising_edge(clk);
|
|
||||||
check <= '0';
|
|
||||||
wait for 8*CLK_PERIOD;
|
|
||||||
end loop;
|
|
||||||
end loop;
|
|
||||||
|
|
||||||
wait;
|
|
||||||
|
|
||||||
end process;
|
|
||||||
|
|
||||||
END;
|
|
||||||
@@ -1,434 +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;
|
|
||||||
use work.async_types.all;
|
|
||||||
use work.async_defs.all;
|
|
||||||
|
|
||||||
ENTITY tb_mips_top IS
|
|
||||||
END tb_mips_top;
|
|
||||||
|
|
||||||
ARCHITECTURE behavior OF tb_mips_top IS
|
|
||||||
|
|
||||||
constant CLK_PERIOD : time := 10 ns;
|
|
||||||
constant SRAM_ADDR_WIDTH : integer := 14; -- bits
|
|
||||||
constant FLASH_ADDR_WIDTH : integer := 14; -- bits
|
|
||||||
|
|
||||||
signal debug : unsigned(1 downto 0);
|
|
||||||
|
|
||||||
-- Master
|
|
||||||
signal rst : STD_LOGIC := '1';
|
|
||||||
signal clk : STD_LOGIC := '0';
|
|
||||||
signal ACK_I : STD_LOGIC := '0';
|
|
||||||
signal SRDY_I : STD_LOGIC := '0';
|
|
||||||
signal ADDR_O : unsigned(31 downto 0);
|
|
||||||
signal DAT_I : unsigned(31 downto 0) := (others => '0');
|
|
||||||
signal DAT_O : unsigned(31 downto 0);
|
|
||||||
signal WE_O : STD_LOGIC;
|
|
||||||
signal SEL_O : unsigned(3 downto 0);
|
|
||||||
signal CYC_O : STD_LOGIC;
|
|
||||||
signal STB_O : STD_LOGIC;
|
|
||||||
signal MRDY_O : STD_LOGIC;
|
|
||||||
signal INT : unsigned (5 downto 0) := (others => '0');
|
|
||||||
|
|
||||||
-- Slaves
|
|
||||||
signal CYC_I_rom : std_logic;
|
|
||||||
signal ACK_O_rom : std_logic;
|
|
||||||
signal SRDY_O_rom : std_logic;
|
|
||||||
signal DAT_O_rom : unsigned(31 downto 0);
|
|
||||||
|
|
||||||
signal CYC_I_flash : std_logic;
|
|
||||||
signal ACK_O_flash : std_logic;
|
|
||||||
signal SRDY_O_flash : std_logic;
|
|
||||||
signal DAT_O_flash : unsigned(31 downto 0);
|
|
||||||
|
|
||||||
signal CYC_I_sram : std_logic;
|
|
||||||
signal ACK_O_sram : std_logic;
|
|
||||||
signal SRDY_O_sram : std_logic;
|
|
||||||
signal DAT_O_sram : unsigned(31 downto 0);
|
|
||||||
|
|
||||||
signal CYC_I_gpio : std_logic;
|
|
||||||
signal ACK_O_gpio : std_logic;
|
|
||||||
signal SRDY_O_gpio : std_logic;
|
|
||||||
signal DAT_O_gpio : unsigned(31 downto 0);
|
|
||||||
|
|
||||||
signal CYC_I_uart : std_logic;
|
|
||||||
signal ACK_O_uart : std_logic;
|
|
||||||
signal SRDY_O_uart : std_logic;
|
|
||||||
signal DAT_O_uart : unsigned(31 downto 0);
|
|
||||||
|
|
||||||
signal flash_cs_n : std_logic;
|
|
||||||
signal flash_oe_n : std_logic;
|
|
||||||
signal flash_be_n : unsigned(3 downto 0);
|
|
||||||
signal sram_cs_n : std_logic;
|
|
||||||
signal sram_be_n : unsigned(3 downto 0);
|
|
||||||
signal sram_wr_n : std_logic;
|
|
||||||
signal sram_oe_n : std_logic;
|
|
||||||
signal sram_a : unsigned(SRAM_ADDR_WIDTH-1 downto 0);
|
|
||||||
signal sram_d : unsigned(31 downto 0);
|
|
||||||
signal flash_a : unsigned(FLASH_ADDR_WIDTH-1 downto 0);
|
|
||||||
signal flash_d : unsigned(31 downto 0);
|
|
||||||
|
|
||||||
signal gpo0 : unsigned(31 downto 0);
|
|
||||||
signal gpo1 : unsigned(31 downto 0);
|
|
||||||
signal gpi0 : unsigned(31 downto 0) := (others => '0');
|
|
||||||
signal gpi1 : unsigned(31 downto 0) := (others => '0');
|
|
||||||
|
|
||||||
signal int_uart_rx : std_logic;
|
|
||||||
signal rx : std_logic := '1';
|
|
||||||
signal tx : std_logic;
|
|
||||||
|
|
||||||
type mem_area_t is (mem_dead, mem_flash, mem_sram, mem_rom, mem_gpio, mem_uart);
|
|
||||||
signal mem_area : mem_area_t;
|
|
||||||
|
|
||||||
type word_array_t is array (natural range <>) of unsigned(31 downto 0);
|
|
||||||
signal sram_data : word_array_t(0 to 2**SRAM_ADDR_WIDTH-1);
|
|
||||||
signal flash_data : word_array_t(0 to 2**FLASH_ADDR_WIDTH-1);
|
|
||||||
|
|
||||||
BEGIN
|
|
||||||
|
|
||||||
------------------------------------------------------------------
|
|
||||||
CLK_GEN: process
|
|
||||||
begin
|
|
||||||
wait for CLK_PERIOD/2;
|
|
||||||
clk <= not clk;
|
|
||||||
end process;
|
|
||||||
|
|
||||||
------------------------------------------------------------------
|
|
||||||
-- Memory mux
|
|
||||||
------------------------------------------------------------------
|
|
||||||
mem_mux:
|
|
||||||
process(ADDR_O)
|
|
||||||
begin
|
|
||||||
mem_area <= mem_dead;
|
|
||||||
if ADDR_O(31 downto 28) = X"0" then
|
|
||||||
mem_area <= mem_flash;
|
|
||||||
elsif ADDR_O(31 downto 28) = X"A" then
|
|
||||||
if ADDR_O(27 downto 26) = "00" then
|
|
||||||
if ADDR_O(18 downto 16) = "000" then
|
|
||||||
mem_area <= mem_gpio;
|
|
||||||
elsif ADDR_O(18 downto 16) = "001" then
|
|
||||||
mem_area <= mem_uart;
|
|
||||||
end if;
|
|
||||||
elsif ADDR_O(27 downto 26) = "01" then
|
|
||||||
mem_area <= mem_flash;
|
|
||||||
end if;
|
|
||||||
elsif (ADDR_O(31 downto 28) = X"B" and ADDR_O(15) = '0') then
|
|
||||||
mem_area <= mem_rom;
|
|
||||||
elsif (ADDR_O(31 downto 28) = X"8" or ADDR_O(30) = '1') then
|
|
||||||
mem_area <= mem_sram;
|
|
||||||
end if;
|
|
||||||
end process;
|
|
||||||
|
|
||||||
signal_mux:
|
|
||||||
process(mem_area, CYC_O)
|
|
||||||
begin
|
|
||||||
|
|
||||||
CYC_I_uart <= '0';
|
|
||||||
CYC_I_gpio <= '0';
|
|
||||||
CYC_I_flash <= '0';
|
|
||||||
CYC_I_rom <= '0';
|
|
||||||
CYC_I_sram <= '0';
|
|
||||||
|
|
||||||
case mem_area is
|
|
||||||
|
|
||||||
when mem_gpio =>
|
|
||||||
CYC_I_gpio <= CYC_O;
|
|
||||||
|
|
||||||
when mem_uart =>
|
|
||||||
CYC_I_uart <= CYC_O;
|
|
||||||
|
|
||||||
when mem_flash =>
|
|
||||||
CYC_I_flash <= CYC_O;
|
|
||||||
|
|
||||||
when mem_rom =>
|
|
||||||
CYC_I_rom <= CYC_O;
|
|
||||||
|
|
||||||
when mem_sram =>
|
|
||||||
CYC_I_sram <= CYC_O;
|
|
||||||
|
|
||||||
when others => null;
|
|
||||||
|
|
||||||
end case;
|
|
||||||
|
|
||||||
end process;
|
|
||||||
|
|
||||||
SRDY_I <= SRDY_O_flash or SRDY_O_sram or SRDY_O_rom or SRDY_O_uart or SRDY_O_gpio;
|
|
||||||
ACK_I <= ACK_O_flash or ACK_O_sram or ACK_O_rom or ACK_O_uart or ACK_O_gpio;
|
|
||||||
DAT_I <= DAT_O_sram when CYC_I_sram = '1' else
|
|
||||||
DAT_O_rom when CYC_I_rom = '1' else
|
|
||||||
DAT_O_flash when CYC_I_flash = '1' else
|
|
||||||
DAT_O_uart when CYC_I_uart = '1' else
|
|
||||||
DAT_O_gpio when CYC_I_gpio = '1' else X"DEADBEEF";
|
|
||||||
|
|
||||||
|
|
||||||
------------------------------------------------------------------
|
|
||||||
uut: entity work.mips_top
|
|
||||||
GENERIC MAP
|
|
||||||
(
|
|
||||||
icache_size => 1024, -- words
|
|
||||||
dcache_size => 1024 -- words
|
|
||||||
)
|
|
||||||
PORT MAP
|
|
||||||
(
|
|
||||||
debug => debug,
|
|
||||||
RST_I => rst,
|
|
||||||
CLK_I => clk,
|
|
||||||
ACK_I => ACK_I,
|
|
||||||
SRDY_I => SRDY_I,
|
|
||||||
ADDR_O => ADDR_O,
|
|
||||||
DAT_I => DAT_I,
|
|
||||||
DAT_O => DAT_O,
|
|
||||||
WE_O => WE_O,
|
|
||||||
SEL_O => SEL_O,
|
|
||||||
CYC_O => CYC_O,
|
|
||||||
STB_O => STB_O,
|
|
||||||
MRDY_O => MRDY_O,
|
|
||||||
INT => INT
|
|
||||||
);
|
|
||||||
INT(1) <= int_uart_rx;
|
|
||||||
|
|
||||||
inst_rom : entity work.rom_wb
|
|
||||||
PORT MAP
|
|
||||||
(
|
|
||||||
CLK_I => clk,
|
|
||||||
RST_I => rst,
|
|
||||||
CYC_I => CYC_I_rom,
|
|
||||||
STB_I => STB_O,
|
|
||||||
ACK_O => ACK_O_rom,
|
|
||||||
MRDY_I => MRDY_O,
|
|
||||||
SRDY_O => SRDY_O_rom,
|
|
||||||
ADDR_I => ADDR_O,
|
|
||||||
DAT_O => DAT_O_rom
|
|
||||||
);
|
|
||||||
|
|
||||||
inst_gpio : entity work.gpio_wb
|
|
||||||
PORT MAP
|
|
||||||
(
|
|
||||||
CLK_I => clk,
|
|
||||||
RST_I => rst,
|
|
||||||
CYC_I => CYC_I_gpio,
|
|
||||||
STB_I => STB_O,
|
|
||||||
SEL_I => SEL_O,
|
|
||||||
WE_I => WE_O,
|
|
||||||
ACK_O => ACK_O_gpio,
|
|
||||||
SRDY_O => SRDY_O_gpio,
|
|
||||||
MRDY_I => MRDY_O,
|
|
||||||
ADDR_I => ADDR_O,
|
|
||||||
DAT_I => DAT_O,
|
|
||||||
DAT_O => DAT_O_gpio,
|
|
||||||
|
|
||||||
sys_gpo0 => gpo0,
|
|
||||||
sys_gpo1 => gpo1,
|
|
||||||
sys_gpi0 => gpi0,
|
|
||||||
sys_gpi1 => gpi1
|
|
||||||
);
|
|
||||||
|
|
||||||
inst_flash_port : entity work.async_port_wb
|
|
||||||
GENERIC MAP
|
|
||||||
(
|
|
||||||
addr_width => FLASH_ADDR_WIDTH,
|
|
||||||
data_width => 32,
|
|
||||||
byte_sel_width => 4,
|
|
||||||
async_timespec => ts_flash
|
|
||||||
)
|
|
||||||
PORT MAP
|
|
||||||
(
|
|
||||||
CLK_I => clk,
|
|
||||||
RST_I => rst,
|
|
||||||
CYC_I => CYC_I_flash,
|
|
||||||
STB_I => STB_O,
|
|
||||||
WE_I => WE_O,
|
|
||||||
ACK_O => ACK_O_flash,
|
|
||||||
SRDY_O => SRDY_O_flash,
|
|
||||||
MRDY_I => MRDY_O,
|
|
||||||
SEL_I => SEL_O,
|
|
||||||
ADDR_I => ADDR_O,
|
|
||||||
DAT_I => DAT_O,
|
|
||||||
DAT_O => DAT_O_flash,
|
|
||||||
async_a => flash_a,
|
|
||||||
async_d => flash_d,
|
|
||||||
async_cs => flash_cs_n,
|
|
||||||
async_wr => open,
|
|
||||||
async_rd => flash_oe_n,
|
|
||||||
async_be => flash_be_n,
|
|
||||||
async_rst => open
|
|
||||||
);
|
|
||||||
|
|
||||||
inst_sram_port : entity work.async_port_wb
|
|
||||||
GENERIC MAP
|
|
||||||
(
|
|
||||||
addr_width => SRAM_ADDR_WIDTH,
|
|
||||||
data_width => 32,
|
|
||||||
byte_sel_width => 4,
|
|
||||||
async_timespec => ts_sram
|
|
||||||
)
|
|
||||||
PORT MAP
|
|
||||||
(
|
|
||||||
CLK_I => clk,
|
|
||||||
RST_I => rst,
|
|
||||||
CYC_I => CYC_I_sram,
|
|
||||||
STB_I => STB_O,
|
|
||||||
WE_I => WE_O,
|
|
||||||
ACK_O => ACK_O_sram,
|
|
||||||
SRDY_O => SRDY_O_sram,
|
|
||||||
MRDY_I => MRDY_O,
|
|
||||||
SEL_I => SEL_O,
|
|
||||||
ADDR_I => ADDR_O,
|
|
||||||
DAT_I => DAT_O,
|
|
||||||
DAT_O => DAT_O_sram,
|
|
||||||
async_a => sram_a,
|
|
||||||
async_d => sram_d,
|
|
||||||
async_cs => sram_cs_n,
|
|
||||||
async_wr => sram_wr_n,
|
|
||||||
async_rd => sram_oe_n,
|
|
||||||
async_be => sram_be_n,
|
|
||||||
async_rst => open
|
|
||||||
);
|
|
||||||
|
|
||||||
inst_uart : entity work.uart_wb
|
|
||||||
PORT MAP
|
|
||||||
(
|
|
||||||
CLK_I => clk,
|
|
||||||
RST_I => rst,
|
|
||||||
CYC_I => CYC_I_uart,
|
|
||||||
STB_I => STB_O,
|
|
||||||
SEL_I => SEL_O,
|
|
||||||
WE_I => WE_O,
|
|
||||||
ACK_O => ACK_O_uart,
|
|
||||||
SRDY_O => SRDY_O_uart,
|
|
||||||
MRDY_I => MRDY_O,
|
|
||||||
ADDR_I => ADDR_O,
|
|
||||||
DAT_I => DAT_O,
|
|
||||||
DAT_O => DAT_O_uart,
|
|
||||||
INT_RX_O => int_uart_rx,
|
|
||||||
INT_TX_O => open,
|
|
||||||
ser_rx => rx,
|
|
||||||
ser_tx => tx
|
|
||||||
);
|
|
||||||
|
|
||||||
------------------------------------------------------------------
|
|
||||||
SRAM_READ:
|
|
||||||
process(sram_a, sram_cs_n, sram_oe_n, sram_be_n)
|
|
||||||
begin
|
|
||||||
sram_d <= (others => 'Z') after 10 ns;
|
|
||||||
if sram_oe_n = '0' then
|
|
||||||
if sram_cs_n = '0' then
|
|
||||||
if sram_be_n(0) = '0' then
|
|
||||||
sram_d(7 downto 0) <= sram_data(to_integer(sram_a(SRAM_ADDR_WIDTH-1 downto 2)))(7 downto 0) after 10 ns;
|
|
||||||
end if;
|
|
||||||
if sram_be_n(1) = '0' then
|
|
||||||
sram_d(15 downto 8) <= sram_data(to_integer(sram_a(SRAM_ADDR_WIDTH-1 downto 2)))(15 downto 8) after 10 ns;
|
|
||||||
end if;
|
|
||||||
if sram_be_n(2) = '0' then
|
|
||||||
sram_d(23 downto 16) <= sram_data(to_integer(sram_a(SRAM_ADDR_WIDTH-1 downto 2)))(23 downto 16) after 10 ns;
|
|
||||||
end if;
|
|
||||||
if sram_be_n(3) = '0' then
|
|
||||||
sram_d(31 downto 24) <= sram_data(to_integer(sram_a(SRAM_ADDR_WIDTH-1 downto 2)))(31 downto 24) after 10 ns;
|
|
||||||
end if;
|
|
||||||
end if;
|
|
||||||
end if;
|
|
||||||
end process;
|
|
||||||
|
|
||||||
SRAM_WRITE:
|
|
||||||
process(sram_wr_n)
|
|
||||||
begin
|
|
||||||
if rising_edge(sram_wr_n) then
|
|
||||||
if sram_cs_n = '0' then
|
|
||||||
if sram_be_n(0) = '0' then
|
|
||||||
sram_data(to_integer(sram_a(SRAM_ADDR_WIDTH-1 downto 2)))(7 downto 0) <= sram_d(7 downto 0);
|
|
||||||
end if;
|
|
||||||
if sram_be_n(1) = '0' then
|
|
||||||
sram_data(to_integer(sram_a(SRAM_ADDR_WIDTH-1 downto 2)))(15 downto 8) <= sram_d(15 downto 8);
|
|
||||||
end if;
|
|
||||||
if sram_be_n(2) = '0' then
|
|
||||||
sram_data(to_integer(sram_a(SRAM_ADDR_WIDTH-1 downto 2)))(23 downto 16) <= sram_d(23 downto 16);
|
|
||||||
end if;
|
|
||||||
if sram_be_n(3) = '0' then
|
|
||||||
sram_data(to_integer(sram_a(SRAM_ADDR_WIDTH-1 downto 2)))(31 downto 24) <= sram_d(31 downto 24);
|
|
||||||
end if;
|
|
||||||
end if;
|
|
||||||
end if;
|
|
||||||
end process;
|
|
||||||
|
|
||||||
------------------------------------------------------------------
|
|
||||||
FLASH_READ:
|
|
||||||
process(rst, flash_cs_n, flash_oe_n, flash_a)
|
|
||||||
type file_t is file of integer;
|
|
||||||
file load_flash : file_t open read_mode is "hello.flash.bin";
|
|
||||||
variable instr : integer;
|
|
||||||
variable index : natural;
|
|
||||||
variable temp : signed(31 downto 0);
|
|
||||||
begin
|
|
||||||
if rst = '1' then
|
|
||||||
index := 0;
|
|
||||||
while not endfile(load_flash) loop
|
|
||||||
read(load_flash, instr);
|
|
||||||
temp := to_signed(instr, word_t'length);
|
|
||||||
flash_data(index) <= unsigned(temp);
|
|
||||||
index := index + 1;
|
|
||||||
end loop;
|
|
||||||
else
|
|
||||||
flash_d <= (others => 'Z') after 10 ns;
|
|
||||||
index := to_integer(flash_a(FLASH_ADDR_WIDTH-1 downto 2));
|
|
||||||
if flash_oe_n = '0' then
|
|
||||||
if flash_cs_n = '0' then
|
|
||||||
if flash_be_n(0) = '0' then
|
|
||||||
flash_d(7 downto 0) <= flash_data(index)(7 downto 0) after 10 ns;
|
|
||||||
end if;
|
|
||||||
if flash_be_n(1) = '0' then
|
|
||||||
flash_d(15 downto 8) <= flash_data(index)(15 downto 8) after 10 ns;
|
|
||||||
end if;
|
|
||||||
if flash_be_n(2) = '0' then
|
|
||||||
flash_d(23 downto 16) <= flash_data(index)(23 downto 16) after 10 ns;
|
|
||||||
end if;
|
|
||||||
if flash_be_n(3) = '0' then
|
|
||||||
flash_d(31 downto 24) <= flash_data(index)(31 downto 24) after 10 ns;
|
|
||||||
end if;
|
|
||||||
end if;
|
|
||||||
end if;
|
|
||||||
end if;
|
|
||||||
end process;
|
|
||||||
|
|
||||||
------------------------------------------------------------------
|
|
||||||
STIMULUS: process
|
|
||||||
|
|
||||||
begin
|
|
||||||
|
|
||||||
|
|
||||||
wait for 3*CLK_PERIOD;
|
|
||||||
wait until rising_edge(clk);
|
|
||||||
rst <= '0';
|
|
||||||
|
|
||||||
wait;
|
|
||||||
|
|
||||||
end process;
|
|
||||||
|
|
||||||
END;
|
|
||||||
@@ -1,20 +0,0 @@
|
|||||||
vhdl work "../../src/core/mips_types.vhd"
|
|
||||||
vhdl work "../../../../misc/dpram_2w2r.vhd"
|
|
||||||
vhdl work "../../../../misc/dpram_1w1r_dist.vhd"
|
|
||||||
vhdl work "../../../../misc/dpram_1w1r.vhd"
|
|
||||||
vhdl work "../../../../FIFO/src/fifo_sync_ctrl.vhd"
|
|
||||||
vhdl work "../../../../FIFO/src/fifo_ctrl_pkg.vhd"
|
|
||||||
vhdl work "../../src/core/mips_instr.vhd"
|
|
||||||
vhdl work "../../../../FIFO/src/fifo_sync_dist.vhd"
|
|
||||||
vhdl work "../../src/core/mips_shifter.vhd"
|
|
||||||
vhdl work "../../src/core/mips_reg.vhd"
|
|
||||||
vhdl work "../../src/core/mips_muldiv.vhd"
|
|
||||||
vhdl work "../../src/core/mips_idecode_rom.vhd"
|
|
||||||
vhdl work "../../src/core/mips_icache.vhd"
|
|
||||||
vhdl work "../../src/core/mips_dcache.vhd"
|
|
||||||
vhdl work "../../src/core/mips_cop.vhd"
|
|
||||||
vhdl work "../../src/core/mips_bcu.vhd"
|
|
||||||
vhdl work "../../src/core/mips_alu.vhd"
|
|
||||||
vhdl work "../../src/core/mips_pipeline.vhd"
|
|
||||||
vhdl work "../../src/core/mips_biu.vhd"
|
|
||||||
vhdl work "../../src/core/mips_top.vhd"
|
|
||||||
@@ -1,20 +0,0 @@
|
|||||||
vhdl work "W:\vhdl\lib\CPUs\MIPS\src\core\mips_types.vhd"
|
|
||||||
vhdl work "W:\vhdl\lib\misc\dpram_2w2r.vhd"
|
|
||||||
vhdl work "W:\vhdl\lib\misc\dpram_1w1r_dist.vhd"
|
|
||||||
vhdl work "W:\vhdl\lib\misc\dpram_1w1r.vhd"
|
|
||||||
vhdl work "W:\vhdl\lib\FIFO\src\fifo_sync_ctrl.vhd"
|
|
||||||
vhdl work "W:\vhdl\lib\FIFO\src\fifo_ctrl_pkg.vhd"
|
|
||||||
vhdl work "W:\vhdl\lib\CPUs\MIPS\src\core\mips_instr.vhd"
|
|
||||||
vhdl work "W:\vhdl\lib\FIFO\src\fifo_sync_dist.vhd"
|
|
||||||
vhdl work "W:\vhdl\lib\CPUs\MIPS\src\core\mips_shifter.vhd"
|
|
||||||
vhdl work "W:\vhdl\lib\CPUs\MIPS\src\core\mips_reg.vhd"
|
|
||||||
vhdl work "W:\vhdl\lib\CPUs\MIPS\src\core\mips_muldiv.vhd"
|
|
||||||
vhdl work "W:\vhdl\lib\CPUs\MIPS\src\core\mips_idecode_rom.vhd"
|
|
||||||
vhdl work "W:\vhdl\lib\CPUs\MIPS\src\core\mips_icache.vhd"
|
|
||||||
vhdl work "W:\vhdl\lib\CPUs\MIPS\src\core\mips_dcache.vhd"
|
|
||||||
vhdl work "W:\vhdl\lib\CPUs\MIPS\src\core\mips_cop.vhd"
|
|
||||||
vhdl work "W:\vhdl\lib\CPUs\MIPS\src\core\mips_bcu.vhd"
|
|
||||||
vhdl work "W:\vhdl\lib\CPUs\MIPS\src\core\mips_alu.vhd"
|
|
||||||
vhdl work "W:\vhdl\lib\CPUs\MIPS\src\core\mips_pipeline.vhd"
|
|
||||||
vhdl work "W:\vhdl\lib\CPUs\MIPS\src\core\mips_biu.vhd"
|
|
||||||
vhdl work "W:\vhdl\lib\CPUs\MIPS\src\core\mips_top.vhd"
|
|
||||||
@@ -1,17 +0,0 @@
|
|||||||
2008-10-26
|
|
||||||
- Area-Optimierung: DIV und MUL verwenden gleiche Ressourcen
|
|
||||||
- Area-Optimierung: MUL32x32 primitive für Virtex-4
|
|
||||||
- shifter: log shifter besser als built-in sll, srl, sra? Nein (2008-10-27)
|
|
||||||
- External COP 1..3 interface
|
|
||||||
- FPU (COP1)
|
|
||||||
- MMU
|
|
||||||
|
|
||||||
2008-10-27
|
|
||||||
- Area vs. speed : Pipeline-stall statt forwarding
|
|
||||||
- Caches: - Lock-up free cache (refill critical word first then un-lock CPU) (geringer Effekt, zu kompliziert => geringere Zuverlässigkeit)
|
|
||||||
- 1,2,4-way assoziative
|
|
||||||
- 2nd-Level cache in System
|
|
||||||
- Write-back policy
|
|
||||||
|
|
||||||
2008-11-15
|
|
||||||
- Bus exceptions IBE DBE (BUI/Cache restart notwendig)
|
|
||||||
Some files were not shown because too many files have changed in this diff Show More
Reference in New Issue
Block a user