Compare commits
1
Commits
| Author | SHA1 | Date | |
|---|---|---|---|
|
|
aacb0c448b |
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;
|
||||
@@ -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,200 +0,0 @@
|
||||
ENDIAN_FLAGS=-EB
|
||||
CFLAGS=$(ENDIAN_FLAGS) -msoft-float -O2 -march=r3000 -I. -Wl,-M
|
||||
LIBS=-lc -lm
|
||||
|
||||
|
||||
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=flashgen
|
||||
|
||||
PROG = hello testbench test_irq dhry queens stanford paranoia rmd160_test Bessel whet phrasen dttl richards_benchmark test_exception life r3 gunzip basic_math jman_patches jman_patchmeshes jman_polys
|
||||
|
||||
all: $(PROG)
|
||||
|
||||
libsys: startup.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 -DSTDERR_FUNCTION=_ser_putchar -DSTDOUT_FUNCTION=_ser_putchar -D_putchar=_ser_putchar -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
|
||||
$(CC) $(CFLAGS) -G 0 -c dbg.c -o dbg.o
|
||||
$(CC) $(CFLAGS) -G 0 -c mipsdis.c -o mipsdis.o
|
||||
$(AR) -r libsys.a libsys.o xcpt.o irq.o dbg.o mipsdis.o
|
||||
|
||||
hello: hello.c
|
||||
$(CC) $(CFLAGS) -o $@.elf -Os hello.c $(LIBS) >$@.map
|
||||
$(OBJDUMP) -d $@.elf > $@.dis
|
||||
$(OBJCOPY) $@.elf -O binary $@.bin
|
||||
$(OBJCOPY) -O srec $@.elf $@.srec
|
||||
$(FLASHGEN) $@.bin $(ENDIAN_FLAGS)
|
||||
|
||||
testbench: testbench.c
|
||||
$(CC) $(CFLAGS) -O3 -o $@.elf -DNOSIGNAL -DBATCHMODE -DNOMAIN -Os -g testbench.c paranoia.c $(LIBS) >$@.map
|
||||
$(OBJDUMP) -d $@.elf > $@.dis
|
||||
$(OBJCOPY) $@.elf -O binary $@.bin
|
||||
$(OBJCOPY) -O srec $@.elf $@.srec
|
||||
$(FLASHGEN) $@.bin $(ENDIAN_FLAGS)
|
||||
|
||||
test_irq: test_irq.c
|
||||
$(CC) $(CFLAGS) -o $@.elf test_irq.c $(LIBS) >$@.map
|
||||
$(OBJDUMP) -d $@.elf > $@.dis
|
||||
$(OBJCOPY) $@.elf -O binary $@.bin
|
||||
$(OBJCOPY) -O srec $@.elf $@.srec
|
||||
$(FLASHGEN) $@.bin $(ENDIAN_FLAGS)
|
||||
|
||||
dhry: dhry_1.c dhry_2.c dhry.h
|
||||
$(CC) $(CFLAGS) -o $@.elf -DHZ=1000 dhry_1.c dhry_2.c $(LIBS) >$@.map
|
||||
$(OBJDUMP) -d $@.elf > $@.dis
|
||||
$(OBJCOPY) $@.elf -O binary $@.bin
|
||||
$(OBJCOPY) -O srec $@.elf $@.srec
|
||||
$(FLASHGEN) $@.bin $(ENDIAN_FLAGS)
|
||||
|
||||
queens: queens.c
|
||||
$(CC) $(CFLAGS) -o $@.elf -DUNIX_Old -DHZ=1000 queens.c $(LIBS) >$@.map
|
||||
$(OBJDUMP) -d $@.elf > $@.dis
|
||||
$(OBJCOPY) $@.elf -O binary $@.bin
|
||||
$(OBJCOPY) -O srec $@.elf $@.srec
|
||||
$(FLASHGEN) $@.bin $(ENDIAN_FLAGS)
|
||||
|
||||
stanford: stanford.c
|
||||
$(CC) $(CFLAGS) -O3 -o $@.elf -DHZ=1000 stanford.c $(LIBS) >$@.map
|
||||
$(OBJDUMP) -d $@.elf > $@.dis
|
||||
$(OBJCOPY) $@.elf -O binary $@.bin
|
||||
$(OBJCOPY) -O srec $@.elf $@.srec
|
||||
$(FLASHGEN) $@.bin $(ENDIAN_FLAGS)
|
||||
|
||||
paranoia: paranoia.c
|
||||
$(CC) $(CFLAGS) -O3 -o $@.elf -DNOSIGNAL -DBATCHMODE paranoia.c $(LIBS) >$@.map
|
||||
$(OBJDUMP) -d $@.elf > $@.dis
|
||||
$(OBJCOPY) $@.elf -O binary $@.bin
|
||||
$(OBJCOPY) -O srec $@.elf $@.srec
|
||||
$(FLASHGEN) $@.bin $(ENDIAN_FLAGS)
|
||||
|
||||
rmd160_test: rmd160_test.c rmd160.c rmd160.h
|
||||
$(CC) $(CFLAGS) -O2 -o $@.elf -DNOSIGNAL -DBATCHMODE rmd160.c rmd160_test.c $(LIBS) >$@.map
|
||||
$(OBJDUMP) -d $@.elf > $@.dis
|
||||
$(OBJCOPY) $@.elf -O binary $@.bin
|
||||
$(OBJCOPY) -O srec $@.elf $@.srec
|
||||
$(FLASHGEN) $@.bin $(ENDIAN_FLAGS)
|
||||
|
||||
Bessel: Bessel.c
|
||||
$(CC) $(CFLAGS) -o $@.elf Bessel.c $(LIBS) >$@.map
|
||||
$(OBJDUMP) -d $@.elf > $@.dis
|
||||
$(OBJCOPY) $@.elf -O binary $@.bin
|
||||
$(OBJCOPY) -O srec $@.elf $@.srec
|
||||
$(FLASHGEN) $@.bin $(ENDIAN_FLAGS)
|
||||
|
||||
whet: whet.c
|
||||
$(CC) $(CFLAGS) -o $@.elf whet.c $(LIBS) >$@.map
|
||||
$(OBJDUMP) -d $@.elf > $@.dis
|
||||
$(OBJCOPY) $@.elf -O binary $@.bin
|
||||
$(OBJCOPY) -O srec $@.elf $@.srec
|
||||
$(FLASHGEN) $@.bin $(ENDIAN_FLAGS)
|
||||
|
||||
phrasen: phrasen.c
|
||||
$(CC) $(CFLAGS) -o $@.elf phrasen.c $(LIBS) >$@.map
|
||||
$(OBJDUMP) -d $@.elf > $@.dis
|
||||
$(OBJCOPY) $@.elf -O binary $@.bin
|
||||
$(OBJCOPY) -O srec $@.elf $@.srec
|
||||
$(FLASHGEN) $@.bin $(ENDIAN_FLAGS)
|
||||
|
||||
dttl: dttl.c random.c
|
||||
$(CC) $(CFLAGS) -o $@.elf dttl.c random.c $(LIBS) >$@.map
|
||||
$(OBJDUMP) -d $@.elf > $@.dis
|
||||
$(OBJCOPY) $@.elf -O binary $@.bin
|
||||
$(OBJCOPY) -O srec $@.elf $@.srec
|
||||
$(FLASHGEN) $@.bin $(ENDIAN_FLAGS)
|
||||
|
||||
richards_benchmark: richards_benchmark.c
|
||||
$(CC) $(CFLAGS) -o $@.elf richards_benchmark.c $(LIBS) >$@.map
|
||||
$(OBJDUMP) -d $@.elf > $@.dis
|
||||
$(OBJCOPY) $@.elf -O binary $@.bin
|
||||
$(OBJCOPY) -O srec $@.elf $@.srec
|
||||
$(FLASHGEN) $@.bin $(ENDIAN_FLAGS)
|
||||
|
||||
test_exception: test_exception.c
|
||||
$(CC) $(CFLAGS) -o $@.elf -O1 test_exception.c $(LIBS) >$@.map
|
||||
$(OBJDUMP) -d $@.elf > $@.dis
|
||||
$(OBJCOPY) $@.elf -O binary $@.bin
|
||||
$(OBJCOPY) -O srec $@.elf $@.srec
|
||||
$(FLASHGEN) $@.bin $(ENDIAN_FLAGS)
|
||||
|
||||
life: life.c
|
||||
$(CC) $(CFLAGS) -o $@.elf -g life.c $(LIBS) >$@.map
|
||||
$(OBJDUMP) -d $@.elf > $@.dis
|
||||
$(OBJCOPY) $@.elf -O binary $@.bin
|
||||
$(OBJCOPY) -O srec $@.elf $@.srec
|
||||
$(FLASHGEN) $@.bin $(ENDIAN_FLAGS)
|
||||
|
||||
r3: r3.c
|
||||
$(CC) $(CFLAGS) -O3 -o $@.elf -DJMIPS_VGA -O2 r3.c $(LIBS) >$@.map
|
||||
$(OBJDUMP) -d $@.elf > $@.dis
|
||||
$(OBJCOPY) $@.elf -O binary $@.bin
|
||||
$(OBJCOPY) -O srec $@.elf $@.srec
|
||||
$(FLASHGEN) $@.bin $(ENDIAN_FLAGS)
|
||||
|
||||
gunzip: gunzip.c inflate.c crc32.c
|
||||
$(CC) $(CFLAGS) -o $@.elf -o $@.elf gunzip.c inflate.c crc32.c $(LIBS) >$@.map
|
||||
$(OBJDUMP) -d $@.elf > $@.dis
|
||||
$(OBJCOPY) $@.elf -O binary $@.bin
|
||||
$(OBJCOPY) -O srec $@.elf $@.srec
|
||||
$(FLASHGEN) $@.bin $(ENDIAN_FLAGS)
|
||||
|
||||
basic_math: basicmath_small.c rad2deg.c cubic.c isqrt.c
|
||||
$(CC) $(CFLAGS) -o $@.elf -o $@.elf basicmath_small.c rad2deg.c cubic.c isqrt.c $(LIBS) >$@.map
|
||||
$(OBJDUMP) -d $@.elf > $@.dis
|
||||
$(OBJCOPY) $@.elf -O binary $@.bin
|
||||
$(OBJCOPY) -O srec $@.elf $@.srec
|
||||
$(FLASHGEN) $@.bin $(ENDIAN_FLAGS)
|
||||
|
||||
JMAN_SRC= \
|
||||
jman/bintree.c \
|
||||
jman/camset.c \
|
||||
jman/engine.c \
|
||||
jman/graph_state.c \
|
||||
jman/grid.c \
|
||||
jman/imageio.c \
|
||||
jman/linklist.c \
|
||||
jman/matrix.c \
|
||||
jman/object.c \
|
||||
jman/render.c \
|
||||
jman/ri.c \
|
||||
jman/ribgen.c \
|
||||
jman/stack.c \
|
||||
jman/vars.c
|
||||
|
||||
jman_patches: $(JMAN_SRC) jman/main_patches.c
|
||||
$(CC) $(CFLAGS) -I../ -o $@.elf -o $@.elf jman/main_patches.c $(JMAN_SRC) $(LIBS) >$@.map
|
||||
$(OBJDUMP) -d $@.elf > $@.dis
|
||||
$(OBJCOPY) $@.elf -O binary $@.bin
|
||||
$(OBJCOPY) -O srec $@.elf $@.srec
|
||||
$(FLASHGEN) $@.bin $(ENDIAN_FLAGS)
|
||||
|
||||
jman_patchmeshes: $(JMAN_SRC) jman/main_patchmeshes.c jman/patches2.c
|
||||
$(CC) $(CFLAGS) -I../ -o $@.elf -o $@.elf jman/main_patchmeshes.c jman/patches2.c $(JMAN_SRC) $(LIBS) >$@.map
|
||||
$(OBJDUMP) -d $@.elf > $@.dis
|
||||
$(OBJCOPY) $@.elf -O binary $@.bin
|
||||
$(OBJCOPY) -O srec $@.elf $@.srec
|
||||
$(FLASHGEN) $@.bin $(ENDIAN_FLAGS)
|
||||
|
||||
jman_polys: $(JMAN_SRC) jman/main_polypin.c jman/polys.c
|
||||
$(CC) $(CFLAGS) -I../ -o $@.elf -o $@.elf jman/main_polypin.c jman/polys.c $(JMAN_SRC) $(LIBS) >$@.map
|
||||
$(OBJDUMP) -d $@.elf > $@.dis
|
||||
$(OBJCOPY) $@.elf -O binary $@.bin
|
||||
$(OBJCOPY) -O srec $@.elf $@.srec
|
||||
$(FLASHGEN) $@.bin $(ENDIAN_FLAGS)
|
||||
|
||||
serdump: serdump.c
|
||||
$(CC) $(CFLAGS) -O3 -o $@.elf -O2 serdump.c $(LIBS) >$@.map
|
||||
$(OBJDUMP) -d $@.elf > $@.dis
|
||||
$(OBJCOPY) $@.elf -O binary $@.bin
|
||||
$(OBJCOPY) -O srec $@.elf $@.srec
|
||||
$(FLASHGEN) $@.bin $(ENDIAN_FLAGS)
|
||||
|
||||
|
||||
clean:
|
||||
rm -rf *.a *.o *.bin *.map *.dis *.srec *.elf $(PROG) > /dev/null
|
||||
@@ -1,47 +0,0 @@
|
||||
ENDIAN='big'
|
||||
|
||||
ifeq ($(ENDIAN), 'big')
|
||||
ENDIAN_FLAGS=-EB
|
||||
LIB_DIRS=-L $(MIPS_TOOLS_PREFIX)/mipsel-elf/lib/eb -L $(MIPS_TOOLS_PREFIX)/lib/gcc/mipsel-elf/$(MIPS_GCC_VER)/eb
|
||||
else
|
||||
ENDIAN_FLAGS=-EL
|
||||
LIB_DIRS=-L $(MIPS_TOOLS_PREFIX)/mipsel-elf/lib -L $(MIPS_TOOLS_PREFIX)/lib/gcc/mipsel-elf/$(MIPS_GCC_VER)
|
||||
endif
|
||||
|
||||
CFLAGS=$(ENDIAN_FLAGS) -Os -I. -I../ -msoft-float -march=r3000
|
||||
LFLAGS=$(ENDIAN_FLAGS) -M -T bootloader.ld
|
||||
|
||||
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
|
||||
romgen bootloader.ROM.bin 10 $(ENDIAN_FLAGS)
|
||||
|
||||
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
|
||||
romgen bootloader.ROM.bin 11 $(ENDIAN_FLAGS)
|
||||
|
||||
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,53 +0,0 @@
|
||||
MEMORY
|
||||
{
|
||||
rom : ORIGIN = 0xBFC00000, LENGTH = 0x00002000 /* 8K */
|
||||
ram : ORIGIN = 0x40000000, LENGTH = 0x00002000 /* 8K */
|
||||
}
|
||||
|
||||
OUTPUT_ARCH(mips)
|
||||
SEARCH_DIR(".");
|
||||
SEARCH_DIR("/usr/local/mipsel-elf/lib:/usr/local/mipsel-elf/lib/eb");
|
||||
SEARCH_DIR("/usr/local/lib/gcc/mipsel-elf/4.3.3:/usr/local/lib/gcc/mipsel-elf/4.3.3/eb");
|
||||
|
||||
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
|
||||
{
|
||||
.init 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,391 +0,0 @@
|
||||
#include "libsys_boot.h"
|
||||
#include "cfiflash.h"
|
||||
|
||||
#define MAGIC_EB 0x4A464931 // "JFI1" in big-endian;
|
||||
#define MAGIC_EL 0x3149464A // "JFI1" in little-endian;
|
||||
|
||||
typedef struct _ssrec_t
|
||||
{
|
||||
UINT32 addr;
|
||||
UINT32 size;
|
||||
UINT32 type;
|
||||
UINT8 *data;
|
||||
|
||||
} srec_t;
|
||||
typedef struct _sflash_alloc_tbl_t
|
||||
{
|
||||
UINT32 images[16];
|
||||
|
||||
} flash_alloc_tbl_t;
|
||||
|
||||
typedef struct _sflash_img_hdr_t
|
||||
{
|
||||
UINT32 magic;
|
||||
UINT32 target_base;
|
||||
UINT32 img_base;
|
||||
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
|
||||
(
|
||||
"li $26, 0x10000000\n"
|
||||
"mtc0 $26, $12\n"
|
||||
);
|
||||
|
||||
__asm
|
||||
(
|
||||
"jr %[pEntry]\n" // jump entry
|
||||
:
|
||||
: [pEntry] "r" (pEntry)
|
||||
);
|
||||
|
||||
__asm
|
||||
(
|
||||
"rfe\n"
|
||||
);
|
||||
|
||||
__asm
|
||||
(
|
||||
".set reorder\n"
|
||||
);
|
||||
}
|
||||
|
||||
void Exec_RE_at(void *pEntry)
|
||||
{
|
||||
__asm
|
||||
(
|
||||
".set noreorder\n"
|
||||
);
|
||||
|
||||
__asm
|
||||
(
|
||||
"mfc0 $26, $12\n" // change exception vector
|
||||
"li $27, 0xFFBFFFFF\n"
|
||||
"and $26, $27\n"
|
||||
"li $27, 0x02000000\n" // Reverse Endianess
|
||||
"or $26, $27\n"
|
||||
"mtc0 $26, $12\n"
|
||||
);
|
||||
|
||||
__asm
|
||||
(
|
||||
"jr %[pEntry]\n" // jump entry
|
||||
:
|
||||
: [pEntry] "r" (pEntry)
|
||||
);
|
||||
|
||||
__asm
|
||||
(
|
||||
"rfe\n"
|
||||
);
|
||||
|
||||
__asm
|
||||
(
|
||||
".set reorder\n"
|
||||
);
|
||||
}
|
||||
|
||||
#define MAX_IMG_SIZE (1024*1024) // bytes
|
||||
#define SDRAM_BASE 0x40000000
|
||||
#define FLASH_USE_BLOCK 1
|
||||
|
||||
int main(int argc, char *argv[])
|
||||
{
|
||||
UINT8 buf[256];
|
||||
srec_t srec;
|
||||
int srec_state, i;
|
||||
UINT32 haddr, result;
|
||||
flash_t flash;
|
||||
flash_img_hdr_t img_hdr = {0};
|
||||
flash_img_hdr_t *pImg_hdr;
|
||||
UINT32 img_size, block_sel;
|
||||
|
||||
volatile UINT32 *pReg = (UINT32*)sys_led_port;
|
||||
volatile UINT32 *pBtn = (UINT32*)sys_gpio0;
|
||||
volatile UINT32 *pDip = (UINT32*)sys_gpio1;
|
||||
volatile UINT8 *pMem;
|
||||
volatile UINT32 *pROM32;
|
||||
volatile UINT32 *pMem32;
|
||||
volatile UINT32 *pFlashIO = (UINT32*)sys_flash_io; // Flash in uncached area
|
||||
volatile UINT32 *pFlashMem = (UINT32*)sys_flash_mem; // Flash in cached area
|
||||
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;
|
||||
UINT32 flash_offset;
|
||||
|
||||
*pReg = 0;
|
||||
haddr = 0;
|
||||
block_sel = 0x7F & (UINT32)*pDip;
|
||||
|
||||
// ----------------------------------------------------------
|
||||
if (IS_ERROR(flash_find(&flash, sys_flash_io)))
|
||||
{
|
||||
sputs("Cannot find flash device. Exit now!\n\n");
|
||||
return 1;
|
||||
}
|
||||
|
||||
// Get flash offset by value of DIP-switch
|
||||
flash_offset = flash_get_offset_by_blocknum(&flash, block_sel);
|
||||
|
||||
ram32 = (UINT32*)(SDRAM_BASE);
|
||||
pFlashIO = (UINT32*)(sys_flash_io + flash_offset);
|
||||
|
||||
if (!(*pBtn & 8))
|
||||
{
|
||||
sputs("\n\n");
|
||||
pImg_hdr = (flash_img_hdr_t*)pFlashIO;
|
||||
if ((pImg_hdr->magic != MAGIC_EL) && (pImg_hdr->magic != MAGIC_EB))
|
||||
{
|
||||
sputs("\n\n");
|
||||
sputs("Invalid image found at ");print_word(flash_offset); sputs(". Abort.\n");
|
||||
return 1;
|
||||
}
|
||||
|
||||
sputs("Booting application from flash (");print_word(flash_offset);sputs(")...");
|
||||
|
||||
ram32 = (UINT32*)pImg_hdr->target_base;
|
||||
img_size = pImg_hdr->img_size;
|
||||
|
||||
// It's safe to use cached Flash,
|
||||
// because D-Cache was invalidated during execution of start code
|
||||
// pFlashIO = (UINT32*)(sys_flash_io + pImg_hdr->img_base);
|
||||
pFlashMem = (UINT32*)(sys_flash_mem + pImg_hdr->img_base);
|
||||
|
||||
for (i=0; i < img_size/4; i++)
|
||||
// ram32[i] = pFlashIO[i];
|
||||
ram32[i] = pFlashMem[i];
|
||||
|
||||
sputs("done\n");
|
||||
|
||||
sputs("Execute at ");print_word(pImg_hdr->target_base); sputs("\n\n");
|
||||
Exec_at((void*)ram32);
|
||||
}
|
||||
else
|
||||
{
|
||||
|
||||
sputs("\n\n");
|
||||
|
||||
sputs("Reading HEX-Record from UART..");
|
||||
|
||||
// Erase SDRAM
|
||||
for (i=0; i < MAX_IMG_SIZE/4; i++)
|
||||
ram32[i] = 0;
|
||||
|
||||
|
||||
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 = MAGIC_EB;
|
||||
img_hdr.target_base = srec.addr;
|
||||
img_hdr.img_size = haddr - srec.addr;
|
||||
img_hdr.img_base = flash_offset + sizeof(flash_img_hdr_t);
|
||||
img_hdr.hdr_next = flash_get_offset_blockaligned(&flash, img_hdr.img_base + img_hdr.img_size);
|
||||
sputs("Size of application : ");print_word(img_hdr.img_size); sputs("\n");
|
||||
sputs("Programming flash at : ");print_word(flash_offset); sputs("\n");
|
||||
sputs("Next free flash offset : ");print_word(img_hdr.hdr_next); sputs("\n");
|
||||
|
||||
sputs("Flash erase...");
|
||||
result = flash_erase(&flash, flash_offset, img_hdr.img_size + sizeof(flash_img_hdr_t));
|
||||
if (IS_ERROR(result))
|
||||
{
|
||||
sputs("failed (");print_word(result);sputs(")\n");
|
||||
break;
|
||||
}
|
||||
sputs("done\n");
|
||||
|
||||
sputs("Flash write...");
|
||||
result = flash_program(&flash, flash_offset, (UINT8*)&img_hdr, sizeof(flash_img_hdr_t));
|
||||
if (IS_ERROR(result))
|
||||
{
|
||||
sputs("failed (");print_word(result);sputs(")\n");
|
||||
break;
|
||||
}
|
||||
result = flash_program(&flash, img_hdr.img_base, (UINT8*)img_hdr.target_base, img_hdr.img_size);
|
||||
if (IS_ERROR(result))
|
||||
{
|
||||
sputs("failed (");print_word(result);sputs(")\n");
|
||||
break;
|
||||
}
|
||||
sputs("done\n");
|
||||
|
||||
sputs("Flash verify...");
|
||||
result = flash_verify(&flash, img_hdr.img_base, (UINT8*)img_hdr.target_base, img_hdr.img_size);
|
||||
if (IS_ERROR(result))
|
||||
{
|
||||
sputs("failed (");print_word(result);sputs(")\n");
|
||||
break;
|
||||
}
|
||||
sputs("passed\n");
|
||||
|
||||
// Jump to reset vector
|
||||
Jump_to((void*)0xBFC00000);
|
||||
|
||||
break;
|
||||
|
||||
default:
|
||||
result = -1;
|
||||
break;
|
||||
}
|
||||
if (IS_ERROR(result))
|
||||
{
|
||||
*pReg = 0x40000000;
|
||||
break;
|
||||
}
|
||||
|
||||
};
|
||||
}
|
||||
}
|
||||
return 0;
|
||||
}
|
||||
|
||||
@@ -1,19 +0,0 @@
|
||||
.file "init.S"
|
||||
|
||||
.text
|
||||
.section .init,"ax"
|
||||
.align 2
|
||||
.globl _init
|
||||
.extern end
|
||||
|
||||
_init:
|
||||
.set noreorder
|
||||
|
||||
# set uart
|
||||
la $26, sys_uart_baud
|
||||
addiu $27, $0, baudrate
|
||||
sw $27, 0($26)
|
||||
|
||||
jr $ra
|
||||
|
||||
.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,214 +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;
|
||||
}
|
||||
}
|
||||
|
||||
// ---------------------------------------------------------------------------------
|
||||
// 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)
|
||||
{
|
||||
memdump(pBuf, 1, nbpr, len);
|
||||
}
|
||||
|
||||
void memdump(UINT8 *pBuf, int print_offset_only, int num_bytes_per_row, int len)
|
||||
{
|
||||
int i, j, cnt_hex, cnt_asc, base;
|
||||
unsigned char c;
|
||||
|
||||
i = j = 0;
|
||||
cnt_hex = len;
|
||||
cnt_asc = len;
|
||||
base = 0;
|
||||
if (!print_offset_only)
|
||||
base = (int)pBuf;
|
||||
|
||||
do
|
||||
{
|
||||
print_word(base + i);
|
||||
sputs(": ");
|
||||
for (j=0; j < num_bytes_per_row; j++)
|
||||
{
|
||||
if (cnt_hex)
|
||||
{
|
||||
print_byte(pBuf[i+j]);
|
||||
sputs(" ");
|
||||
cnt_hex--;
|
||||
}
|
||||
else
|
||||
{
|
||||
sputs(" ");
|
||||
break;
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
sputs(" ");
|
||||
for (j=0; j < num_bytes_per_row; j++)
|
||||
{
|
||||
if (cnt_asc)
|
||||
{
|
||||
c = pBuf[i+j];
|
||||
if((c < 0x20) || (c > 0x7F))
|
||||
c = '.';
|
||||
|
||||
_putchar(c);
|
||||
cnt_asc--;
|
||||
}
|
||||
else
|
||||
{
|
||||
sputs(" ");
|
||||
break;
|
||||
}
|
||||
}
|
||||
sputs("\n");
|
||||
i += num_bytes_per_row;
|
||||
|
||||
} while (cnt_hex);
|
||||
}
|
||||
|
||||
@@ -1,54 +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 IS_ERROR(e) ((e & 0x80000000) == 0x80000000)
|
||||
|
||||
#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
|
||||
#define sys_flash_mem 0x00000000
|
||||
|
||||
// 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);
|
||||
void PrintBuffer8(UINT8 *pBuf, int nbpr, int len);
|
||||
void memdump(UINT8 *pBuf, int print_offset_only, int num_bytes_per_row, int len);
|
||||
|
||||
#endif // LIBSYS_H
|
||||
|
||||
@@ -1,43 +0,0 @@
|
||||
.file "startup.S"
|
||||
|
||||
.text
|
||||
.section .init,"ax"
|
||||
.extern _init
|
||||
.align 2
|
||||
|
||||
_start:
|
||||
.set noreorder
|
||||
|
||||
# set stack pointer
|
||||
la $sp, stack_ptr
|
||||
|
||||
# Set Kernel mode
|
||||
li $26, 0x1040000C
|
||||
mtc0 $26, $12
|
||||
li $26, 0x00000000
|
||||
mtc0 $26, $13
|
||||
|
||||
mfc0 $26, $15
|
||||
nop
|
||||
mtc0 $26, $31
|
||||
|
||||
# Invalidate I-Cache
|
||||
cop0 32
|
||||
|
||||
# Invalidate D-Cache
|
||||
cop0 34
|
||||
|
||||
# jump init
|
||||
la $26, _init
|
||||
jalr $26
|
||||
nop
|
||||
|
||||
la $26, main
|
||||
jalr $26
|
||||
nop
|
||||
_terminate:
|
||||
nop
|
||||
j _terminate
|
||||
nop
|
||||
|
||||
.set reorder
|
||||
@@ -1,415 +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;
|
||||
UINT32 endian;
|
||||
UINT8 *pEndian;
|
||||
|
||||
pObj->pBase = (void*)base_addr;
|
||||
|
||||
pInfo = (UINT8*)&pObj->info;
|
||||
for (i=0; i < sizeof(flash_info_t); i++)
|
||||
{
|
||||
pInfo[i] = 0;
|
||||
}
|
||||
pObj->eb = 0;
|
||||
endian = 0x12345678;
|
||||
pEndian = (UINT8*)&endian;
|
||||
if (*pEndian == 0x12)
|
||||
{
|
||||
pObj->eb = 1;
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
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 = (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_is_locked(flash_t *pObj, UINT32 word_index)
|
||||
{
|
||||
volatile UINT32 *pF;
|
||||
UINT32 status, block_index, block_mask;
|
||||
UINT32 error;
|
||||
|
||||
pF = (UINT32*)pObj->pBase;
|
||||
|
||||
if (word_index >= (pObj->info.flashsize/4))
|
||||
return CFI_ERR_INVPARAM;
|
||||
|
||||
block_mask = ((pObj->info.nblocks-1) << 16);
|
||||
block_index = word_index & block_mask;
|
||||
|
||||
*pF = 0x00900090;
|
||||
|
||||
error = ((UINT32)pF[block_index+2] & 0x00010001) != 0;
|
||||
*pF = 0x00FF00FF;
|
||||
|
||||
return error;
|
||||
}
|
||||
|
||||
UINT32 cfi_block_erase(flash_t *pObj, UINT32 word_index)
|
||||
{
|
||||
volatile UINT32 *pF;
|
||||
UINT32 status, block_index, block_mask;
|
||||
UINT32 error;
|
||||
|
||||
pF = (UINT32*)pObj->pBase;
|
||||
|
||||
if (word_index >= (pObj->info.flashsize/4))
|
||||
return CFI_ERR_INVPARAM;
|
||||
|
||||
block_mask = ((pObj->info.nblocks-1) << 16);
|
||||
block_index = word_index & block_mask;
|
||||
|
||||
pF[block_index] = 0x00200020;
|
||||
pF[block_index] = 0x00D000D0;
|
||||
|
||||
error = 0;
|
||||
do
|
||||
{
|
||||
status = pF[block_index];
|
||||
|
||||
} while((status & SR_BIT_ISMS) != SR_BIT_ISMS);
|
||||
|
||||
if (status & (SR_BIT_ECLBS | SR_BIT_VPENS | SR_BIT_DPS))
|
||||
{
|
||||
error = CFI_ERR_DEV_FAIL | status;
|
||||
}
|
||||
|
||||
pF[block_index] = 0x00FF00FF;
|
||||
|
||||
return error;
|
||||
}
|
||||
|
||||
UINT32 cfi_block_lock(flash_t *pObj, UINT32 word_index)
|
||||
{
|
||||
volatile UINT32 *pF;
|
||||
UINT32 status, block_index, block_mask;
|
||||
UINT32 error;
|
||||
|
||||
pF = (UINT32*)pObj->pBase;
|
||||
|
||||
if (word_index >= (pObj->info.flashsize/4))
|
||||
return CFI_ERR_INVPARAM;
|
||||
|
||||
block_mask = ((pObj->info.nblocks-1) << 16);
|
||||
block_index = word_index & block_mask;
|
||||
|
||||
pF[block_index] = 0x00600060;
|
||||
pF[block_index] = 0x00010001;
|
||||
|
||||
error = 0;
|
||||
do
|
||||
{
|
||||
status = pF[block_index];
|
||||
|
||||
} while((status & SR_BIT_ISMS) != SR_BIT_ISMS);
|
||||
|
||||
if (status & (SR_BIT_PSLBS | SR_BIT_VPENS | SR_BIT_ECLBS))
|
||||
{
|
||||
error = CFI_ERR_DEV_FAIL | status;
|
||||
}
|
||||
|
||||
pF[block_index] = 0x00FF00FF;
|
||||
|
||||
return error;
|
||||
}
|
||||
|
||||
UINT32 cfi_block_unlock(flash_t *pObj, UINT32 word_index)
|
||||
{
|
||||
volatile UINT32 *pF;
|
||||
UINT32 status, block_index, block_mask;
|
||||
UINT32 error;
|
||||
|
||||
pF = (UINT32*)pObj->pBase;
|
||||
|
||||
if (word_index >= (pObj->info.flashsize/4))
|
||||
return CFI_ERR_INVPARAM;
|
||||
|
||||
block_mask = ((pObj->info.nblocks-1) << 16);
|
||||
block_index = word_index & block_mask;
|
||||
|
||||
pF[block_index] = 0x00600060;
|
||||
pF[block_index] = 0x00D000D0;
|
||||
|
||||
error = 0;
|
||||
do
|
||||
{
|
||||
status = pF[block_index];
|
||||
|
||||
} while((status & SR_BIT_ISMS) != SR_BIT_ISMS);
|
||||
|
||||
if (status & (SR_BIT_PSLBS | SR_BIT_VPENS | SR_BIT_ECLBS))
|
||||
{
|
||||
error = CFI_ERR_DEV_FAIL | status;
|
||||
}
|
||||
|
||||
pF[block_index] = 0x00FF00FF;
|
||||
|
||||
return error;
|
||||
}
|
||||
|
||||
UINT32 cfi_program_single(flash_t *pObj, UINT32 word_index, UINT32 word)
|
||||
{
|
||||
volatile UINT32 *pF;
|
||||
UINT32 status, error;
|
||||
|
||||
pF = (UINT32*)pObj->pBase;
|
||||
|
||||
if (word_index >= (pObj->info.flashsize/4))
|
||||
return CFI_ERR_INVPARAM;
|
||||
|
||||
pF[word_index] = 0x00400040;
|
||||
pF[word_index] = word;
|
||||
|
||||
error = 0;
|
||||
do
|
||||
{
|
||||
status = pF[word_index];
|
||||
|
||||
} while((status & SR_BIT_ISMS) != SR_BIT_ISMS);
|
||||
|
||||
if (status & (SR_BIT_PSLBS | SR_BIT_VPENS | SR_BIT_DPS))
|
||||
{
|
||||
error = CFI_ERR_DEV_FAIL | status;
|
||||
}
|
||||
|
||||
pF[word_index] = 0x00FF00FF;
|
||||
|
||||
return error;
|
||||
|
||||
}
|
||||
|
||||
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;
|
||||
UINT32 error;
|
||||
|
||||
pF = (UINT32*)pObj->pBase;
|
||||
|
||||
if (word_index >= (pObj->info.flashsize/4))
|
||||
return CFI_ERR_INVPARAM;
|
||||
|
||||
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;
|
||||
|
||||
while(nblock_write)
|
||||
{
|
||||
error = 0;
|
||||
pF[bcurr] = 0x00E800E8;
|
||||
do
|
||||
{
|
||||
status = pF[bcurr];
|
||||
|
||||
} while((status & SR_BIT_ISMS) != SR_BIT_ISMS);
|
||||
if (status & (SR_BIT_PSLBS | SR_BIT_VPENS | SR_BIT_DPS))
|
||||
{
|
||||
error = CFI_ERR_DEV_FAIL | status;
|
||||
break;
|
||||
}
|
||||
|
||||
nbuf_write = nblock_write;
|
||||
if (nblock_write > pObj->info.wbuf_size/4)
|
||||
nbuf_write = pObj->info.wbuf_size/4;
|
||||
|
||||
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;
|
||||
|
||||
error = 0;
|
||||
pF[bcurr] = 0x00D000D0;
|
||||
do
|
||||
{
|
||||
status = pF[bcurr];
|
||||
|
||||
} while((status & SR_BIT_ISMS) != SR_BIT_ISMS);
|
||||
if (status & (SR_BIT_PSLBS | SR_BIT_VPENS | SR_BIT_DPS))
|
||||
{
|
||||
error = CFI_ERR_DEV_FAIL | status;
|
||||
break;
|
||||
}
|
||||
|
||||
pF[bcurr] = 0x00FF00FF;
|
||||
}
|
||||
|
||||
if (IS_ERROR(error))
|
||||
{
|
||||
pF[bcurr] = 0x00FF00FF;
|
||||
break;
|
||||
}
|
||||
bcurr = bnext;
|
||||
}
|
||||
|
||||
return error;
|
||||
|
||||
}
|
||||
|
||||
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, error;
|
||||
|
||||
if (size % 4)
|
||||
size = 4*(size/4 + 1);
|
||||
|
||||
offset_end = offset + size;
|
||||
|
||||
for (i=offset; i < offset_end; i += pObj->info.blocksize)
|
||||
{
|
||||
if (cfi_block_is_locked(pObj, i/4))
|
||||
{
|
||||
error = cfi_block_unlock(pObj, i/4);
|
||||
if (IS_ERROR(error))
|
||||
break;
|
||||
}
|
||||
error = cfi_block_erase(pObj, i/4);
|
||||
if (IS_ERROR(error))
|
||||
break;
|
||||
}
|
||||
|
||||
return error;
|
||||
|
||||
}
|
||||
|
||||
UINT32 flash_program(flash_t *pObj, UINT32 offset, UINT8 *pData, UINT32 size)
|
||||
{
|
||||
if (size % 4)
|
||||
size = 4*(size/4 + 1);
|
||||
|
||||
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 CFI_ERR_VFY_FAIL;
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
UINT32 flash_get_blocknum_by_offset(flash_t *pObj, UINT32 offset)
|
||||
{
|
||||
UINT32 blocknum;
|
||||
|
||||
blocknum = offset/pObj->info.blocksize;
|
||||
if (offset%pObj->info.blocksize)
|
||||
blocknum++;
|
||||
|
||||
return blocknum;
|
||||
}
|
||||
|
||||
UINT32 flash_get_offset_by_blocknum(flash_t *pObj, UINT32 blocknum)
|
||||
{
|
||||
if (blocknum >= pObj->info.nblocks)
|
||||
blocknum = pObj->info.nblocks - 1;
|
||||
|
||||
return blocknum*pObj->info.blocksize;
|
||||
}
|
||||
|
||||
UINT32 flash_get_offset_blockaligned(flash_t *pObj, UINT32 offset)
|
||||
{
|
||||
return flash_get_blocknum_by_offset(pObj, offset) * pObj->info.blocksize;
|
||||
}
|
||||
|
||||
@@ -1,58 +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
|
||||
|
||||
#define CFI_ERR_BASE (LSYS_ERR_BASE + 0x00100000)
|
||||
#define CFI_ERR_GENERAL (CFI_ERR_BASE + 0)
|
||||
#define CFI_ERR_NOTFOUND (CFI_ERR_BASE + 1)
|
||||
#define CFI_ERR_INVPARAM (CFI_ERR_BASE + 2)
|
||||
#define CFI_ERR_VFY_FAIL (CFI_ERR_BASE + 3)
|
||||
#define CFI_ERR_DEV_FAIL (CFI_ERR_BASE + 0x10000000)
|
||||
|
||||
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;
|
||||
UINT32 eb;
|
||||
flash_info_t info;
|
||||
|
||||
} flash_t;
|
||||
|
||||
void cfi_init(flash_t *pObj, UINT32 base_addr);
|
||||
UINT32 cfi_find(flash_t *pObj);
|
||||
UINT32 cfi_block_is_locked(flash_t *pObj, UINT32 word_index);
|
||||
UINT32 cfi_block_erase(flash_t *pObj, UINT32 word_index);
|
||||
UINT32 cfi_block_lock(flash_t *pObj, UINT32 word_index);
|
||||
UINT32 cfi_block_unlock(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_get_offset_by_blocknum(flash_t *pObj, UINT32 blocknum);
|
||||
UINT32 flash_get_blocknum_by_offset(flash_t *pObj, UINT32 offset);
|
||||
UINT32 flash_get_offset_blockaligned(flash_t *pObj, UINT32 offset);
|
||||
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,54 +0,0 @@
|
||||
#include <stdio.h>
|
||||
|
||||
unsigned long MakeCRC32(char *data, unsigned int len, unsigned int CRC)
|
||||
{
|
||||
/* ========================================================================
|
||||
* Table of CRC-32's of all single-byte values (made by makecrc.c)
|
||||
*/
|
||||
unsigned long crc_32_tab[] = {
|
||||
0x00000000L, 0x77073096L, 0xee0e612cL, 0x990951baL, 0x076dc419L, 0x706af48fL, 0xe963a535L, 0x9e6495a3L,
|
||||
0x0edb8832L, 0x79dcb8a4L, 0xe0d5e91eL, 0x97d2d988L, 0x09b64c2bL, 0x7eb17cbdL, 0xe7b82d07L, 0x90bf1d91L,
|
||||
0x1db71064L, 0x6ab020f2L, 0xf3b97148L, 0x84be41deL, 0x1adad47dL, 0x6ddde4ebL, 0xf4d4b551L, 0x83d385c7L,
|
||||
0x136c9856L, 0x646ba8c0L, 0xfd62f97aL, 0x8a65c9ecL, 0x14015c4fL, 0x63066cd9L, 0xfa0f3d63L, 0x8d080df5L,
|
||||
0x3b6e20c8L, 0x4c69105eL, 0xd56041e4L, 0xa2677172L, 0x3c03e4d1L, 0x4b04d447L, 0xd20d85fdL, 0xa50ab56bL,
|
||||
0x35b5a8faL, 0x42b2986cL, 0xdbbbc9d6L, 0xacbcf940L, 0x32d86ce3L, 0x45df5c75L, 0xdcd60dcfL, 0xabd13d59L,
|
||||
0x26d930acL, 0x51de003aL, 0xc8d75180L, 0xbfd06116L, 0x21b4f4b5L, 0x56b3c423L, 0xcfba9599L, 0xb8bda50fL,
|
||||
0x2802b89eL, 0x5f058808L, 0xc60cd9b2L, 0xb10be924L, 0x2f6f7c87L, 0x58684c11L, 0xc1611dabL, 0xb6662d3dL,
|
||||
0x76dc4190L, 0x01db7106L, 0x98d220bcL, 0xefd5102aL, 0x71b18589L, 0x06b6b51fL, 0x9fbfe4a5L, 0xe8b8d433L,
|
||||
0x7807c9a2L, 0x0f00f934L, 0x9609a88eL, 0xe10e9818L, 0x7f6a0dbbL, 0x086d3d2dL, 0x91646c97L, 0xe6635c01L,
|
||||
0x6b6b51f4L, 0x1c6c6162L, 0x856530d8L, 0xf262004eL, 0x6c0695edL, 0x1b01a57bL, 0x8208f4c1L, 0xf50fc457L,
|
||||
0x65b0d9c6L, 0x12b7e950L, 0x8bbeb8eaL, 0xfcb9887cL, 0x62dd1ddfL, 0x15da2d49L, 0x8cd37cf3L, 0xfbd44c65L,
|
||||
0x4db26158L, 0x3ab551ceL, 0xa3bc0074L, 0xd4bb30e2L, 0x4adfa541L, 0x3dd895d7L, 0xa4d1c46dL, 0xd3d6f4fbL,
|
||||
0x4369e96aL, 0x346ed9fcL, 0xad678846L, 0xda60b8d0L, 0x44042d73L, 0x33031de5L, 0xaa0a4c5fL, 0xdd0d7cc9L,
|
||||
0x5005713cL, 0x270241aaL, 0xbe0b1010L, 0xc90c2086L, 0x5768b525L, 0x206f85b3L, 0xb966d409L, 0xce61e49fL,
|
||||
0x5edef90eL, 0x29d9c998L, 0xb0d09822L, 0xc7d7a8b4L, 0x59b33d17L, 0x2eb40d81L, 0xb7bd5c3bL, 0xc0ba6cadL,
|
||||
0xedb88320L, 0x9abfb3b6L, 0x03b6e20cL, 0x74b1d29aL, 0xead54739L, 0x9dd277afL, 0x04db2615L, 0x73dc1683L,
|
||||
0xe3630b12L, 0x94643b84L, 0x0d6d6a3eL, 0x7a6a5aa8L, 0xe40ecf0bL, 0x9309ff9dL, 0x0a00ae27L, 0x7d079eb1L,
|
||||
0xf00f9344L, 0x8708a3d2L, 0x1e01f268L, 0x6906c2feL, 0xf762575dL, 0x806567cbL, 0x196c3671L, 0x6e6b06e7L,
|
||||
0xfed41b76L, 0x89d32be0L, 0x10da7a5aL, 0x67dd4accL, 0xf9b9df6fL, 0x8ebeeff9L, 0x17b7be43L, 0x60b08ed5L,
|
||||
0xd6d6a3e8L, 0xa1d1937eL, 0x38d8c2c4L, 0x4fdff252L, 0xd1bb67f1L, 0xa6bc5767L, 0x3fb506ddL, 0x48b2364bL,
|
||||
0xd80d2bdaL, 0xaf0a1b4cL, 0x36034af6L, 0x41047a60L, 0xdf60efc3L, 0xa867df55L, 0x316e8eefL, 0x4669be79L,
|
||||
0xcb61b38cL, 0xbc66831aL, 0x256fd2a0L, 0x5268e236L, 0xcc0c7795L, 0xbb0b4703L, 0x220216b9L, 0x5505262fL,
|
||||
0xc5ba3bbeL, 0xb2bd0b28L, 0x2bb45a92L, 0x5cb36a04L, 0xc2d7ffa7L, 0xb5d0cf31L, 0x2cd99e8bL, 0x5bdeae1dL,
|
||||
0x9b64c2b0L, 0xec63f226L, 0x756aa39cL, 0x026d930aL, 0x9c0906a9L, 0xeb0e363fL, 0x72076785L, 0x05005713L,
|
||||
0x95bf4a82L, 0xe2b87a14L, 0x7bb12baeL, 0x0cb61b38L, 0x92d28e9bL, 0xe5d5be0dL, 0x7cdcefb7L, 0x0bdbdf21L,
|
||||
0x86d3d2d4L, 0xf1d4e242L, 0x68ddb3f8L, 0x1fda836eL, 0x81be16cdL, 0xf6b9265bL, 0x6fb077e1L, 0x18b74777L,
|
||||
0x88085ae6L, 0xff0f6a70L, 0x66063bcaL, 0x11010b5cL, 0x8f659effL, 0xf862ae69L, 0x616bffd3L, 0x166ccf45L,
|
||||
0xa00ae278L, 0xd70dd2eeL, 0x4e048354L, 0x3903b3c2L, 0xa7672661L, 0xd06016f7L, 0x4969474dL, 0x3e6e77dbL,
|
||||
0xaed16a4aL, 0xd9d65adcL, 0x40df0b66L, 0x37d83bf0L, 0xa9bcae53L, 0xdebb9ec5L, 0x47b2cf7fL, 0x30b5ffe9L,
|
||||
0xbdbdf21cL, 0xcabac28aL, 0x53b39330L, 0x24b4a3a6L, 0xbad03605L, 0xcdd70693L, 0x54de5729L, 0x23d967bfL,
|
||||
0xb3667a2eL, 0xc4614ab8L, 0x5d681b02L, 0x2a6f2b94L, 0xb40bbe37L, 0xc30c8ea1L, 0x5a05df1bL, 0x2d02ef8dL
|
||||
};
|
||||
|
||||
if (data == NULL)
|
||||
return 0;
|
||||
|
||||
CRC = ~CRC;
|
||||
while (len --)
|
||||
{
|
||||
CRC = crc_32_tab[((unsigned char) CRC ^ *data) & 0xFF] ^ (CRC >> 8);
|
||||
data ++;
|
||||
}
|
||||
|
||||
return ~CRC;
|
||||
}
|
||||
@@ -1,13 +0,0 @@
|
||||
// CRC32 function
|
||||
// To create a CRC from a new buffer, use this:
|
||||
// crc = MakeCRC32(mydata, data_len, 0);
|
||||
// If you need to continue the CRC (e.g. your data is in multiple buffers),
|
||||
// continue like this:
|
||||
// crc = MakeCRC32(moredata, more_len, crc);
|
||||
//
|
||||
// Your desired CRC should be the complement of the CRC generated by
|
||||
// MakeCRC32:
|
||||
// desired = crc
|
||||
// desired - crc = 0
|
||||
|
||||
unsigned long MakeCRC32(char *data, unsigned int len, unsigned long CRC);
|
||||
@@ -1,341 +0,0 @@
|
||||
#include <stdio.h>
|
||||
#include <stdlib.h>
|
||||
#include <string.h>
|
||||
#include "irq.h"
|
||||
#include "libsys.h"
|
||||
#include "mipsdis.h"
|
||||
|
||||
#define MAX_USER_BP 16
|
||||
#define BP_MASK_ID 0x00FFF
|
||||
#define BP_MASK_TYPE 0xFF000
|
||||
|
||||
#define BP_GET_ID(bp) ((bp >> 6) & 0xFFF)
|
||||
|
||||
#define BP_USER_BASE 0x10000
|
||||
#define BP_USER(id) (((BP_USER_BASE + id) << 6) | 0x0D)
|
||||
|
||||
#define BP_MGMT_BASE_SS 0x20000
|
||||
#define BP_MGMT_SS(id) (((BP_MGMT_BASE_SS + id) << 6) | 0x0D)
|
||||
|
||||
#define BP_MGMT_BASE_RU 0x30000
|
||||
#define BP_MGMT_RU(id) (((BP_MGMT_BASE_RU + id) << 6) | 0x0D)
|
||||
|
||||
static char g_buf[80];
|
||||
|
||||
typedef struct _sbp_t
|
||||
{
|
||||
UINT32 *pAddr;
|
||||
UINT32 instr;
|
||||
} bp_t;
|
||||
|
||||
static bp_t user_bp[MAX_USER_BP];
|
||||
static bp_t mgmt_bp_ss[2];
|
||||
static bp_t mgmt_bp_ru[2];
|
||||
static int g_is_ss;
|
||||
static int g_bp_index;
|
||||
|
||||
int IsBreak(UINT32 instr)
|
||||
{
|
||||
return ((instr & 0xFC00003F) == 0x0000000D);
|
||||
}
|
||||
|
||||
UINT32 BreakGetType(UINT32 instr)
|
||||
{
|
||||
return (instr >> 6) & BP_MASK_TYPE;
|
||||
}
|
||||
|
||||
void dbg_handler(struct xcptcontext * xcp)
|
||||
{
|
||||
|
||||
UINT32 bp_addr, bp_index = 0, branch_addr, reg, result, bp_type;
|
||||
int junk, i, leave_isr, is_branch_shadow, is_user_bp;
|
||||
UINT32 volatile *pBtn = (UINT32*)sys_gpio0;
|
||||
UINT32 *pInstr, *pAddr_curr, *pAddr_prev, *pAddr_next;
|
||||
|
||||
sputs("\n");
|
||||
PRINT_REG(" Status : ", xcp->sr);
|
||||
PRINT_REG(" Cause : ", xcp->cr);
|
||||
PRINT_REG(" EPC : ", xcp->epc);
|
||||
PRINT_REG("BadAddr : ", xcp->baddr);
|
||||
sputs("\n");
|
||||
PRINT_REG(" MDLO : ", xcp->mdlo);
|
||||
PRINT_REG(" MDHI : ", xcp->mdhi);
|
||||
|
||||
sputs("\n");
|
||||
|
||||
sputs("Registers:\n");
|
||||
PRINT_REG(" 0 (ze) : ", xcp->regs[0]);
|
||||
PRINT_REG(" 1 (at) : ", xcp->regs[1]);
|
||||
PRINT_REG(" 2 (v0) : ", xcp->regs[2]);
|
||||
PRINT_REG(" 3 (v1) : ", xcp->regs[3]);
|
||||
sputs("\n");
|
||||
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]);
|
||||
sputs("\n");
|
||||
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]);
|
||||
sputs("\n");
|
||||
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]);
|
||||
sputs("\n");
|
||||
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]);
|
||||
sputs("\n");
|
||||
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]);
|
||||
sputs("\n");
|
||||
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]);
|
||||
sputs("\n");
|
||||
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");
|
||||
sputs("\n");
|
||||
|
||||
is_user_bp = 0;
|
||||
pAddr_curr = (UINT32*)xcp->epc;
|
||||
is_branch_shadow = ((xcp->cr & 0x80000000) == 0x80000000);
|
||||
if (is_branch_shadow)
|
||||
pAddr_curr++;
|
||||
|
||||
pAddr_prev = pAddr_curr - 1;
|
||||
pAddr_next = pAddr_curr + 1;
|
||||
|
||||
if (IsBreak(*pAddr_curr))
|
||||
{
|
||||
bp_type = BreakGetType(*pAddr_curr);
|
||||
|
||||
switch (bp_type)
|
||||
{
|
||||
case BP_MGMT_BASE_SS:
|
||||
|
||||
// Restore original instructions after single-step
|
||||
sputs("1. Restore after single-step at ");print_word((long)mgmt_bp_ss[0].pAddr);sputs("\n");
|
||||
*(mgmt_bp_ss[0].pAddr) = mgmt_bp_ss[0].instr;
|
||||
ICACHE_invalidate_at(mgmt_bp_ss[0].pAddr);
|
||||
if (mgmt_bp_ss[1].pAddr)
|
||||
{
|
||||
sputs("2. Restore after single-step at ");print_word((long)mgmt_bp_ss[1].pAddr);sputs("\n");
|
||||
*(mgmt_bp_ss[1].pAddr) = mgmt_bp_ss[1].instr;
|
||||
ICACHE_invalidate_at(mgmt_bp_ss[1].pAddr);
|
||||
}
|
||||
|
||||
break;
|
||||
|
||||
case BP_MGMT_BASE_RU:
|
||||
|
||||
bp_index = BP_GET_ID(*pAddr_curr);
|
||||
sputs("Restore user break at ");print_word((long)user_bp[bp_index].pAddr);sputs("\n");
|
||||
|
||||
*(user_bp[bp_index].pAddr) = BP_USER(bp_index);
|
||||
ICACHE_invalidate_at(user_bp[bp_index].pAddr);
|
||||
|
||||
*(mgmt_bp_ru[0].pAddr) = mgmt_bp_ru[0].instr;
|
||||
ICACHE_invalidate_at(mgmt_bp_ru[0].pAddr);
|
||||
sputs("1. Restore after RU at ");print_word((long)mgmt_bp_ru[0].pAddr);sputs("\n");
|
||||
if (mgmt_bp_ru[1].pAddr)
|
||||
{
|
||||
*(mgmt_bp_ru[1].pAddr) = mgmt_bp_ru[1].instr;
|
||||
ICACHE_invalidate_at(mgmt_bp_ru[1].pAddr);
|
||||
sputs("2. Restore after RU at ");print_word((long)mgmt_bp_ru[1].pAddr);sputs("\n");
|
||||
}
|
||||
if (!g_is_ss)
|
||||
return;
|
||||
|
||||
break;
|
||||
|
||||
case BP_USER_BASE:
|
||||
|
||||
is_user_bp = 1;
|
||||
bp_index = BP_GET_ID(*pAddr_curr);
|
||||
sputs("Restore instruction at ");print_word((long)user_bp[bp_index].pAddr);sputs("\n");
|
||||
*(user_bp[bp_index].pAddr) = user_bp[bp_index].instr;
|
||||
ICACHE_invalidate_at(user_bp[bp_index].pAddr);
|
||||
break;
|
||||
|
||||
default:
|
||||
break;
|
||||
|
||||
}
|
||||
}
|
||||
|
||||
pInstr = pAddr_prev;
|
||||
// Disassemble instructions
|
||||
for (i=0; i < 3; i++)
|
||||
{
|
||||
print_word((long)pInstr);
|
||||
if (IsBreak(*pInstr) && (BreakGetType(*pInstr) == BP_USER_BASE))
|
||||
{
|
||||
tdisasm(g_buf, (long)user_bp[BP_GET_ID(*pInstr)].pAddr, user_bp[BP_GET_ID(*pInstr)].instr, 0, &junk, &junk, &junk);
|
||||
sputs(": b ");
|
||||
}
|
||||
else
|
||||
{
|
||||
tdisasm(g_buf, (long)pInstr, *pInstr, 0, &junk, &junk, &junk);
|
||||
if (pInstr == pAddr_curr)
|
||||
if (is_user_bp == 1)
|
||||
sputs(": b-> ");
|
||||
else
|
||||
sputs(": -> ");
|
||||
else
|
||||
sputs(": ");
|
||||
}
|
||||
sputs(g_buf);
|
||||
sputs("\n");
|
||||
pInstr++;
|
||||
}
|
||||
|
||||
if (is_user_bp)
|
||||
{
|
||||
// Save original instruction
|
||||
mgmt_bp_ru[0].pAddr = pAddr_next;
|
||||
mgmt_bp_ru[0].instr = *(mgmt_bp_ru[0].pAddr);
|
||||
// Replace instruction with managment breakpoint
|
||||
*(mgmt_bp_ru[0].pAddr) = BP_MGMT_RU(bp_index);
|
||||
ICACHE_invalidate_at(mgmt_bp_ru[0].pAddr);
|
||||
mgmt_bp_ru[1].pAddr = NULL;
|
||||
mgmt_bp_ru[1].pAddr = 0;
|
||||
sputs("1. Insert RU-break at ");print_word((long)mgmt_bp_ru[0].pAddr);sputs("\n");
|
||||
|
||||
// We have two possible management breaks, if previous instruction was branch or jump
|
||||
if (is_branch_shadow)
|
||||
{
|
||||
result = tdisasm(g_buf, (long)pAddr_prev, *pAddr_prev, 0, &junk, &branch_addr, ®);
|
||||
// Is jump target stored in register
|
||||
if (result == 3)
|
||||
{
|
||||
branch_addr = xcp->regs[reg&0x1F];
|
||||
}
|
||||
// Save original instruction
|
||||
mgmt_bp_ru[1].pAddr = (UINT32*)branch_addr;
|
||||
mgmt_bp_ru[1].instr = *(mgmt_bp_ru[1].pAddr);
|
||||
// Replace instruction with managment breakpoint
|
||||
*(mgmt_bp_ru[1].pAddr) = BP_MGMT_RU(bp_index);
|
||||
ICACHE_invalidate_at(mgmt_bp_ru[1].pAddr);
|
||||
sputs("2. Insert RU-break at ");print_word((long)mgmt_bp_ru[1].pAddr);sputs("\n");
|
||||
}
|
||||
}
|
||||
|
||||
do
|
||||
{
|
||||
leave_isr = 0;
|
||||
switch(readchar())
|
||||
{
|
||||
case 'g':
|
||||
leave_isr = 1;
|
||||
g_is_ss = 0;
|
||||
break;
|
||||
|
||||
case 'b':
|
||||
printf("Enter breakpoint: ");
|
||||
scanf("%x", &bp_addr);
|
||||
printf("Insert breakpoint at %.8X\n", bp_addr);
|
||||
user_bp[g_bp_index].pAddr = (UINT32*)bp_addr;
|
||||
user_bp[g_bp_index].instr = *(user_bp[g_bp_index].pAddr);
|
||||
*(user_bp[g_bp_index].pAddr) = BP_USER(g_bp_index);
|
||||
|
||||
tdisasm(g_buf, (long)user_bp[g_bp_index].pAddr, user_bp[g_bp_index].instr, 0, &junk, &junk, &junk);
|
||||
print_word((long)user_bp[g_bp_index].pAddr);sputs(": b ");sputs(g_buf);sputs("\n");
|
||||
ICACHE_invalidate_at(user_bp[g_bp_index].pAddr);
|
||||
g_bp_index++;
|
||||
break;
|
||||
|
||||
case 's':
|
||||
g_is_ss = 1;
|
||||
leave_isr = 1;
|
||||
// Don't overwrite RU breaks
|
||||
if (is_user_bp)
|
||||
break;
|
||||
// Don't overwrite user breaks
|
||||
if (IsBreak(*pInstr) && (BreakGetType(*pInstr) == BP_USER_BASE))
|
||||
break;
|
||||
|
||||
// Save original instruction
|
||||
mgmt_bp_ss[0].pAddr = pAddr_next;
|
||||
mgmt_bp_ss[0].instr = *(mgmt_bp_ss[0].pAddr);
|
||||
// Replace instruction with managment breakpoint
|
||||
*(mgmt_bp_ss[0].pAddr) = BP_MGMT_SS(1);
|
||||
ICACHE_invalidate_at(mgmt_bp_ss[0].pAddr);
|
||||
mgmt_bp_ss[1].pAddr = NULL;
|
||||
mgmt_bp_ss[1].pAddr = 0;
|
||||
// We have two possible management breaks, if previous instruction was branch or jump
|
||||
if (is_branch_shadow)
|
||||
{
|
||||
result = tdisasm(g_buf, (long)pAddr_prev, *pAddr_prev, 0, &junk, &branch_addr, ®);
|
||||
// Is jump target stored in register
|
||||
if (result == 3)
|
||||
{
|
||||
branch_addr = xcp->regs[reg&0x1F];
|
||||
}
|
||||
// Save original instruction
|
||||
mgmt_bp_ss[1].pAddr = (UINT32*)branch_addr;
|
||||
mgmt_bp_ss[1].instr = *(mgmt_bp_ss[1].pAddr);
|
||||
// Replace instruction with managment breakpoint
|
||||
*(mgmt_bp_ss[1].pAddr) = BP_MGMT_SS(2);
|
||||
ICACHE_invalidate_at(mgmt_bp_ss[1].pAddr);
|
||||
}
|
||||
break;
|
||||
|
||||
case 'P':
|
||||
g_is_ss = 1;
|
||||
leave_isr = 1;
|
||||
// Don't overwrite RU breaks
|
||||
if (is_user_bp)
|
||||
break;
|
||||
// Don't overwrite user breaks
|
||||
if (IsBreak(*pInstr) && (BreakGetType(*pInstr) == BP_USER_BASE))
|
||||
break;
|
||||
|
||||
// Save original instruction
|
||||
mgmt_bp_ss[0].pAddr = (UINT32*)xcp->regs[0x1F];
|
||||
mgmt_bp_ss[0].instr = *(mgmt_bp_ss[0].pAddr);
|
||||
// Replace instruction with managment breakpoint
|
||||
*(mgmt_bp_ss[0].pAddr) = BP_MGMT_SS(1);
|
||||
ICACHE_invalidate_at(mgmt_bp_ss[0].pAddr);
|
||||
mgmt_bp_ss[1].pAddr = NULL;
|
||||
mgmt_bp_ss[1].pAddr = 0;
|
||||
break;
|
||||
|
||||
default:
|
||||
break;
|
||||
}
|
||||
} while (!leave_isr);
|
||||
|
||||
}
|
||||
|
||||
void debug_int(struct xcptcontext * xcp)
|
||||
{
|
||||
dbg_handler(xcp);
|
||||
|
||||
}
|
||||
|
||||
int debug_break(struct xcptcontext * xcp)
|
||||
{
|
||||
dbg_handler(xcp);
|
||||
return 0;
|
||||
|
||||
}
|
||||
|
||||
void dbg_init(void)
|
||||
{
|
||||
|
||||
interrupt_register(2, debug_int);
|
||||
interrupt_enable(2);
|
||||
|
||||
xcpt_register(Bp, debug_break);
|
||||
}
|
||||
|
||||
@@ -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,198 +0,0 @@
|
||||
#include <stdio.h>
|
||||
#include <stdlib.h>
|
||||
#include <string.h>
|
||||
#include <math.h>
|
||||
#include <ctype.h>
|
||||
#include <time.h>
|
||||
|
||||
#define CPU_FREQ_HZ 100000000
|
||||
#include "libsys.h"
|
||||
|
||||
#include "crc32.h"
|
||||
#include "inflate.h"
|
||||
|
||||
char buffer[1024*1024];
|
||||
char * volatile pPtr_r;
|
||||
char * volatile pPtr_w;
|
||||
volatile int timeout_cnt;
|
||||
volatile int file_len;
|
||||
|
||||
void handler3(void)
|
||||
{
|
||||
volatile UINT32 *pUART_stat = (UINT32*)sys_uart0_stat;
|
||||
volatile UINT32 *pUART_data = (UINT32*)sys_uart0_data;
|
||||
|
||||
while(0x200 & *pUART_stat)
|
||||
{
|
||||
// sputs("w: "); print_word((int)pPtr_w); sputs("\n");
|
||||
if (pPtr_w == &buffer[sizeof(buffer)-1])
|
||||
pPtr_w = buffer;
|
||||
*(pPtr_w++) = *pUART_data;
|
||||
timeout_cnt = 100;
|
||||
file_len++;
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
int READBYTE(z_stream *zs) {
|
||||
if (zs->avail_in <= 0)
|
||||
return -1;
|
||||
|
||||
zs->avail_in --;
|
||||
return *(zs->next_in ++);
|
||||
}
|
||||
|
||||
#define MAX_BUFOUT 16*1024*1024
|
||||
int main(int argc, char **argv)
|
||||
{
|
||||
volatile UINT32 *pUART_stat = (UINT32*)sys_uart0_stat;
|
||||
unsigned char outData[MAX_BUFOUT];
|
||||
FILE *infp;
|
||||
int i, gpflags, tmp[4];
|
||||
unsigned long size, crc;
|
||||
unsigned char *fileData;
|
||||
unsigned long bytes, InflatedSize, InflatedCRC, speed_count;
|
||||
z_stream zs;
|
||||
time_t start_time, work_time;
|
||||
|
||||
UART0_setbaud(460800);
|
||||
|
||||
printf("Reading gzipped stream..\n");
|
||||
|
||||
pPtr_r = buffer;
|
||||
pPtr_w = buffer;
|
||||
*pUART_stat = (1 << 6);
|
||||
interrupt_register(3, handler3);
|
||||
interrupt_enable(3);
|
||||
|
||||
file_len = 0;
|
||||
timeout_cnt = 1000000;
|
||||
while(timeout_cnt--)
|
||||
{
|
||||
sleep(1);
|
||||
}
|
||||
|
||||
printf("file_len: %d\n", file_len);
|
||||
bytes = file_len;
|
||||
fileData = pPtr_r;
|
||||
|
||||
zs.next_in = fileData;
|
||||
zs.avail_in = (unsigned int) bytes;
|
||||
zs.next_out = outData;
|
||||
zs.avail_out = MAX_BUFOUT;
|
||||
|
||||
tmp[0] = READBYTE(&zs);
|
||||
if (tmp[0] == -1)
|
||||
{
|
||||
// error reading from file
|
||||
printf("error reading data from file\n");
|
||||
return 0;
|
||||
}
|
||||
tmp[1] = READBYTE(&zs);
|
||||
|
||||
if (tmp[0] != 0x1f || tmp[1] != 0x8b) {
|
||||
// fprintf(stderr, "Magic number mismatch 0x%02x%02x\n",
|
||||
// tmp[0], tmp[1]);
|
||||
return 20;
|
||||
}
|
||||
|
||||
tmp[0] = READBYTE(&zs);
|
||||
if(tmp[0] != 8) {
|
||||
// fprintf(stderr, "Unknown compression method: 0x%02x\n", tmp[0]);
|
||||
return 20;
|
||||
}
|
||||
|
||||
gpflags = READBYTE(&zs);
|
||||
if ((gpflags & ~0x1f)) {
|
||||
printf("Unknown flags set!\n");
|
||||
}
|
||||
|
||||
/* Skip file modification time (4 bytes) */
|
||||
READBYTE(&zs);
|
||||
READBYTE(&zs);
|
||||
READBYTE(&zs);
|
||||
READBYTE(&zs);
|
||||
/* Skip extra flags and operating system fields (2 bytes) */
|
||||
READBYTE(&zs);
|
||||
READBYTE(&zs);
|
||||
|
||||
if ((gpflags & 4)) {
|
||||
/* Skip extra field */
|
||||
tmp[0] = READBYTE(&zs);
|
||||
tmp[1] = READBYTE(&zs);
|
||||
i = tmp[0] + 256*tmp[1];
|
||||
while (i--)
|
||||
{
|
||||
READBYTE(&zs);
|
||||
}
|
||||
}
|
||||
if((gpflags & 8)) {
|
||||
while((READBYTE(&zs))) {
|
||||
}
|
||||
}
|
||||
if((gpflags & 16)) {
|
||||
while((READBYTE(&zs))) {
|
||||
}
|
||||
}
|
||||
if((gpflags & 2)) {
|
||||
/* Skip CRC16 */
|
||||
READBYTE(&zs);
|
||||
READBYTE(&zs);
|
||||
}
|
||||
|
||||
printf("Go\n");
|
||||
// normal test
|
||||
start_time = clock();
|
||||
if (InflateData(&zs))
|
||||
{
|
||||
printf("Problem during decompression!\n");
|
||||
return 0;
|
||||
}
|
||||
work_time = clock() - start_time;
|
||||
|
||||
|
||||
/*
|
||||
// speed test
|
||||
fprintf(stdout, "SPEED TEST!\n");
|
||||
speed_count = 0;
|
||||
while (time(NULL) - start_time < 20)
|
||||
{
|
||||
zs_speed.next_in = zs.next_in;
|
||||
zs_speed.next_out = zs.next_out;
|
||||
zs_speed.avail_in = zs.avail_in;
|
||||
zs_speed.avail_out = zs.avail_out;
|
||||
if (InflateData(&zs_speed))
|
||||
{
|
||||
fprintf(stdout, "Problem during decompression!\n");
|
||||
return 0;
|
||||
}
|
||||
speed_count ++;
|
||||
}
|
||||
fprintf(stdout, "speed count %ld\n", speed_count);
|
||||
zs.next_in = zs_speed.next_in;
|
||||
zs.next_out = zs_speed.next_out;
|
||||
zs.avail_in = zs_speed.avail_in;
|
||||
zs.avail_out = zs_speed.avail_out;
|
||||
*/
|
||||
|
||||
crc = READBYTE(&zs);
|
||||
crc |= (READBYTE(&zs)<<8);
|
||||
crc |= (READBYTE(&zs)<<16);
|
||||
crc |= (READBYTE(&zs)<<24);
|
||||
|
||||
size = READBYTE(&zs);
|
||||
size |= (READBYTE(&zs)<<8);
|
||||
size |= (READBYTE(&zs)<<16);
|
||||
size |= (READBYTE(&zs)<<24);
|
||||
|
||||
InflatedSize = MAX_BUFOUT - zs.avail_out;
|
||||
InflatedCRC = MakeCRC32(outData, InflatedSize, 0);
|
||||
|
||||
// write(1, outData, InflatedSize);
|
||||
fprintf(stdout, "CRC: %08lx %08lx %s\n", crc, InflatedCRC, (crc != InflatedCRC)?"**error**":"");
|
||||
fprintf(stdout, "Size: %08lx %08lx %s\n", size, InflatedSize, (size != InflatedSize)?"**error**":"");
|
||||
fprintf(stdout, "Time for decompression was %.2f seconds\n", (float)work_time/1000);
|
||||
fprintf(stdout, "Throughput is %d kByte/s\n", InflatedSize/work_time);
|
||||
|
||||
return 0;
|
||||
}
|
||||
@@ -1,19 +0,0 @@
|
||||
#include <stdio.h>
|
||||
#define A 0.5
|
||||
#define B 0.55
|
||||
|
||||
_Sat long _Fract sat_add3 (_Sat long _Fract a, _Sat long _Fract b)
|
||||
{
|
||||
return a + b;
|
||||
}
|
||||
|
||||
long _Fract mul3 (long _Fract a, long _Fract b)
|
||||
{
|
||||
return a * b;
|
||||
}
|
||||
|
||||
int main()
|
||||
{
|
||||
printf("hello %X + %X = %X\n", (_Sat long _Fract)A, (_Sat long _Fract)B, sat_add3(A, B));
|
||||
printf("hello %X * %X = %X\n", (_Sat long _Fract)A, (_Sat long _Fract)B, mul3(A, B));
|
||||
}
|
||||
@@ -1,504 +0,0 @@
|
||||
/* inflate routines for Palm OS (to inflate a deflated stream)
|
||||
*
|
||||
* Based heavily upon gunzip.c by Pasi Ojala <albert@cs.tut.fi>
|
||||
* http://www.cs.tut.fi/~albert/Dev/gunzip/
|
||||
* Many, many thanks for that code!
|
||||
*
|
||||
* Changes:
|
||||
* 2002-12-30 - Added #defines to use zlib's struct instead of mine, just
|
||||
* in case you want to compile it that way.
|
||||
* 2002-12-29 - Found out that this is VERY slow. ZLib is 3x faster.
|
||||
* Worked on speeding it up. Partially successful. Profiled
|
||||
* code and marked critical areas. 1932 bytes added to a
|
||||
* Palm program by linking in the .o file. Schweet!
|
||||
* 2002-12-21 - Finished surgery. Only one function to inflate dynamic and
|
||||
* fixed data. Rewrote table generation to be iterative.
|
||||
* Hacked and slashed my way through unnecessary code.
|
||||
* The size is now down to 3512 bytes.
|
||||
* 2002-12-20 - Started major surgery
|
||||
* 2002-12-19 - Looked at the code a bit more
|
||||
* 2002-12-17 - Continued work. Down to about 6k for the .o file
|
||||
* 2002-12-09 - Continued work, added z_stream_fid instead of globals
|
||||
* 2002-12-08 - Started work so that it decompresses up to 64k (one memory
|
||||
* chunk on the Palm.
|
||||
* 2002-12-07 - Removed bit reverse table. Removed unzip code.
|
||||
*/
|
||||
#include "libsys.h"
|
||||
#include "inflate.h"
|
||||
#ifdef VERBOSE
|
||||
#include <stdio.h> // Just in case you put a printf() function back in
|
||||
#endif
|
||||
|
||||
void Status(char *, int);
|
||||
|
||||
typedef struct HufNode_struct {
|
||||
// b0 and b1 are either values in the tree array to jump to (branches)
|
||||
// or are literal values.
|
||||
// if (bX & 0x8000)
|
||||
// value = bX ^ 0x8000;
|
||||
// else
|
||||
// link_to_array_element = bX;
|
||||
unsigned int b0; // Bigger than 1 byte (2 is ideal)
|
||||
unsigned int b1; // Bigger than 1 byte (2 is ideal)
|
||||
} HufNode;
|
||||
|
||||
|
||||
// Not that rhobust anymore -- If out of data, this will
|
||||
// return a whole lot of 1 bits.
|
||||
//
|
||||
// This function consumes a large percentage of time (#1)
|
||||
char READBIT(z_stream *zs)
|
||||
{
|
||||
char carry;
|
||||
|
||||
if (zs->reserved == 1)
|
||||
{
|
||||
if (zs->avail_in == 0)
|
||||
return 1;
|
||||
zs->reserved = *(zs->next_in ++) | 0x0100;
|
||||
zs->avail_in --;
|
||||
}
|
||||
|
||||
carry = zs->reserved & 1;
|
||||
zs->reserved >>= 1;
|
||||
|
||||
return carry;
|
||||
}
|
||||
|
||||
|
||||
// Make sure that [a] is <= 16
|
||||
// If there are endian problems, force [a] to be <= 8
|
||||
// Might be faster if all (up to [a] bits) of zs->reserved was read into res
|
||||
// right away.
|
||||
//
|
||||
// This function consumes a large percentage of time (#4)
|
||||
int READBITS(z_stream *zs, int a)
|
||||
{
|
||||
int res = 0, pos = 0;
|
||||
|
||||
while (a --)
|
||||
{
|
||||
if (zs->reserved == 1)
|
||||
{
|
||||
if (zs->avail_in == 0)
|
||||
return 1;
|
||||
zs->reserved = *(zs->next_in ++) | 0x0100;
|
||||
zs->avail_in --;
|
||||
}
|
||||
|
||||
res += (zs->reserved & 1) << pos;
|
||||
zs->reserved >>= 1;
|
||||
pos ++;
|
||||
}
|
||||
|
||||
return res;
|
||||
}
|
||||
|
||||
|
||||
// Huffman tree structures, variables and related routines
|
||||
//
|
||||
// These routines are one-bit-at-a-time decode routines. They
|
||||
// are not as fast as multi-bit routines, but maybe a bit easier
|
||||
// to understand and use a lot less memory.
|
||||
//
|
||||
// The tree is created in an array
|
||||
//
|
||||
// currentTree = where to put the tree (in an array)
|
||||
// numval = Number of elements in the lengths array
|
||||
// lengths = array of lengths
|
||||
//
|
||||
//
|
||||
// This function consumes a large percentage of time (#5)
|
||||
int CreateTree(HufNode *currentTree, int numval, unsigned char *lengths) {
|
||||
int i, j, len; // basically scratch values
|
||||
int BlankNode; // Where is the next blank array index
|
||||
int this_code, mask, *bitData; // used in tree generation
|
||||
int bl_count[16] = { 0, }; // Counter of code lengths
|
||||
int next_code[16] = { 0, }; // Code for a specific length
|
||||
// 16 = (15 is max length of a code when inflating) + (1 for zero)
|
||||
|
||||
// Step 1: Count the code lengths
|
||||
for (i = 0; i < numval; i ++)
|
||||
{
|
||||
j = lengths[i];
|
||||
if (j > 15)
|
||||
return 1;
|
||||
bl_count[j] ++;
|
||||
}
|
||||
|
||||
// Step 2: Find numerical value of the smallest code of each length
|
||||
// Also note that I've inserted some weak validation code here. I'm
|
||||
// not 100% sure that it is up to RFC specs, but it seems to work fine
|
||||
// in my tests
|
||||
//
|
||||
// The validation theory is that at the root node, you have 2 branches or
|
||||
// values possible. If you branch, you get 2 more potentials. If you
|
||||
// get a value, you lose one potential. So, if the root node has one of
|
||||
// each, the number of potentials at the next level is still two. If that
|
||||
// node just has branches, the number of potentials is four. If both of
|
||||
// the nodes on the following level just have values, the number of
|
||||
// potentials is 0, leaving us with a complete tree.
|
||||
//
|
||||
// If I don't validate and if an invalid tree gets generated, an
|
||||
// infinite loop is possible
|
||||
bl_count[0] = 0;
|
||||
j = 0;
|
||||
len = 2;
|
||||
for (i = 1; i < 16; i ++)
|
||||
{
|
||||
len -= bl_count[i];
|
||||
len *= 2;
|
||||
j = (j + bl_count[i - 1]) << 1;
|
||||
next_code[i] = j;
|
||||
}
|
||||
if (len)
|
||||
return 1;
|
||||
|
||||
// Step 3: Assign numerical values to all codes
|
||||
BlankNode = 1;
|
||||
currentTree[0].b0 = 0x0000;
|
||||
currentTree[0].b1 = 0x0000;
|
||||
for (i = 0; i < numval; i ++)
|
||||
{
|
||||
len = lengths[i];
|
||||
if (len != 0)
|
||||
{
|
||||
this_code = next_code[len];
|
||||
next_code[len] ++;
|
||||
mask = 1 << (len - 1);
|
||||
j = 0;
|
||||
while (mask > 1)
|
||||
{
|
||||
if (this_code & mask)
|
||||
bitData = &(currentTree[j].b1);
|
||||
else
|
||||
bitData = &(currentTree[j].b0);
|
||||
|
||||
if (*bitData == 0x0000)
|
||||
{
|
||||
*bitData = BlankNode;
|
||||
j = BlankNode;
|
||||
BlankNode ++;
|
||||
currentTree[j].b0 = 0x0000;
|
||||
currentTree[j].b1 = 0x0000;
|
||||
}
|
||||
else
|
||||
j = *bitData;
|
||||
|
||||
mask >>= 1;
|
||||
}
|
||||
if (this_code & 0x01)
|
||||
currentTree[j].b1 = 0x8000 | i;
|
||||
else
|
||||
currentTree[j].b0 = 0x8000 | i;
|
||||
}
|
||||
}
|
||||
|
||||
#ifdef VERBOSE
|
||||
fprintf(stderr, "%d table entries used\n",
|
||||
BlankNode);
|
||||
if (numval < 20) {
|
||||
for (i = 0; i < BlankNode; i ++)
|
||||
{
|
||||
fprintf(stderr, "0x%03x - ", i);
|
||||
if (currentTree[i].b0 & 0x8000)
|
||||
fprintf(stderr, "value: 0x%03x ", currentTree[i].b0 ^ 0x8000);
|
||||
else
|
||||
fprintf(stderr, " link: 0x%03x ", currentTree[i].b0);
|
||||
|
||||
if (currentTree[i].b1 & 0x8000)
|
||||
fprintf(stderr, "value: 0x%03x\n", currentTree[i].b1 ^ 0x8000);
|
||||
else
|
||||
fprintf(stderr, " link: 0x%03x\n", currentTree[i].b1);
|
||||
}
|
||||
}
|
||||
#endif
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
|
||||
// Using the tree passed in, read bits from the data stream until we arrive
|
||||
// at the proper value
|
||||
//
|
||||
// This function consumes a large percentage of time (#2)
|
||||
int DecodeValue(z_stream *zs, HufNode *currentTree)
|
||||
{
|
||||
unsigned int i = 0;
|
||||
|
||||
// decode one symbol of the data per iteration
|
||||
// Infinite loop detection code could go here. Maximum
|
||||
// bits to read is 15.
|
||||
while (i < 0x8000)
|
||||
{
|
||||
if (READBIT(zs))
|
||||
i = currentTree[i].b1;
|
||||
else
|
||||
i = currentTree[i].b0;
|
||||
}
|
||||
return i & 0x7FFF;
|
||||
}
|
||||
|
||||
|
||||
int Decompress_Stored(z_stream *zs)
|
||||
{
|
||||
int blockLen, cSum;
|
||||
|
||||
#ifdef VERBOSE
|
||||
fprintf(stderr, "Stored\n");
|
||||
#endif
|
||||
|
||||
zs->reserved = 1;;
|
||||
if (zs->avail_in < 4)
|
||||
return -1;
|
||||
|
||||
zs->avail_in -= 4;
|
||||
blockLen = *(zs->next_in ++);
|
||||
blockLen |= *(zs->next_in ++) << 8;
|
||||
|
||||
cSum = *(zs->next_in ++);
|
||||
cSum |= (*(zs->next_in ++) << 8);
|
||||
|
||||
if ((blockLen + cSum) ^ 0xFFFF)
|
||||
return 1;
|
||||
if (zs->avail_in < blockLen || zs->avail_out < blockLen)
|
||||
return -1;
|
||||
zs->avail_in -= blockLen;
|
||||
zs->avail_out -= blockLen;
|
||||
|
||||
while (blockLen --)
|
||||
{
|
||||
*(zs->next_out) = *(zs->next_in);
|
||||
zs->next_out ++;
|
||||
zs->next_in ++;
|
||||
}
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
|
||||
int MakeTrees(z_stream *zs, char is_fixed, HufNode *literalTree,
|
||||
HufNode *distanceTree)
|
||||
{
|
||||
// Order of the bit length code lengths
|
||||
static const unsigned border[] = {
|
||||
16, 17, 18, 0, 8, 7, 9, 6, 10, 5, 11, 4, 12, 3, 13, 2, 14, 1, 15 };
|
||||
unsigned char ll[288+32];
|
||||
int i, j, n, l, literalCodes, distCodes;
|
||||
|
||||
if (is_fixed)
|
||||
{
|
||||
literalCodes = 288;
|
||||
|
||||
// Set a large range to 8
|
||||
for (i = 0; i < 288; i ++)
|
||||
ll[i] = 8;
|
||||
// In that range, set some to 9 and others to 7
|
||||
// (smaller code, but slightly slower table generation)
|
||||
for (i = 144; i < 256; i ++)
|
||||
ll[i] = 9;
|
||||
for (; i < 280; i ++)
|
||||
ll[i] = 7;
|
||||
|
||||
distCodes = 32;
|
||||
|
||||
for (i = 288; i < 320; i ++)
|
||||
ll[i] = 5;
|
||||
}
|
||||
else
|
||||
{
|
||||
literalCodes = 257 + READBITS(zs, 5);
|
||||
distCodes = 1 + READBITS(zs, 5);
|
||||
l = 4 + READBITS(zs, 4);
|
||||
|
||||
for (j = 0; j < 19; j ++)
|
||||
ll[j] = 0;
|
||||
|
||||
// Get the decode tree code lengths
|
||||
// The decode tree is Huffman encoded
|
||||
|
||||
for (j = 0; j < l; j++)
|
||||
{
|
||||
ll[border[j]] = READBITS(zs, 3);
|
||||
}
|
||||
if (CreateTree(distanceTree, 19, ll))
|
||||
return 1;
|
||||
|
||||
// read in literal and distance code lengths
|
||||
n = literalCodes + distCodes;
|
||||
i = 0;
|
||||
while (i < n)
|
||||
{
|
||||
j = DecodeValue(zs, distanceTree);
|
||||
if (j < 16) // length of code in bits (0..15)
|
||||
ll[i++] = j;
|
||||
else if (j == 16)
|
||||
{ // repeat last length 3 to 6 times
|
||||
j = 3 + READBITS(zs, 2);
|
||||
|
||||
if (i + j > n)
|
||||
return 1;
|
||||
|
||||
l = i ? ll[i-1] : 0;
|
||||
while (j --)
|
||||
ll[i++] = l;
|
||||
}
|
||||
else
|
||||
{
|
||||
if (j == 17) // 3 to 10 zero length codes
|
||||
j = 3 + READBITS(zs, 3);
|
||||
else // j == 18: 11 to 138 zero length codes
|
||||
j = 11 + READBITS(zs, 7);
|
||||
|
||||
if (i + j > n)
|
||||
return 1;
|
||||
|
||||
while (j --)
|
||||
ll[i++] = 0;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
// Can overwrite tree decode tree as it is not used anymore
|
||||
if (CreateTree(literalTree, literalCodes, &ll[0]))
|
||||
return 1;
|
||||
|
||||
if(CreateTree(distanceTree, distCodes, &ll[literalCodes]))
|
||||
return 1;
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
|
||||
// This function consumes a large percentage of time (#3)
|
||||
// Most output produced by gzip/zlib/etc is dynamic.
|
||||
int Decompress_DynamicOrFixed(z_stream *zs, char is_fixed)
|
||||
{
|
||||
// Copy lengths for literal codes 257..285
|
||||
static const unsigned short cplens[] = {
|
||||
3, 4, 5, 6, 7, 8, 9, 10, 11, 13, 15, 17, 19, 23, 27, 31,
|
||||
35, 43, 51, 59, 67, 83, 99, 115, 131, 163, 195, 227, 258, 0, 0 };
|
||||
// Extra bits for literal codes 257..285
|
||||
static const unsigned short cplext[] = {
|
||||
0, 0, 0, 0, 0, 0, 0, 0, 1, 1, 1, 1, 2, 2, 2, 2,
|
||||
3, 3, 3, 3, 4, 4, 4, 4, 5, 5, 5, 5, 0, 99, 99 }; // 99==invalid
|
||||
// Copy offsets for distance codes 0..29
|
||||
static const unsigned short cpdist[] = {
|
||||
0x0001, 0x0002, 0x0003, 0x0004, 0x0005, 0x0007, 0x0009, 0x000d,
|
||||
0x0011, 0x0019, 0x0021, 0x0031, 0x0041, 0x0061, 0x0081, 0x00c1,
|
||||
0x0101, 0x0181, 0x0201, 0x0301, 0x0401, 0x0601, 0x0801, 0x0c01,
|
||||
0x1001, 0x1801, 0x2001, 0x3001, 0x4001, 0x6001 };
|
||||
// Extra bits for distance codes
|
||||
static const unsigned short cpdext[] = {
|
||||
0, 0, 0, 0, 1, 1, 2, 2,
|
||||
3, 3, 4, 4, 5, 5, 6, 6,
|
||||
7, 7, 8, 8, 9, 9, 10, 10,
|
||||
11, 11, 12, 12, 13, 13 };
|
||||
HufNode literalTree[288];
|
||||
HufNode distanceTree[32];
|
||||
int j, l, dist;
|
||||
|
||||
#ifdef VERBOSE
|
||||
if (is_fixed)
|
||||
fprintf(stderr, "Fixed Huffman codes\n");
|
||||
else
|
||||
fprintf(stderr, "Dynamic Huffman codes\n");
|
||||
#endif
|
||||
|
||||
if (MakeTrees(zs, is_fixed, literalTree, distanceTree))
|
||||
return 1;
|
||||
|
||||
while (1)
|
||||
{
|
||||
j = DecodeValue(zs, literalTree);
|
||||
if (j >= 256)
|
||||
{
|
||||
if (j == 256) // EOF
|
||||
break;
|
||||
|
||||
//printf("%04x ", j);
|
||||
j -= 256 + 1; // bytes + EOF
|
||||
|
||||
l = READBITS(zs, cplext[j]) + cplens[j];
|
||||
//printf("%04x ", l);
|
||||
|
||||
j = DecodeValue(zs, distanceTree);
|
||||
//printf("%02x ", j);
|
||||
|
||||
dist = READBITS(zs, cpdext[j]) + cpdist[j];
|
||||
//printf("%04x ", dist);
|
||||
|
||||
//printf("LZ77 len %d dist %d @%04x\n", l, dist, bIdx);
|
||||
while(l--)
|
||||
{
|
||||
//printf("%02x ", c);
|
||||
if (! zs->avail_out --)
|
||||
return -1;
|
||||
|
||||
*(zs->next_out ++) = *(zs->next_out - dist);
|
||||
}
|
||||
//printf("\n");
|
||||
}
|
||||
else
|
||||
{
|
||||
//printf("%02x\n", j);
|
||||
if (! zs->avail_out --)
|
||||
return -1;
|
||||
*(zs->next_out ++) = (unsigned char) j;
|
||||
}
|
||||
}
|
||||
return 0;
|
||||
}
|
||||
|
||||
|
||||
// Returns 0 if success
|
||||
int InflateData(z_stream *zs) {
|
||||
int last, type;
|
||||
|
||||
zs->reserved = 1;;
|
||||
|
||||
do
|
||||
{
|
||||
last = READBIT(zs);
|
||||
#ifdef VERBOSE
|
||||
if (last)
|
||||
fprintf(stderr, "Last Block: ");
|
||||
else
|
||||
fprintf(stderr, "Not Last Block: ");
|
||||
#endif
|
||||
|
||||
type = READBITS(zs, 2);
|
||||
|
||||
if (type == 0)
|
||||
{
|
||||
#ifdef VERBOSE
|
||||
fprintf(stderr, "Decompress_Stored..");
|
||||
#endif
|
||||
if (Decompress_Stored(zs))
|
||||
return 1;
|
||||
}
|
||||
else if (type > 2)
|
||||
{
|
||||
#ifdef VERBOSE
|
||||
if (type == 3)
|
||||
fprintf(stderr, "Reserved block type!!\n");
|
||||
else // the "else" should never happen
|
||||
fprintf(stderr, "Unexpected value %d!\n", type);
|
||||
#endif
|
||||
zs->reserved = 1;;
|
||||
return 1;
|
||||
}
|
||||
else
|
||||
{
|
||||
#ifdef VERBOSE
|
||||
fprintf(stderr, "Decompress_DynamicOrFixed..");
|
||||
#endif
|
||||
if (Decompress_DynamicOrFixed(zs, type & 0x01))
|
||||
return 1;
|
||||
}
|
||||
} while(!last);
|
||||
|
||||
zs->reserved = 1;;
|
||||
return 0;
|
||||
}
|
||||
@@ -1,15 +0,0 @@
|
||||
#ifdef USE_ZLIB_STRUCT
|
||||
#include "SysZLib.h" // For PalmOS. Change to your liking.
|
||||
#else
|
||||
typedef struct z_stream_s
|
||||
{
|
||||
unsigned char *next_in; // Next input byte (CHANGES)
|
||||
unsigned int avail_in; // number of bytes left at next_in
|
||||
unsigned char *next_out; // Next output byte goes here (CHANGES)
|
||||
unsigned int avail_out; // number of bytes left at next_out
|
||||
unsigned int reserved; // For the readbit() and readbits() functions
|
||||
// Bigger than 1 byte
|
||||
} z_stream;
|
||||
#endif
|
||||
|
||||
int InflateData(z_stream *zs);
|
||||
@@ -1,92 +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_irq_t g_irq_handler[MAX_NUM_IRQ] = {NULL};
|
||||
|
||||
int _irq_dispatch(struct xcptcontext * xcp)
|
||||
{
|
||||
int i, ip, cause;
|
||||
|
||||
cause = xcp->cr & xcp->sr;
|
||||
ip = (cause >> 8) & 0xFF;
|
||||
|
||||
for (i=0; i < MAX_NUM_IRQ; i++)
|
||||
{
|
||||
if (ip & 1)
|
||||
if (g_irq_handler[i])
|
||||
(g_irq_handler[i])(xcp);
|
||||
|
||||
ip >>= 1;
|
||||
}
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
void interrupt_register(int irq_num, fp_irq_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_irq_t)(struct xcptcontext * xcp);
|
||||
|
||||
int _irq_dispatch(struct xcptcontext * xcp);
|
||||
void interrupt_register(int irq_num, fp_irq_t fp);
|
||||
void interrupt_enable(int irq_num);
|
||||
void interrupt_disable(int irq_num);
|
||||
|
||||
#endif // IRQ_H
|
||||
@@ -1,184 +0,0 @@
|
||||
#include <regdef.h>
|
||||
#include <xcpt_asm.h>
|
||||
|
||||
.section .exc_vect
|
||||
_xcpt_vector_tbl:
|
||||
.fill 16, 4, 0
|
||||
|
||||
.text
|
||||
|
||||
LEAF(_xcpt_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 _xcpt_call
|
||||
move ra, zero # fake return address
|
||||
|
||||
/* This strange call to _xcpt_call 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(_xcpt_handler)
|
||||
|
||||
|
||||
LEAF(_xcpt_call)
|
||||
/* 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(_xcpt_call)
|
||||
@@ -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,577 +0,0 @@
|
||||
#include <sys/times.h>
|
||||
#include <sys/time.h>
|
||||
#include <sys/resource.h>
|
||||
#include <sys/stat.h>
|
||||
#include <errno.h>
|
||||
#include <stdio.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;
|
||||
}
|
||||
|
||||
void CP0_TR_write_ptr(UINT32* pPtr)
|
||||
{
|
||||
__asm__
|
||||
(
|
||||
"swc0 $31, 0(%[pPtr])\n"
|
||||
:
|
||||
: [pPtr] "r" (pPtr)
|
||||
);
|
||||
}
|
||||
|
||||
void CP0_TR_read_ptr(UINT32* pPtr)
|
||||
{
|
||||
__asm__
|
||||
(
|
||||
"lwc0 $31, 0(%[pPtr])\n"
|
||||
:
|
||||
: [pPtr] "r" (pPtr)
|
||||
);
|
||||
}
|
||||
|
||||
void ICACHE_invalidate_all(void)
|
||||
{
|
||||
__asm__
|
||||
(
|
||||
"cop0 32\n"
|
||||
);
|
||||
}
|
||||
|
||||
void ICACHE_invalidate_at(UINT32* pPtr)
|
||||
{
|
||||
__asm__
|
||||
(
|
||||
"mtc0 %[pPtr], $31\n"
|
||||
"cop0 33\n"
|
||||
:
|
||||
: [pPtr] "r" (pPtr)
|
||||
);
|
||||
}
|
||||
|
||||
void DCACHE_invalidate_all(void)
|
||||
{
|
||||
__asm__
|
||||
(
|
||||
"cop0 34\n"
|
||||
);
|
||||
}
|
||||
|
||||
void DCACHE_invalidate_at(UINT32* pPtr)
|
||||
{
|
||||
__asm__
|
||||
(
|
||||
"mtc0 %[pPtr], $31\n"
|
||||
"cop0 35\n"
|
||||
:
|
||||
: [pPtr] "r" (pPtr)
|
||||
);
|
||||
}
|
||||
|
||||
// ---------------------------------------------------------------------------------
|
||||
int UART0_readchar(void)
|
||||
{
|
||||
volatile UINT32 *pUART_stat = (UINT32*)sys_uart0_stat;
|
||||
volatile UINT32 *pUART_data = (UINT32*)sys_uart0_data;
|
||||
|
||||
if (0x10 & *pUART_stat)
|
||||
return (*pUART_data & 0xFF);
|
||||
|
||||
return -1;
|
||||
}
|
||||
|
||||
void UART0_writechar(char c)
|
||||
{
|
||||
volatile UINT32 *pUART_stat = (UINT32*)sys_uart0_stat;
|
||||
volatile UINT32 *pUART_data = (UINT32*)sys_uart0_data;
|
||||
|
||||
while((0x01 & *pUART_stat) != 0);
|
||||
|
||||
*pUART_data = (UINT32)c;
|
||||
}
|
||||
|
||||
int UART1_readchar(void)
|
||||
{
|
||||
volatile UINT32 *pUART_stat = (UINT32*)sys_uart1_stat;
|
||||
volatile UINT32 *pUART_data = (UINT32*)sys_uart1_data;
|
||||
|
||||
if (0x10 & *pUART_stat)
|
||||
return (*pUART_data & 0xFF);
|
||||
|
||||
return -1;
|
||||
}
|
||||
|
||||
void UART1_writechar(char c)
|
||||
{
|
||||
volatile UINT32 *pUART_stat = (UINT32*)sys_uart1_stat;
|
||||
volatile UINT32 *pUART_data = (UINT32*)sys_uart1_data;
|
||||
|
||||
while((0x01 & *pUART_stat) != 0);
|
||||
|
||||
*pUART_data = (UINT32)c;
|
||||
}
|
||||
|
||||
int UART2_readchar(void)
|
||||
{
|
||||
volatile UINT32 *pUART_stat = (UINT32*)sys_uart2_stat;
|
||||
volatile UINT32 *pUART_data = (UINT32*)sys_uart2_data;
|
||||
|
||||
if (0x10 & *pUART_stat)
|
||||
return (*pUART_data & 0xFF);
|
||||
|
||||
return -1;
|
||||
}
|
||||
|
||||
void UART2_writechar(char c)
|
||||
{
|
||||
volatile UINT32 *pUART_stat = (UINT32*)sys_uart2_stat;
|
||||
volatile UINT32 *pUART_data = (UINT32*)sys_uart2_data;
|
||||
|
||||
while((0x01 & *pUART_stat) != 0);
|
||||
|
||||
*pUART_data = (UINT32)c;
|
||||
}
|
||||
|
||||
char readchar(void)
|
||||
{
|
||||
int c;
|
||||
|
||||
do
|
||||
{
|
||||
c = UART0_readchar();
|
||||
|
||||
} while(c < 0);
|
||||
|
||||
return (char)c;
|
||||
}
|
||||
|
||||
void writechar(char c)
|
||||
{
|
||||
UART0_writechar(c);
|
||||
}
|
||||
|
||||
void _ser_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)
|
||||
{
|
||||
fflush(stdout);
|
||||
fflush(stderr);
|
||||
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;
|
||||
extern char stack_ptr;
|
||||
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\n");
|
||||
// sputs("Stack Ptr = ");print_word(&stack_ptr);sputs("\n");
|
||||
// sputs("Heap end = ");print_word(heap_end);sputs("\n");
|
||||
// sputs("Increment = ");print_word(incr);sputs("\n");
|
||||
exit(1);
|
||||
}
|
||||
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;
|
||||
char c;
|
||||
|
||||
// sputs("read\n");
|
||||
i = 0;
|
||||
while (i < len)
|
||||
{
|
||||
c = readchar();
|
||||
if ((c == 0x0D) || (c == 0x0A))
|
||||
{
|
||||
writechar(0x0D);
|
||||
writechar(0x0A);
|
||||
if (i==0)
|
||||
continue;
|
||||
|
||||
ptr[i++] = c;
|
||||
break;
|
||||
}
|
||||
else
|
||||
{
|
||||
ptr[i++] = c;
|
||||
writechar(c);
|
||||
}
|
||||
}
|
||||
return i;
|
||||
}
|
||||
|
||||
int write(int file, char *ptr, int len)
|
||||
{
|
||||
int i = 0;
|
||||
|
||||
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)
|
||||
{
|
||||
memdump(pBuf, 1, nbpr, len);
|
||||
}
|
||||
|
||||
void memdump(UINT8 *pBuf, int print_offset_only, int num_bytes_per_row, int len)
|
||||
{
|
||||
int i, j, cnt_hex, cnt_asc, base;
|
||||
unsigned char c;
|
||||
|
||||
i = j = 0;
|
||||
cnt_hex = len;
|
||||
cnt_asc = len;
|
||||
base = 0;
|
||||
if (!print_offset_only)
|
||||
base = (int)pBuf;
|
||||
|
||||
do
|
||||
{
|
||||
print_word(base + i);
|
||||
sputs(": ");
|
||||
for (j=0; j < num_bytes_per_row; j++)
|
||||
{
|
||||
if (cnt_hex)
|
||||
{
|
||||
print_byte(pBuf[i+j]);
|
||||
sputs(" ");
|
||||
cnt_hex--;
|
||||
}
|
||||
else
|
||||
{
|
||||
sputs(" ");
|
||||
break;
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
sputs(" ");
|
||||
for (j=0; j < num_bytes_per_row; j++)
|
||||
{
|
||||
if (cnt_asc)
|
||||
{
|
||||
c = pBuf[i+j];
|
||||
if((c < 0x20) || (c > 0x7F))
|
||||
c = '.';
|
||||
|
||||
_putchar(c);
|
||||
cnt_asc--;
|
||||
}
|
||||
else
|
||||
{
|
||||
sputs(" ");
|
||||
break;
|
||||
}
|
||||
}
|
||||
sputs("\n");
|
||||
i += num_bytes_per_row;
|
||||
|
||||
} while (cnt_hex);
|
||||
}
|
||||
|
||||
@@ -1,134 +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 NO_ERROR LSYS_SUCCESS
|
||||
#define ERROR LSYS_ERR_BASE
|
||||
#define LSYS_SUCCESS 0
|
||||
#define LSYS_ERR_BASE 0x80000000
|
||||
|
||||
#define IS_ERROR(e) ((e & LSYS_ERR_BASE) == LSYS_ERR_BASE)
|
||||
|
||||
#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_itim_ctrl 0xA0000018
|
||||
#define sys_itim_stat 0xA000001C
|
||||
#define sys_itim0_cnt 0xA0000020
|
||||
#define sys_itim1_cnt 0xA0000024
|
||||
#define sys_itim2_cnt 0xA0000028
|
||||
#define sys_itim3_cnt 0xA000002C
|
||||
#define sys_itim0_cmp 0xA0000030
|
||||
#define sys_itim1_cmp 0xA0000034
|
||||
#define sys_itim2_cmp 0xA0000038
|
||||
#define sys_itim3_cmp 0xA000003C
|
||||
|
||||
#define sys_uart_data sys_uart0_data
|
||||
#define sys_uart_stat sys_uart0_stat
|
||||
#define sys_uart_baud sys_uart0_baud
|
||||
#define sys_uart0_data 0xA0010000
|
||||
#define sys_uart0_stat 0xA0010004
|
||||
#define sys_uart0_baud 0xA0010008
|
||||
#define sys_uart1_data 0xA0010100
|
||||
#define sys_uart1_stat 0xA0010104
|
||||
#define sys_uart1_baud 0xA0010108
|
||||
#define sys_uart2_data 0xA0010200
|
||||
#define sys_uart2_stat 0xA0010204
|
||||
#define sys_uart2_baud 0xA0010208
|
||||
#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_cgcol 0xA0030080
|
||||
#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_flash_mem 0x00000000
|
||||
#define sys_ssram_io 0xA8000000
|
||||
|
||||
//#define STDOUT_FUNCTION _cg_putchar // Video character
|
||||
//#define STDERR_FUNCTION _putchar // Serial output
|
||||
|
||||
#ifndef _putchar
|
||||
#define _putchar _ser_putchar // Serial output
|
||||
#endif
|
||||
|
||||
#ifndef STDOUT_FUNCTION
|
||||
#define STDOUT_FUNCTION _ser_putchar // Serial output
|
||||
#endif
|
||||
#ifndef STDERR_FUNCTION
|
||||
#define STDERR_FUNCTION _ser_putchar // Serial output
|
||||
#endif
|
||||
|
||||
|
||||
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);
|
||||
void CP0_TR_write_ptr(UINT32* pPtr);
|
||||
void CP0_TR_read_ptr(UINT32* pPtr);
|
||||
void ICACHE_invalidate_all(void);
|
||||
void ICACHE_invalidate_at(UINT32* pPtr);
|
||||
void DCACHE_invalidate_all(void);
|
||||
void DCACHE_invalidate_at(UINT32* pPtr);
|
||||
|
||||
#define CALC_BAUD(b) \
|
||||
((UINT32)((float)CPU_FREQ_HZ/(16*b) + 0.5f) - 1);
|
||||
|
||||
#define UART0_setbaud(b) \
|
||||
*((UINT32*)sys_uart0_baud) = CALC_BAUD(b);
|
||||
|
||||
#define UART1_setbaud(b) \
|
||||
*((UINT32*)sys_uart1_baud) = CALC_BAUD(b);
|
||||
|
||||
#define UART2_setbaud(b) \
|
||||
*((UINT32*)sys_uart2_baud) = CALC_BAUD(b);
|
||||
|
||||
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);
|
||||
void memdump(UINT8 *pBuf, int print_offset_only, int num_bytes_per_row, int len);
|
||||
|
||||
#endif // LIBSYS_H
|
||||
|
||||
@@ -1,249 +0,0 @@
|
||||
/* life.c - demonstrator for later Mips+LCD game of life
|
||||
*
|
||||
* 23.03.06 - MACRO-based version
|
||||
* 22.02.06 - new file
|
||||
*/
|
||||
|
||||
//#include "ks0108.h"
|
||||
|
||||
#include <stdio.h>
|
||||
#include <stdlib.h>
|
||||
#include <string.h>
|
||||
#include "libsys.h"
|
||||
|
||||
|
||||
#define NX 200 // 70 // 128 // 48 // 128
|
||||
#define NY 150 // 31 // 64 // 27 // 64
|
||||
|
||||
#define SCREEN_X 800
|
||||
#define SCREEN_Y 600
|
||||
|
||||
#define SCALE_X (4)
|
||||
#define SCALE_Y (4)
|
||||
#define OFFSET_X ((SCREEN_X-(SCALE_X*NX))/2)
|
||||
#define OFFSET_Y ((SCREEN_Y-(SCALE_Y*NY))/2)
|
||||
|
||||
// OCCUPIED must be uneven, EMPTY even.
|
||||
#define OCCUPIED 0x77771111
|
||||
#define EMPTY 0xeeee0000
|
||||
|
||||
#define MATRIX( row, col ) (*(matrix + (NX*col) + row ))
|
||||
#define FUTURE( row, col ) (*(future + (NX*col) + row ))
|
||||
|
||||
UINT32 *g_gx_buff;
|
||||
|
||||
int clock_lfsr32()
|
||||
{
|
||||
return rand();
|
||||
}
|
||||
|
||||
|
||||
/* return a pseudo-random integer in the range 0..1023 */
|
||||
int random1023() {
|
||||
int tmp;
|
||||
|
||||
tmp = clock_lfsr32();
|
||||
return tmp & 0x000003ff;
|
||||
}
|
||||
|
||||
typedef struct _scolor_t
|
||||
{
|
||||
UINT8 r, g, b, a;
|
||||
} __attribute__ ((__packed__)) color_t;
|
||||
|
||||
|
||||
void DrawPixel(UINT32 x, UINT32 y, color_t *pColor)
|
||||
{
|
||||
int i, j;
|
||||
for (i=0; i < SCALE_Y; i++)
|
||||
for (j=0; j < SCALE_X; j++)
|
||||
g_gx_buff[(OFFSET_X+SCALE_X*x+j) + SCREEN_X*(OFFSET_Y+SCALE_Y*y+i)] = *((UINT32*)pColor);
|
||||
}
|
||||
|
||||
|
||||
/* MSB/LSB in y-Richtung vertauscht */
|
||||
void displayBoard1( int* matrix )
|
||||
{
|
||||
int x, y;
|
||||
int mask, accu;
|
||||
UINT32 color;
|
||||
|
||||
for( x=0; x < NX; x++ )
|
||||
{
|
||||
mask = 0x80;
|
||||
accu = 0x00;
|
||||
for( y=0; y < NY; y++ )
|
||||
{
|
||||
color = (UINT32)-(MATRIX(x,y) & 0x1);
|
||||
DrawPixel(x, y, (color_t*)&color);
|
||||
// if (MATRIX( x, y ) != OCCUPIED)
|
||||
// {
|
||||
// accu |= mask;
|
||||
// }
|
||||
// mask = mask >> 1;
|
||||
|
||||
// color = 0;
|
||||
// DrawPixel(x, (y>>3), (color_t*)&color);
|
||||
// if (mask == 0)
|
||||
// {
|
||||
// color = accu;
|
||||
// DrawPixel(x, (y>>3), (color_t*)&color);
|
||||
// mask = 0x80;
|
||||
// accu = 0x00;
|
||||
// }
|
||||
}
|
||||
// color = accu;
|
||||
// DrawPixel(x, (y>>3), (color_t*)&color);
|
||||
|
||||
}
|
||||
// *(matrix-15) = 0xdead0000;
|
||||
// *(matrix-16) = *(matrix-16) + 1;
|
||||
}
|
||||
|
||||
void initializeBoard( int* matrix ) {
|
||||
int x, y;
|
||||
for( x=0; x < NX; x++ ) {
|
||||
for( y=0; y < NY; y++ ) {
|
||||
int d = random1023();
|
||||
if (d > 920) MATRIX( x, y ) = OCCUPIED;
|
||||
else MATRIX( x, y ) = EMPTY;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
int countNeighbors( int* matrix, int i, int j ) {
|
||||
int im = i-1;
|
||||
int ip = i+1;
|
||||
|
||||
int jm = j-1;
|
||||
int jp = j+1;
|
||||
|
||||
int n = 0;
|
||||
// wrap-around
|
||||
if (ip >= NX) ip = 0;
|
||||
if (jp >= NY) jp = 0;
|
||||
|
||||
if (im < 0) im = NX-1;
|
||||
if (jm < 0) jm = NY-1;
|
||||
|
||||
// check eight neighbors
|
||||
n += MATRIX(im, jm ) & 0x1; // nw
|
||||
n += MATRIX(im, j ) & 0x1; // west
|
||||
n += MATRIX(im, jp ) & 0x1; // sw
|
||||
|
||||
n += MATRIX(i, jm ) & 0x1; // north
|
||||
// n += MATRIX(i, j ) & 0x1; // center
|
||||
n += MATRIX(i, jp ) & 0x1; // south
|
||||
|
||||
n += MATRIX(ip, jm ) & 0x1; // ne
|
||||
n += MATRIX(ip, j ) & 0x1; // east
|
||||
n += MATRIX(ip, jp ) & 0x1; // se
|
||||
|
||||
return n;
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* the actual game of life algorithm: cell is born when three neighbors,
|
||||
* survives when exactly two live neighbors, dies otherwise.
|
||||
*/
|
||||
void nextGeneration( int* matrix, int* future ) {
|
||||
int i, j;
|
||||
int lifes = 0;
|
||||
|
||||
for( i=0; i < NX; i++ ) {
|
||||
for( j=0; j < NY; j++ ) {
|
||||
// count neighbors
|
||||
int n = countNeighbors( matrix, i, j );
|
||||
|
||||
//if ((n != 0) && (random1023() > 990)) { // some slight random offset
|
||||
// if (random1023() > 500) FUTURE(i,j) = OCCUPIED;
|
||||
// else FUTURE(i,j) = EMPTY;
|
||||
//}
|
||||
// else if (n == 3) FUTURE(i,j) = OCCUPIED;
|
||||
|
||||
if (n == 3) FUTURE(i,j) = OCCUPIED;
|
||||
else if ((n == 2) && (MATRIX(i,j) == OCCUPIED)) FUTURE(i,j) = OCCUPIED;
|
||||
else FUTURE(i,j) = EMPTY;
|
||||
|
||||
if (FUTURE(i,j) == OCCUPIED) lifes++;
|
||||
}
|
||||
}
|
||||
// generation ++;
|
||||
|
||||
// avoid extinction :-)
|
||||
if (lifes < 10) {
|
||||
// printf( "CREATING A NEW POPULATION\n\n\n" );
|
||||
initializeBoard( matrix );
|
||||
}
|
||||
else { // swap buffers: C PROHIBITS ASSIGNING TO ARRAY TYPES
|
||||
for( i=0; i < NX; i++ ) {
|
||||
for( j=0; j < NY; j++ ) {
|
||||
MATRIX(i,j) = FUTURE(i,j);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
void gx_init(void)
|
||||
{
|
||||
volatile UINT32 *pVGA_mctrl = (UINT32*)sys_vga_mctrl;
|
||||
volatile UINT32 *pVGA_moffs = (UINT32*)sys_vga_moffs;
|
||||
|
||||
sleep(500);
|
||||
|
||||
g_gx_buff = (UINT32*)malloc(SCREEN_X*SCREEN_Y*sizeof(UINT32));
|
||||
memset(g_gx_buff, 0, SCREEN_X*SCREEN_Y*sizeof(UINT32));
|
||||
printf("g_gx_buff : %8.8X\n", (UINT32)g_gx_buff);
|
||||
|
||||
*pVGA_mctrl = 1;
|
||||
*pVGA_moffs = (UINT32)g_gx_buff;
|
||||
|
||||
}
|
||||
|
||||
int main( int argc, char* argv[] ) {
|
||||
|
||||
int* ptr, cnt = 0;
|
||||
|
||||
int* matrix;
|
||||
int* future;
|
||||
volatile UINT32 *pBtn = (UINT32*)sys_gpio0;
|
||||
|
||||
// lcdEnableDisplay( 1 );
|
||||
// lcdSetColor( 1 );
|
||||
// lcdSetPixel( 0, 0 );
|
||||
// lcdSetPixel( 3, 5 );
|
||||
|
||||
// if we have stdlib:
|
||||
matrix = (void*) malloc( NX*NY*sizeof(int) );
|
||||
future = (void*) malloc( NX*NY*sizeof(int) );
|
||||
|
||||
|
||||
gx_init();
|
||||
|
||||
// matrix = (void *) 0x00004000;
|
||||
// future = (void *) 0x00014000;
|
||||
|
||||
// init_lfsr32( 0xcafebabe );
|
||||
// init_lfsr32( 0x13 );
|
||||
|
||||
srand(clock());
|
||||
initializeBoard( matrix );
|
||||
|
||||
while( 1 )
|
||||
{
|
||||
|
||||
if (*pBtn)
|
||||
{
|
||||
srand(clock());
|
||||
initializeBoard( matrix );
|
||||
cnt = 0;
|
||||
}
|
||||
sputs("Generation #"); print_word(cnt++); sputs("\n");
|
||||
displayBoard1( matrix );
|
||||
nextGeneration( matrix, future );
|
||||
}
|
||||
|
||||
// return 0
|
||||
}
|
||||
@@ -1,224 +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(".");
|
||||
SEARCH_DIR("/usr/local/mipsel-elf/lib:/usr/local/mipsel-elf/lib/eb");
|
||||
SEARCH_DIR("/usr/local/lib/gcc/mipsel-elf/4.3.3:/usr/local/lib/gcc/mipsel-elf/4.3.3/eb");
|
||||
|
||||
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)
|
||||
|
||||
SECTIONS
|
||||
{
|
||||
/* Read-only sections, merged into text segment: */
|
||||
PROVIDE (__executable_start = 0x40000000); . = 0x40000000;
|
||||
.start __executable_start :
|
||||
{
|
||||
start = ALIGN(2);
|
||||
entry = ALIGN(2);
|
||||
_entry = ALIGN(2);
|
||||
__entry = ALIGN(2);
|
||||
*(.start)
|
||||
}
|
||||
/* Kernel text with low-level exception handler */
|
||||
.exc_vector __executable_start + 0x080 :
|
||||
{
|
||||
_exc_vect_start = .;
|
||||
*(.exc_vect)
|
||||
_exc_vect_end = .;
|
||||
}
|
||||
.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.*)
|
||||
} =0
|
||||
.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) }
|
||||
}
|
||||
@@ -1,625 +0,0 @@
|
||||
/* +----------------------------------------------------------------+ */
|
||||
/* | Copyright (c) 1994 Stanford University. | */
|
||||
/* | All Rights Reserved. | */
|
||||
/* | | */
|
||||
/* | This software is distributed with *ABSOLUTELY NO SUPPORT* | */
|
||||
/* | and *NO WARRANTY*. Use or reproduction of this code for | */
|
||||
/* | commerical gains is strictly prohibited. Otherwise, you | */
|
||||
/* | are given permission to use or modify this code as long | */
|
||||
/* | as you do not remove this notice. | */
|
||||
/* +----------------------------------------------------------------+ */
|
||||
/* --------------------------------------------------- */
|
||||
/* | Copyright (c) 1986 MIPS Computer Systems, Inc. | */
|
||||
/* | All Rights Reserved. | */
|
||||
/* --------------------------------------------------- */
|
||||
|
||||
/*
|
||||
* Copyright 1985 by MIPS Computer Systems, Inc.
|
||||
*/
|
||||
|
||||
/* TORCH disassembler */
|
||||
/* derived from MIPS instruction dissassembler by PGL October 91 */
|
||||
|
||||
#include <stdio.h>
|
||||
#include <string.h>
|
||||
#include "mipsdis.h"
|
||||
|
||||
#define false 0
|
||||
#define true 1
|
||||
typedef int boolean;
|
||||
char *strcat();
|
||||
|
||||
#define ZERO 0
|
||||
|
||||
#define COMPILER_NAMES tdis_reg_names[0]
|
||||
#define HARDWARE_NAMES tdis_reg_names[1]
|
||||
#define ASSEMBLER_NAMES tdis_reg_names[2]
|
||||
#define DIS_REG_NAMES(x) tdis_reg_names[x]
|
||||
|
||||
union extension_byte {
|
||||
unsigned char byte;
|
||||
struct { /* extension byte bits in little-endian order */
|
||||
#if (defined __MIPSEB || defined _MIPSEB || defined MIPSEB)
|
||||
unsigned reserved:1;
|
||||
unsigned dyn_nop:1;
|
||||
unsigned rs_boost:2;
|
||||
unsigned rt_boost:2;
|
||||
unsigned rd_boost:2;
|
||||
#elif (defined __MIPSEL || defined _MIPSEL || defined MIPSEL)
|
||||
unsigned rd_boost:2;
|
||||
unsigned rt_boost:2;
|
||||
unsigned rs_boost:2;
|
||||
unsigned dyn_nop:1;
|
||||
unsigned reserved:1;
|
||||
#endif /*MIPSEB*/
|
||||
} e;
|
||||
};
|
||||
|
||||
#define blez_op_T blez_op
|
||||
#define blez_op_N (blez_op | 0x10)
|
||||
#define bgtz_op_T bgtz_op
|
||||
#define bgtz_op_N (bgtz_op | 0x10)
|
||||
#define beq_op_T beq_op
|
||||
#define beq_op_N (beq_op | 0x10)
|
||||
#define bne_op_T bne_op
|
||||
#define bne_op_N (bne_op | 0x10)
|
||||
#define bc_op_T bc_op
|
||||
#define bc_op_N (bc_op | 0x02)
|
||||
|
||||
static char *op_name[64] = {
|
||||
/* 0 */ "special", "regimm","j", "jal", "beq", "bne", "blez", "bgtz",
|
||||
/* 8 */ "addi", "addiu","slti", "sltiu","andi", "ori", "xori", "lui",
|
||||
/*16 */ "cop0", "cop1", "cop2", "cop3", "beql","bnel","blezl","bgtzl",
|
||||
/*24 */ "op60", "op64", "op68", "op6c", "op70", "op74", "op78", "op7c",
|
||||
/*32 */ "lb", "lh", "lwl", "lw", "lbu", "lhu", "lwr", "ld",
|
||||
/*40 */ "sb", "sh", "swl", "sw", "opb0", "opb4", "swr", "sd",
|
||||
/*48 */ "lwc0", "lwc1", "lwc2", "lwc3", "ldc0", "ldc1", "ldc2", "ldc3",
|
||||
/*56 */ "swc0", "swc1", "swc2", "swc3", "sdc0", "sdc1", "sdc2", "sdc3"
|
||||
};
|
||||
|
||||
static char *spec_name[64] = {
|
||||
/* 0*/ "sll", "spec01","srl", "sra", "sllv", "spec05","srlv","srav",
|
||||
/* 8*/ "jr", "jalr", "spec12","spec13","syscall","break","vcall","spec17",
|
||||
/*16*/ "mfhi", "mthi", "mflo", "mtlo", "spec24","spec25","spec26","spec27",
|
||||
/*24*/ "mult", "multu","div", "divu", "spec34","spec35","spec36","spec37",
|
||||
/*32*/ "add", "addu", "sub", "subu", "and", "or", "xor", "nor",
|
||||
/*40*/ "spec50","spec51","slt","sltu", "spec54","spec55","spec56","spec57",
|
||||
/*48*/ "spec60","spec61","spec62","spec63","spec64","spec65","spec66","spec67",
|
||||
/*56*/ "spec70","spec71","spec72","spec73","spec74","spec75","spec76","spec77"
|
||||
};
|
||||
|
||||
static char *bcond_name[32] = {
|
||||
"bltz",
|
||||
"bgez",
|
||||
"bltzl",
|
||||
"bgezl",
|
||||
"bcond04",
|
||||
"bcond05",
|
||||
"bcond06",
|
||||
"bcond07",
|
||||
"tgei",
|
||||
"tgeiu",
|
||||
"tlti",
|
||||
"tltiu",
|
||||
"teqi",
|
||||
"bcond0d",
|
||||
"tnei",
|
||||
"bcond0f",
|
||||
"bltzal",
|
||||
"bgezal",
|
||||
"bltzall",
|
||||
"bgezall",
|
||||
"bcond14",
|
||||
"bcond15",
|
||||
"bcond16",
|
||||
"bcond17",
|
||||
"bcond18",
|
||||
"bcond19",
|
||||
"bcond1a",
|
||||
"bcond1b",
|
||||
"bcond1c",
|
||||
"bcond1d",
|
||||
"bcond1e",
|
||||
"bcond1f"
|
||||
};
|
||||
|
||||
static char *cop1_name[64] = {
|
||||
/* 0 */ "add", "sub", "mul", "div", "sqrt", "abs", "mov", "neg",
|
||||
/* 8 */ "fop08","fop09","fop0a","fop0b","fop0c","fop0d","fop0e","fop0f",
|
||||
/*16 */ "fop10","fop11","fop12","fop13","fop14","fop15","fop16","fop17",
|
||||
/*24 */ "fop18","fop19","fop1a","fop1b","fop1c","fop1d","fop1e","fop1f",
|
||||
/*32 */ "cvt.s","cvt.d","cvt.e","fop23","cvt.w","fop25","fop26","fop27",
|
||||
/*40 */ "fop28","fop29","fop2a","fop2b","fop2c","fop2d","fop2e","fop2f",
|
||||
/*48 */ "c.f", "c.un","c.eq","c.ueq","c.olt","c.ult","c.ole","c.ule",
|
||||
/*56 */ "c.sf","c.ngle","c.seq","c.ngl","c.lt","c.nge","c.le","c.ngt"
|
||||
};
|
||||
|
||||
static char *fmt_name[16] = {
|
||||
"s", "d", "e", "q",
|
||||
"w", "fmt5", "fmt6", "fmt7",
|
||||
"fmt8", "fmt9", "fmta", "fmtb",
|
||||
"fmtc", "fmtd", "fmte", "fmtf"
|
||||
};
|
||||
|
||||
/* public */
|
||||
/* Three sets of commonly used register names */
|
||||
const char *tdis_reg_names[3][64] = {
|
||||
{ /* compiler names */
|
||||
"zero", "at", "v0", "v1", "a0", "a1", "a2", "a3",
|
||||
"t0", "t1", "t2", "t3", "t4", "t5", "t6", "t7",
|
||||
"s0", "s1", "s2", "s3", "s4", "s5", "s6", "s7",
|
||||
"t8", "t9", "k0", "k1", "gp", "sp", "s8", "ra",
|
||||
"zero.B","at.B","v0.B", "v1.B", "a0.B", "a1.B", "a2.B", "a3.B",
|
||||
"t0.B", "t1.B", "t2.B", "t3.B", "t4.B", "t5.B", "t6.B", "t7.B",
|
||||
"s0.B", "s1.B", "s2.B", "s3.B", "s4.B", "s5.B", "s6.B", "s7.B",
|
||||
"t8.B", "t9.B", "k0.B", "k1.B", "gp.B", "sp.B", "s8.B", "ra.B"
|
||||
},
|
||||
{ /* hardware names */
|
||||
"r0", "r1", "r2", "r3", "r4", "r5", "r6", "r7",
|
||||
"r8", "r9", "r10", "r11", "r12", "r13", "r14", "r15",
|
||||
"r16", "r17", "r18", "r19", "r20", "r21", "r22", "r23",
|
||||
"r24", "r25", "r26", "r27", "gp", "sp", "r30", "r31",
|
||||
"r0.B", "r1.B", "r2.B", "r3.B", "r4.B", "r5.B", "r6.B", "r7.B",
|
||||
"r8.B", "r9.B", "r10.B","r11.B","r12.B","r13.B","r14.B","r15.B",
|
||||
"r16.B","r17.B","r18.B","r19.B","r20.B","r21.B","r22.B","r23.B",
|
||||
"r24.B","r25.B","r26.B","r27.B","gp.B", "sp.B", "r30.B","r31.B"
|
||||
},
|
||||
{ /* assembler names */
|
||||
"$0", "$at", "$2", "$3", "$4", "$5", "$6", "$7",
|
||||
"$8", "$9", "$10", "$11", "$12", "$13", "$14", "$15",
|
||||
"$16", "$17", "$18", "$19", "$20", "$21", "$22", "$23",
|
||||
"$24", "$25", "$26", "$27", "$gp", "$sp", "$30", "$31",
|
||||
"$0.B", "$at.B","$2.B", "$3.B", "$4.B", "$5.B", "$6.B", "$7.B",
|
||||
"$8.B", "$9.B", "$10.B","$11.B","$12.B","$13.B","$14.B","$15.B",
|
||||
"$16.B","$17.B","$18.B","$19.B","$20.B","$21.B","$22.B","$23.B",
|
||||
"$24.B","$25.B","$26.B","$27.B","$gp.B","$sp.B","$30.B","$31.B"
|
||||
}
|
||||
};
|
||||
|
||||
static char *c0_opname[64] = {
|
||||
"c0op0","tlbr","tlbwi","c0op3","c0op4","c0op5","tlbwr","c0op7",
|
||||
"tlbp","c0op9","c0op10","c0op11","c0op12","c0op13","c0op14","c0op15",
|
||||
"rfe","c0op17","c0op18","c0op19","c0op20","c0op21","c0op22","c0op23",
|
||||
"c0op24","c0op25","c0op26","c0op27","c0op28","c0op29","c0op30","c0op31",
|
||||
"c0op32","c0op33","c0op34","c0op35","c0op36","c0op37","c0op38","c0op39",
|
||||
"c0op40","c0op41","c0op42","c0op43","c0op44","c0op45","c0op46","c0op47",
|
||||
"c0op48","c0op49","c0op50","c0op51","c0op52","c0op53","c0op54","c0op55",
|
||||
"c0op56","c0op57","c0op58","c0op59","c0op60","c0op61","c0op62","c0op63"
|
||||
};
|
||||
|
||||
static char *c0_reg[32] = {
|
||||
"index","random","tlblo","c0r3","context","c0r5","c0r6","c0r7",
|
||||
"badvaddr","c0r9","tlbhi","epcn","sr", "cause","epc", "c0r15",
|
||||
"c0r16","c0r17","c0r18","c0r19","c0r20","c0r21","c0r22","c0r23",
|
||||
"c0r24","c0r25","c0r26","c0r27","c0r28","c0r29","c0r30","c0r31"
|
||||
};
|
||||
|
||||
/* Remember the options set by dis_init */
|
||||
//#define ADDR_DEFAULT "%#010x:\t"
|
||||
#define ADDR_DEFAULT 0
|
||||
//#define VALUE_DEFAULT "%#010x\t"
|
||||
#define VALUE_DEFAULT 0
|
||||
#define NAME_DEFAULT COMPILER_NAMES
|
||||
static struct {
|
||||
char *addr_format;
|
||||
char *value_format;
|
||||
const char **reg_names;
|
||||
int print_jal_targets;
|
||||
} save = {
|
||||
ADDR_DEFAULT,
|
||||
VALUE_DEFAULT,
|
||||
NAME_DEFAULT,
|
||||
true
|
||||
};
|
||||
|
||||
/* Update regmask to reflect the use of this general-purpose (not fp)
|
||||
register, and return its name */
|
||||
static const char *
|
||||
register_name(ireg, boosted, regmask)
|
||||
unsigned ireg, *regmask;
|
||||
int boosted;
|
||||
{
|
||||
if (!boosted)
|
||||
*regmask |= (1 << ireg);
|
||||
return save.reg_names[boosted ? ireg + 32 : ireg];
|
||||
}
|
||||
|
||||
/* public -- see dissassembler.h */
|
||||
int
|
||||
tdisasm(buffer, address, iword, ext, regmask, symbol_value, ls_register)
|
||||
char *buffer;
|
||||
unsigned char ext; /* extension byte */
|
||||
unsigned address, iword, *regmask, *symbol_value, *ls_register;
|
||||
{
|
||||
int return_value = 0;
|
||||
char *bufptr = buffer;
|
||||
boolean do_b_displacement = false;
|
||||
boolean do_loadstore = false;
|
||||
union mips_instruction i;
|
||||
union extension_byte e;
|
||||
|
||||
*bufptr = 0;
|
||||
i.word = iword;
|
||||
e.byte = ext;
|
||||
*regmask = *symbol_value = *ls_register = 0;
|
||||
|
||||
/* Put out the address and hex value of the instruction,
|
||||
leaving bufptr set at the end */
|
||||
if (save.addr_format) {
|
||||
sprintf(bufptr, save.addr_format, address);
|
||||
bufptr += strlen(bufptr);
|
||||
}
|
||||
if (save.value_format) {
|
||||
sprintf(bufptr, save.value_format, iword);
|
||||
bufptr += strlen(bufptr);
|
||||
}
|
||||
|
||||
/* check for dynamic NOP */
|
||||
if (e.e.dyn_nop) {
|
||||
strcat(bufptr, "D.");
|
||||
bufptr += 2;
|
||||
}
|
||||
|
||||
/* decode the instruction */
|
||||
switch (i.j_format.opcode) {
|
||||
|
||||
case spec_op:
|
||||
|
||||
if (i.word == 0x20) {
|
||||
strcat(bufptr, "nop");
|
||||
if (e.e.rd_boost)
|
||||
strcat(bufptr, ".B");
|
||||
bufptr += strlen(bufptr);
|
||||
break;
|
||||
} else if (i.r_format.func == addu_op && i.r_format.rt == ZERO) {
|
||||
sprintf(bufptr, "move%s\t%s,%s",
|
||||
e.e.rd_boost ? ".B" : "",
|
||||
register_name(i.r_format.rd, e.e.rd_boost, regmask),
|
||||
register_name(i.r_format.rs, e.e.rs_boost, regmask));
|
||||
bufptr += strlen(bufptr);
|
||||
break;
|
||||
}
|
||||
strcat(bufptr, spec_name[i.r_format.func]);
|
||||
if (e.e.rd_boost)
|
||||
strcat(bufptr, ".B");
|
||||
bufptr += strlen(bufptr);
|
||||
|
||||
switch (i.r_format.func) {
|
||||
case sll_op:
|
||||
case srl_op:
|
||||
case sra_op:
|
||||
sprintf(bufptr, "\t%s,%s,%d",
|
||||
register_name(i.r_format.rd, e.e.rd_boost, regmask),
|
||||
register_name(i.r_format.rt, e.e.rt_boost, regmask),
|
||||
i.r_format.re);
|
||||
break;
|
||||
case sllv_op:
|
||||
case srlv_op:
|
||||
case srav_op:
|
||||
sprintf(bufptr, "\t%s,%s,%s",
|
||||
register_name(i.r_format.rd, e.e.rd_boost, regmask),
|
||||
register_name(i.r_format.rt, e.e.rt_boost, regmask),
|
||||
register_name(i.r_format.rs, e.e.rs_boost, regmask));
|
||||
break;
|
||||
case mfhi_op:
|
||||
case mflo_op:
|
||||
sprintf(bufptr, "\t%s",
|
||||
register_name(i.r_format.rd, e.e.rd_boost, regmask));
|
||||
break;
|
||||
case jalr_op:
|
||||
return_value = 3;
|
||||
sprintf(bufptr, "\t%s,%s",
|
||||
register_name(i.r_format.rd, e.e.rd_boost, regmask),
|
||||
register_name(i.r_format.rs, e.e.rs_boost, regmask));
|
||||
*ls_register = i.r_format.rs;
|
||||
break;
|
||||
case jr_op:
|
||||
return_value = 3;
|
||||
*ls_register = i.r_format.rs;
|
||||
/* fall through */
|
||||
case mtlo_op:
|
||||
case mthi_op:
|
||||
sprintf(bufptr, "\t%s",
|
||||
register_name(i.r_format.rs, e.e.rs_boost, regmask));
|
||||
break;
|
||||
case mult_op:
|
||||
case multu_op:
|
||||
case div_op:
|
||||
case divu_op:
|
||||
sprintf(bufptr, "\t%s,%s",
|
||||
register_name(i.r_format.rs, e.e.rs_boost, regmask),
|
||||
register_name(i.r_format.rt, e.e.rt_boost, regmask));
|
||||
break;
|
||||
case syscall_op:
|
||||
break;
|
||||
case break_op:
|
||||
case vcall_op:
|
||||
{
|
||||
char *format = "\t%d";
|
||||
unsigned op2 = i.r_format.rd * 32 + i.r_format.re;
|
||||
|
||||
if (op2)
|
||||
format = "\t%d,%d";
|
||||
sprintf(bufptr, format, i.r_format.rs*32+i.r_format.rt,
|
||||
op2);
|
||||
}
|
||||
break;
|
||||
default:
|
||||
sprintf(bufptr, "\t%s,%s,%s",
|
||||
register_name(i.r_format.rd, e.e.rd_boost, regmask),
|
||||
register_name(i.r_format.rs, e.e.rs_boost, regmask),
|
||||
register_name(i.r_format.rt, e.e.rt_boost, regmask));
|
||||
break;
|
||||
};
|
||||
break;
|
||||
|
||||
case bcond_op:
|
||||
sprintf(bufptr, "%s%s\t%s,",
|
||||
bcond_name[i.i_format.rt],
|
||||
e.e.rd_boost ? ".B" : "",
|
||||
register_name(i.i_format.rs, e.e.rs_boost, regmask));
|
||||
do_b_displacement = true;
|
||||
break;
|
||||
|
||||
case blez_op_T:
|
||||
case bgtz_op_T:
|
||||
case blez_op_N:
|
||||
case bgtz_op_N:
|
||||
sprintf(bufptr, "%s%s\t%s,", op_name[i.i_format.opcode],
|
||||
e.e.rd_boost ? ".B" : "",
|
||||
register_name(i.i_format.rs, e.e.rs_boost, regmask));
|
||||
do_b_displacement = true;
|
||||
break;
|
||||
case beq_op_T:
|
||||
case beq_op_N:
|
||||
if (i.i_format.rs == ZERO && i.i_format.rt == ZERO) {
|
||||
strcat(bufptr, "b");
|
||||
if (i.j_format.opcode == beq_op_T)
|
||||
strcat(bufptr, ".T");
|
||||
else
|
||||
strcat(bufptr, ".N");
|
||||
if (e.e.rd_boost)
|
||||
strcat(bufptr, ".B\t");
|
||||
else
|
||||
strcat(bufptr, "\t");
|
||||
do_b_displacement = true;
|
||||
break;
|
||||
}
|
||||
/* fall through */
|
||||
case bne_op_T:
|
||||
case bne_op_N:
|
||||
sprintf(bufptr, "%s%s\t%s,%s,", op_name[i.i_format.opcode],
|
||||
e.e.rd_boost ? ".B" : "",
|
||||
register_name(i.i_format.rs, e.e.rs_boost, regmask),
|
||||
register_name(i.i_format.rt, e.e.rt_boost, regmask));
|
||||
do_b_displacement = true;
|
||||
break;
|
||||
|
||||
case cop0_op:
|
||||
case cop1_op:
|
||||
case cop2_op:
|
||||
case cop3_op:
|
||||
{
|
||||
unsigned which_cop = i.j_format.opcode - cop0_op;
|
||||
char *f_or_r = "rf";
|
||||
|
||||
switch (i.r_format.rs) {
|
||||
case bc_op_T:
|
||||
sprintf(bufptr, "bc%d%c.T%s\t", which_cop,
|
||||
"ft"[i.r_format.rt],
|
||||
e.e.rd_boost ? ".B" : "");
|
||||
do_b_displacement = true;
|
||||
break;
|
||||
case bc_op_N:
|
||||
sprintf(bufptr, "bc%d%c.N%s\t", which_cop,
|
||||
"ft"[i.r_format.rt],
|
||||
e.e.rd_boost ? ".B" : "");
|
||||
do_b_displacement = true;
|
||||
break;
|
||||
case mtc_op:
|
||||
if (which_cop == 0)
|
||||
sprintf(bufptr, "mtc%d%s\t%s,%s", which_cop,
|
||||
e.e.rd_boost ? ".B" : "",
|
||||
register_name(i.r_format.rt, e.e.rt_boost,regmask),
|
||||
c0_reg[i.f_format.rd]);
|
||||
else
|
||||
sprintf(bufptr, "mtc%d%s\t%s,%c%d", which_cop,
|
||||
e.e.rd_boost ? ".B" : "",
|
||||
register_name(i.r_format.rt, e.e.rt_boost,regmask),
|
||||
f_or_r[(which_cop == 1)],
|
||||
i.f_format.rd);
|
||||
break;
|
||||
case mfc_op:
|
||||
if (which_cop == 0)
|
||||
sprintf(bufptr, "mfc%d%s\t%s,%s", which_cop,
|
||||
e.e.rd_boost ? ".B" : "",
|
||||
register_name(i.r_format.rt, e.e.rt_boost,regmask),
|
||||
c0_reg[i.f_format.rd]);
|
||||
else
|
||||
sprintf(bufptr, "mfc%d%s\t%s,%c%d", which_cop,
|
||||
e.e.rd_boost ? ".B" : "",
|
||||
register_name(i.r_format.rt, e.e.rt_boost,regmask),
|
||||
f_or_r[(which_cop == 1)],
|
||||
i.f_format.rd);
|
||||
break;
|
||||
case cfc_op:
|
||||
sprintf(bufptr, "cfc%d%s\t%s,%c%d", which_cop,
|
||||
e.e.rd_boost ? ".B" : "",
|
||||
register_name(i.r_format.rt, e.e.rt_boost, regmask),
|
||||
f_or_r[(which_cop == 1)],
|
||||
i.f_format.rd);
|
||||
break;
|
||||
case ctc_op:
|
||||
sprintf(bufptr, "ctc%d%s\t%s,%c%d", which_cop,
|
||||
e.e.rd_boost ? ".B" : "",
|
||||
register_name(i.r_format.rt, e.e.rt_boost, regmask),
|
||||
f_or_r[(which_cop == 1)],
|
||||
i.f_format.rd);
|
||||
break;
|
||||
default:
|
||||
if (which_cop != 1)
|
||||
sprintf(bufptr, "c0%s\t%s", e.e.rd_boost ? ".B" : "",
|
||||
c0_opname[i.f_format.func]);
|
||||
else
|
||||
{
|
||||
sprintf(bufptr, "%s.%s%s\t",
|
||||
cop1_name[i.f_format.func],
|
||||
fmt_name[i.f_format.fmt],
|
||||
e.e.rd_boost ? ".B" : "");
|
||||
bufptr += strlen(bufptr);
|
||||
switch (i.f_format.func) {
|
||||
case fsqrt_op:
|
||||
case fabs_op:
|
||||
case fmov_op:
|
||||
case fcvts_op:
|
||||
case fcvtd_op:
|
||||
case fcvte_op:
|
||||
case fcvtw_op:
|
||||
sprintf(bufptr, "f%d,f%d",
|
||||
i.f_format.re,
|
||||
i.f_format.rd);
|
||||
break;
|
||||
case fcmp_op+0x0:
|
||||
case fcmp_op+0x1:
|
||||
case fcmp_op+0x2:
|
||||
case fcmp_op+0x3:
|
||||
case fcmp_op+0x4:
|
||||
case fcmp_op+0x5:
|
||||
case fcmp_op+0x6:
|
||||
case fcmp_op+0x7:
|
||||
case fcmp_op+0x8:
|
||||
case fcmp_op+0x9:
|
||||
case fcmp_op+0xa:
|
||||
case fcmp_op+0xb:
|
||||
case fcmp_op+0xc:
|
||||
case fcmp_op+0xd:
|
||||
case fcmp_op+0xe:
|
||||
case fcmp_op+0xf:
|
||||
sprintf(bufptr, "f%d,f%d",
|
||||
i.f_format.rd,
|
||||
i.f_format.rt);
|
||||
break;
|
||||
default:
|
||||
sprintf(bufptr, "f%d,f%d,f%d",
|
||||
i.f_format.re,
|
||||
i.f_format.rd,
|
||||
i.f_format.rt);
|
||||
break;
|
||||
} /* switch on func */
|
||||
}
|
||||
break; /* End of default */
|
||||
} /* switch on rs */
|
||||
}
|
||||
break; /* End of cop0, cop1, cop2, cop3 */
|
||||
|
||||
case jal_op:
|
||||
case j_op:
|
||||
sprintf(bufptr, "%s%s\t", op_name[i.j_format.opcode],
|
||||
e.e.rd_boost ? ".B" : "");
|
||||
*symbol_value = (address & 0xF0000000) | i.j_format.target << 2;
|
||||
if (save.print_jal_targets)
|
||||
{
|
||||
bufptr += strlen(bufptr);
|
||||
sprintf(bufptr, "%#x", *symbol_value);
|
||||
}
|
||||
return_value = 1;
|
||||
break;
|
||||
|
||||
case swc1_op:
|
||||
case sdc1_op:
|
||||
case lwc1_op:
|
||||
case ldc1_op:
|
||||
sprintf(bufptr, "%s%s\tf%d,", op_name[i.i_format.opcode],
|
||||
e.e.rd_boost ? ".B" : "",
|
||||
i.i_format.rt);
|
||||
do_loadstore = true;
|
||||
break;
|
||||
|
||||
case lb_op:
|
||||
case lh_op:
|
||||
case lw_op:
|
||||
case ld_op:
|
||||
case lbu_op:
|
||||
case lhu_op:
|
||||
case sb_op:
|
||||
case sh_op:
|
||||
case sw_op:
|
||||
case sd_op:
|
||||
case lwl_op:
|
||||
case lwr_op:
|
||||
sprintf(bufptr, "%s%s\t%s,", op_name[i.i_format.opcode],
|
||||
e.e.rd_boost ? ".B" : "",
|
||||
register_name(i.i_format.rt, e.e.rt_boost, regmask));
|
||||
do_loadstore = true;
|
||||
break;
|
||||
|
||||
case ori_op:
|
||||
case xori_op:
|
||||
if (i.u_format.rs == ZERO) {
|
||||
sprintf(bufptr, "li%s\t%s,%d",
|
||||
e.e.rd_boost ? ".B" : "",
|
||||
register_name(i.u_format.rt, e.e.rt_boost, regmask),
|
||||
i.u_format.uimmediate);
|
||||
break;
|
||||
}
|
||||
/* fall through */
|
||||
case andi_op:
|
||||
sprintf(bufptr, "%s%s\t%s,%s,%#x", op_name[i.u_format.opcode],
|
||||
e.e.rd_boost ? ".B" : "",
|
||||
register_name(i.u_format.rt, e.e.rt_boost, regmask),
|
||||
register_name(i.u_format.rs, e.e.rs_boost, regmask),
|
||||
i.u_format.uimmediate);
|
||||
break;
|
||||
case lui_op:
|
||||
sprintf(bufptr, "%s%s\t%s,%#x", op_name[i.u_format.opcode],
|
||||
e.e.rd_boost ? ".B" : "",
|
||||
register_name(i.u_format.rt, e.e.rt_boost, regmask),
|
||||
i.u_format.uimmediate);
|
||||
break;
|
||||
case addi_op:
|
||||
case addiu_op:
|
||||
if (i.i_format.rs == ZERO) {
|
||||
short sign_extender = i.i_format.simmediate;
|
||||
sprintf(bufptr, "li%s\t%s,%d",
|
||||
e.e.rd_boost ? ".B" : "",
|
||||
register_name(i.i_format.rt, e.e.rt_boost, regmask),
|
||||
sign_extender);
|
||||
break;
|
||||
}
|
||||
/* fall through */
|
||||
default:
|
||||
{
|
||||
short sign_extender = i.i_format.simmediate;
|
||||
sprintf(bufptr, "%s%s\t%s,%s,%d", op_name[i.i_format.opcode],
|
||||
e.e.rd_boost ? ".B" : "",
|
||||
register_name(i.i_format.rt, e.e.rt_boost, regmask),
|
||||
register_name(i.i_format.rs, e.e.rs_boost, regmask),
|
||||
sign_extender);
|
||||
}
|
||||
break;
|
||||
}
|
||||
|
||||
/* Some instructions require more than just registers */
|
||||
|
||||
if (do_loadstore)
|
||||
{
|
||||
short sign_extender = i.i_format.simmediate;
|
||||
*symbol_value = sign_extender;
|
||||
*ls_register = i.i_format.rs;
|
||||
bufptr += strlen(bufptr);
|
||||
sprintf(bufptr, "%d(%s)", sign_extender,
|
||||
register_name(i.i_format.rs, e.e.rs_boost, regmask));
|
||||
return_value = -1;
|
||||
}
|
||||
else if (do_b_displacement)
|
||||
{
|
||||
short sign_extender = i.i_format.simmediate;
|
||||
bufptr += strlen(bufptr);
|
||||
*symbol_value = 4 + address + ((((long)sign_extender & 0xFFFD0000) | (0x3FFFF & (sign_extender << 2))));
|
||||
sprintf(bufptr, "%#x", *symbol_value);
|
||||
return_value = 2;
|
||||
}
|
||||
|
||||
return return_value;
|
||||
}
|
||||
|
||||
@@ -1,450 +0,0 @@
|
||||
/* ------------------------------------------------------------------ */
|
||||
/* | Copyright Unpublished, MIPS Computer Systems, Inc. All Rights | */
|
||||
/* | Reserved. This software contains proprietary and confidential | */
|
||||
/* | information of MIPS and its suppliers. Use, disclosure or | */
|
||||
/* | reproduction is prohibited without the prior express written | */
|
||||
/* | consent of MIPS. | */
|
||||
/* ------------------------------------------------------------------ */
|
||||
/* inst.h 4.2 */
|
||||
/*
|
||||
* inst.h -- instruction format defines
|
||||
*/
|
||||
|
||||
/**
|
||||
** UPDATE - 19 Sept 89 by Michael Smith
|
||||
**
|
||||
** Removed signed type to remove obnoxious C++ warning message.
|
||||
**/
|
||||
|
||||
#ifdef LANGUAGE_C
|
||||
#ifdef MIPSEB
|
||||
union mips_instruction {
|
||||
unsigned word;
|
||||
unsigned char byte[4];
|
||||
struct {
|
||||
unsigned opcode : 6;
|
||||
unsigned target : 26;
|
||||
} j_format;
|
||||
struct {
|
||||
unsigned opcode : 6;
|
||||
unsigned rs : 5;
|
||||
unsigned rt : 5;
|
||||
unsigned simmediate : 16;
|
||||
} i_format;
|
||||
struct {
|
||||
unsigned opcode : 6;
|
||||
unsigned rs : 5;
|
||||
unsigned rt : 5;
|
||||
unsigned uimmediate : 16;
|
||||
} u_format;
|
||||
struct {
|
||||
unsigned opcode : 6;
|
||||
unsigned rs : 5;
|
||||
unsigned rt : 5;
|
||||
unsigned rd : 5;
|
||||
unsigned re : 5;
|
||||
unsigned func : 6;
|
||||
} r_format;
|
||||
struct {
|
||||
unsigned opcode : 6;
|
||||
unsigned : 1;
|
||||
unsigned fmt : 4;
|
||||
unsigned rt : 5;
|
||||
unsigned rd : 5;
|
||||
unsigned re : 5;
|
||||
unsigned func : 6;
|
||||
} f_format;
|
||||
};
|
||||
#endif
|
||||
|
||||
#ifdef MIPSEL
|
||||
union mips_instruction {
|
||||
unsigned word;
|
||||
unsigned char byte[4];
|
||||
struct {
|
||||
unsigned target : 26;
|
||||
unsigned opcode : 6;
|
||||
} j_format;
|
||||
struct {
|
||||
unsigned simmediate : 16;
|
||||
unsigned rt : 5;
|
||||
unsigned rs : 5;
|
||||
unsigned opcode : 6;
|
||||
} i_format;
|
||||
struct {
|
||||
unsigned uimmediate : 16;
|
||||
unsigned rt : 5;
|
||||
unsigned rs : 5;
|
||||
unsigned opcode : 6;
|
||||
} u_format;
|
||||
struct {
|
||||
unsigned func : 6;
|
||||
unsigned re : 5;
|
||||
unsigned rd : 5;
|
||||
unsigned rt : 5;
|
||||
unsigned rs : 5;
|
||||
unsigned opcode : 6;
|
||||
} r_format;
|
||||
struct {
|
||||
unsigned func : 6;
|
||||
unsigned re : 5;
|
||||
unsigned rd : 5;
|
||||
unsigned rt : 5;
|
||||
unsigned fmt : 4;
|
||||
unsigned : 1;
|
||||
unsigned opcode : 6;
|
||||
} f_format;
|
||||
};
|
||||
#endif
|
||||
|
||||
#define spec_op 0x00
|
||||
#define bcond_op 0x01
|
||||
#define j_op 0x02
|
||||
#define jal_op 0x03
|
||||
|
||||
#define beq_op 0x04
|
||||
#define bne_op 0x05
|
||||
#define blez_op 0x06
|
||||
#define bgtz_op 0x07
|
||||
|
||||
#define addi_op 0x08
|
||||
#define addiu_op 0x09
|
||||
#define slti_op 0x0A
|
||||
#define sltiu_op 0x0B
|
||||
|
||||
#define andi_op 0x0C
|
||||
#define ori_op 0x0D
|
||||
#define xori_op 0x0E
|
||||
#define lui_op 0x0F
|
||||
|
||||
#define lb_op 0x20
|
||||
#define lh_op 0x21
|
||||
#define lw_op 0x23
|
||||
#define lbu_op 0x24
|
||||
#define lhu_op 0x25
|
||||
#define ld_op 0x27
|
||||
#define sb_op 0x28
|
||||
#define sh_op 0x29
|
||||
#define sw_op 0x2B
|
||||
#define sd_op 0x2F
|
||||
#define lwl_op 0x22
|
||||
#define lwr_op 0x26
|
||||
#define swl_op 0x2a
|
||||
#define swr_op 0x2e
|
||||
|
||||
/* Co-processor sub-opcodes */
|
||||
#define bc_op 0x08
|
||||
#define mfc_op 0x00
|
||||
#define cfc_op 0x02
|
||||
#define mtc_op 0x04
|
||||
#define ctc_op 0x06
|
||||
|
||||
/* Co-processor 0 opcodes */
|
||||
#define cop0_op 0x10
|
||||
#define lwc0_op 0x30
|
||||
#define ldc0_op 0x34
|
||||
#define swc0_op 0x38
|
||||
#define sdc0_op 0x3c
|
||||
|
||||
/* Co-processor 0 sub-opcodes */
|
||||
#define tlbr_op 0x1
|
||||
#define tlbwi_op 0x2
|
||||
#define tlbwr_op 0x6
|
||||
#define tlbp_op 0x8
|
||||
#define rfe_op 0x10
|
||||
|
||||
/* Co-processor 1 opcodes */
|
||||
#define cop1_op 0x11
|
||||
#define lwc1_op 0x31
|
||||
#define ldc1_op 0x35
|
||||
#define swc1_op 0x39
|
||||
#define sdc1_op 0x3D
|
||||
|
||||
/* Co-processor 1 sub-opcodes */
|
||||
#define fadd_op 0x00
|
||||
#define fsub_op 0x01
|
||||
#define fmpy_op 0x02
|
||||
#define fdiv_op 0x03
|
||||
#define fsqrt_op 0x04
|
||||
#define fabs_op 0x05
|
||||
#define fmov_op 0x06
|
||||
#define fneg_op 0x07
|
||||
#define fcvts_op 0x20
|
||||
#define fcvtd_op 0x21
|
||||
#define fcvte_op 0x22
|
||||
#define fcvtw_op 0x24
|
||||
#define fcmp_op 0x30
|
||||
#define s_fmt 0
|
||||
#define d_fmt 1
|
||||
#define e_fmt 2
|
||||
#define w_fmt 4
|
||||
|
||||
/* Other coprocessor opcodes */
|
||||
#define cop2_op 0x12
|
||||
#define lwc2_op 0x32
|
||||
#define ldc2_op 0x36
|
||||
#define swc2_op 0x3a
|
||||
#define sdc2_op 0x3e
|
||||
|
||||
#define cop3_op 0x13
|
||||
#define lwc3_op 0x33
|
||||
#define ldc3_op 0x37
|
||||
#define swc3_op 0x3b
|
||||
#define sdc3_op 0x3f
|
||||
|
||||
|
||||
/* bcond subopcodes */
|
||||
#define bltz_op 0x00
|
||||
#define bgez_op 0x01
|
||||
#define bltzal_op 0x10
|
||||
#define bgezal_op 0x11
|
||||
|
||||
/* special subopcodes */
|
||||
#define sll_op 0x00
|
||||
#define srl_op 0x02
|
||||
#define sra_op 0x03
|
||||
#define sllv_op 0x04
|
||||
#define srlv_op 0x06
|
||||
#define srav_op 0x07
|
||||
#define jr_op 0x08
|
||||
#define jalr_op 0x09
|
||||
#define syscall_op 0x0C
|
||||
#define break_op 0x0D
|
||||
#define vcall_op 0x0E
|
||||
|
||||
#define mfhi_op 0x10
|
||||
#define mthi_op 0x11
|
||||
#define mflo_op 0x12
|
||||
#define mtlo_op 0x13
|
||||
#define mult_op 0x18
|
||||
#define multu_op 0x19
|
||||
#define div_op 0x1A
|
||||
#define divu_op 0x1B
|
||||
|
||||
#define add_op 0x20
|
||||
#define addu_op 0x21
|
||||
#define and_op 0x24
|
||||
#define or_op 0x25
|
||||
#define xor_op 0x26
|
||||
#define nor_op 0x27
|
||||
#define sub_op 0x22
|
||||
#define subu_op 0x23
|
||||
#define slt_op 0x2A
|
||||
#define sltu_op 0x2B
|
||||
|
||||
#endif /* LANGUAGE_C */
|
||||
|
||||
#ifdef LANGUAGE_PASCAL
|
||||
|
||||
#ifdef MIPSEB
|
||||
type
|
||||
mips_instruction =
|
||||
packed record
|
||||
case cardinal of
|
||||
0: (
|
||||
word: cardinal;
|
||||
);
|
||||
1: (
|
||||
byte: packed array[0..3] of 0..255;
|
||||
);
|
||||
2: (
|
||||
opcode: 0..63;
|
||||
target: 0..67108863;
|
||||
);
|
||||
3: (
|
||||
opcode3: 0..63;
|
||||
rs: 0..31;
|
||||
rt: 0..31;
|
||||
simmediate: -32768..32767;
|
||||
);
|
||||
4: (
|
||||
opcode4: 0..63;
|
||||
rs4: 0..63;
|
||||
rt4: 0..63;
|
||||
uimmediate: 0..65535;
|
||||
);
|
||||
5: (
|
||||
opcode5: 0..63;
|
||||
rs5: 0..63;
|
||||
rt5: 0..63;
|
||||
rd5: 0..63;
|
||||
re5: 0..63;
|
||||
func: 0..63;
|
||||
);
|
||||
end {record};
|
||||
#endif
|
||||
|
||||
#ifdef MIPSEL
|
||||
type
|
||||
mips_instruction =
|
||||
packed record
|
||||
case cardinal of
|
||||
0: (
|
||||
word: cardinal;
|
||||
);
|
||||
1: (
|
||||
byte: packed array[0..3] of 0..255;
|
||||
);
|
||||
2: (
|
||||
target: 0..67108863;
|
||||
opcode: 0..63;
|
||||
);
|
||||
3: (
|
||||
simmediate: -32768..32767;
|
||||
rt: 0..31;
|
||||
rs: 0..31;
|
||||
opcode3: 0..63;
|
||||
);
|
||||
4: (
|
||||
uimmediate: 0..65535;
|
||||
rt4: 0..63;
|
||||
rs4: 0..63;
|
||||
opcode4: 0..63;
|
||||
);
|
||||
5: (
|
||||
func: 0..63;
|
||||
re5: 0..63;
|
||||
rd5: 0..63;
|
||||
rt5: 0..63;
|
||||
rs5: 0..63;
|
||||
opcode5: 0..63;
|
||||
);
|
||||
end {record};
|
||||
#endif
|
||||
|
||||
#define spec_op 16#00
|
||||
#define bcond_op 16#01
|
||||
#define j_op 16#02
|
||||
#define jal_op 16#03
|
||||
|
||||
#define beq_op 16#04
|
||||
#define bne_op 16#05
|
||||
#define blez_op 16#06
|
||||
#define bgtz_op 16#07
|
||||
|
||||
#define addi_op 16#08
|
||||
#define addiu_op 16#09
|
||||
#define slti_op 16#0A
|
||||
#define sltiu_op 16#0B
|
||||
|
||||
#define andi_op 16#0C
|
||||
#define ori_op 16#0D
|
||||
#define xori_op 16#0E
|
||||
#define lui_op 16#0F
|
||||
|
||||
#define lb_op 16#20
|
||||
#define lh_op 16#21
|
||||
#define lw_op 16#23
|
||||
#define lbu_op 16#24
|
||||
#define lhu_op 16#25
|
||||
#define ld_op 16#27
|
||||
#define sb_op 16#28
|
||||
#define sh_op 16#29
|
||||
#define sw_op 16#2B
|
||||
#define sd_op 16#2F
|
||||
#define lwl_op 16#22
|
||||
#define lwr_op 16#26
|
||||
#define swl_op 16#2a
|
||||
#define swr_op 16#2e
|
||||
|
||||
/* Co-processor sub-opcodes */
|
||||
#define bc_op 16#08
|
||||
#define mfc_op 16#00
|
||||
#define cfc_op 16#02
|
||||
#define mtc_op 16#04
|
||||
#define ctc_op 16#06
|
||||
|
||||
/* Co-processor 0 opcodes */
|
||||
#define cop0_op 16#10
|
||||
#define lwc0_op 16#30
|
||||
#define ldc0_op 16#34
|
||||
#define swc0_op 16#38
|
||||
#define sdc0_op 16#3c
|
||||
|
||||
/* Co-processor 0 sub-opcodes */
|
||||
#define tlbr_op 16#1
|
||||
#define tlbwi_op 16#2
|
||||
#define tlbwr_op 16#6
|
||||
#define tlbp_op 16#8
|
||||
#define rfe_op 16#10
|
||||
|
||||
/* Co-processor 1 opcodes */
|
||||
#define cop1_op 16#11
|
||||
#define lwc1_op 16#31
|
||||
#define ldc1_op 16#35
|
||||
#define swc1_op 16#39
|
||||
#define sdc1_op 16#3D
|
||||
|
||||
/* Co-processor 1 sub-opcodes */
|
||||
#define fadd_op 16#00
|
||||
#define fsub_op 16#01
|
||||
#define fmpy_op 16#02
|
||||
#define fdiv_op 16#03
|
||||
#define fsqrt_op 16#04
|
||||
#define fabs_op 16#05
|
||||
#define fmov_op 16#06
|
||||
#define fneg_op 16#07
|
||||
#define fcvts_op 16#20
|
||||
#define fcvtd_op 16#21
|
||||
#define fcvte_op 16#22
|
||||
#define fcvtw_op 16#24
|
||||
#define fcmp_op 16#30
|
||||
#define s_fmt 0
|
||||
#define d_fmt 1
|
||||
#define e_fmt 2
|
||||
#define w_fmt 4
|
||||
|
||||
/* Other coprocessor opcodes */
|
||||
#define cop2_op 16#12
|
||||
#define lwc2_op 16#32
|
||||
#define ldc2_op 16#36
|
||||
#define swc2_op 16#3a
|
||||
#define sdc2_op 16#3e
|
||||
|
||||
#define cop3_op 16#13
|
||||
#define lwc3_op 16#33
|
||||
#define ldc3_op 16#37
|
||||
#define swc3_op 16#3b
|
||||
#define sdc3_op 16#3f
|
||||
|
||||
|
||||
/* bcond subopcodes */
|
||||
#define bltz_op 16#00
|
||||
#define bgez_op 16#01
|
||||
#define bltzal_op 16#10
|
||||
#define bgezal_op 16#11
|
||||
|
||||
/* special subopcodes */
|
||||
#define sll_op 16#00
|
||||
#define srl_op 16#02
|
||||
#define sra_op 16#03
|
||||
#define sllv_op 16#04
|
||||
#define srlv_op 16#06
|
||||
#define srav_op 16#07
|
||||
#define jr_op 16#08
|
||||
#define jalr_op 16#09
|
||||
#define syscall_op 16#0C
|
||||
#define break_op 16#0D
|
||||
#define vcall_op 16#0E
|
||||
|
||||
#define mfhi_op 16#10
|
||||
#define mthi_op 16#11
|
||||
#define mflo_op 16#12
|
||||
#define mtlo_op 16#13
|
||||
#define mult_op 16#18
|
||||
#define multu_op 16#19
|
||||
#define div_op 16#1A
|
||||
#define divu_op 16#1B
|
||||
|
||||
#define add_op 16#20
|
||||
#define addu_op 16#21
|
||||
#define and_op 16#24
|
||||
#define or_op 16#25
|
||||
#define xor_op 16#26
|
||||
#define nor_op 16#27
|
||||
#define sub_op 16#22
|
||||
#define subu_op 16#23
|
||||
#define slt_op 16#2A
|
||||
#define sltu_op 16#2B
|
||||
|
||||
#endif /* LANGUAGE_PASCAL */
|
||||
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,466 +0,0 @@
|
||||
/*
|
||||
* IOCCC Raytracer by Anders Gavare.
|
||||
*
|
||||
* The raytracer was one of the winners of the 17th IOCCC.
|
||||
*
|
||||
* NOTE: This is the UNOBFUSCATED version of the raytracer I used
|
||||
* during development, not the actual entry sent to the contest.
|
||||
*
|
||||
*
|
||||
* How to build:
|
||||
* cc r3.c -o r3 (plus optimization flags)
|
||||
*
|
||||
* How to run:
|
||||
* ./r3 > ray.ppm
|
||||
* or
|
||||
* ./r3 | xv -
|
||||
*/
|
||||
#include "libsys.h"
|
||||
UINT32 *pP;
|
||||
|
||||
xsize = 800;
|
||||
ysize = 600;
|
||||
An = 3;
|
||||
|
||||
camera_X = 0;
|
||||
camera_Y = -10;
|
||||
camera_Z = -7;
|
||||
|
||||
scale = 1296;
|
||||
RootOfScale = 36;
|
||||
maxcolor = 255;
|
||||
|
||||
MaxDepth=9;
|
||||
_=1<<15;
|
||||
|
||||
/*
|
||||
double sphere_x[44] = {
|
||||
-15,-15,-15,-15, // I
|
||||
-8,-8,-10,-6,-10,-6, // O
|
||||
-1,-1, 1,1, // C
|
||||
6, 6, 8,8, // C
|
||||
13,13,15,15, // C
|
||||
-11,-11,-11,-11,-9,-9,-7,-7, // r
|
||||
0,0,-2,-2,-2,2,2,2, // a
|
||||
7,7,9,9,11,11, // y
|
||||
};
|
||||
double sphere_z[44] = {
|
||||
3,0,-3,-6, // I
|
||||
-6, 3,0,0,-3,-3, // O
|
||||
0,-3,-6, 3, // C
|
||||
0,-3,-6, 3, // C
|
||||
0,-3,-6, 3, // C
|
||||
-11,-13,-15,-17,-11,-15,-13,-17, // r
|
||||
-11,-15,-13,-15,-17,-13,-15,-17, // a
|
||||
-11,-13,-15,-17,-11,-13, // y
|
||||
};
|
||||
*/
|
||||
|
||||
/* Common return variable: */
|
||||
return_var;
|
||||
return_var2;
|
||||
return_var3;
|
||||
return_var4;
|
||||
|
||||
|
||||
get_sphere_coordinates(b)
|
||||
{
|
||||
return_var = "1111886:6:??AAFFHHMMOO55557799@@>>>BBBGGIIKK"[b]-64;
|
||||
return_var3 = "C@=::C@@==@=:C@=:C@=:C531/513/5131/31/531/53"[b]-64;
|
||||
|
||||
/* return_var = sphere_x[b]; */
|
||||
return_var2 = b<22? 9 : 0;
|
||||
/* return_var3 = sphere_z[b]; */
|
||||
return_var4 = 2;
|
||||
}
|
||||
|
||||
|
||||
/* sqroot(x) returns the square root of x in return_var */
|
||||
sqroot_sub(x, mask, guess)
|
||||
{
|
||||
mask?
|
||||
(
|
||||
guess ^= mask,
|
||||
guess*guess > x ?
|
||||
( guess ^= mask )
|
||||
:
|
||||
0,
|
||||
sqroot_sub(x, mask/2, guess)
|
||||
)
|
||||
:
|
||||
( return_var = guess );
|
||||
}
|
||||
|
||||
|
||||
sqroot(x)
|
||||
{
|
||||
sqroot_sub(x, _, 0);
|
||||
}
|
||||
|
||||
|
||||
/*
|
||||
* hit_sphere():
|
||||
*
|
||||
* returns where on a sphere we hit
|
||||
* Returns distance in hit_sphere_q. (Negative return
|
||||
* value if we didn't hit anything.)
|
||||
*/
|
||||
hit_sphere_q;
|
||||
hit_sphere(objnr, x, y, z,
|
||||
dx, dy, dz,
|
||||
a, b)
|
||||
{
|
||||
get_sphere_coordinates(objnr);
|
||||
x -= return_var*scale;
|
||||
y -= return_var2*scale;
|
||||
z -= return_var3*scale;
|
||||
|
||||
/*
|
||||
* Solve the following equation:
|
||||
*
|
||||
* q^2 (dx^2+dy^2+dz^2) + q * 2(x*dx+y*dy+z*dz)
|
||||
* + x^2+y^2+z^2 - r^2 = 0
|
||||
*
|
||||
* We assume that |dx,dy,dz| is 1.
|
||||
*
|
||||
* q^2 + a q + b = 0
|
||||
*
|
||||
* The solution is (of course)
|
||||
*
|
||||
* q = -a/2 +- sqrt(a^2/4 - b)
|
||||
*/
|
||||
|
||||
b = x*x/scale+y*y/scale+z*z/scale-return_var4*return_var4*scale;
|
||||
|
||||
/* a = 2*(...), and then divide by -2 */
|
||||
a = -x*dx/scale-y*dy/scale-z*dz/scale;
|
||||
|
||||
hit_sphere_q =
|
||||
(
|
||||
(b = a*a/scale - b) >= 0 ?
|
||||
(
|
||||
/* b = scale*sqrt((double)b/(double)scale), */
|
||||
/* sqroot(b*scale), */
|
||||
|
||||
/* sqroot_sub(b, _, 0),
|
||||
b = return_var * RootOfScale,
|
||||
*/
|
||||
sqroot_sub(b*scale, _, 0),
|
||||
b = return_var,
|
||||
|
||||
/*
|
||||
* Return the lowest q (a+b or a-b) which is more
|
||||
* than 0. Return negative if neither
|
||||
* a+b or a-b is more than 0.
|
||||
*/
|
||||
|
||||
a + (a>b? -b : b)
|
||||
)
|
||||
:
|
||||
-1.0
|
||||
);
|
||||
}
|
||||
|
||||
|
||||
/*
|
||||
* find_closest():
|
||||
*
|
||||
* find_closest() scans objects and returns an index
|
||||
* to the object which was closest (has the lowest 'q').
|
||||
* x,y,z,dx,dy,dz are scaled.
|
||||
* find_closest_i is the index number of the found object,
|
||||
* -1 if none was found. find_closest_q is the distance
|
||||
* (scaled).
|
||||
*/
|
||||
find_closest_i; /* index ("sphere number") */
|
||||
find_closest_q; /* distance (scaled) */
|
||||
find_closest(objnr, x, y, z,
|
||||
dx, dy, dz, notindex)
|
||||
{
|
||||
/* Initialize find_closest_i on first call: */
|
||||
find_closest_i =
|
||||
!objnr ? -1 : find_closest_i;
|
||||
|
||||
objnr < 44 ?
|
||||
(
|
||||
hit_sphere(objnr, x,y,z, dx,dy,dz, 0,0),
|
||||
(hit_sphere_q > 0 && objnr!=notindex &&
|
||||
(hit_sphere_q<find_closest_q || find_closest_i<0)) ?
|
||||
(
|
||||
find_closest_q = hit_sphere_q,
|
||||
find_closest_i = objnr
|
||||
) : 0,
|
||||
find_closest(objnr+1, x,y,z,dx,dy,dz, notindex)
|
||||
)
|
||||
: 0;
|
||||
}
|
||||
|
||||
|
||||
/*
|
||||
* trace_ray():
|
||||
*
|
||||
* Traces one ray. orig_xyz and dir_xyz are scaled.
|
||||
* Return value in trace_ray_R, G, and B.
|
||||
*/
|
||||
trace_ray_R;
|
||||
trace_ray_G;
|
||||
trace_ray_B;
|
||||
nX;
|
||||
nY;
|
||||
nZ; /* tmp normal, and tmp
|
||||
sphere_light calculation */
|
||||
trace_ray(orig_x, orig_y, orig_z,
|
||||
dir_x, dir_y, dir_z,
|
||||
depth, notindex,
|
||||
tmpcol, closest_i_saved)
|
||||
{
|
||||
/*
|
||||
* "Scan" through the list of all objects
|
||||
* to see which one is closest:
|
||||
*/
|
||||
|
||||
find_closest(0, orig_x, orig_y, orig_z,
|
||||
dir_x, dir_y, dir_z, notindex);
|
||||
|
||||
depth>0 && find_closest_i >= 0?
|
||||
(
|
||||
/* find_closest_i and _q are the object
|
||||
number and distance of the object we
|
||||
hit. */
|
||||
|
||||
orig_x += dir_x*find_closest_q/scale,
|
||||
orig_y += dir_y*find_closest_q/scale,
|
||||
orig_z += dir_z*find_closest_q/scale,
|
||||
|
||||
/*
|
||||
* Calculate color (diffuse light):
|
||||
* (Note: use nZ as a temp variable while
|
||||
* calculating nY)
|
||||
*/
|
||||
get_sphere_coordinates(find_closest_i),
|
||||
nX = orig_x - return_var*scale,
|
||||
nY = orig_y - return_var2*scale,
|
||||
nZ = orig_z - return_var3*scale,
|
||||
|
||||
tmpcol = (-2*nX -2*nY + nZ) / 3, /* sqrt(9), */
|
||||
/* Set return_var to the length of the normal
|
||||
vector (in this case the sphere radius) */
|
||||
/* return_var = sqrt(nX*nX + nY*nY +nZ*nZ), */
|
||||
sqroot(nX*nX + nY*nY +nZ*nZ),
|
||||
// return_var = return_var4*scale,
|
||||
/* divide by return_var to get the color */
|
||||
// tmpcol = return_var!=0? tmpcol*scale/return_var : 0,
|
||||
tmpcol /= return_var4,
|
||||
|
||||
/* color is now -1..1 */
|
||||
tmpcol *= tmpcol, /* square the color 1..-1 => 1..1 */
|
||||
tmpcol *= 200,
|
||||
tmpcol /= (scale*scale),
|
||||
/* tmpcol += 5, */
|
||||
|
||||
closest_i_saved = find_closest_i,
|
||||
|
||||
/* Mirror: out = in - 2*(-normal)*cos v
|
||||
where v is the angle between in and
|
||||
-normal */
|
||||
|
||||
/* -normal: (normalized to len=1.0) */
|
||||
/* return_var = sqrt(nX*nX + nY*nY + nZ*nZ), */
|
||||
return_var!=0?
|
||||
(
|
||||
nX = -nX * scale / return_var,
|
||||
nY = -nY * scale / return_var,
|
||||
nZ = -nZ * scale / return_var
|
||||
) : 0,
|
||||
|
||||
/* use return_var as a temp variable,
|
||||
calculate cosinus between the vectors */
|
||||
return_var = (dir_x*nX + dir_y*nY + dir_z*nZ)/scale,
|
||||
/*
|
||||
dir_x -= 2 * nX * return_var / scale,
|
||||
dir_y -= 2 * nY * return_var / scale,
|
||||
dir_z -= 2 * nZ * return_var / scale,
|
||||
*/
|
||||
dir_x -= nX * return_var / (scale/2),
|
||||
dir_y -= nY * return_var / (scale/2),
|
||||
dir_z -= nZ * return_var / (scale/2),
|
||||
|
||||
trace_ray(orig_x, orig_y, orig_z,
|
||||
dir_x, dir_y, dir_z,
|
||||
depth-1, find_closest_i, 0,0),
|
||||
|
||||
trace_ray_R /= 2,
|
||||
trace_ray_G /= 2,
|
||||
trace_ray_B /= 2,
|
||||
/*
|
||||
closest_i_saved &= 7,
|
||||
!closest_i_saved? (closest_i_saved++) : 0,
|
||||
*/
|
||||
/*
|
||||
closest_i_saved = closest_i_saved<4? closest_i_saved+1 : 7,
|
||||
*/
|
||||
/*
|
||||
tvinga gråskalor: closest_i_saved = 7,
|
||||
*/
|
||||
closest_i_saved = closest_i_saved<22? 7 :
|
||||
(
|
||||
closest_i_saved<30 ? 1 :
|
||||
(
|
||||
closest_i_saved<38 ? 2 :
|
||||
(
|
||||
closest_i_saved<44 ? 4 :
|
||||
(
|
||||
closest_i_saved == 44 ? 6 :
|
||||
3
|
||||
)
|
||||
)
|
||||
)
|
||||
),
|
||||
|
||||
trace_ray_R += closest_i_saved & 1 ? tmpcol : 0,
|
||||
trace_ray_G += closest_i_saved & 2 ? tmpcol : 0,
|
||||
trace_ray_B += closest_i_saved & 4 ? tmpcol : 0
|
||||
)
|
||||
:
|
||||
(
|
||||
/* If we didn't hit anything, set the color anyway: */
|
||||
|
||||
depth==MaxDepth? /* True if this is a ray originating
|
||||
from the camera */
|
||||
(
|
||||
orig_z += 2,
|
||||
dir_z = orig_z > 0? orig_z / 8 : orig_z / 20
|
||||
)
|
||||
: 0,
|
||||
|
||||
/*
|
||||
* Colors according to Horizon_1 in gimp:
|
||||
* At top of sky: 13,92,146 (light blue)
|
||||
* At bottom sky: 255,255,255 (white)
|
||||
* Top of ground: 213,168,111 (light brown)
|
||||
* Bottom of ground: 103, 55, 26 (brown)
|
||||
*/
|
||||
|
||||
dir_z > 0?
|
||||
(
|
||||
trace_ray_B = dir_z * dir_z / scale,
|
||||
trace_ray_R = 255 - 250 * trace_ray_B / scale,
|
||||
trace_ray_G = 255 - 150 * trace_ray_B / scale,
|
||||
trace_ray_B = 255 - 100 * trace_ray_B / scale
|
||||
)
|
||||
:
|
||||
(
|
||||
trace_ray_B = dir_z * dir_z / scale,
|
||||
trace_ray_B < scale/5?
|
||||
(
|
||||
trace_ray_R = 255 - 210 * trace_ray_B / scale,
|
||||
trace_ray_G = 255 - 435 * trace_ray_B / scale,
|
||||
trace_ray_B = 255 - 720 * trace_ray_B / scale
|
||||
)
|
||||
:
|
||||
(
|
||||
trace_ray_B -= scale/5,
|
||||
trace_ray_R = 213 - 110 * trace_ray_B / scale,
|
||||
trace_ray_G = 168 - 113 * trace_ray_B / scale,
|
||||
trace_ray_B = 111 - 85 * trace_ray_B / scale
|
||||
)
|
||||
),
|
||||
|
||||
depth!=MaxDepth?
|
||||
(
|
||||
trace_ray_R /= 2,
|
||||
trace_ray_G /= 2,
|
||||
trace_ray_B /= 2
|
||||
)
|
||||
: 0
|
||||
);
|
||||
|
||||
trace_ray_R = trace_ray_R<0? 0 : trace_ray_R>maxcolor? maxcolor: trace_ray_R;
|
||||
trace_ray_G = trace_ray_G<0? 0 : trace_ray_G>maxcolor? maxcolor : trace_ray_G;
|
||||
trace_ray_B = trace_ray_B<0? 0 : trace_ray_B>maxcolor? maxcolor : trace_ray_B;
|
||||
}
|
||||
|
||||
|
||||
/*
|
||||
* do_pixels_in_line():
|
||||
*
|
||||
* the horizontal "for loop"
|
||||
*/
|
||||
R; G; B;
|
||||
dpil_helper(x,y, a,b)
|
||||
{
|
||||
trace_ray(
|
||||
scale*camera_X + scale*40*(An*x+a)/xsize/An - scale*20,
|
||||
scale*camera_Y,
|
||||
scale*camera_Z - scale*30*(An*y+b)/ysize/An + scale*15,
|
||||
0, scale, 0, MaxDepth, -1, 0,0);
|
||||
|
||||
R += trace_ray_R;
|
||||
G += trace_ray_G;
|
||||
B += trace_ray_B;
|
||||
|
||||
++a<An?
|
||||
dpil_helper(x,y,a,b)
|
||||
: (
|
||||
++b<An?
|
||||
dpil_helper(x,y,0,b)
|
||||
: 0
|
||||
);
|
||||
}
|
||||
do_pixels_in_line(x, y)
|
||||
{
|
||||
R = G = B = 0;
|
||||
dpil_helper(x,y,0,0);
|
||||
|
||||
x < xsize ?
|
||||
(
|
||||
/* output the pixel to stdout, */
|
||||
|
||||
#ifndef JMIPS_VGA
|
||||
printf("%c%c%c", R/An/An, G/An/An, B/An/An),
|
||||
#else
|
||||
pP[x+800*y] = (R/An/An & 0xFF) | ((G/An/An & 0xFF) << 8) | ((B/An/An & 0xFF) << 16),
|
||||
#endif
|
||||
/* and then do the next pixel in this line: */
|
||||
do_pixels_in_line(x+1, y)
|
||||
) : 0;
|
||||
}
|
||||
|
||||
|
||||
/*
|
||||
* do_line():
|
||||
*
|
||||
* the vertical "for loop"
|
||||
*/
|
||||
do_line(y)
|
||||
{
|
||||
/* Do all lines: */
|
||||
do_pixels_in_line(0, --y? do_line(y),y:y);
|
||||
}
|
||||
|
||||
main()
|
||||
{
|
||||
#ifdef JMIPS_VGA
|
||||
volatile UINT32 *pVGA_mctrl = (UINT32*)sys_vga_mctrl;
|
||||
volatile UINT32 *pVGA_moffs = (UINT32*)sys_vga_moffs;
|
||||
UINT64 *pPixelBuf;
|
||||
|
||||
pPixelBuf = (UINT64*)malloc(800*600*sizeof(UINT32));
|
||||
pP = (UINT32*)pPixelBuf;
|
||||
printf("pPixelBuf : %8.8X\n", (UINT32)pPixelBuf);
|
||||
|
||||
*pVGA_moffs = (UINT32)pPixelBuf;
|
||||
*pVGA_mctrl = 1;
|
||||
|
||||
memset(pPixelBuf, 0, 800*600*sizeof(UINT32));
|
||||
#else
|
||||
|
||||
/* Output PPM file header ... */
|
||||
printf("P6\n%i %i\n255\n", xsize, ysize);
|
||||
|
||||
#endif
|
||||
|
||||
/* and do all lines: */
|
||||
do_line(ysize);
|
||||
}
|
||||
|
||||
@@ -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,104 +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};
|
||||
char msg[MSG_SIZE/8+1];
|
||||
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 = time(NULL);
|
||||
stop = start + 1;
|
||||
while(1)
|
||||
{
|
||||
hashcode = RMD((byte *)msg);
|
||||
start = time(NULL);
|
||||
if (memcmp(hashcode, hashref, sizeof(hashref)))
|
||||
{
|
||||
printf("Error RipeMD-160!\n");
|
||||
printf("Hash expected: ");
|
||||
for (i=0; i<sizeof(hashref); i++)
|
||||
printf("%2.2X", hashref[i]);
|
||||
|
||||
printf("\n");
|
||||
printf("Hash computed: ");
|
||||
for (i=0; i<sizeof(hashref); i++)
|
||||
printf("%2.2X", hashcode[i]);
|
||||
|
||||
printf("\n");
|
||||
return 1;
|
||||
}
|
||||
if (start >= stop)
|
||||
{
|
||||
for (i=0; i<sizeof(hashref); 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 = time(NULL);
|
||||
stop = start + 1;
|
||||
cnt = 0;
|
||||
}
|
||||
cnt++;
|
||||
}
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
File diff suppressed because it is too large
Load Diff
@@ -1,87 +0,0 @@
|
||||
.file "startup.S"
|
||||
|
||||
.section .rodata
|
||||
.data
|
||||
argv0: .asciz "\"This-MIPS-program\""
|
||||
argv: .word argv0
|
||||
|
||||
.text
|
||||
.section .start, "ax"
|
||||
.extern _init
|
||||
.extern dbg_init
|
||||
.extern _exc_vect_start
|
||||
.extern _xcpt_handler
|
||||
.align 2
|
||||
.globl _start
|
||||
_start:
|
||||
.set noreorder
|
||||
j init
|
||||
nop
|
||||
.set reorder
|
||||
|
||||
.text
|
||||
.set noreorder
|
||||
init:
|
||||
# Set stack pointer
|
||||
la $sp, stack_ptr
|
||||
# Set global pointer
|
||||
la $gp, _gp
|
||||
|
||||
# zero bss
|
||||
la $8, __bss_start
|
||||
la $9, _end
|
||||
$zeroise:
|
||||
sw $0, 0($8)
|
||||
bne $8, $9, $zeroise
|
||||
addiu $8, 4
|
||||
|
||||
# Install exception vector jump code
|
||||
la $t1, _exc_vect_copy_start
|
||||
la $t2, _exc_vect_copy_end
|
||||
la $t0, _exc_vect_start
|
||||
|
||||
$install: lw $v0, 0($t1)
|
||||
addiu $t1, 4
|
||||
sw $v0, 0($t0)
|
||||
bne $t1, $t2, $install
|
||||
addiu $t0, 4
|
||||
|
||||
# Call _init
|
||||
la $k0, _init
|
||||
jalr $k0
|
||||
nop
|
||||
|
||||
# Call dbg_init
|
||||
la $k0, dbg_init
|
||||
jalr $k0
|
||||
nop
|
||||
|
||||
# Set user-mode
|
||||
mfc0 $a0, $12
|
||||
li $a1, 3
|
||||
or $a0, $a1
|
||||
mtc0 $a0, $12
|
||||
|
||||
# Set environment
|
||||
li $a0, 1
|
||||
la $a1, argv
|
||||
|
||||
# Call main
|
||||
la $k0, main
|
||||
jalr $k0
|
||||
nop
|
||||
|
||||
# Terminate after main returns
|
||||
_terminate:
|
||||
nop
|
||||
la $t0, exit
|
||||
jalr $t0
|
||||
move $a0, $v0
|
||||
|
||||
_exc_vect_copy_start:
|
||||
la $k0, _xcpt_handler
|
||||
jr $k0
|
||||
nop
|
||||
_exc_vect_copy_end:
|
||||
|
||||
.set reorder
|
||||
@@ -1,277 +0,0 @@
|
||||
#include <stdlib.h>
|
||||
#include <stdio.h>
|
||||
#include "libsys.h"
|
||||
|
||||
void _exc_break(void)
|
||||
{
|
||||
__asm
|
||||
(
|
||||
".set noreorder\n"
|
||||
"break 0x9\n"
|
||||
".set reorder\n"
|
||||
|
||||
);
|
||||
}
|
||||
|
||||
void _exc_syscall(void)
|
||||
{
|
||||
__asm
|
||||
(
|
||||
".set noreorder\n"
|
||||
"syscall\n"
|
||||
".set reorder\n"
|
||||
|
||||
);
|
||||
}
|
||||
|
||||
void _exc_arith(void)
|
||||
{
|
||||
__asm
|
||||
(
|
||||
".set noreorder\n"
|
||||
" li $t0, 0x7FFFFFFF\n"
|
||||
" addi $t1, $t0, 2\n"
|
||||
".set reorder\n"
|
||||
|
||||
);
|
||||
}
|
||||
|
||||
void _exc_store_err(void)
|
||||
{
|
||||
volatile int *pSrc = (int*)sys_timer_sec;
|
||||
volatile int *pDst = (int*)0x40000001;
|
||||
|
||||
*pDst = *pSrc;
|
||||
|
||||
}
|
||||
|
||||
void _exc_load_err(void)
|
||||
{
|
||||
__asm
|
||||
(
|
||||
".set noreorder\n"
|
||||
" li $t0, 0x40000000\n"
|
||||
" li $t1, 0x40000000\n"
|
||||
" lw $t1, 0($t1)\n"
|
||||
" lw $t0, 2($t0)\n"
|
||||
" lw $t1, 4($t0)\n"
|
||||
"nop\n"
|
||||
".set reorder\n"
|
||||
|
||||
);
|
||||
|
||||
}
|
||||
|
||||
void _exc_kaddr_err(void)
|
||||
{
|
||||
__asm
|
||||
(
|
||||
".set noreorder\n"
|
||||
" li $t0, 0x80000000\n"
|
||||
" jr $t0\n"
|
||||
"nop\n"
|
||||
".set reorder\n"
|
||||
|
||||
);
|
||||
|
||||
}
|
||||
|
||||
void _exc_iaddr_daddr_err(void)
|
||||
{
|
||||
__asm
|
||||
(
|
||||
".set noreorder\n"
|
||||
" li $t0, 0x40000003\n"
|
||||
" li $t1, 0x40000002\n"
|
||||
" jr $t0\n"
|
||||
" lw $t1, 0($t1)\n"
|
||||
"nop\n"
|
||||
".set reorder\n"
|
||||
|
||||
);
|
||||
|
||||
}
|
||||
|
||||
void _exc_daddr_iaddr_err(void)
|
||||
{
|
||||
__asm
|
||||
(
|
||||
".set noreorder\n"
|
||||
" li $t0, 0x40000003\n"
|
||||
" li $t1, 0x40000002\n"
|
||||
" lw $t1, 0($t1)\n"
|
||||
" jr $t0\n"
|
||||
"nop\n"
|
||||
".set reorder\n"
|
||||
|
||||
);
|
||||
|
||||
}
|
||||
|
||||
void _exc_iaddr_err(void)
|
||||
{
|
||||
__asm
|
||||
(
|
||||
".set noreorder\n"
|
||||
" li $t0, 0x40000003\n"
|
||||
" jr $t0\n"
|
||||
"nop\n"
|
||||
".set reorder\n"
|
||||
|
||||
);
|
||||
|
||||
}
|
||||
|
||||
void _exc_ri(void)
|
||||
{
|
||||
__asm
|
||||
(
|
||||
".set noreorder\n"
|
||||
" li $t0, 0x40010000\n"
|
||||
" li $t1, 0x9c563442\n"
|
||||
" sw $t1, 0($t0)\n"
|
||||
" jr $t0\n"
|
||||
"nop\n"
|
||||
".set reorder\n"
|
||||
|
||||
);
|
||||
|
||||
}
|
||||
|
||||
void _exc_ibe(void)
|
||||
{
|
||||
__asm
|
||||
(
|
||||
".set noreorder\n"
|
||||
" li $t1, 0x10000000\n"
|
||||
" jr $t1\n"
|
||||
"nop\n"
|
||||
".set reorder\n"
|
||||
|
||||
);
|
||||
|
||||
}
|
||||
|
||||
void _exc_dbe(void)
|
||||
{
|
||||
__asm
|
||||
(
|
||||
".set noreorder\n"
|
||||
" li $t1, 0x10000000\n"
|
||||
" lw $t0, 0($t1)\n"
|
||||
"nop\n"
|
||||
" jr $t0\n"
|
||||
"nop\n"
|
||||
".set reorder\n"
|
||||
|
||||
);
|
||||
|
||||
}
|
||||
|
||||
void handler0(void)
|
||||
{
|
||||
printf("Interrupt 0\n");
|
||||
interrupt_clr(0);
|
||||
}
|
||||
|
||||
void handler1(void)
|
||||
{
|
||||
printf("Interrupt 1\n");
|
||||
interrupt_clr(1);
|
||||
}
|
||||
|
||||
int main(void)
|
||||
{
|
||||
int buf[256];
|
||||
int i, sel;
|
||||
|
||||
interrupt_register(0, handler0);
|
||||
interrupt_enable(0);
|
||||
interrupt_register(1, handler1);
|
||||
interrupt_enable(1);
|
||||
|
||||
while(1)
|
||||
{
|
||||
printf("Welche exception möchten Sie testen?\n");
|
||||
printf(" 1 : Reserved instruction\n");
|
||||
printf(" 2 : Privileged address (BadVAddr = 0x80000000)\n");
|
||||
printf(" 3 : Arithmetic overflow\n");
|
||||
printf(" 4 : Syscall\n");
|
||||
printf(" 5 : Breakpoint\n");
|
||||
printf(" 6 : Load error on instruction (BadVAddr = 0x40000003)\n");
|
||||
printf(" 7 : Load error on data (BadVAddr = 0x40000002)\n");
|
||||
printf(" 8 : Store error on data (BadVAddr = 0x40000001)\n");
|
||||
printf(" 9 : Bus error on instruction\n");
|
||||
printf("10 : Bus error on data\n");
|
||||
printf("11 : SW-interrupt 0\n");
|
||||
printf("12 : SW-interrupt 1\n");
|
||||
printf("13 : Load error on instruction and Load error on data (BadVAddr = 0x40000003)\n");
|
||||
printf("14 : Load error on data and Load error on instruction (BadVAddr = 0x40000002)\n");
|
||||
|
||||
scanf("%d", &sel);
|
||||
printf("Jetzt kommt die exception (%d)!\n", sel);
|
||||
|
||||
switch(sel)
|
||||
{
|
||||
case 1:
|
||||
_exc_ri();
|
||||
break;
|
||||
|
||||
case 2:
|
||||
_exc_kaddr_err();
|
||||
break;
|
||||
|
||||
case 3:
|
||||
_exc_arith();
|
||||
break;
|
||||
|
||||
case 4:
|
||||
_exc_syscall();
|
||||
break;
|
||||
|
||||
case 5:
|
||||
_exc_break();
|
||||
break;
|
||||
|
||||
case 6:
|
||||
_exc_iaddr_err();
|
||||
break;
|
||||
|
||||
case 7:
|
||||
_exc_load_err();
|
||||
break;
|
||||
|
||||
case 8:
|
||||
_exc_store_err();
|
||||
break;
|
||||
|
||||
case 9:
|
||||
printf("IBE: Exception not implemented in current CPU!\nPush reset to restart!\n");
|
||||
_exc_ibe();
|
||||
break;
|
||||
|
||||
case 10:
|
||||
printf("DBE: Exception not implemented in current CPU!\nPush reset to restart!\n");
|
||||
_exc_dbe();
|
||||
break;
|
||||
|
||||
case 11:
|
||||
case 12:
|
||||
interrupt_set(sel-11);
|
||||
break;
|
||||
|
||||
case 13:
|
||||
_exc_iaddr_daddr_err();
|
||||
break;
|
||||
|
||||
case 14:
|
||||
_exc_daddr_iaddr_err();
|
||||
break;
|
||||
|
||||
default:
|
||||
break;
|
||||
}
|
||||
sel = 0;
|
||||
}
|
||||
return 0;
|
||||
}
|
||||
@@ -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,154 +0,0 @@
|
||||
#include <stdio.h>
|
||||
#include <stdlib.h>
|
||||
#include <string.h>
|
||||
#include "irq.h"
|
||||
|
||||
#define CPU_FREQ_HZ 100000000
|
||||
|
||||
#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 UINT32 *pUART0_stat = (UINT32*)sys_uart0_stat;
|
||||
volatile UINT32 *pUART0_data = (UINT32*)sys_uart0_data;
|
||||
volatile UINT32 *pUART1_stat = (UINT32*)sys_uart1_stat;
|
||||
volatile UINT32 *pUART1_data = (UINT32*)sys_uart1_data;
|
||||
|
||||
while(0x200 & *pUART0_stat)
|
||||
{
|
||||
// sputs("w: "); print_word((int)pPtr_w); sputs("\n");
|
||||
if (pPtr_w == &buffer[16383])
|
||||
pPtr_w = buffer;
|
||||
*(pPtr_w++) = *pUART0_data;
|
||||
}
|
||||
|
||||
while(0x200 & *pUART1_stat)
|
||||
{
|
||||
// sputs("w: "); print_word((int)pPtr_w); sputs("\n");
|
||||
if (pPtr_w == &buffer[16383])
|
||||
pPtr_w = buffer;
|
||||
*(pPtr_w++) = *pUART1_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)
|
||||
{
|
||||
|
||||
volatile UINT32 *pUART0_stat = (UINT32*)sys_uart0_stat;
|
||||
volatile UINT32 *pUART1_stat = (UINT32*)sys_uart1_stat;
|
||||
volatile UINT32 *pUART0_baud = (UINT32*)sys_uart0_baud;
|
||||
volatile UINT32 *pUART1_baud = (UINT32*)sys_uart1_baud;
|
||||
|
||||
UART1_setbaud(460800);
|
||||
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);
|
||||
|
||||
printf("UART0 Status = 0x%8.8X\n", *pUART0_stat);
|
||||
printf("UART0 Baud = 0x%8.8X\n", *pUART0_baud);
|
||||
printf("UART1 Status = 0x%8.8X\n", *pUART1_stat);
|
||||
printf("UART1 Baud = 0x%8.8X\n", *pUART1_baud);
|
||||
|
||||
// enable RX interrupt
|
||||
*pUART0_stat |= (1 << 6);
|
||||
*pUART1_stat |= (1 << 6);
|
||||
printf("UART0 Status = 0x%8.8X\n", *pUART0_stat);
|
||||
printf("UART1 Status = 0x%8.8X\n", *pUART1_stat);
|
||||
|
||||
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,853 +0,0 @@
|
||||
#include <stdio.h>
|
||||
#include <stdlib.h>
|
||||
#include <string.h>
|
||||
#include <math.h>
|
||||
#include <time.h>
|
||||
#include <sys/times.h>
|
||||
#include <sys/time.h>
|
||||
#include "libsys.h"
|
||||
|
||||
#define TEST10_ERROR (ERROR | 0x10)
|
||||
#define TEST11_ERROR (ERROR | 0x11)
|
||||
#define TEST12_ERROR (ERROR | 0x12)
|
||||
#define TEST13_ERROR (ERROR | 0x13)
|
||||
#define TEST14_ERROR (ERROR | 0x14)
|
||||
#define TEST15_ERROR (ERROR | 0x15)
|
||||
|
||||
char buffer[16384];
|
||||
int g_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;
|
||||
volatile UINT32 *pLED = (UINT32*)sys_led_port;
|
||||
|
||||
while((0x10 & *pUART_stat))
|
||||
{
|
||||
buffer[g_i] = (char)*pUART_data;
|
||||
_cg_putchar(buffer[g_i]);
|
||||
g_i = (g_i+1)%sizeof(buffer);
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
int g_cnt;
|
||||
void handler7(void)
|
||||
{
|
||||
UINT32 volatile *pGPIO0 = (UINT32*)sys_gpio0;
|
||||
UINT32 volatile *pTim_stat = (UINT32*)sys_itim_stat;
|
||||
UINT32 volatile *pTim_ctrl = (UINT32*)sys_itim_ctrl;
|
||||
UINT32 volatile *pTim0_cmp = (UINT32*)sys_itim0_cmp;
|
||||
time_t curr_date;
|
||||
struct tm *pDate;
|
||||
|
||||
if (*pTim0_cmp < 0x200)
|
||||
{
|
||||
*pTim0_cmp = 0x200;
|
||||
}
|
||||
if (*pTim_stat & 1)
|
||||
{
|
||||
*pTim_stat = 1;
|
||||
*pGPIO0 = g_cnt++;
|
||||
}
|
||||
|
||||
if (*pTim_stat & 4)
|
||||
{
|
||||
*pTim_stat = 4;
|
||||
curr_date = time(NULL);
|
||||
pDate = gmtime(&curr_date);
|
||||
fprintf(stderr, "%s", asctime(pDate));
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
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;
|
||||
int cache_size, cache_line;
|
||||
|
||||
char *cpu_type_str[7] = {"invalid", "R2000", "R3000", "R6000", "R4000", "reserved", "R6000A"};
|
||||
|
||||
// Print Status register
|
||||
result = CP0_SR_read();
|
||||
|
||||
printf("--------------------------------------------------\n");
|
||||
printf("Status : %8.8X\n", result);
|
||||
|
||||
// Print Revision
|
||||
result = CP0_PRID_read();
|
||||
rev_id = (result >> 8) & 0xFF;
|
||||
printf("CPU type : MIPS ");
|
||||
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");
|
||||
cache_size = (result >> 16) & 7;
|
||||
cache_line = (result >> 19) & 7;
|
||||
printf("I-Cache : %d kBytes (%d Bytes per line)\n", 4*(int)pow(2.0, (double)(8+cache_size))/1024, 4*(int)pow(2.0, (double)(cache_line)));
|
||||
cache_size = (result >> 24) & 7;
|
||||
cache_line = (result >> 27) & 7;
|
||||
printf("D-Cache : %d kBytes (%d Bytes per line)\n", 4*(int)pow(2.0, (double)(8+cache_size))/1024, 4*(int)pow(2.0, (double)(cache_line)));
|
||||
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 10000
|
||||
#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;
|
||||
long cl;
|
||||
|
||||
cl = (long)clock();
|
||||
srand(cl);
|
||||
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;
|
||||
if (!s2)
|
||||
{
|
||||
fprintf(stderr, "Test12_MulDiv(): Division by zero!\n");
|
||||
fprintf(stderr, "Clock() was 0x%8.8X\n", cl);
|
||||
continue;
|
||||
}
|
||||
|
||||
div_res = div(s1, s2);
|
||||
|
||||
sp = s2*div_res.quot;
|
||||
st = div_res.rem + sp;
|
||||
if (st != s1)
|
||||
return TEST12_ERROR;
|
||||
}
|
||||
}
|
||||
return NO_ERROR;
|
||||
}
|
||||
|
||||
int Test13_COP0_Load_Store(void)
|
||||
{
|
||||
int i,size;
|
||||
UINT32 *pSrc32, *pDst32;
|
||||
|
||||
size = 0x2000;
|
||||
pSrc32 = (UINT32*)0xBFC00000;
|
||||
pDst32 = (UINT32*)calloc(size,sizeof(UINT32));
|
||||
for (i=0; i < size/4; i++)
|
||||
{
|
||||
CP0_TR_read_ptr(&pSrc32[i]);
|
||||
CP0_TR_write_ptr(&pDst32[i]);
|
||||
}
|
||||
for (i=size/4-1; i >= 0; i--)
|
||||
if (pDst32[i] != pSrc32[i])
|
||||
break;
|
||||
|
||||
free(pDst32);
|
||||
i++;
|
||||
if (i)
|
||||
return TEST13_ERROR;
|
||||
|
||||
return NO_ERROR;
|
||||
}
|
||||
|
||||
int Test14_DCACHE_invalidate(void)
|
||||
{
|
||||
int i,size;
|
||||
UINT32 *pSrc32, *pDst32;
|
||||
|
||||
size = 0x2000;
|
||||
pSrc32 = (UINT32*)0xBFC00000;
|
||||
pDst32 = (UINT32*)calloc(size,sizeof(UINT32));
|
||||
for (i=0; i < size/4; i++)
|
||||
{
|
||||
pDst32[i] = pSrc32[i];
|
||||
DCACHE_invalidate_at(&pDst32[i]);
|
||||
}
|
||||
for (i=size/4-1; i >= 0; i--)
|
||||
{
|
||||
DCACHE_invalidate_at(&pDst32[i]);
|
||||
if (pDst32[i] != pSrc32[i])
|
||||
break;
|
||||
}
|
||||
|
||||
free(pDst32);
|
||||
i++;
|
||||
if (i)
|
||||
return TEST14_ERROR;
|
||||
|
||||
pDst32 = (UINT32*)calloc(size,sizeof(UINT32));
|
||||
for (i=0; i < size/4; i++)
|
||||
{
|
||||
pDst32[i] = pSrc32[i];
|
||||
}
|
||||
DCACHE_invalidate_all();
|
||||
for (i=size/4-1; i >= 0; i--)
|
||||
if (pDst32[i] != pSrc32[i])
|
||||
break;
|
||||
|
||||
free(pDst32);
|
||||
i++;
|
||||
if (i)
|
||||
return TEST14_ERROR;
|
||||
|
||||
return NO_ERROR;
|
||||
}
|
||||
|
||||
#define PI_SCALE 10000
|
||||
#define PI_MAXARR 2800
|
||||
#define PI_ARRINIT 2000
|
||||
|
||||
int Test15_pi_calc()
|
||||
{
|
||||
int i, j, k;
|
||||
int carry = 0;
|
||||
int arr[PI_MAXARR+1];
|
||||
UINT32 int_part, result;
|
||||
UINT16 pi_res[200] = {0};
|
||||
UINT16 pi_ref[200] =
|
||||
{
|
||||
3141,5926,5358,9793,2384,6264,3383,2795, 288,4197,1693,9937,5105,8209,7494,4592,3078,1640,6286,2089,9862,8034,8253,4211,
|
||||
7067,9821,4808,6513,2823, 664,7093,8446, 955, 582,2317,2535,9408,1284,8111,7450,2841, 270,1938,5211, 555,9644,6229,4895,
|
||||
4930,3819,6442,8810,9756,6593,3446,1284,7564,8233,7867,8316,5271,2019, 914,5648,5669,2346, 348,6104,5432,6648,2133,9360,
|
||||
7260,2491,4127,3724,5870, 660,6315,5881,7488,1520,9209,6282,9254, 917,1536,4367,8925,9036, 11,3305,3054,8820,4665,2138,
|
||||
4146,9519,4151,1609,4330,5727, 365,7595,9195,3092,1861,1738,1932,6117,9310,5118,5480,7446,2379,9627,4956,7351,8857,5272,
|
||||
4891,2279,3818,3011,9491,2983,3673,3624,4065,6643, 860,2139,4946,3952,2473,7190,7021,7986, 943,7027,7053,9217,1762,9317,
|
||||
6752,3846,7481,8467,6694, 513,2000,5681,2714,5263,5608,2778,5771,3427,5778,9609,1736,3717,8721,4684,4090,1224,9534,3014,
|
||||
6549,5853,7105, 792,2796,8925,8923,5420,1995,6112,1290,2196, 864, 344,1815,9813,6297,7477,1309,9605,1870,7211,3499,9999,
|
||||
8372,9780,4995,1059,7317,3281,6096,3185
|
||||
};
|
||||
|
||||
// setbuf(stdout, NULL);
|
||||
k = 0;
|
||||
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);
|
||||
}
|
||||
result = carry + sum/PI_SCALE;
|
||||
int_part = PI_SCALE * (result / PI_SCALE);
|
||||
pi_res[k] = (UINT16)(result - int_part);
|
||||
carry = sum % PI_SCALE;
|
||||
k++;
|
||||
}
|
||||
|
||||
for (k=0; k < sizeof(pi_ref)/sizeof(UINT16); k++)
|
||||
{
|
||||
printf("%d", pi_res[k]);
|
||||
}
|
||||
printf("\n");
|
||||
|
||||
if(memcmp(pi_res, pi_ref, sizeof(pi_ref)))
|
||||
return TEST15_ERROR;
|
||||
|
||||
return NO_ERROR;
|
||||
}
|
||||
|
||||
#define TEST_SIZE (16*1024*1024) // Bytes
|
||||
#define SMALL_TEST_SIZE (8192) // Bytes
|
||||
int main (void)
|
||||
{
|
||||
int result, i, j, cnt, size;
|
||||
UINT32 volatile *pUART_baud = (UINT32*)sys_uart_baud;
|
||||
UINT32 volatile *pReg = (UINT32*)sys_led_port;
|
||||
UINT32 volatile *pReg_usec = (UINT32*)sys_timer_usec;
|
||||
UINT32 volatile *pReg_sec = (UINT32*)sys_timer_sec;
|
||||
UINT32 volatile *pSSRAM = (UINT32*)sys_ssram_io;
|
||||
UINT32 volatile *pTim_ctrl = (UINT32*)sys_itim_ctrl;
|
||||
UINT32 volatile *pTim_stat = (UINT32*)sys_itim_stat;
|
||||
UINT32 volatile *pTim0_cnt = (UINT32*)sys_itim0_cnt;
|
||||
UINT32 volatile *pTim0_cmp = (UINT32*)sys_itim0_cmp;
|
||||
UINT32 volatile *pTim1_cnt = (UINT32*)sys_itim1_cnt;
|
||||
UINT32 volatile *pTim1_cmp = (UINT32*)sys_itim1_cmp;
|
||||
|
||||
g_cnt = 1;
|
||||
|
||||
srand(clock());
|
||||
|
||||
*pTim0_cnt = 0;
|
||||
*pTim1_cnt = 0;
|
||||
*pTim0_cmp = (UINT32)(rand() & 0x3FF);
|
||||
*pTim1_cmp = 100000000;
|
||||
*pTim_stat = (1 << 2) | (1 << 0);
|
||||
*pTim_ctrl = (3 << 2);
|
||||
|
||||
time_t curr_date;
|
||||
struct tm *pDate, date;
|
||||
UINT32 start, end;
|
||||
char sel[80];
|
||||
struct timeval time_sec;
|
||||
|
||||
UINT8 *ram8 = NULL;
|
||||
UINT16 *ram16 = NULL;
|
||||
UINT32 *ram32 = NULL;
|
||||
|
||||
UINT32 *pSrc32, *pDst32;
|
||||
|
||||
// *pUART_baud = 1;
|
||||
|
||||
setbuf(stdout, NULL);
|
||||
PrintCPUinfo();
|
||||
|
||||
g_i = 0;
|
||||
memset(buffer, 0, sizeof(buffer));
|
||||
interrupt_register(3, handler3);
|
||||
fprintf(stderr, "UART interrupt registered.\n");
|
||||
|
||||
interrupt_register(7, handler7);
|
||||
fprintf(stderr, "Timer interrupt registered.\n");
|
||||
|
||||
// ----------------------------------------------------------
|
||||
// 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)));
|
||||
|
||||
// -------------------------------------------------------------------
|
||||
// Verify
|
||||
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);
|
||||
|
||||
printf("Boot code read \n");
|
||||
size = 0x2000;
|
||||
pSrc32 = (UINT32*)0xBFC00000;
|
||||
pDst32 = (UINT32*)calloc(size,sizeof(UINT32));
|
||||
memcpy(pDst32, pSrc32, size);
|
||||
printf("Verify Boot code...");
|
||||
for (i=size/4-1; i >= 0; i--)
|
||||
if (pDst32[i] != pSrc32[i])
|
||||
break;
|
||||
i++;
|
||||
if (i)
|
||||
printf("failed\r\n");
|
||||
else
|
||||
printf("passed\r\n");
|
||||
|
||||
free(pDst32);
|
||||
|
||||
memdump((UINT8*)pSrc32, 0, 16, size);
|
||||
memdump((UINT8*)0x40000000, 0, 16, 1024);
|
||||
|
||||
// Memtest END
|
||||
// ----------------------------------------------------------
|
||||
sputs("\r\n");
|
||||
|
||||
printf("Aktuelles Datum\n");
|
||||
curr_date = time(NULL);
|
||||
pDate = gmtime(&curr_date);
|
||||
puts(asctime(pDate));
|
||||
printf("Datum und Uhrzeit setzen? [j/N]: ");
|
||||
scanf("%s", sel);
|
||||
if (toupper(sel[0]) == 'J')
|
||||
{
|
||||
do
|
||||
{
|
||||
printf("Datum\n");
|
||||
printf("Jahr : ");
|
||||
scanf("%d", &date.tm_year);
|
||||
printf("Monat : ");
|
||||
scanf("%d", &date.tm_mon);
|
||||
printf("Tag : ");
|
||||
scanf("%d", &date.tm_mday);
|
||||
|
||||
printf("Uhrzeit\n");
|
||||
printf("Stunde : ");
|
||||
scanf("%d", &date.tm_hour);
|
||||
printf("Minute : ");
|
||||
scanf("%d", &date.tm_min);
|
||||
printf("Sekunde : ");
|
||||
scanf("%d", &date.tm_sec);
|
||||
|
||||
date.tm_year -= 1900;
|
||||
date.tm_mon -= 1;
|
||||
time_sec.tv_sec = mktime(&date);
|
||||
time_sec.tv_usec = 0;
|
||||
settimeofday(&time_sec, NULL);
|
||||
|
||||
printf("Datum\n");
|
||||
curr_date = time(NULL);
|
||||
pDate = gmtime(&curr_date);
|
||||
puts(asctime(pDate));
|
||||
printf("\nOK? [J/n]: ");
|
||||
scanf("%s", sel);
|
||||
printf("sel=%d\n", (int)sel[0]);
|
||||
|
||||
|
||||
} while(toupper(sel[0]) == 'N');
|
||||
}
|
||||
|
||||
interrupt_enable(7);
|
||||
interrupt_enable(3);
|
||||
*pTim_ctrl |= 3;
|
||||
|
||||
cnt = 0;
|
||||
while (1)
|
||||
{
|
||||
for (i=0; i < 100000; i++)
|
||||
{
|
||||
interrupt_disable(7);
|
||||
}
|
||||
for (i=0; i < 100000; i++)
|
||||
{
|
||||
interrupt_enable(7);
|
||||
}
|
||||
|
||||
*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("-- Cop0 LWZ0 and SWC0 ---------------------\n");
|
||||
printf("-------------------------------------------\n");
|
||||
result = Test13_COP0_Load_Store();
|
||||
if (IS_ERROR(result))
|
||||
break;
|
||||
printf("passed\n\n");
|
||||
|
||||
printf("-------------------------------------------\n");
|
||||
printf("-- D-Cache invalidate ---------------------\n");
|
||||
printf("-------------------------------------------\n");
|
||||
result = Test14_DCACHE_invalidate();
|
||||
if (IS_ERROR(result))
|
||||
break;
|
||||
printf("passed\n\n");
|
||||
|
||||
printf("-------------------------------------------\n");
|
||||
printf("-- PI calc --------------------------------\n");
|
||||
printf("-------------------------------------------\n");
|
||||
result = Test15_pi_calc();
|
||||
if (IS_ERROR(result))
|
||||
break;
|
||||
printf("passed\n\n");
|
||||
|
||||
printf("-------------------------------------------\n");
|
||||
printf("-- Paranoia -------------------------------\n");
|
||||
printf("-------------------------------------------\n");
|
||||
paranoia(1, NULL);
|
||||
printf("passed\n\n");
|
||||
|
||||
printf("Iteration %d: Passed\n", cnt);
|
||||
curr_date = time(NULL);
|
||||
pDate = gmtime(&curr_date);
|
||||
puts(asctime(pDate));
|
||||
cnt++;
|
||||
*pTim0_cmp = (UINT32)(rand() & 0x3FF);
|
||||
*pTim_ctrl |= 1;
|
||||
|
||||
// printf("V=%.17e\n", pow((double)cnt-1, (double)cnt));
|
||||
}
|
||||
*pReg = 0x40000000 | cnt;
|
||||
fprintf(stderr, "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,139 +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"
|
||||
|
||||
static fp_xcpt_t g_xcpt_handler[MAX_NUM_XCPT] = {NULL};
|
||||
|
||||
char *_xcpt_code_str[MAX_NUM_XCPT] =
|
||||
{
|
||||
"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"
|
||||
};
|
||||
|
||||
void xcpt_register(int xcpt_num, fp_xcpt_t fp)
|
||||
{
|
||||
if ((xcpt_num >= Mod) && (xcpt_num <= VCED))
|
||||
g_xcpt_handler[xcpt_num] = fp;
|
||||
|
||||
}
|
||||
|
||||
int _xcpt_dispatch(struct xcptcontext * xcp)
|
||||
{
|
||||
int xcpt_code, result, i;
|
||||
|
||||
xcpt_code = ((0xFF & xcp->cr) >> 2);
|
||||
|
||||
result = XCPT_ERR_NOTHANDLED;
|
||||
switch(xcpt_code)
|
||||
{
|
||||
case Int:
|
||||
result = _irq_dispatch(xcp);
|
||||
break;
|
||||
|
||||
default:
|
||||
if (g_xcpt_handler[xcpt_code])
|
||||
{
|
||||
result = (g_xcpt_handler[xcpt_code])(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) == XCPT_ERR_NOTHANDLED)
|
||||
{
|
||||
sputs("\n");
|
||||
PRINT_REG(" Status : ", _xcp->sr);
|
||||
PRINT_REG(" Cause : ", _xcp->cr);
|
||||
PRINT_REG(" EPC : ", _xcp->epc);
|
||||
PRINT_REG("BadAddr : ", _xcp->baddr);
|
||||
sputs("\n");
|
||||
PRINT_REG(" MDLO : ", _xcp->mdlo);
|
||||
PRINT_REG(" MDHI : ", _xcp->mdhi);
|
||||
|
||||
sputs("\n");
|
||||
|
||||
sputs("Registers:\n");
|
||||
PRINT_REG(" 0 (ze) : ", _xcp->regs[0]);
|
||||
PRINT_REG(" 1 (at) : ", _xcp->regs[1]);
|
||||
PRINT_REG(" 2 (v0) : ", _xcp->regs[2]);
|
||||
PRINT_REG(" 3 (v1) : ", _xcp->regs[3]);
|
||||
sputs("\n");
|
||||
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]);
|
||||
sputs("\n");
|
||||
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]);
|
||||
sputs("\n");
|
||||
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]);
|
||||
sputs("\n");
|
||||
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]);
|
||||
sputs("\n");
|
||||
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]);
|
||||
sputs("\n");
|
||||
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]);
|
||||
sputs("\n");
|
||||
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");
|
||||
sputs("\n");
|
||||
|
||||
exc_code = (_xcp->cr >> 2) & 0x1F;
|
||||
|
||||
sputs("Unhandled exception <");
|
||||
sputs(_xcpt_code_str[exc_code]);
|
||||
sputs("> at PC : ");
|
||||
|
||||
if (_xcp->cr & 0x80000000)
|
||||
{
|
||||
pInstr = (int*)(_xcp->epc + 4);
|
||||
}
|
||||
else
|
||||
{
|
||||
pInstr = (int*)(_xcp->epc);
|
||||
}
|
||||
print_word((int)pInstr);
|
||||
sputs("\n");
|
||||
|
||||
sputs("Instruction at exception address : ");
|
||||
print_word(*pInstr);
|
||||
sputs("\n");
|
||||
|
||||
sputs("Terminate.\n");
|
||||
_exit(exc_code);
|
||||
}
|
||||
|
||||
return 0;
|
||||
}
|
||||
@@ -1,49 +0,0 @@
|
||||
#ifndef XCPT_H
|
||||
#define XCPT_H
|
||||
|
||||
#define MAX_NUM_XCPT 32
|
||||
#define XCPT_ERR_NOTHANDLED 0x80000000
|
||||
|
||||
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;
|
||||
|
||||
typedef int (*fp_xcpt_t)(struct xcptcontext * xcp);
|
||||
|
||||
#define PRINT_REG(tag_str, reg) \
|
||||
sputs(tag_str); \
|
||||
print_word(reg); \
|
||||
sputs(" ");
|
||||
|
||||
|
||||
|
||||
// Public functions
|
||||
void xcpt_register(int xcpt_num, fp_xcpt_t fp);
|
||||
|
||||
#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 32768
|
||||
|
||||
/* 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,151 +0,0 @@
|
||||
#!/bin/sh
|
||||
TARGET=mipsel-elf
|
||||
PREFIX=/usr/local
|
||||
|
||||
SRC_BINUTILS=binutils-2.19
|
||||
SRC_GCC=gcc-4.3.3
|
||||
SRC_NEWLIB=newlib-1.16.0
|
||||
SRC_GMP=gmp-4.2.4
|
||||
SRC_MPFR=mpfr-2.4.0
|
||||
|
||||
# ---------------------------------------------------------------
|
||||
# 1. Binutils bauen und installieren
|
||||
# ---------------------------------------------------------------
|
||||
if [ ! -e $SRC_BINUTILS.tar.bz2 ]; then
|
||||
echo Downloading $SRC_BINUTILS
|
||||
wget ftp://ftp-stud.fht-esslingen.de/pub/Mirrors/ftp.gnu.org/binutils/$SRC_BINUTILS.tar.bz2 || exit 1
|
||||
else
|
||||
echo Skipped downloading $SRC_BINUTILS
|
||||
fi
|
||||
|
||||
if [ ! -e ./$SRC_BINUTILS ]; then
|
||||
echo Unpacking $SRC_BINUTILS
|
||||
tar -xjf $SRC_BINUTILS.tar.bz2 || exit 1
|
||||
else
|
||||
echo Skipped unpacking $SRC_BINUTILS
|
||||
fi
|
||||
|
||||
if [ ! -e ./$SRC_BINUTILS-build ]; then
|
||||
echo Building $SRC_BINUTILS
|
||||
mkdir -p $SRC_BINUTILS-build
|
||||
cd $SRC_BINUTILS-build
|
||||
../$SRC_BINUTILS/configure --target=$TARGET --prefix=$PREFIX || exit 1
|
||||
make || exit 1
|
||||
make install || exit 1
|
||||
cd ..
|
||||
else
|
||||
echo $SRC_BINUTILS is already built.
|
||||
fi
|
||||
|
||||
# ---------------------------------------------------------------
|
||||
# 2. GMP bauen und installieren
|
||||
# ---------------------------------------------------------------
|
||||
if [ ! -e $SRC_GMP.tar.bz2 ]; then
|
||||
echo Downloading $SRC_GMP
|
||||
wget http://ftp.sunet.se/pub/gnu/gmp/$SRC_GMP.tar.bz2 || exit 1
|
||||
else
|
||||
echo Skipped downloading $SRC_GMP
|
||||
fi
|
||||
|
||||
if [ ! -e ./$SRC_GMP ]; then
|
||||
echo Unpacking $SRC_GMP
|
||||
tar -xjf $SRC_GMP.tar.bz2 || exit 1
|
||||
else
|
||||
echo Skipped unpacking $SRC_GMP
|
||||
fi
|
||||
|
||||
if [ ! -e ./$SRC_GMP-build ]; then
|
||||
echo Building $SRC_GMP
|
||||
mkdir -p $SRC_GMP-build
|
||||
cd $SRC_GMP-build
|
||||
../$SRC_GMP/configure --prefix=$PREFIX || exit 1
|
||||
make || exit 1
|
||||
make check || exit 1
|
||||
make install || exit 1
|
||||
cd ..
|
||||
else
|
||||
echo $SRC_GMP is already built.
|
||||
fi
|
||||
|
||||
# ---------------------------------------------------------------
|
||||
# 3. MPFR bauen und installieren
|
||||
# ---------------------------------------------------------------
|
||||
if [ ! -e $SRC_MPFR.tar.bz2 ]; then
|
||||
echo Downloading $SRC_MPFR
|
||||
wget http://www.mpfr.org/mpfr-current/$SRC_MPFR.tar.bz2 || exit 1
|
||||
else
|
||||
echo Skipped downloading $SRC_MPFR
|
||||
fi
|
||||
|
||||
if [ ! -e ./$SRC_MPFR ]; then
|
||||
echo Unpacking $SRC_MPFR
|
||||
tar -xjf $SRC_MPFR.tar.bz2 || exit 1
|
||||
else
|
||||
echo Skipped unpacking $SRC_MPFR
|
||||
fi
|
||||
|
||||
if [ ! -e ./$SRC_MPFR-build ]; then
|
||||
echo Building $SRC_MPFR
|
||||
mkdir -p $SRC_MPFR-build
|
||||
cd $SRC_MPFR-build
|
||||
../$SRC_MPFR/configure --prefix=$PREFIX || exit 1
|
||||
make || exit 1
|
||||
make check || exit 1
|
||||
make install || exit 1
|
||||
cd ..
|
||||
else
|
||||
echo $SRC_MPFR is already built.
|
||||
fi
|
||||
|
||||
# ---------------------------------------------------------------
|
||||
# 4. GCC & newlib bauen und installieren
|
||||
# ---------------------------------------------------------------
|
||||
if [ ! -e $SRC_NEWLIB.tar.gz ]; then
|
||||
echo Downloading $SRC_NEWLIB
|
||||
wget ftp://sources.redhat.com/pub/newlib/$SRC_NEWLIB.tar.gz || exit 1
|
||||
else
|
||||
echo Skipped downloading $SRC_NEWLIB
|
||||
fi
|
||||
|
||||
if [ ! -e ./$SRC_NEWLIB ]; then
|
||||
echo Unpacking $SRC_NEWLIB
|
||||
tar -xzf $SRC_NEWLIB.tar.gz || exit 1
|
||||
if [ -e $SRC_NEWLIB-jens.patch ]; then
|
||||
echo Patching $SRC_NEWLIB
|
||||
patch -p0 < $SRC_NEWLIB-jens.patch || exit 1
|
||||
fi
|
||||
else
|
||||
echo Skipped unpacking $SRC_NEWLIB
|
||||
fi
|
||||
|
||||
if [ ! -e $SRC_GCC.tar.bz2 ]; then
|
||||
echo Downloading $SRC_GCC
|
||||
wget ftp://ftp-stud.fht-esslingen.de/pub/Mirrors/ftp.gnu.org/gcc/$SRC_GCC/$SRC_GCC.tar.bz2 || exit 1
|
||||
else
|
||||
echo Skipped downloading $SRC_GCC
|
||||
fi
|
||||
|
||||
if [ ! -e ./$SRC_GCC ]; then
|
||||
echo Unpacking $SRC_GCC
|
||||
tar -xjf $SRC_GCC.tar.bz2 || exit 1
|
||||
cd ./$SRC_GCC
|
||||
ln -sf ../$SRC_NEWLIB/newlib/ .
|
||||
cd ..
|
||||
else
|
||||
echo Skipped unpacking $SRC_GCC
|
||||
fi
|
||||
|
||||
if [ ! -e ./$SRC_GCC-build ]; then
|
||||
echo Building $SRC_GCC
|
||||
mkdir -p $SRC_GCC-build
|
||||
cd $SRC_GCC-build
|
||||
../$SRC_GCC/configure --target=$TARGET --prefix=$PREFIX --with-float=soft --with-newlib --verbose --enable-languages="c,c++" || exit 1
|
||||
LD_LIBRARY_PATH=$LD_LIBRARY_PATH:$PREFIX/lib make all || exit 1
|
||||
make info || exit 1
|
||||
make install || exit 1
|
||||
cd ..
|
||||
echo $PREFIX/lib >/etc/ld.so.conf.d/local.conf
|
||||
ldconfig
|
||||
else
|
||||
echo $SRC_GCC is already built.
|
||||
fi
|
||||
@@ -1,11 +0,0 @@
|
||||
diff -Naur newlib-1.16.0/newlib/libc/machine/mips/strlen.c newlib-1.16.0-fixed/newlib/libc/machine/mips/strlen.c
|
||||
--- newlib-1.16.0/newlib/libc/machine/mips/strlen.c 2002-03-14 03:41:43.000000000 +0100
|
||||
+++ newlib-1.16.0-fixed/newlib/libc/machine/mips/strlen.c 2009-02-14 15:52:58.000000000 +0100
|
||||
@@ -60,6 +60,7 @@
|
||||
" addiu $2,$4,1\n"
|
||||
"\n"
|
||||
"1: lbu $3,0($4)\n"
|
||||
+ " nop\n"
|
||||
" bnez $3,1b\n"
|
||||
" addiu $4,$4,1\n"
|
||||
"\n"
|
||||
@@ -1,11 +0,0 @@
|
||||
diff -Naur newlib-1.17.0/newlib/libc/machine/mips/strlen.c newlib-1.17.0-fixed/newlib/libc/machine/mips/strlen.c
|
||||
--- newlib-1.17.0/newlib/libc/machine/mips/strlen.c 2002-03-14 03:41:43.000000000 +0100
|
||||
+++ newlib-1.17.0-fixed/newlib/libc/machine/mips/strlen.c 2009-02-14 15:45:19.000000000 +0100
|
||||
@@ -60,6 +60,7 @@
|
||||
" addiu $2,$4,1\n"
|
||||
"\n"
|
||||
"1: lbu $3,0($4)\n"
|
||||
+ " nop\n"
|
||||
" bnez $3,1b\n"
|
||||
" addiu $4,$4,1\n"
|
||||
"\n"
|
||||
Vendored
-35
@@ -1,35 +0,0 @@
|
||||
../../../misc/dpram_2w2r.vhd
|
||||
../../../misc/dpram_1w1r.vhd
|
||||
../../../FIFO/src/fifo_ctrl_pkg.vhd
|
||||
../../../FIFO/src/fifo_sync_ctrl.vhd
|
||||
../../../FIFO/src/fifo_sync.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_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
-48
@@ -1,48 +0,0 @@
|
||||
#!/bin/sh
|
||||
|
||||
PROJECT="mips_top"
|
||||
DIST_FILE="./files.dist"
|
||||
DIST_DIR="./release/mips.r12"
|
||||
|
||||
# ---------------------------------------------------------------
|
||||
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/notes.txt $DIST_DIR/
|
||||
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/
|
||||
cp -a ./tmpl/mips_sys.vhd $DIST_DIR/src/
|
||||
|
||||
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.
Vendored
-338
@@ -1,338 +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 mips_sys IS
|
||||
GENERIC
|
||||
(
|
||||
ICACHE_SIZE : natural := 512; -- words
|
||||
DCACHE_SIZE : natural := 512; -- words
|
||||
SRAM_ADDR_WIDTH : integer := 14;
|
||||
FLASH_ADDR_WIDTH : integer := 14
|
||||
);
|
||||
PORT
|
||||
(
|
||||
eb : in std_logic;
|
||||
nmi : in std_logic;
|
||||
rst : in std_logic;
|
||||
clk : in std_logic;
|
||||
flash_cs_n : out std_logic;
|
||||
flash_oe_n : out std_logic;
|
||||
flash_we_n : out std_logic;
|
||||
flash_be_n : out unsigned(3 downto 0);
|
||||
sram_cs_n : out std_logic;
|
||||
sram_we_n : out std_logic;
|
||||
sram_oe_n : out std_logic;
|
||||
sram_be_n : out unsigned(3 downto 0);
|
||||
sram_a : out unsigned(SRAM_ADDR_WIDTH-1 downto 0);
|
||||
sram_d : inout unsigned(31 downto 0);
|
||||
flash_a : out unsigned(FLASH_ADDR_WIDTH-1 downto 0);
|
||||
flash_d : inout unsigned(31 downto 0);
|
||||
|
||||
gpo0 : out unsigned(31 downto 0);
|
||||
gpo1 : out unsigned(31 downto 0);
|
||||
gpi0 : in unsigned(31 downto 0);
|
||||
gpi1 : in unsigned(31 downto 0);
|
||||
|
||||
rx : in std_logic;
|
||||
tx : out std_logic;
|
||||
|
||||
debug : out unsigned(1 downto 0)
|
||||
);
|
||||
END mips_sys;
|
||||
|
||||
ARCHITECTURE behavior OF mips_sys IS
|
||||
|
||||
constant CLK_PERIOD : time := 10 ns;
|
||||
|
||||
-- Master
|
||||
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 int_uart : 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;
|
||||
|
||||
BEGIN
|
||||
|
||||
------------------------------------------------------------------
|
||||
-- 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";
|
||||
|
||||
|
||||
------------------------------------------------------------------
|
||||
inst_mips_top: entity work.mips_top
|
||||
GENERIC MAP
|
||||
(
|
||||
icache_size => ICACHE_SIZE, -- words
|
||||
dcache_size => DCACHE_SIZE -- words
|
||||
)
|
||||
PORT MAP
|
||||
(
|
||||
debug => debug,
|
||||
nmi => nmi,
|
||||
eb => eb,
|
||||
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;
|
||||
|
||||
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 => flash_we_n,
|
||||
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_we_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_O => int_uart,
|
||||
ser_rx => rx,
|
||||
ser_tx => tx
|
||||
);
|
||||
|
||||
END;
|
||||
Vendored
-84
@@ -1,84 +0,0 @@
|
||||
-----------------------------------------------------------------
|
||||
Changes in release 12
|
||||
-----------------------------------------------------------------
|
||||
- reworked GCC-toolchain: Valid mips*-elf-binaries are now compiled and linked
|
||||
using a single mips*-elf-gcc command.
|
||||
To use: Copy $THIS_RELEASE/bsp/toolchain/specs to $MIPS_GCC_PREFIX/lib/gcc/mipsel-elf/$GCC_VERSION/,
|
||||
and see bsp/examples/Makefile gcc usage
|
||||
GCC-provided crt*-functions are now called without problems.
|
||||
In summary: The toolchain is now more compliant to the intentional use of GCC.
|
||||
- mips_biu.vhd: Addresses 0xA0000000..0xBFFFFFFF are now un-dcached for memory-mapped I/O,
|
||||
which is now compliant to literature.
|
||||
- gpio_wb.vhd: Timer hard-reset is now removed. This helps to keep current time in case of CPU hard-reset.
|
||||
- new bsp-example source: gunzip
|
||||
- updated drawing 'mips_jbus_timing.pdf'
|
||||
- added drawing 'memory_map.pdf'
|
||||
- moved COP0 from mips_pipeline.vhd to mips_top.vhd. Created new cop-interface for later COPz connection.
|
||||
- added I/D-cache info (size and linesize) to upper 16 bits of PrID-Register.
|
||||
Example of reading cache info is done in bsp/examples/testbench::PrintCPUinfo()
|
||||
- simplified instruction decoder in mips_instr.vhd. Now there are less warnings during synthesis.
|
||||
Removed idecode_rom.vhd from project as consequence.
|
||||
- added cop0 instructions to invalidate I-cache and D-Cache
|
||||
- added copz instructions lwcz and swcz
|
||||
- gpio_wb.vhd: added 32 bit timer with interrupt and auto reload
|
||||
- added debugger in libsys. New files are mipsdis.c/h and dbg.c/h
|
||||
- exception handlers can now be registered to any exception type
|
||||
- bugfix: cop0 registers were not written during exception commit. Cop registers now behave like general registers.
|
||||
- added pin 'eb' to mips_top.vhd to select CPU-endianess at reset time (eb = 0 : little-endian, eb = 1 : big-endian)
|
||||
- Status register bit 'RE'= 1 (bit 25) reverses endianess in user-mode
|
||||
- Status register bit 'TS' (TLB Shutdown, bit 21) is tied high to indicate the absence of an MMU.
|
||||
- uart_wb.vhd: added interrupt enable
|
||||
- Interrupt pending flags (IP) are not anymore masked by Interrupt mask flags (IM) in H/W.
|
||||
Masking has to be done in S/W. H/W masking was removed because it isn't MIPS-compliant.
|
||||
- added NMI/RST pin (more MIPS compliant). Transition Asserting/Deasserting causes exception.
|
||||
Exception vector is reset (0xBFC00000). It's a soft-reset, which can help debugging. NMI/RST is not maskable.
|
||||
Using NMI/RST as reset is dangerous because periphery may not be reseted. Has to be done in S/W.
|
||||
Drawback of using NMI/RST: Unitialized/unreseted periphery may cause trouble (e.g. firing unwanted interrupts), but I think you know that already.
|
||||
- Bootloader: Startup.S now invalidates I/D-Caches at boot.
|
||||
- uart_wb.vhd: fixed crappy tx-empty interrupt, Added Tx-IRQ acknowledge.
|
||||
- Bugfix: register bypass with same target register, used for unaligned loads (LWL, LWR), was incorrect.
|
||||
Newlib's MIPS-optimized version of memcpy() uses this for unaligned copy which revealed the bug.
|
||||
Symptom: Consecutive load instructions without nops using same target register (which is legal) like
|
||||
lw $1, 0(mem)
|
||||
lwl $1, 1(mem)
|
||||
or
|
||||
lwl $1, 0(mem)
|
||||
lwr $1, 1(mem)
|
||||
or similar, lead to incorrect result. Now it's fixed.
|
||||
|
||||
-----------------------------------------------------------------
|
||||
Changes in release 11
|
||||
-----------------------------------------------------------------
|
||||
- bugfix in mips_pipeline: pc_is_branch is now initialized at reset
|
||||
(fixes CPU unrecoverable state after reset)
|
||||
- reverted "optimization" in mips_dcache, which behaved buggy during exceptions
|
||||
- new example source: test_exception
|
||||
- minor changes in libsys
|
||||
- added async_port_timing in doc
|
||||
- examples/testbench: date set now really works
|
||||
|
||||
-----------------------------------------------------------------
|
||||
Changes in release 10b
|
||||
-----------------------------------------------------------------
|
||||
- bugfix: fixed compiler bug (missing nop after lw) in bootloader,
|
||||
which caused exception during boot
|
||||
|
||||
-----------------------------------------------------------------
|
||||
Changes in release 10a
|
||||
-----------------------------------------------------------------
|
||||
async_port_wb:
|
||||
- added byte enable for async_port
|
||||
|
||||
bootloader.c
|
||||
- bugfix: fixed compiler bug (missing nop after lw)
|
||||
|
||||
mips-core
|
||||
- bugfix: SEL_O lines are also asserted correctly during reads
|
||||
|
||||
tools/romgen
|
||||
- TCL-Jtag now compatible with Chipscope 10.1
|
||||
|
||||
mips_sys.c
|
||||
- use byte enable for sram and flash
|
||||
|
||||
|
||||
-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,107 +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
|
||||
- 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
|
||||
-----------------------------------------------------------------
|
||||
- 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
|
||||
|
||||
|
||||
@@ -1,2 +0,0 @@
|
||||
%PDF-1.3
|
||||
%庆
|
||||
Binary file not shown.
Binary file not shown.
Binary file not shown.
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,58 +0,0 @@
|
||||
## NOTE: Do not edit this file.
|
||||
##
|
||||
vlib work
|
||||
|
||||
# RAMS
|
||||
vcom -explicit -93 "../../../misc/dpram_2w2r1c_sim.vhd"
|
||||
vcom -explicit -93 "../../../misc/dpram_2w2r.vhd"
|
||||
vcom -explicit -93 "../../../misc/dpram_1w2r1c_sim.vhd"
|
||||
vcom -explicit -93 "../../../misc/dpram_1w1r.vhd"
|
||||
vcom -explicit -93 "../../../misc/dpram_1w1r1c_sim.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.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_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 4000us
|
||||
@@ -1,207 +0,0 @@
|
||||
onerror {resume}
|
||||
quietly WaveActivateNextPane {} 0
|
||||
add wave -noupdate -divider {TOP interface}
|
||||
add wave -noupdate -format Logic /tb_mips_top/nmi
|
||||
add wave -noupdate -format Logic /tb_mips_top/rst
|
||||
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 -format Literal -radix hexadecimal /tb_mips_top/uut/inst_pipeline/inst_shifter/dout
|
||||
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/inst_uart/tx_complete
|
||||
add wave -noupdate -format Logic /tb_mips_top/inst_uart/tx_empty
|
||||
add wave -noupdate -format Literal /tb_mips_top/inst_uart/uart_status_port
|
||||
add wave -noupdate -divider {Interrupt Timer}
|
||||
add wave -noupdate -format Literal -radix hexadecimal /tb_mips_top/inst_gpio/timer_cnt
|
||||
add wave -noupdate -format Literal -radix hexadecimal /tb_mips_top/inst_gpio/timer_cmp
|
||||
add wave -noupdate -format Literal /tb_mips_top/inst_gpio/timer_en
|
||||
add wave -noupdate -format Literal /tb_mips_top/inst_gpio/timer_inten
|
||||
add wave -noupdate -format Literal /tb_mips_top/inst_gpio/timer_irq
|
||||
add wave -noupdate -format Literal /tb_mips_top/inst_gpio/timer_ovl
|
||||
add wave -noupdate -format Literal /tb_mips_top/inst_gpio/timer_irq_ack
|
||||
add wave -noupdate -format Literal /tb_mips_top/inst_gpio/timer_cmp_we
|
||||
add wave -noupdate -format Literal -radix hexadecimal /tb_mips_top/inst_gpio/reg_data_wr
|
||||
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 /tb_mips_top/inst_flash_port/s
|
||||
add wave -noupdate -format Logic /tb_mips_top/inst_flash_port/ack
|
||||
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/we_o
|
||||
add wave -noupdate -format Logic /tb_mips_top/inst_flash_port/we_i_r
|
||||
add wave -noupdate -format Literal -radix hexadecimal /tb_mips_top/addr_o
|
||||
add wave -noupdate -format Literal -radix hexadecimal /tb_mips_top/inst_flash_port/addr_i_r
|
||||
add wave -noupdate -format Logic /tb_mips_top/inst_flash_port/page_mode_en
|
||||
add wave -noupdate -format Logic /tb_mips_top/inst_flash_port/rdy
|
||||
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/ack_i
|
||||
add wave -noupdate -format Logic /tb_mips_top/flash_cs_n
|
||||
add wave -noupdate -format Logic /tb_mips_top/flash_we_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 -format Literal -expand /tb_mips_top/uut/inst_pipeline/sdu
|
||||
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/pc
|
||||
add wave -noupdate -divider COP0
|
||||
add wave -noupdate -format Logic /tb_mips_top/uut/inst_cop/ir_en
|
||||
add wave -noupdate -format Literal -radix hexadecimal /tb_mips_top/uut/inst_cop/ir
|
||||
add wave -noupdate -format Literal -radix hexadecimal /tb_mips_top/uut/inst_cop/test_reg
|
||||
add wave -noupdate -format Logic /tb_mips_top/uut/inst_cop/test_reg_we
|
||||
add wave -noupdate -format Literal -radix hexadecimal /tb_mips_top/uut/inst_cop/icache_info
|
||||
add wave -noupdate -format Literal -radix hexadecimal /tb_mips_top/uut/inst_cop/dcache_info
|
||||
add wave -noupdate -format Literal -radix hexadecimal /tb_mips_top/uut/inst_cop/cop_pipe_id
|
||||
add wave -noupdate -format Literal -radix hexadecimal /tb_mips_top/uut/inst_cop/cop_pipe_ex
|
||||
add wave -noupdate -format Literal -expand /tb_mips_top/uut/inst_cop/ctrl_in
|
||||
add wave -noupdate -format Logic /tb_mips_top/uut/inst_biu/inst_icache/cpu_en
|
||||
add wave -noupdate -format Literal -radix hexadecimal /tb_mips_top/uut/inst_biu/inst_icache/cpu_addr
|
||||
add wave -noupdate -format Literal -radix hexadecimal /tb_mips_top/uut/inst_biu/inst_icache/cpu_dout
|
||||
add wave -noupdate -format Logic /tb_mips_top/uut/inst_biu/inst_icache/cpu_busy
|
||||
add wave -noupdate -format Literal -radix hexadecimal -expand /tb_mips_top/uut/inst_cop/ctrl_out
|
||||
add wave -noupdate -format Literal -radix hexadecimal /tb_mips_top/uut/inst_cop/epc
|
||||
add wave -noupdate -format Literal -radix hexadecimal /tb_mips_top/uut/inst_cop/cause
|
||||
add wave -noupdate -format Literal -radix hexadecimal /tb_mips_top/uut/inst_cop/status
|
||||
add wave -noupdate -format Literal -radix hexadecimal /tb_mips_top/uut/inst_cop/badvaddr
|
||||
add wave -noupdate -format Literal /tb_mips_top/uut/inst_cop/eflags
|
||||
add wave -noupdate -format Logic /tb_mips_top/uut/inst_cop/status_save
|
||||
add wave -noupdate -format Logic /tb_mips_top/uut/inst_cop/status_rest
|
||||
add wave -noupdate -format Logic /tb_mips_top/uut/inst_cop/stat_reg_we
|
||||
add wave -noupdate -format Literal /tb_mips_top/uut/inst_cop/exc_state
|
||||
add wave -noupdate -divider Pipestages
|
||||
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 Logic -label .stall_all /tb_mips_top/uut/inst_pipeline/sdu.stall_all
|
||||
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_run
|
||||
add wave -noupdate -format Literal -radix hexadecimal /tb_mips_top/uut/inst_pipeline/inst_reg_dual/reg_mem
|
||||
add wave -noupdate -divider I-Cache
|
||||
add wave -noupdate -format Literal -radix hexadecimal /tb_mips_top/uut/inst_biu/inst_icache/ctrl
|
||||
add wave -noupdate -format Literal -radix hexadecimal /tb_mips_top/uut/inst_biu/inst_icache/flush_count
|
||||
add wave -noupdate -format Logic /tb_mips_top/clk
|
||||
add wave -noupdate -format Logic /tb_mips_top/uut/inst_biu/inst_icache/en
|
||||
add wave -noupdate -format Logic /tb_mips_top/uut/inst_biu/inst_icache/cpu_en
|
||||
add wave -noupdate -format Literal -radix hexadecimal /tb_mips_top/uut/inst_biu/inst_icache/cpu_addr
|
||||
add wave -noupdate -format Literal -radix hexadecimal /tb_mips_top/uut/inst_biu/inst_icache/cpu_dout
|
||||
add wave -noupdate -format Logic /tb_mips_top/uut/inst_biu/inst_icache/cpu_busy
|
||||
add wave -noupdate -format Literal /tb_mips_top/uut/inst_biu/inst_icache/s
|
||||
add wave -noupdate -format Logic /tb_mips_top/uut/inst_biu/inst_icache/cache_busy
|
||||
add wave -noupdate -format Logic /tb_mips_top/uut/inst_biu/inst_icache/cache_miss
|
||||
add wave -noupdate -format Logic /tb_mips_top/uut/inst_biu/inst_icache/tag_match
|
||||
add wave -noupdate -format Literal -radix hexadecimal /tb_mips_top/uut/inst_biu/inst_icache/word_index_reg
|
||||
add wave -noupdate -format Literal -radix hexadecimal /tb_mips_top/uut/inst_biu/inst_icache/cache_index_reg
|
||||
add wave -noupdate -format Logic /tb_mips_top/uut/inst_biu/inst_icache/was_miss
|
||||
add wave -noupdate -format Literal /tb_mips_top/uut/inst_biu/inst_icache/cache_entry_out
|
||||
add wave -noupdate -format Literal /tb_mips_top/uut/inst_biu/inst_icache/request_count
|
||||
add wave -noupdate -format Literal /tb_mips_top/uut/inst_biu/inst_icache/fill_count
|
||||
add wave -noupdate -format Logic /tb_mips_top/uut/inst_biu/inst_dcache/cache_req
|
||||
add wave -noupdate -format Logic /tb_mips_top/uut/inst_biu/inst_dcache/cache_ack
|
||||
add wave -noupdate -format Literal /tb_mips_top/uut/inst_biu/inst_icache/inst_tag_ram/ram
|
||||
add wave -noupdate -format Literal /tb_mips_top/uut/inst_biu/inst_icache/inst_tag_ram/addr_a
|
||||
add wave -noupdate -format Literal /tb_mips_top/uut/inst_biu/inst_icache/inst_tag_ram/addr_b
|
||||
add wave -noupdate -format Literal /tb_mips_top/uut/inst_biu/inst_icache/inst_tag_ram/din_a
|
||||
add wave -noupdate -format Literal /tb_mips_top/uut/inst_biu/inst_icache/inst_tag_ram/din_b
|
||||
add wave -noupdate -format Literal /tb_mips_top/uut/inst_biu/inst_icache/inst_tag_ram/dout_a
|
||||
add wave -noupdate -format Literal /tb_mips_top/uut/inst_biu/inst_icache/inst_tag_ram/dout_b
|
||||
add wave -noupdate -format Logic /tb_mips_top/uut/inst_biu/inst_icache/inst_tag_ram/we_a
|
||||
add wave -noupdate -format Logic /tb_mips_top/uut/inst_biu/inst_icache/inst_tag_ram/we_b
|
||||
add wave -noupdate -format Logic /tb_mips_top/uut/inst_biu/inst_icache/inst_tag_ram/en_b
|
||||
add wave -noupdate -format Logic /tb_mips_top/uut/inst_biu/inst_icache/inst_tag_ram/en_a
|
||||
add wave -noupdate -format Logic /tb_mips_top/uut/inst_biu/inst_icache/inst_tag_ram/clk_a
|
||||
add wave -noupdate -format Logic /tb_mips_top/uut/inst_biu/inst_icache/inst_tag_ram/clk_b
|
||||
add wave -noupdate -divider D-Cache
|
||||
add wave -noupdate -format Logic /tb_mips_top/clk
|
||||
add wave -noupdate -format Literal -radix hexadecimal -expand /tb_mips_top/uut/inst_biu/inst_dcache/ctrl
|
||||
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 Logic /tb_mips_top/uut/inst_biu/dcached
|
||||
add wave -noupdate -format Logic /tb_mips_top/uut/inst_biu/inst_dcache/cpu_busy
|
||||
add wave -noupdate -format Logic /tb_mips_top/uut/inst_biu/inst_dcache/cpu_en
|
||||
add wave -noupdate -format Logic /tb_mips_top/uut/inst_biu/inst_dcache/cpu_we
|
||||
add wave -noupdate -format Logic /tb_mips_top/uut/inst_biu/inst_dcache/cache_hit
|
||||
add wave -noupdate -format Logic /tb_mips_top/uut/inst_biu/inst_dcache/cache_busy
|
||||
add wave -noupdate -format Logic /tb_mips_top/uut/inst_biu/inst_dcache/was_miss
|
||||
add wave -noupdate -format Logic /tb_mips_top/uut/inst_biu/inst_dcache/cpu_hit_we
|
||||
add wave -noupdate -format Logic /tb_mips_top/uut/inst_biu/inst_dcache/instant_raw
|
||||
add wave -noupdate -format Literal /tb_mips_top/uut/inst_biu/inst_dcache/s
|
||||
add wave -noupdate -format Literal -radix hexadecimal /tb_mips_top/uut/inst_biu/inst_dcache/cpu_addr
|
||||
add wave -noupdate -format Literal -radix hexadecimal /tb_mips_top/uut/inst_biu/inst_dcache/cpu_din
|
||||
add wave -noupdate -format Literal -radix hexadecimal /tb_mips_top/uut/inst_biu/inst_dcache/cpu_dout
|
||||
add wave -noupdate -format Literal -radix hexadecimal -expand /tb_mips_top/uut/inst_biu/inst_dcache/cache_entry_out
|
||||
add wave -noupdate -format Logic /tb_mips_top/uut/inst_biu/inst_dcache/tag_match
|
||||
add wave -noupdate -format Literal -radix hexadecimal /tb_mips_top/uut/inst_biu/inst_dcache/tag_reg
|
||||
add wave -noupdate -format Literal -radix hexadecimal /tb_mips_top/uut/inst_biu/inst_dcache/word_index_reg
|
||||
add wave -noupdate -format Literal -radix hexadecimal /tb_mips_top/uut/inst_biu/inst_dcache/addr_windex_reg
|
||||
add wave -noupdate -format Literal -radix hexadecimal /tb_mips_top/uut/inst_biu/inst_dcache/cache_index_reg
|
||||
add wave -noupdate -format Literal /tb_mips_top/uut/inst_biu/inst_dcache/fill_count
|
||||
add wave -noupdate -format Logic /tb_mips_top/uut/inst_biu/inst_dcache/fill_count_en
|
||||
add wave -noupdate -format Logic /tb_mips_top/uut/inst_biu/inst_dcache/fill_count_rdy
|
||||
add wave -noupdate -format Literal /tb_mips_top/uut/inst_biu/inst_dcache/flush_count
|
||||
add wave -noupdate -format Logic /tb_mips_top/uut/inst_biu/inst_dcache/flush_count_en
|
||||
add wave -noupdate -format Logic /tb_mips_top/uut/inst_biu/inst_dcache/flush_count_rdy
|
||||
add wave -noupdate -format Literal /tb_mips_top/uut/inst_biu/inst_dcache/request_count
|
||||
add wave -noupdate -format Logic /tb_mips_top/uut/inst_biu/inst_dcache/request_count_en
|
||||
add wave -noupdate -format Logic /tb_mips_top/uut/inst_biu/inst_dcache/request_count_rdy
|
||||
add wave -noupdate -format Literal -radix hexadecimal /tb_mips_top/uut/inst_biu/inst_dcache/cpu_data_reg
|
||||
add wave -noupdate -format Literal /tb_mips_top/uut/inst_biu/inst_dcache/cpu_be_reg
|
||||
add wave -noupdate -format Logic /tb_mips_top/uut/inst_biu/inst_dcache/cpu_we_reg
|
||||
add wave -noupdate -format Literal -radix hexadecimal /tb_mips_top/uut/inst_biu/inst_dcache/ctrl_data_ram_addr
|
||||
add wave -noupdate -format Literal /tb_mips_top/uut/inst_biu/inst_dcache/ctrl_data_ram_we
|
||||
add wave -noupdate -format Literal /tb_mips_top/uut/inst_biu/inst_dcache/cpu_data_ram_we
|
||||
add wave -noupdate -format Logic /tb_mips_top/uut/inst_biu/inst_dcache/cpu_we2
|
||||
add wave -noupdate -format Literal -radix hexadecimal /tb_mips_top/uut/inst_biu/inst_dcache/tag_ram_addr_rd
|
||||
add wave -noupdate -format Literal -radix hexadecimal /tb_mips_top/uut/inst_biu/inst_dcache/tag_ram_addr_wr
|
||||
add wave -noupdate -format Literal -radix hexadecimal /tb_mips_top/uut/inst_biu/inst_dcache/tag_ram_din
|
||||
add wave -noupdate -format Logic /tb_mips_top/uut/inst_biu/inst_dcache/tag_ram_we
|
||||
add wave -noupdate -format Literal -radix hexadecimal /tb_mips_top/uut/inst_biu/inst_dcache/cpu_tag
|
||||
add wave -noupdate -format Literal -radix hexadecimal /tb_mips_top/uut/inst_biu/inst_dcache/cpu_cache_index
|
||||
add wave -noupdate -format Literal -radix hexadecimal /tb_mips_top/uut/inst_biu/inst_dcache/cpu_word_index
|
||||
TreeUpdate [SetDefaultTree]
|
||||
WaveRestoreCursors {{Cursor 1} {944616660 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 {944394558 ps} {945180650 ps}
|
||||
@@ -1,68 +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_leadin => 1,
|
||||
ncyc_pulse_rd => 12,
|
||||
ncyc_pulse_wr => 7,
|
||||
ncyc_leadout => 2,
|
||||
ncyc_release => 3,
|
||||
ncyc_pulse_rst => 8,
|
||||
can_page_rd => true,
|
||||
nbits_page_rd => 4,
|
||||
ncyc_pulse_page_rd => 6,
|
||||
pol_cs => '0',
|
||||
pol_oe => '0',
|
||||
pol_we => '0',
|
||||
pol_be => '0',
|
||||
pol_rst => '0'
|
||||
);
|
||||
|
||||
constant ts_sram : async_timespec_t :=
|
||||
(
|
||||
ncyc_leadin => 1,
|
||||
ncyc_pulse_rd => 12,
|
||||
ncyc_pulse_wr => 7,
|
||||
ncyc_leadout => 1,
|
||||
ncyc_release => 1,
|
||||
ncyc_pulse_rst => 8,
|
||||
can_page_rd => false,
|
||||
nbits_page_rd => 0,
|
||||
ncyc_pulse_page_rd => 0,
|
||||
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,496 +0,0 @@
|
||||
LIBRARY IEEE;
|
||||
USE IEEE.STD_LOGIC_1164.ALL;
|
||||
USE IEEE.NUMERIC_STD.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;
|
||||
ctrl : in cache_ctrl_t;
|
||||
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;
|
||||
|
||||
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 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 : tag_ram_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_tag_ram_data(x : dcache_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, invalidate, flush, mem_request, mem_access, mem_data, rd_cache);
|
||||
signal s, sn : cache_state_t;
|
||||
|
||||
signal cache_req : std_logic;
|
||||
signal cache_ack : std_logic;
|
||||
signal cache_busy : std_logic;
|
||||
signal cache_hit : std_logic;
|
||||
signal tag_match : std_logic;
|
||||
signal cache_hit_inv : std_logic;
|
||||
signal tag_match_inv : 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 cache_index_inv : unsigned(cache_index_width-1 downto 0);
|
||||
signal tag_reg : unsigned(tag_width-1 downto 0);
|
||||
signal tag_inv : unsigned(tag_width-1 downto 0);
|
||||
signal tag_reg_inv : unsigned(tag_width-1 downto 0);
|
||||
|
||||
signal cache_entry_in : dcache_entry_t;
|
||||
signal cache_entry_out : dcache_entry_t;
|
||||
signal cache_entry_out_inv : dcache_entry_t;
|
||||
signal cpu_data_ram_addr : unsigned(lg2(cache_size)-1 downto 0);
|
||||
signal cpu_data_ram_dout : word_t;
|
||||
signal cpu_data_reg : word_t;
|
||||
signal cpu_be_reg : unsigned(3 downto 0);
|
||||
signal cpu_we_reg : std_logic;
|
||||
signal ctrl_data_ram_addr : unsigned(lg2(cache_size)-1 downto 0);
|
||||
signal ctrl_data_ram_we : unsigned(3 downto 0);
|
||||
signal cpu_data_ram_we : unsigned(3 downto 0);
|
||||
signal cpu_we2 : std_logic;
|
||||
|
||||
signal tag_ram_addr_rd : unsigned(cache_index_width-1 downto 0);
|
||||
signal tag_ram_dout : tag_ram_data_t;
|
||||
signal tag_ram_dout_inv : tag_ram_data_t;
|
||||
signal tag_ram_addr_wr : unsigned(cache_index_width-1 downto 0);
|
||||
signal tag_ram_din : tag_ram_data_t;
|
||||
signal tag_ram_we : std_logic;
|
||||
|
||||
signal fill_count : natural range 0 to 2**word_index_width-1;
|
||||
signal fill_count_en : std_logic;
|
||||
signal fill_count_rdy : std_logic;
|
||||
signal flush_count : natural range 0 to 2**cache_index_width-1;
|
||||
signal flush_count_rst : std_logic;
|
||||
signal flush_count_en : std_logic;
|
||||
signal flush_count_rdy : std_logic;
|
||||
signal request_count : natural range 0 to 2**word_index_width-1;
|
||||
signal request_count_en : std_logic;
|
||||
signal request_count_rdy : std_logic;
|
||||
signal was_miss : std_logic;
|
||||
signal invalidate_all : std_logic;
|
||||
signal invalidate_ack : std_logic;
|
||||
signal invalidate_en : std_logic;
|
||||
signal invalidate_req : std_logic;
|
||||
signal cpu_hit_we : std_logic;
|
||||
signal instant_raw : std_logic;
|
||||
|
||||
begin
|
||||
|
||||
cache_index_inv <= ctrl.inv_addr(cache_index_width+word_index_width+1 downto word_index_width+2);
|
||||
tag_inv <= ctrl.inv_addr(tag_width+cache_index_width+word_index_width+1 downto cache_index_width+word_index_width+2);
|
||||
|
||||
cpu_hit_we <= cpu_we2 and cache_hit;
|
||||
|
||||
cpu_index_register:
|
||||
process(CLK_I)
|
||||
begin
|
||||
if rising_edge(CLK_I) then
|
||||
if fill_count_en = '1' then
|
||||
if ACK_I = '1' then
|
||||
word_index_reg <= word_index_reg + 1;
|
||||
end if;
|
||||
elsif cache_busy = '0' then
|
||||
word_index_reg <= cpu_word_index;
|
||||
cache_index_reg <= cpu_cache_index;
|
||||
tag_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'then
|
||||
if SRDY_I = '1' then
|
||||
addr_windex_reg <= addr_windex_reg + 1;
|
||||
end if;
|
||||
elsif cache_busy = '0' then
|
||||
addr_windex_reg <= cpu_word_index;
|
||||
end if;
|
||||
end if;
|
||||
end process;
|
||||
|
||||
cpu_request_register:
|
||||
process(CLK_I)
|
||||
begin
|
||||
if rising_edge(CLK_I) then
|
||||
if RST_I = '1' then
|
||||
cpu_we_reg <= '0';
|
||||
cache_req <= '0';
|
||||
elsif cpu_en = '1' and en = '1' then
|
||||
if cache_busy = '0' then
|
||||
cpu_we2 <= cpu_we;
|
||||
cache_req <= '1';
|
||||
cpu_data_reg <= cpu_din;
|
||||
cpu_be_reg <= cpu_be;
|
||||
cpu_we_reg <= cpu_we;
|
||||
end if;
|
||||
elsif cache_ack = '1' then
|
||||
cache_req <= '0';
|
||||
cpu_we2 <= '0';
|
||||
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_2w2r
|
||||
GENERIC MAP
|
||||
(
|
||||
addr_width => tag_ram_addr_width,
|
||||
data_width => tag_ram_data_width
|
||||
)
|
||||
PORT MAP
|
||||
(
|
||||
clk_a => CLK_I,
|
||||
clk_b => CLK_I,
|
||||
en_a => '1',
|
||||
en_b => '1',
|
||||
we_a => tag_ram_we,
|
||||
we_b => '0',
|
||||
addr_a => tag_ram_addr_wr,
|
||||
addr_b => tag_ram_addr_rd,
|
||||
din_a => tag_ram_din,
|
||||
din_b => tag_ram_din,
|
||||
dout_a => tag_ram_dout_inv,
|
||||
dout_b => tag_ram_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_data_ram_we(i),
|
||||
we_b => ctrl_data_ram_we(i),
|
||||
addr_a => ctrl_data_ram_addr,
|
||||
addr_b => cpu_data_ram_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_data_ram_dout(8*(i+1)-1 downto 8*i)
|
||||
);
|
||||
end generate;
|
||||
|
||||
|
||||
|
||||
cache_invalidate_request:
|
||||
process(CLK_I)
|
||||
begin
|
||||
if rising_edge(CLK_I) then
|
||||
if RST_I = '1' or ctrl.inv_all = '1' or ctrl.inv_at = '1' then
|
||||
invalidate_req <= '1';
|
||||
invalidate_all <= ctrl.inv_all or RST_I;
|
||||
tag_reg_inv <= tag_inv;
|
||||
elsif invalidate_ack = '1' then
|
||||
invalidate_req <= '0';
|
||||
invalidate_all <= '0';
|
||||
end if;
|
||||
end if;
|
||||
end process;
|
||||
|
||||
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 <= cpu_data_ram_dout;
|
||||
|
||||
tag_match <= '1' when tag_reg = cache_entry_out.tag else '0';
|
||||
cache_hit <= tag_match and cache_entry_out.valid;
|
||||
tag_match_inv <= '1' when tag_reg_inv = cache_entry_out_inv.tag else '0';
|
||||
cache_hit_inv <= tag_match_inv and cache_entry_out_inv.valid;
|
||||
tag_ram_din <= to_tag_ram_data(cache_entry_in);
|
||||
tag_ram_addr_wr <= to_unsigned(flush_count, cache_index_width) when invalidate_en = '1' else cache_index_reg;
|
||||
tag_ram_addr_rd <= cpu_cache_index when (was_miss = '0' and instant_raw = '0') else cache_index_reg;
|
||||
|
||||
cache_entry_out <= to_dcache_entry(tag_ram_dout);
|
||||
cache_entry_out_inv <= to_dcache_entry(tag_ram_dout_inv);
|
||||
|
||||
cpu_data_ram_addr <= (cpu_cache_index & cpu_word_index) when (was_miss = '0' and instant_raw = '0' and fill_count_en = '0') else (cache_index_reg & word_index_reg);
|
||||
ADDR_O <= tag_reg & cache_index_reg & addr_windex_reg & "00";
|
||||
ctrl_data_ram_addr <= cache_index_reg & word_index_reg;
|
||||
ctrl_data_ram_we <= (others => fill_count_en and ACK_I);
|
||||
cpu_data_ram_we <= cpu_be_reg when (cpu_hit_we = '1') else (others => '0');
|
||||
|
||||
cache_state:
|
||||
process(s, cache_req, instant_raw, cache_hit, cache_hit_inv, flush_count_rdy, fill_count_rdy, request_count_rdy, tag_reg, SRDY_I, cpu_we_reg, invalidate_req, invalidate_all)
|
||||
begin
|
||||
cache_busy <= cache_req;
|
||||
cache_ack <= '0';
|
||||
tag_ram_we <= '0';
|
||||
flush_count_en <= '0';
|
||||
flush_count_rst <= '0';
|
||||
invalidate_en <= '0';
|
||||
request_count_en <= '0';
|
||||
fill_count_en <= '0';
|
||||
CYC_O <= '0';
|
||||
STB_O <= '0';
|
||||
was_miss <= '0';
|
||||
invalidate_ack <= '0';
|
||||
|
||||
cache_entry_in.tv_p <= (others => '0');
|
||||
cache_entry_in.tag <= tag_reg;
|
||||
cache_entry_in.valid <= '0';
|
||||
sn <= s;
|
||||
|
||||
case s is
|
||||
when init =>
|
||||
sn <= ready;
|
||||
when ready =>
|
||||
if invalidate_req = '1' then
|
||||
sn <= invalidate;
|
||||
invalidate_en <= '1';
|
||||
else
|
||||
if cache_req = '1' then
|
||||
if cache_hit = '0' and cpu_we_reg = '0' then
|
||||
sn <= mem_request;
|
||||
cache_busy <= '1';
|
||||
CYC_O <= '1';
|
||||
else
|
||||
cache_busy <= instant_raw;
|
||||
cache_ack <= not instant_raw;
|
||||
end if;
|
||||
end if;
|
||||
end if;
|
||||
when invalidate =>
|
||||
sn <= rd_cache;
|
||||
invalidate_en <= '1';
|
||||
invalidate_ack <= '1';
|
||||
if invalidate_all = '1' then
|
||||
sn <= flush;
|
||||
flush_count_rst <= '1';
|
||||
elsif cache_hit_inv = '1' then
|
||||
tag_ram_we <= '1';
|
||||
cache_entry_in.valid <= '0';
|
||||
cache_entry_in.tag <= (others => '0');
|
||||
sn <= rd_cache;
|
||||
end if;
|
||||
|
||||
when flush =>
|
||||
flush_count_en <= '1';
|
||||
invalidate_en <= '1';
|
||||
tag_ram_we <= '1';
|
||||
cache_entry_in.valid <= '0';
|
||||
cache_entry_in.tag <= (others => '0');
|
||||
if flush_count_rdy = '1' then
|
||||
tag_ram_we <= '0';
|
||||
sn <= rd_cache;
|
||||
end if;
|
||||
when mem_request =>
|
||||
CYC_O <= '1';
|
||||
if SRDY_I = '1' then
|
||||
sn <= mem_access;
|
||||
end if;
|
||||
when mem_access =>
|
||||
fill_count_en <= '1';
|
||||
request_count_en <= '1';
|
||||
CYC_O <= '1';
|
||||
STB_O <= '1';
|
||||
if request_count_rdy = '1' then
|
||||
STB_O <= '0';
|
||||
sn <= mem_data;
|
||||
end if;
|
||||
when mem_data =>
|
||||
CYC_O <= '1';
|
||||
fill_count_en <= '1';
|
||||
if fill_count_rdy = '1' then
|
||||
tag_ram_we <= '1';
|
||||
cache_entry_in.valid <= '1';
|
||||
sn <= rd_cache;
|
||||
end if;
|
||||
when rd_cache =>
|
||||
was_miss <= '1';
|
||||
sn <= ready;
|
||||
|
||||
when others =>
|
||||
sn <= ready;
|
||||
end case;
|
||||
|
||||
end process;
|
||||
|
||||
flush_counter:
|
||||
process(CLK_I)
|
||||
begin
|
||||
if rising_edge(CLK_I) then
|
||||
if ctrl.inv_at = '1' then
|
||||
flush_count <= to_integer(cache_index_inv);
|
||||
elsif flush_count_rst = '1' then
|
||||
flush_count_rdy <= '0';
|
||||
flush_count <= 2**cache_index_width-1;
|
||||
elsif flush_count_en = '1' then
|
||||
if flush_count /= 0 then
|
||||
flush_count <= flush_count - 1;
|
||||
else
|
||||
flush_count_rdy <= '1';
|
||||
end if;
|
||||
end if;
|
||||
end if;
|
||||
end process;
|
||||
|
||||
request_counter:
|
||||
process(CLK_I)
|
||||
begin
|
||||
if rising_edge(CLK_I) then
|
||||
if request_count_en = '0' then
|
||||
request_count_rdy <= '0';
|
||||
request_count <= 2**word_index_width-1;
|
||||
else
|
||||
if SRDY_I = '1' then
|
||||
if request_count /= 0 then
|
||||
request_count <= request_count - 1;
|
||||
else
|
||||
request_count_rdy <= '1';
|
||||
end if;
|
||||
end if;
|
||||
end if;
|
||||
end if;
|
||||
end process;
|
||||
|
||||
fill_counter:
|
||||
process(CLK_I)
|
||||
begin
|
||||
if rising_edge(CLK_I) then
|
||||
if fill_count_en = '0' then
|
||||
fill_count_rdy <= '0';
|
||||
fill_count <= 2**word_index_width-1;
|
||||
else
|
||||
if ACK_I = '1' then
|
||||
if fill_count /= 0 then
|
||||
fill_count <= fill_count - 1;
|
||||
else
|
||||
fill_count_rdy <= '1';
|
||||
end if;
|
||||
end if;
|
||||
end if;
|
||||
end if;
|
||||
end process;
|
||||
|
||||
end behavior;
|
||||
@@ -1,460 +0,0 @@
|
||||
LIBRARY IEEE;
|
||||
USE IEEE.STD_LOGIC_1164.ALL;
|
||||
USE IEEE.NUMERIC_STD.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;
|
||||
ctrl : in cache_ctrl_t;
|
||||
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;
|
||||
|
||||
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;
|
||||
|
||||
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, invalidate, flush, mem_request, mem_access, mem_data, rd_cache, upd_cache);
|
||||
signal s, sn : cache_state_t;
|
||||
|
||||
signal cache_req : std_logic;
|
||||
signal cache_ack : std_logic;
|
||||
signal cache_busy : std_logic;
|
||||
signal cache_miss : std_logic;
|
||||
signal tag_match : std_logic;
|
||||
signal cache_miss_inv : std_logic;
|
||||
signal tag_match_inv : 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 cache_index_inv : unsigned(cache_index_width-1 downto 0);
|
||||
signal tag_reg : unsigned(tag_width-1 downto 0);
|
||||
signal tag_inv : unsigned(tag_width-1 downto 0);
|
||||
signal tag_reg_inv : unsigned(tag_width-1 downto 0);
|
||||
|
||||
signal cache_entry_in : icache_entry_t;
|
||||
signal cache_entry_out : icache_entry_t;
|
||||
signal cache_entry_out_inv : 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 tag_ram_addr_rd : unsigned(cache_index_width-1 downto 0);
|
||||
signal tag_ram_data_rd : tag_ram_data_t;
|
||||
signal tag_ram_data_rd_inv : 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 fill_count : natural range 0 to 2**word_index_width-1;
|
||||
signal fill_count_en : std_logic;
|
||||
signal fill_count_rdy : std_logic;
|
||||
signal flush_count : natural range 0 to 2**cache_index_width-1;
|
||||
signal flush_count_rst : std_logic;
|
||||
signal flush_count_en : std_logic;
|
||||
signal flush_count_rdy : std_logic;
|
||||
signal request_count : natural range 0 to 2**word_index_width-1;
|
||||
signal request_count_en : std_logic;
|
||||
signal request_count_rdy : std_logic;
|
||||
signal ram_read_en : std_logic;
|
||||
signal was_miss : std_logic;
|
||||
signal invalidate_all : std_logic;
|
||||
signal invalidate_ack : std_logic;
|
||||
signal invalidate_en : std_logic;
|
||||
signal invalidate_req : std_logic;
|
||||
|
||||
begin
|
||||
|
||||
ram_read_en <= cpu_en or was_miss;
|
||||
cache_index_inv <= ctrl.inv_addr(cache_index_width+word_index_width+1 downto word_index_width+2);
|
||||
tag_inv <= ctrl.inv_addr(tag_width+cache_index_width+word_index_width+1 downto cache_index_width+word_index_width+2);
|
||||
|
||||
|
||||
cpu_index_reg:
|
||||
process(CLK_I)
|
||||
begin
|
||||
if rising_edge(CLK_I) then
|
||||
if RST_I = '1' then
|
||||
cache_index_reg <= (others => '0');
|
||||
tag_reg <= (others => '0');
|
||||
elsif fill_count_en = '1' then
|
||||
if ACK_I = '1' then
|
||||
word_index_reg <= word_index_reg + 1;
|
||||
end if;
|
||||
elsif cache_busy = '0' then
|
||||
word_index_reg <= cpu_word_index;
|
||||
cache_index_reg <= cpu_cache_index;
|
||||
tag_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'then
|
||||
if SRDY_I = '1' then
|
||||
addr_windex_reg <= addr_windex_reg + 1;
|
||||
end if;
|
||||
elsif cache_busy = '0' then
|
||||
addr_windex_reg <= cpu_word_index;
|
||||
end if;
|
||||
end if;
|
||||
end process;
|
||||
|
||||
cpu_request_register:
|
||||
process(CLK_I)
|
||||
begin
|
||||
if rising_edge(CLK_I) then
|
||||
if RST_I = '1' then
|
||||
cache_req <= '0';
|
||||
elsif cpu_en = '1' then
|
||||
if cache_busy = '0' then
|
||||
cache_req <= en;
|
||||
end if;
|
||||
elsif cache_ack = '1' then
|
||||
cache_req <= '0';
|
||||
end if;
|
||||
end if;
|
||||
end process;
|
||||
|
||||
cache_invalidate_request:
|
||||
process(CLK_I)
|
||||
begin
|
||||
if rising_edge(CLK_I) then
|
||||
if RST_I = '1' or ctrl.inv_all = '1' or ctrl.inv_at = '1' then
|
||||
invalidate_req <= '1';
|
||||
invalidate_all <= ctrl.inv_all or RST_I;
|
||||
tag_reg_inv <= tag_inv;
|
||||
elsif invalidate_ack = '1' then
|
||||
invalidate_req <= '0';
|
||||
invalidate_all <= '0';
|
||||
end if;
|
||||
end if;
|
||||
end process;
|
||||
|
||||
inst_tag_ram : dpram_2w2r
|
||||
GENERIC MAP
|
||||
(
|
||||
addr_width => tag_ram_addr_width,
|
||||
data_width => tag_ram_data_width
|
||||
)
|
||||
PORT MAP
|
||||
(
|
||||
clk_a => CLK_I,
|
||||
clk_b => CLK_I,
|
||||
en_a => '1',
|
||||
en_b => ram_read_en,
|
||||
we_a => tag_ram_we,
|
||||
we_b => '0',
|
||||
addr_a => tag_ram_addr_wr,
|
||||
addr_b => tag_ram_addr_rd,
|
||||
din_a => tag_ram_data_wr,
|
||||
din_b => tag_ram_data_wr,
|
||||
dout_a => tag_ram_data_rd_inv,
|
||||
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 => ram_read_en,
|
||||
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;
|
||||
|
||||
ADDR_O <= tag_reg & cache_index_reg & addr_windex_reg & "00";
|
||||
cpu_busy <= cache_busy;
|
||||
cpu_dout <= data_ram_data_rd;
|
||||
|
||||
cache_entry_out <= to_icache_entry(tag_ram_data_rd);
|
||||
tag_match <= '1' when tag_reg = cache_entry_out.tag else '0';
|
||||
cache_miss <= not (tag_match and cache_entry_out.valid);
|
||||
|
||||
cache_entry_out_inv <= to_icache_entry(tag_ram_data_rd_inv);
|
||||
tag_match_inv <= '1' when tag_reg_inv = cache_entry_out_inv.tag else '0';
|
||||
cache_miss_inv <= not (tag_match_inv and cache_entry_out_inv.valid);
|
||||
|
||||
tag_ram_data_wr <= to_tag_ram_data(cache_entry_in);
|
||||
tag_ram_addr_wr <= to_unsigned(flush_count, cache_index_width) when invalidate_en = '1' else cache_index_reg;
|
||||
tag_ram_addr_rd <= cpu_cache_index when was_miss = '0' else cache_index_reg;
|
||||
data_ram_addr_rd <= (cpu_cache_index & cpu_word_index) when was_miss = '0' else (cache_index_reg & word_index_reg);
|
||||
data_ram_addr_wr <= cache_index_reg & word_index_reg;
|
||||
data_ram_data_wr <= DAT_I;
|
||||
data_ram_we <= fill_count_en and ACK_I;
|
||||
|
||||
cache_state:
|
||||
process(s, cache_req, cache_miss, cache_miss_inv, flush_count_rdy, fill_count_rdy, request_count_rdy, tag_reg, SRDY_I, invalidate_req, invalidate_all)
|
||||
begin
|
||||
cache_busy <= cache_req;
|
||||
cache_ack <= '0';
|
||||
tag_ram_we <= '0';
|
||||
flush_count_en <= '0';
|
||||
flush_count_rst <= '0';
|
||||
invalidate_en <= '0';
|
||||
request_count_en <= '0';
|
||||
fill_count_en <= '0';
|
||||
CYC_O <= '0';
|
||||
STB_O <= '0';
|
||||
was_miss <= '0';
|
||||
invalidate_ack <= '0';
|
||||
|
||||
cache_entry_in.tv_p <= (others => '0');
|
||||
cache_entry_in.tag <= tag_reg;
|
||||
cache_entry_in.valid <= '0';
|
||||
sn <= s;
|
||||
|
||||
case s is
|
||||
when init =>
|
||||
sn <= ready;
|
||||
when ready =>
|
||||
if invalidate_req = '1' then
|
||||
sn <= invalidate;
|
||||
invalidate_en <= '1';
|
||||
elsif cache_req = '1' then
|
||||
if cache_miss = '1' then
|
||||
sn <= mem_request;
|
||||
CYC_O <= '1';
|
||||
else
|
||||
cache_busy <= '0';
|
||||
cache_ack <= '1';
|
||||
end if;
|
||||
end if;
|
||||
when invalidate =>
|
||||
sn <= rd_cache;
|
||||
invalidate_en <= '1';
|
||||
invalidate_ack <= '1';
|
||||
if invalidate_all = '1' then
|
||||
sn <= flush;
|
||||
flush_count_rst <= '1';
|
||||
elsif cache_miss_inv = '0' then
|
||||
tag_ram_we <= '1';
|
||||
cache_entry_in.valid <= '0';
|
||||
cache_entry_in.tag <= (others => '0');
|
||||
sn <= rd_cache;
|
||||
end if;
|
||||
|
||||
when flush =>
|
||||
flush_count_en <= '1';
|
||||
invalidate_en <= '1';
|
||||
tag_ram_we <= '1';
|
||||
cache_entry_in.valid <= '0';
|
||||
cache_entry_in.tag <= (others => '0');
|
||||
if flush_count_rdy = '1' then
|
||||
tag_ram_we <= '0';
|
||||
sn <= rd_cache;
|
||||
end if;
|
||||
when mem_request =>
|
||||
CYC_O <= '1';
|
||||
if SRDY_I = '1' then
|
||||
sn <= mem_access;
|
||||
end if;
|
||||
when mem_access =>
|
||||
request_count_en <= '1';
|
||||
fill_count_en <= '1';
|
||||
CYC_O <= '1';
|
||||
STB_O <= '1';
|
||||
if request_count_rdy = '1' then
|
||||
STB_O <= '0';
|
||||
sn <= mem_data;
|
||||
end if;
|
||||
when mem_data =>
|
||||
CYC_O <= '1';
|
||||
fill_count_en <= '1';
|
||||
if fill_count_rdy = '1' then
|
||||
tag_ram_we <= '1';
|
||||
cache_entry_in.valid <= '1';
|
||||
sn <= rd_cache;
|
||||
end if;
|
||||
when rd_cache =>
|
||||
was_miss <= '1';
|
||||
sn <= ready;
|
||||
when others =>
|
||||
sn <= ready;
|
||||
end case;
|
||||
|
||||
end process;
|
||||
|
||||
flush_counter:
|
||||
process(CLK_I)
|
||||
begin
|
||||
if rising_edge(CLK_I) then
|
||||
if ctrl.inv_at = '1' then
|
||||
flush_count <= to_integer(cache_index_inv);
|
||||
elsif flush_count_rst = '1' then
|
||||
flush_count_rdy <= '0';
|
||||
flush_count <= 2**cache_index_width-1;
|
||||
elsif flush_count_en = '1' then
|
||||
if flush_count /= 0 then
|
||||
flush_count <= flush_count - 1;
|
||||
else
|
||||
flush_count_rdy <= '1';
|
||||
end if;
|
||||
end if;
|
||||
end if;
|
||||
end process;
|
||||
|
||||
request_counter:
|
||||
process(CLK_I)
|
||||
begin
|
||||
if rising_edge(CLK_I) then
|
||||
if request_count_en = '0' then
|
||||
request_count_rdy <= '0';
|
||||
request_count <= 2**word_index_width-1;
|
||||
else
|
||||
if SRDY_I = '1' then
|
||||
if request_count /= 0 then
|
||||
request_count <= request_count - 1;
|
||||
else
|
||||
request_count_rdy <= '1';
|
||||
end if;
|
||||
end if;
|
||||
end if;
|
||||
end if;
|
||||
end process;
|
||||
|
||||
fill_counter:
|
||||
process(CLK_I)
|
||||
begin
|
||||
if rising_edge(CLK_I) then
|
||||
if fill_count_en = '0' then
|
||||
fill_count_rdy <= '0';
|
||||
fill_count <= 2**word_index_width-1;
|
||||
else
|
||||
if ACK_I = '1' then
|
||||
if fill_count /= 0 then
|
||||
fill_count <= fill_count - 1;
|
||||
else
|
||||
fill_count_rdy <= '1';
|
||||
end if;
|
||||
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,507 +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
|
||||
icache_line : natural := 8; -- words
|
||||
dcache_size : natural := 2048; -- words
|
||||
dcache_line : 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 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;
|
||||
cop0_ctrl_in : in cop0_ctrl_out_t;
|
||||
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;
|
||||
ctrl : in cache_ctrl_t;
|
||||
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;
|
||||
ctrl : in cache_ctrl_t;
|
||||
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 => icache_line -- words
|
||||
)
|
||||
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,
|
||||
ctrl => cop0_ctrl_in.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 => dcache_line -- words
|
||||
)
|
||||
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,
|
||||
ctrl => cop0_ctrl_in.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 29) /= "101" else '0';
|
||||
cpu_dmem_din <= dcache_dout when uncached_access = '0' else DAT_I_dmem_rd;
|
||||
dcache_en <= cpu_dmem_en; -- and not (CYC_O_dmem_rd or write_busy);-- and not busy;
|
||||
|
||||
-- Instantiate synchronous FIFO
|
||||
inst_bout_fifo: entity work.fifo_sync
|
||||
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
|
||||
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,546 +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
|
||||
Generic
|
||||
(
|
||||
icache_size : natural := 2048; -- words
|
||||
icache_line : natural := 8; -- words
|
||||
dcache_size : natural := 2048; -- words
|
||||
dcache_line : natural := 8 -- words
|
||||
);
|
||||
Port
|
||||
(
|
||||
rst : in STD_LOGIC;
|
||||
clk : in STD_LOGIC;
|
||||
eb : in STD_LOGIC;
|
||||
int : in unsigned(5 downto 0);
|
||||
nmi : in STD_LOGIC;
|
||||
ir_en : in STD_LOGIC;
|
||||
ir : in word_t;
|
||||
ctrl_in : in cop0_ctrl_in_t;
|
||||
ctrl_out : out cop0_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 imem_addr : word_t;
|
||||
signal imem_addr_we : STD_LOGIC;
|
||||
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 sw_int : unsigned(1 downto 0);
|
||||
signal ip : unsigned(7 downto 0);
|
||||
signal im : unsigned(7 downto 0);
|
||||
signal status_save : STD_LOGIC;
|
||||
signal status_rest : STD_LOGIC;
|
||||
signal eflags : exc_flags_t;
|
||||
signal EB_reg : STD_LOGIC;
|
||||
signal icache_info : unsigned(7 downto 0);
|
||||
signal dcache_info : unsigned(7 downto 0);
|
||||
signal reg_rptr : reg_ptr_t;
|
||||
signal reg_wptr : reg_ptr_t;
|
||||
signal inject_exc : STD_LOGIC;
|
||||
signal latch_vect_en : STD_LOGIC;
|
||||
signal int_nmi : STD_LOGIC;
|
||||
signal nmi_asserted : std_logic;
|
||||
|
||||
type cop_pipe_t is record
|
||||
opc : opcode_t;
|
||||
RFE : std_logic;
|
||||
CO : std_logic;
|
||||
reg_ptr : reg_ptr_t;
|
||||
rs : reg_ptr_t;
|
||||
rd : reg_ptr_t;
|
||||
rt : 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_idle, exc_pipe_flush, exc_commit, exc_inject, exc_enter, exc_leave, exc_left);
|
||||
signal exc_state, exc_staten : exc_state_t;
|
||||
|
||||
--------------------------------------------------------------------------
|
||||
begin
|
||||
|
||||
icache_info <= "00" & to_unsigned(lg2(icache_line), 3) & to_unsigned(lg2(icache_size)-8, 3);
|
||||
dcache_info <= "00" & to_unsigned(lg2(dcache_line), 3) & to_unsigned(lg2(dcache_size)-8, 3);
|
||||
cop_pipe_ID.cs <= ir_en;
|
||||
cop_pipe_ID.opc <= extract_opc(ir);
|
||||
cop_pipe_ID.rs <= extract_rs(ir);
|
||||
cop_pipe_ID.rd <= extract_rd(ir);
|
||||
cop_pipe_ID.rt <= extract_rt(ir);
|
||||
cop_pipe_ID.func <= extract_func(ir);
|
||||
cop_pipe_ID.CO <= ir(25);
|
||||
cop_pipe_ID.re <= cop_pipe_ID.cs when (cop_pipe_ID.opc = "111000" or (cop_pipe_ID.opc = "010000" and cop_pipe_ID.rs = "00000")) else '0';
|
||||
cop_pipe_ID.we <= cop_pipe_ID.cs when (cop_pipe_ID.opc = "110000" or (cop_pipe_ID.opc = "010000" and cop_pipe_ID.rs = "00100")) else '0';
|
||||
cop_pipe_ID.RFE <= cop_pipe_ID.cs when (cop_pipe_ID.CO = '1' and cop_pipe_ID.func = "010000") else '0';
|
||||
ctrl_out.EB <= EB_reg xor (status(25) and status(1));
|
||||
ctrl_out.user_mode <= status(1);
|
||||
ctrl_out.exc_inject <= inject_exc or rst;
|
||||
cop_pipe_ID.reg_ptr <= cop_pipe_ID.rd when cop_pipe_ID.opc = "010000" else cop_pipe_ID.rt;
|
||||
|
||||
im <= status(15 downto 8);
|
||||
cause <= bd & (30 downto 16 => '0') & ip & '0' & exc_code & "00";
|
||||
|
||||
eflags.Ov <= ctrl_in.events.alu_ovf or ctrl_in.events.alu_uvf;
|
||||
eflags.DAdEL <= ctrl_in.events.data_load_err;
|
||||
eflags.DAdES <= ctrl_in.events.data_store_err;
|
||||
eflags.IAdEL <= ctrl_in.events.inst_load_err;
|
||||
eflags.IAdEK <= ctrl_in.events.inst_priv_addr and status(1);
|
||||
eflags.Sys <= ctrl_in.events.syscall;
|
||||
eflags.Bp <= ctrl_in.events.break;
|
||||
eflags.RI <= ctrl_in.events.illegal;
|
||||
eflags.Int <= ctrl_in.events.int;
|
||||
|
||||
-- NMI/RST transition detector
|
||||
proc_nmi_transition:
|
||||
process(clk)
|
||||
begin
|
||||
if rising_edge(clk) then
|
||||
if rst = '1' then
|
||||
int_nmi <= '0';
|
||||
nmi_asserted <= '0';
|
||||
elsif latch_vect_en = '1' then
|
||||
int_nmi <= '0';
|
||||
elsif nmi_asserted = '1' then
|
||||
if nmi = '0' then
|
||||
nmi_asserted <= '0';
|
||||
int_nmi <= '1';
|
||||
end if;
|
||||
elsif nmi = '1' then
|
||||
nmi_asserted <= '1';
|
||||
end if;
|
||||
end if;
|
||||
end process;
|
||||
|
||||
|
||||
-- Main exception FSM
|
||||
proc_exc_state:
|
||||
process(exc_state, ctrl_in, cop_pipe_ID)
|
||||
begin
|
||||
|
||||
ctrl_out.exc_commit <= '0';
|
||||
ctrl_out.exc_pending <= '0';
|
||||
ctrl_out.exc_exit <= '0';
|
||||
epc_reg_we <= '0';
|
||||
code_reg_we <= '0';
|
||||
status_save <= '0';
|
||||
status_rest <= '0';
|
||||
inject_exc <= '0';
|
||||
imem_addr_we <= '0';
|
||||
latch_vect_en <= '0';
|
||||
|
||||
exc_staten <= exc_state;
|
||||
|
||||
case exc_state is
|
||||
|
||||
when exc_idle =>
|
||||
if cop_pipe_ID.RFE = '1' then
|
||||
exc_staten <= exc_leave;
|
||||
ctrl_out.exc_exit <= '1';
|
||||
ctrl_out.exc_commit <= '1';
|
||||
elsif ctrl_in.exc_req = '1' then
|
||||
exc_staten <= exc_pipe_flush;
|
||||
imem_addr_we <= '1';
|
||||
end if;
|
||||
|
||||
when exc_pipe_flush =>
|
||||
ctrl_out.exc_pending <= '1';
|
||||
ctrl_out.exc_commit <= '1';
|
||||
if ctrl_in.exc_ack = '1' then
|
||||
exc_staten <= exc_commit;
|
||||
end if;
|
||||
|
||||
when exc_commit =>
|
||||
latch_vect_en <= '1';
|
||||
ctrl_out.exc_pending <= '1';
|
||||
ctrl_out.exc_commit <= '1';
|
||||
if ctrl_in.sdu.ID_stall = '0' then
|
||||
exc_staten <= exc_inject;
|
||||
end if;
|
||||
|
||||
when exc_inject =>
|
||||
ctrl_out.exc_pending <= '1';
|
||||
ctrl_out.exc_commit <= '1';
|
||||
code_reg_we <= '1';
|
||||
status_save <= '1';
|
||||
epc_reg_we <= '1';
|
||||
inject_exc <= '1';
|
||||
exc_staten <= exc_enter;
|
||||
|
||||
when exc_enter =>
|
||||
ctrl_out.exc_pending <= '1';
|
||||
exc_staten <= exc_idle;
|
||||
|
||||
when exc_leave =>
|
||||
exc_staten <= exc_left;
|
||||
status_rest <= '1';
|
||||
ctrl_out.exc_exit <= '1';
|
||||
ctrl_out.exc_commit <= '1';
|
||||
|
||||
when exc_left =>
|
||||
exc_staten <= exc_idle;
|
||||
|
||||
when others =>
|
||||
exc_staten <= exc_idle;
|
||||
|
||||
end case;
|
||||
end process;
|
||||
|
||||
proc_exc_state_next:
|
||||
process(clk)
|
||||
begin
|
||||
if rising_edge(clk) then
|
||||
if rst = '1' then
|
||||
exc_state <= exc_idle;
|
||||
else
|
||||
exc_state <= exc_staten;
|
||||
end if;
|
||||
end if;
|
||||
end process;
|
||||
|
||||
-- Endian switch sampled at hard reset
|
||||
sample_endian:
|
||||
process(clk)
|
||||
begin
|
||||
if rising_edge(clk) then
|
||||
if rst = '1' then
|
||||
EB_reg <= eb;
|
||||
end if;
|
||||
end if;
|
||||
end process;
|
||||
|
||||
-- Sample imem_addr for later use
|
||||
exception_last_imem_addr:
|
||||
process(clk)
|
||||
begin
|
||||
if rising_edge(clk) then
|
||||
if imem_addr_we = '1' then
|
||||
imem_addr <= ctrl_in.imem_addr;
|
||||
end if;
|
||||
end if;
|
||||
end process;
|
||||
|
||||
-- EPC reg and BD-bit write
|
||||
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;
|
||||
|
||||
-- BadVaddr and exception code write
|
||||
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 <= imem_addr;
|
||||
elsif eflags.IAdEK = '1' then
|
||||
exc_code <= "00100";
|
||||
BadVAddr <= 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;
|
||||
|
||||
ctrl_out.icache.inv_addr <= test_reg;
|
||||
ctrl_out.dcache.inv_addr <= test_reg;
|
||||
|
||||
-- Custom I/D-Cache operations: invalidate all/line
|
||||
cop_cache_op:
|
||||
process(clk)
|
||||
begin
|
||||
if rising_edge(clk) then
|
||||
ctrl_out.icache.inv_at <= '0';
|
||||
ctrl_out.icache.inv_all <= '0';
|
||||
ctrl_out.dcache.inv_at <= '0';
|
||||
ctrl_out.dcache.inv_all <= '0';
|
||||
if cop_pipe_ID.cs = '1' and cop_pipe_ID.CO = '1' then
|
||||
case cop_pipe_ID.func is
|
||||
when "100000" =>
|
||||
ctrl_out.icache.inv_all <= '1';
|
||||
when "100001" =>
|
||||
ctrl_out.icache.inv_at <= '1';
|
||||
when "100010" =>
|
||||
ctrl_out.dcache.inv_all <= '1';
|
||||
when "100011" =>
|
||||
ctrl_out.dcache.inv_at <= '1';
|
||||
|
||||
when others => null;
|
||||
end case;
|
||||
end if;
|
||||
end if;
|
||||
end process;
|
||||
|
||||
-- IP register write and signalling Int to pipeline
|
||||
cop_ip_reg_write:
|
||||
process(clk)
|
||||
variable ip_v : unsigned(7 downto 0);
|
||||
variable ipm_v : unsigned(7 downto 0);
|
||||
begin
|
||||
if rising_edge(clk) then
|
||||
if rst = '1' then
|
||||
sw_int <= (others => '0');
|
||||
elsif ctrl_in.sdu.WB_nop = '0' then
|
||||
if ip_reg_we = '1' then
|
||||
sw_int <= din(9 downto 8);
|
||||
end if;
|
||||
end if;
|
||||
ip_v := (int & sw_int);
|
||||
ipm_v := ip_v and im;
|
||||
ip <= ip_v;
|
||||
ctrl_out.int <= (eval_int(ipm_v) and status(0));
|
||||
ctrl_out.NMI <= int_nmi;
|
||||
end if;
|
||||
end process;
|
||||
|
||||
-- Exception vector dispatch
|
||||
cop_exc_vector:
|
||||
process(clk)
|
||||
begin
|
||||
if rising_edge(clk) then
|
||||
if rst = '1' then
|
||||
ctrl_out.exc_vec <= X"BFC00000";
|
||||
elsif latch_vect_en = '1' then
|
||||
if ctrl_in.events.nmi = '1' then
|
||||
ctrl_out.exc_vec <= X"BFC00000";
|
||||
else
|
||||
ctrl_out.exc_vec <= X"80000080";
|
||||
if status(22) = '1' then
|
||||
ctrl_out.exc_vec <= X"BFC00180";
|
||||
end if;
|
||||
end if;
|
||||
end if;
|
||||
end if;
|
||||
end process;
|
||||
|
||||
-- Cop pipeline
|
||||
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';
|
||||
elsif ctrl_in.sdu.stall_all = '0' then
|
||||
cop_pipe_EX <= cop_pipe_ID;
|
||||
if cop_pipe_ID.we = '1' then
|
||||
reg_wptr <= cop_pipe_ID.reg_ptr;
|
||||
end if;
|
||||
if cop_pipe_ID.re = '1' then
|
||||
reg_rptr <= cop_pipe_ID.reg_ptr;
|
||||
end if;
|
||||
end if;
|
||||
end if;
|
||||
end process;
|
||||
|
||||
-- COP Register read
|
||||
cop_register_read:
|
||||
process(reg_rptr, BadVAddr, status, cause, epc, dcache_info, icache_info, test_reg)
|
||||
variable reg : word_t;
|
||||
begin
|
||||
|
||||
case reg_rptr 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 := dcache_info & icache_info & X"02" & to_unsigned(REVISION ,8);
|
||||
|
||||
when "11111" => -- test_reg
|
||||
reg := test_reg;
|
||||
|
||||
when others =>
|
||||
reg := (others => '-');
|
||||
|
||||
end case;
|
||||
|
||||
dout <= reg after 2 ns;
|
||||
|
||||
end process;
|
||||
|
||||
-- COP Register write strobe generation
|
||||
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';
|
||||
elsif ctrl_in.sdu.stall_all = '0' then
|
||||
test_reg_we <= '0';
|
||||
stat_reg_we <= '0';
|
||||
ip_reg_we <= '0';
|
||||
if cop_pipe_EX.we = '1' then
|
||||
|
||||
case reg_wptr is
|
||||
|
||||
when "01100" =>
|
||||
stat_reg_we <= '1'; -- not status(1) or status(28);
|
||||
when "01101" =>
|
||||
ip_reg_we <= '1'; -- not status(1) or status(28);
|
||||
when "11111" =>
|
||||
test_reg_we <= '1'; -- not status(1) or status(28);
|
||||
when others => null;
|
||||
|
||||
end case;
|
||||
|
||||
end if;
|
||||
end if;
|
||||
end if;
|
||||
end process;
|
||||
|
||||
-- COP Test Register
|
||||
cop_test_reg_write:
|
||||
process(clk)
|
||||
begin
|
||||
if rising_edge(clk) then
|
||||
if rst = '1' then
|
||||
test_reg <= (others => '0');
|
||||
elsif ctrl_in.sdu.WB_nop = '0' then
|
||||
if test_reg_we = '1' then
|
||||
test_reg <= din;
|
||||
end if;
|
||||
end if;
|
||||
end if;
|
||||
end process;
|
||||
|
||||
-- COP Status Register
|
||||
cop_status_reg_write:
|
||||
process(clk)
|
||||
begin
|
||||
if rising_edge(clk) then
|
||||
if rst = '1' then
|
||||
status <= X"00600000";
|
||||
elsif status_save = '1' then
|
||||
if ctrl_in.events.nmi = '0' then
|
||||
status(5 downto 4) <= status(3 downto 2);
|
||||
status(3 downto 2) <= status(1 downto 0);
|
||||
else
|
||||
status(22) <= '1';
|
||||
end if;
|
||||
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 ctrl_in.sdu.WB_nop = '0' then
|
||||
if stat_reg_we = '1' then
|
||||
if status(1) = '0' then
|
||||
status(0) <= din(0); -- IEc
|
||||
status(1) <= din(1); -- KUc
|
||||
status(2) <= din(2); -- IEp
|
||||
status(3) <= din(3); -- KUp
|
||||
status(4) <= din(4); -- IEo
|
||||
status(5) <= din(5); -- KUo
|
||||
end if;
|
||||
status(15 downto 8) <= din(15 downto 8); -- IM
|
||||
status(22) <= din(22); -- BEV
|
||||
status(25) <= din(25); -- RE
|
||||
end if;
|
||||
end if;
|
||||
end if;
|
||||
end process;
|
||||
|
||||
--------------------------------------------------------------------------
|
||||
end Behavioral;
|
||||
File diff suppressed because it is too large
Load Diff
@@ -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,851 +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;
|
||||
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;
|
||||
cop_ir : out word_t;
|
||||
cop_ir_en : out STD_LOGIC;
|
||||
cop_din : in word_t;
|
||||
cop_dout : out word_t;
|
||||
c0_ctrl_out : out cop0_ctrl_in_t;
|
||||
c0_ctrl_in : in cop0_ctrl_out_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 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 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;
|
||||
|
||||
--------------------------------------------------------------------------
|
||||
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 branch_ce : STD_LOGIC;
|
||||
signal cpu_run : STD_LOGIC;
|
||||
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;
|
||||
signal dmem_src : word_t;
|
||||
signal stage_rst : unsigned(3 downto 0);
|
||||
signal pipe_rst : STD_LOGIC;
|
||||
|
||||
signal pc : pc_t;
|
||||
|
||||
--------------------------------------------------------------------------
|
||||
begin
|
||||
|
||||
clk_1 <= clk;
|
||||
clk_2 <= not clk;
|
||||
cpu_run <= ce;
|
||||
|
||||
-- Stall Detection Unit ---------------------------------------------------
|
||||
sdu.ID_nop <= sdu.imem_dep or c0_ctrl_in.exc_pending or ID_stage.exc or EX_stage.exc or MEM_stage.exc;
|
||||
sdu.EX_nop <= sdu.mul_dep or ID_stage.nop or ID_stage.exc;
|
||||
sdu.MEM_nop <= EX_stage.nop or EX_stage.exc;
|
||||
sdu.WB_nop <= sdu.dmem_dep or MEM_stage.nop;
|
||||
|
||||
sdu.stall_all <= sdu.dmem_dep;
|
||||
sdu.ID_stall <= sdu.stall_all or sdu.imem_dep or sdu.mul_dep or c0_ctrl_in.exc_exit;
|
||||
sdu.EX_stall <= sdu.stall_all;
|
||||
sdu.MEM_stall <= sdu.stall_all;
|
||||
sdu.WB_stall <= '0';
|
||||
|
||||
sdu.mul_dep <= ID_stage.ctrl.mul_access and (EX_stage.ctrl.mul_start or mul_busy);
|
||||
sdu.imem_dep <= not imem_rdy;
|
||||
sdu.dmem_dep <= not dmem_rdy and MEM_stage.ctrl.dmem_en;
|
||||
---------------------------------------------------------------------------
|
||||
imem_en <= cpu_run and not (sdu.mul_dep or sdu.dmem_dep or c0_ctrl_in.exc_commit);
|
||||
|
||||
--------------------------------------------------------------------------
|
||||
-- Coprocessor assignments
|
||||
--------------------------------------------------------------------------
|
||||
c0_ctrl_out.bd_wb <= WB_stage.bd;
|
||||
c0_ctrl_out.epc_mem <= MEM_stage.pcn;
|
||||
c0_ctrl_out.epc_wb <= MEM_stage.epc;
|
||||
c0_ctrl_out.imem_addr <= EX_stage.epc;
|
||||
c0_ctrl_out.dmem_addr <= MEM_stage.va;
|
||||
c0_ctrl_out.sdu <= sdu;
|
||||
c0_ctrl_out.events <= WB_stage.events;
|
||||
c0_ctrl_out.exc_req <= MEM_stage.exc;
|
||||
c0_ctrl_out.exc_ack <= WB_stage.exc;
|
||||
cop_ir <= ID_stage.IR;
|
||||
cop_ir_en <= ID_stage.ctrl.cop_instr_en;
|
||||
cop_dout <= dmem_din when MEM_stage.ctrl.dmem_en = '1' else MEM_stage.ex_result;
|
||||
|
||||
--------------------------------------------------------------------------
|
||||
-- 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
|
||||
);
|
||||
|
||||
--------------------------------------------------------------------------
|
||||
-- IF stage
|
||||
--------------------------------------------------------------------------
|
||||
imem_addr <= pc.curr;
|
||||
|
||||
pipe_rst <= stage_rst(0);
|
||||
|
||||
proc_stage_reset:
|
||||
process(clk_1)
|
||||
begin
|
||||
if rising_edge(clk_1) then
|
||||
if rst = '1' then
|
||||
stage_rst <= (others => '1');
|
||||
else
|
||||
stage_rst <= stage_rst(stage_rst'left-1 downto 0) & '0';
|
||||
end if;
|
||||
end if;
|
||||
end process;
|
||||
|
||||
proc_stage_pc:
|
||||
process(pc)
|
||||
begin
|
||||
if pc.branch_take = '1' then
|
||||
pc.curr <= pc.pc_branch after 2 ns;
|
||||
else
|
||||
pc.curr <= pc.nxt after 2 ns;
|
||||
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_branch_ce:
|
||||
process(clk_1)
|
||||
begin
|
||||
if rising_edge(clk_1) then
|
||||
if pipe_rst = '1' then
|
||||
branch_ce <= '1';
|
||||
else
|
||||
branch_ce <= c0_ctrl_in.exc_pending;
|
||||
if sdu.ID_stall = '0' and c0_ctrl_in.exc_inject = '0' then
|
||||
branch_ce <= '1';
|
||||
end if;
|
||||
end if;
|
||||
end if;
|
||||
end process;
|
||||
|
||||
proc_stage_pc_next:
|
||||
process(clk_1)
|
||||
begin
|
||||
if rising_edge(clk_1) then
|
||||
if c0_ctrl_in.exc_inject = '1' then
|
||||
pc.nxt <= c0_ctrl_in.exc_vec;
|
||||
elsif sdu.ID_stall = '0' then
|
||||
pc.last <= pc.curr;
|
||||
if ID_stage.ctrl.jump = '1' then
|
||||
pc.nxt <= ID_stage.jimm32;
|
||||
elsif ID_stage.ctrl.jump_long = '1' then
|
||||
pc.nxt <= ID_stage.reg_a;
|
||||
else
|
||||
pc.nxt <= pc.curr + 4;
|
||||
end if;
|
||||
end if;
|
||||
end if;
|
||||
end process;
|
||||
|
||||
proc_stage_branch:
|
||||
process(clk_2)
|
||||
begin
|
||||
if rising_edge(clk_2) and branch_ce = '1' then
|
||||
pc.branch_take <= '0';
|
||||
if EX_stage.ctrl.branch = '1' then
|
||||
|
||||
case EX_stage.ctrl.bc_src is
|
||||
|
||||
when bc_eq_ne =>
|
||||
pc.branch_take <= EX_stage.ctrl.bc_not xor bcu_flags.eq;
|
||||
|
||||
when bc_lez_gtz =>
|
||||
pc.branch_take <= EX_stage.ctrl.bc_not xor (bcu_flags.eq or bcu_flags.ltz);
|
||||
|
||||
when bc_ltz_gez =>
|
||||
pc.branch_take <= EX_stage.ctrl.bc_not xor bcu_flags.ltz;
|
||||
|
||||
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 <= opcode_ctrl_lines(ID_stage.IR) when sdu.ID_nop = '0' else ctrl_lines_default;
|
||||
ID_stage.reg_write <= ID_stage.ctrl.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, c0_ctrl_in, pc)
|
||||
begin
|
||||
ID_stage.events <= events_clr;
|
||||
ID_stage.events.inst_load_err <= not c0_ctrl_in.exc_pending and (pc.nxt(1) or pc.nxt(0));
|
||||
ID_stage.events.inst_priv_addr <= not c0_ctrl_in.exc_pending and (pc.nxt(word_t'left) and c0_ctrl_in.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_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 stage_rst(1) = '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;
|
||||
EX_stage.epc <= ID_stage.epc;
|
||||
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';
|
||||
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 pipe_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 c0_ctrl_in.EB = '1' then
|
||||
if ID_stage.ctrl.word2_en = '0' then
|
||||
EX_stage.pa_off <= not vaddr(1 downto 0);
|
||||
else
|
||||
EX_stage.pa_off <= not vaddr(1) & vaddr(0);
|
||||
end if;
|
||||
else
|
||||
EX_stage.pa_off <= vaddr(1 downto 0);
|
||||
end if;
|
||||
end if;
|
||||
end if;
|
||||
end process;
|
||||
dmem_src <= cop_din when EX_stage.ctrl.cop_instr_en = '1' else EX_stage.reg_b;
|
||||
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(dmem_src, EX_stage.pa_off, EX_stage.ctrl.shift_offset, EX_stage.ctrl.shift_byp) after 1ns;
|
||||
dmem_addr <= EX_stage.va;
|
||||
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 stage_rst(2) = '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;
|
||||
if EX_stage.ctrl.dmem_en = '1' then
|
||||
MEM_stage.va <= EX_stage.va;
|
||||
end if;
|
||||
MEM_stage.pa_off <= EX_stage.pa_off;
|
||||
MEM_stage.reg_wptr <= EX_stage.reg_wptr;
|
||||
MEM_stage.nop <= sdu.MEM_nop;
|
||||
if MEM_stage.reg_wptr = EX_stage.reg_wptr then
|
||||
if (EX_stage.ctrl.dmem_en and MEM_stage.ctrl.dmem_en) = '1' then
|
||||
MEM_stage.ex_result <= MEM_stage.data;
|
||||
end if;
|
||||
else
|
||||
MEM_stage.ex_result <= EX_stage.reg_b;
|
||||
end if;
|
||||
if EX_stage.ctrl.cop_instr_en = '1' then
|
||||
if EX_stage.ctrl.cop_read = '1' then
|
||||
MEM_stage.ex_result <= cop_din;
|
||||
end if;
|
||||
elsif EX_stage.ctrl.dmem_en = '0' then
|
||||
MEM_stage.ex_result <= EX_stage.result;
|
||||
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;
|
||||
if MEM_stage.ctrl.reg_link = '1' then
|
||||
data := MEM_stage.epc + 8;
|
||||
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);
|
||||
be := load_be(MEM_stage.pa_off, MEM_stage.ctrl.align_left, MEM_stage.ctrl.byte_en_byp);
|
||||
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, c0_ctrl_in)
|
||||
begin
|
||||
MEM_stage.events <= MEM_stage.events_in;
|
||||
MEM_stage.events.Int <= c0_ctrl_in.int;
|
||||
MEM_stage.events.NMI <= c0_ctrl_in.NMI;
|
||||
end process;
|
||||
|
||||
MEM_stage.exc <= event_is_active(MEM_stage.events);
|
||||
|
||||
--------------------------------------------------------------------------
|
||||
-- WB stage
|
||||
--------------------------------------------------------------------------
|
||||
proc_stage_WB_p:
|
||||
process(clk_1)
|
||||
begin
|
||||
if rising_edge(clk_1) then
|
||||
if stage_rst(3) = '1' then
|
||||
WB_stage.op <= NOP;
|
||||
WB_stage.wreg_we <= '1';
|
||||
WB_stage.reg_wptr <= (others => '0');
|
||||
WB_stage.data <= (others => '0');
|
||||
WB_stage.events <= events_clr;
|
||||
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.exc <= '0';
|
||||
if sdu.stall_all = '0' then
|
||||
WB_stage.exc <= MEM_stage.exc;
|
||||
if MEM_stage.exc = '1' then
|
||||
WB_stage.events <= MEM_stage.events;
|
||||
end if;
|
||||
end if;
|
||||
WB_stage.nop <= sdu.WB_nop;
|
||||
if sdu.WB_nop = '1' then
|
||||
WB_stage.op <= NOP;
|
||||
WB_stage.wreg_we <= '0';
|
||||
else
|
||||
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,117 +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;
|
||||
|
||||
type fill_mask_rom_t is array (0 to 2*data_width-1) of unsigned(data_width-1 downto 0);
|
||||
--------------------------------------------------------------------------
|
||||
function gen_fill_mask_rom(data_width : natural) return fill_mask_rom_t is
|
||||
variable result : fill_mask_rom_t;
|
||||
begin
|
||||
result(0) := (data_width-1 downto 0 => '0');
|
||||
for i in 1 to data_width-1 loop
|
||||
result(i) := (data_width-1-i downto 0 => '0') & (i-1 downto 0 => '1');
|
||||
end loop;
|
||||
result(data_width) := (data_width-1 downto 0 => '0');
|
||||
for i in 1 to data_width-1 loop
|
||||
result(data_width+i) := (i-1 downto 0 => '1') & (data_width-1-i downto 0 => '0');
|
||||
end loop;
|
||||
return result;
|
||||
|
||||
end gen_fill_mask_rom;
|
||||
|
||||
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;
|
||||
|
||||
constant fill_mask_rom : fill_mask_rom_t := gen_fill_mask_rom(data_width);
|
||||
signal fill_mask : unsigned(data_width-1 downto 0);
|
||||
signal fill_mask_addr : unsigned(5 downto 0);
|
||||
signal dout_filled : unsigned (data_width-1 downto 0);
|
||||
|
||||
--------------------------------------------------------------------------
|
||||
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);
|
||||
fill_mask_addr <= shift_ctrl.shift_right & shift_ctrl.shamt_nrm;
|
||||
fill_mask <= fill_mask_rom(to_integer(fill_mask_addr));
|
||||
|
||||
proc_fill_neu:
|
||||
process(fill_mask, fill, rot_data(5))
|
||||
begin
|
||||
if fill = '1' then
|
||||
dout_filled <= rot_data(5) or fill_mask;
|
||||
else
|
||||
dout_filled <= rot_data(5) and not fill_mask;
|
||||
end if;
|
||||
end process;
|
||||
|
||||
dout <= dout_filled after 5 ns;
|
||||
|
||||
--------------------------------------------------------------------------
|
||||
end Behavioral;
|
||||
|
||||
Some files were not shown because too many files have changed in this diff Show More
Reference in New Issue
Block a user