Author SHA1 Message Date
jens aacb0c448b This commit was manufactured by cvs2svn to create tag 'JCPU_R4'.
git-svn-id: http://moon:8086/svn/vhdl/tags/JCPU_R4@559 cc03376c-175c-47c8-b038-4cd826a8556b
2009-10-28 23:25:03 +00:00
421 changed files with 0 additions and 109705 deletions
Binary file not shown.
-8
View File
@@ -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
-8
View File
@@ -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
-675
View File
@@ -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;
-87
View File
@@ -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");
}
/************************************************************************/
-200
View File
@@ -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
-415
View File
@@ -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;
}
-58
View File
@@ -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
-54
View File
@@ -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;
}
-13
View File
@@ -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);
-341
View File
@@ -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, &reg);
// 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, &reg);
// 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);
}
-430
View File
@@ -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;
-402
View File
@@ -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
-192
View File
@@ -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 */
-261
View File
@@ -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");
}
-198
View File
@@ -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;
}
-19
View File
@@ -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));
}
-504
View File
@@ -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;
}
-15
View File
@@ -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);
-92
View File
@@ -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);
}
}
-15
View File
@@ -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
-184
View File
@@ -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)
-260
View File
@@ -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
-577
View File
@@ -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);
}
-134
View File
@@ -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
-249
View File
@@ -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
}
-224
View File
@@ -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) }
}
-625
View File
@@ -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;
}
-450
View File
@@ -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
-298
View File
@@ -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;
}
-856
View File
@@ -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! --------*/
-466
View File
@@ -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);
}
-86
View File
@@ -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);
}
-6
View File
@@ -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);
-81
View File
@@ -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;
}
-294
View File
@@ -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 **********************/
-154
View File
@@ -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 ***********************/
-104
View File
@@ -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
-87
View File
@@ -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
-277
View File
@@ -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;
}
-94
View File
@@ -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;
}
-154
View File
@@ -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;
}
-853
View File
@@ -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;
}
-265
View File
@@ -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
-139
View File
@@ -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;
}
-49
View File
@@ -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
-67
View File
@@ -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
-151
View File
@@ -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"
-35
View File
@@ -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
-48
View File
@@ -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
# ---------------------------------------------------------------
-674
View File
@@ -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>.
Binary file not shown.
-338
View File
@@ -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;
-84
View File
@@ -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
View File
@@ -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}
-107
View File
@@ -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
-2
View File
@@ -1,2 +0,0 @@
%PDF-1.3
%庆
View File
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.
-15
View File
@@ -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
-78
View File
@@ -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}
-58
View File
@@ -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
-207
View File
@@ -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}
-68
View File
@@ -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
-12
View File
@@ -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
-496
View File
@@ -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;
-460
View File
@@ -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;
-184
View File
@@ -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;
-52
View File
@@ -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;
-507
View File
@@ -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;
-546
View File
@@ -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
-454
View File
@@ -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;
-851
View File
@@ -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;
-72
View File
@@ -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;
-117
View File
@@ -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