Skip to content
Snippets Groups Projects
Commit dcbde67c authored by Roberto Hexsel's avatar Roberto Hexsel
Browse files

new FP multiply unit, with thanks to Joao Pampanini

parent 2846a6be
Branches
No related tags found
No related merge requests found
......@@ -66,7 +66,7 @@ simulator=tb_cmips
pkg="packageWires.vhd packageMemory.vhd packageExcp.vhd"
src="altera.vhd macnica.vhd aux.vhd memory.vhd cache.vhd instrcache.vhd ram.vhd rom.vhd units.vhd io.vhd uart.vhd pipestages.vhd exception.vhd core.vhd tb_cMIPS.vhd"
src="altera.vhd macnica.vhd aux.vhd memory.vhd cache.vhd instrcache.vhd ram.vhd rom.vhd units.vhd io.vhd uart.vhd fpu.vhd pipestages.vhd exception.vhd core.vhd tb_cMIPS.vhd"
# build simulator
#ghdl --clean
......
#!/bin/bash
###
### this file in NOT a shell script,
### yet it was written to make it easy for cutting-n-pasting with the pointer
###
# to compile GCC, these three libraries may have to be fetched:
......@@ -12,11 +15,13 @@ wget ftp://ftp.gmplib.org/pub/gmp/gmp-6.0.0.tar.bz2
# directory names to mpfr mpc gmp (removing the version suffixes);
# these libraries are then compiled along with GCC
# OTOH, if you are lucky, the libraries installed by aptitude will do...
# OTOH, if you are very lucky, the libraries installed by aptitude will do...
# fetch all the auxiliary programs -- this assumes a Debian installation
aptitude install make flex bison libgmp-dev libmpfr-dev libmpc-dev g++
unset ls
# make sure the installed files are read-exec by all
umask 022
# check the latest version of GCC in http://ftp.gnu.org/gnu/gcc/
......@@ -38,17 +43,22 @@ tar -xvjf ${BINUTILS}.tar.bz2
cd ${BINUTILS}
./configure --target=$TARGET --prefix=$PREFIX --disable-nls
make
# do the next one as root? su ; umask 022 ; make install ; exit
make install
cd ..
tar -xvzf ${COMPILER}.tar.gz
cd ${COMPILER}
# you may want/need to expand the libraries' tarballs at this point
export PATH=$PATH:$PREFIX/bin
./configure --target=$TARGET --prefix=$PREFIX --disable-nls \
--enable-languages=c,c++ --without-headers
make all-gcc
# do the next one as root? su ; umask 022 ; make install-gcc ; exit
make install-gcc
cd ..
......@@ -69,8 +79,13 @@ export MANPATH=${MANPATH}:${PREFIX}/man
# https://sourceforge.net/p/ghdl-updates/wiki/Debian%20Instructions/
# and pick the appropriate version for your computer (32 or 64 bit).
#
# When doing dpkg -i ghdl*.deb it will complain about versions.
# What I have done is use the following DANGEROUS and RISKY command:
# dpkg --ignore-depends=ghdl*.deb -i ghdl*.deb
# this forces dpkg to ignore the dependencies for GHDL and install it
# with whatever version your machine has for gnat. The risk is yours.
# You also need to fetch gnat and libgnat from somewhere; I find it easier
# to download the .deb files onto the same directory as ghdl*.deb
#
# When doing dpkg -i ghdl*.deb it will whine and complain about versions.
# What I have done is to use the following DANGEROUS and RISKY command:
#
# dpkg --ignore-depends=ghdl*.deb --ignore-depends=libgnat-4.6 -i ghdl*.deb
#
# it forces dpkg to ignore the dependencies for GHDL and install it
# with whatever version your machine has for gnat/libgnat. Caveat emptor.
#include "cMIPS.h"
// ALL NaN cases : set i < 11 stop case
// int A[] = {(int)0x7fffffff,(int)0x7fffffff,(int)0x7fffffff,(int)0x7fffffff,(int)0x7fffffff,(int)0x7fffffff,(int)0x7fffffff,(int)0x7f800000,(int)0x7f800000,(int)0xff800000,(int)0xff800000};
// int B[] = {(int)0x7fffffff,(int)0x7f800000,(int)0xff800000,(int)0x00000000,(int)0x80000000,(int)0x1c038000,(int)0x9c038000,(int)0x00000000,(int)0x80000000,(int)0x00000000,(int)0x80000000};
// int C[] = {(int)0x7fffffff,(int)0x7fffffff,(int)0x7fffffff,(int)0x7fffffff,(int)0x7fffffff,(int)0x7fffffff,(int)0x7fffffff,(int)0x7fffffff,(int)0x7fffffff,(int)0x7fffffff,(int)0x7fffffff};
// ALL inf cases : set i < 12 stop case
// int A[] = {(int)0x7f800000,(int)0xff800000,(int)0x7f800000,(int)0xff800000,(int)0x7f000000,(int)0xff000000,(int)0xff800000,(int)0xff800000,(int)0x7f800000,(int)0xff800000,(int)0x7f000000,(int)0xff000000};
// int B[] = {(int)0x7f800000,(int)0xff800000,(int)0x1c038000,(int)0x9c038000,(int)0x7f000000,(int)0xff000000,(int)0x7f800000,(int)0x1c038000,(int)0x9c038000,(int)0x1c038000,(int)0xff000000,(int)0x7f000000};
// int C[] = {(int)0x7f800000,(int)0x7f800000,(int)0x7f800000,(int)0x7f800000,(int)0x7f800000,(int)0x7f800000,(int)0xff800000,(int)0xff800000,(int)0xff800000,(int)0xff800000,(int)0xff800000,(int)0xff800000};
// ALL 0 cases : set i < 12 stop case
// int A[] = {(int)0x00000000,(int)0x80000000,(int)0x00000000,(int)0x80000000,(int)0x00800000,(int)0x80800000,(int)0x00000000,(int)0x00000000,(int)0x80000000,(int)0x80000000,(int)0x00800000,(int)0x80800000};
// int B[] = {(int)0x00000000,(int)0x80000000,(int)0x1c038000,(int)0x9c038000,(int)0x00800000,(int)0x80800000,(int)0x9c038000,(int)0x80000000,(int)0x00000000,(int)0x1c038000,(int)0x80800000,(int)0x00800000};
// int C[] = {(int)0x00000000,(int)0x00000000,(int)0x00000000,(int)0x00000000,(int)0x00000000,(int)0x00000000,(int)0x80800000,(int)0x80800000,(int)0x80800000,(int)0x80800000,(int)0x80800000,(int)0x80800000};
// denorm cases : set i < 3 stop case
// int A[] = {(int)0x3c000000,(int)0x3c000000,(int)0x3f800000};
// int B[] = {(int)0x03800000,(int)0x03000000,(int)0x00200000};
// int C[] = {(int)0x00400000,(int)0x00200000,(int)0x00200000};
int A[] = {
// normal numbers
(int)0x9c038000,(int)0x9c038000,(int)0x9c038000,(int)0x9c038000,
// denormalized
(int)0x3c000000,(int)0x3c000000,(int)0x3f800000,
// all 0 cases : set i < 12 stop case
(int)0x00000000,(int)0x80000000,(int)0x00000000,(int)0x80000000,
(int)0x00800000,(int)0x80800000,(int)0x00000000,(int)0x00000000,
(int)0x80000000,(int)0x80000000,(int)0x00800000,(int)0x80800000,
// all inf cases : set i < 12 stop case
(int)0x7f800000,(int)0xff800000,(int)0x7f800000,(int)0xff800000,
(int)0x7f000000,(int)0xff000000,(int)0xff800000,(int)0xff800000,
(int)0x7f800000,(int)0xff800000,(int)0x7f000000,(int)0xff000000,
// all NaN cases : set i < 11 stop case
(int)0x7fffffff,(int)0x7fffffff,(int)0x7fffffff,(int)0x7fffffff,
(int)0x7fffffff,(int)0x7fffffff,(int)0x7fffffff,(int)0x7f800000,
(int)0x7f800000,(int)0xff800000,(int)0xff800000
};
int B[] = {
// normal numbers
(int)0x3f800000,(int)0x3f800000,(int)0x3f800000,(int)0x3f800000,
// denormalized
(int)0x03800000,(int)0x03000000,(int)0x00200000,
// all 0 cases
(int)0x00000000,(int)0x80000000,(int)0x1c038000,(int)0x9c038000,
(int)0x00800000,(int)0x80800000,(int)0x9c038000,(int)0x80000000,
(int)0x00000000,(int)0x1c038000,(int)0x80800000,(int)0x00800000,
// all inf cases
(int)0x7f800000,(int)0xff800000,(int)0x1c038000,(int)0x9c038000,
(int)0x7f000000,(int)0xff000000,(int)0x7f800000,(int)0x1c038000,
(int)0x9c038000,(int)0x1c038000,(int)0xff000000,(int)0x7f000000,
// all NaN cases
(int)0x7fffffff,(int)0x7f800000,(int)0xff800000,(int)0x00000000,
(int)0x80000000,(int)0x1c038000,(int)0x9c038000,(int)0x00000000,
(int)0x80000000,(int)0x00000000,(int)0x80000000
};
int C[] = {
// normal numbers
(int)0x9c038000,(int)0x9c038000,(int)0x9c038000,(int)0x9c038000,
// denorm
(int)0x00400000,(int)0x00200000,(int)0x00200000,
// all 0 cases
(int)0x00000000,(int)0x00000000,(int)0x00000000,(int)0x00000000,
(int)0x00000000,(int)0x00000000,(int)0x80800000,(int)0x80800000,
(int)0x80800000,(int)0x80800000,(int)0x80800000,(int)0x80800000,
// all inf cases
(int)0x7f800000,(int)0x7f800000,(int)0x7f800000,(int)0x7f800000,
(int)0x7f800000,(int)0x7f800000,(int)0xff800000,(int)0xff800000,
(int)0xff800000,(int)0xff800000,(int)0xff800000,(int)0xff800000,
// all NaN cases
(int)0x7fffffff,(int)0x7fffffff,(int)0x7fffffff,(int)0x7fffffff,
(int)0x7fffffff,(int)0x7fffffff,(int)0x7fffffff,(int)0x7fffffff,
(int)0x7fffffff,(int)0x7fffffff,(int)0x7fffffff
};
void main(void) {
int i,j, acc;
volatile int *fpu,res; // address of fpu
fpu = (int *)IO_FPU_ADDR; // 0x0f0000c0; // MUL
// fpu = (int *)IO_FPU_ADDR + 4; // 0x0f0000c8; // ADD
// fpu = (int *)IO_FPU_ADDR + 8; // 0x0f0000cc; // DIV
acc = 0;
for (i = 0; i < 4; i++) { // ordinary cases
*fpu = A[i];
*(fpu+1) = B[i];
asm("nop");
res = *fpu;
if (res != C[i])
acc = 1;
}
if (acc == 0) {
to_stdout('o'); to_stdout('r'); to_stdout('d'); to_stdout('\n');
} else {
to_stdout('E'); to_stdout('R'); to_stdout('R'); to_stdout('\n');
}
acc = 0;
for ( ; i < 4+3; i++) { // denormalized
*fpu = A[i];
*(fpu+1) = B[i];
asm("nop");
res = *fpu;
if (res != C[i])
acc = 1;
}
if (acc == 0) {
to_stdout('d'); to_stdout('e'); to_stdout('n'); to_stdout('\n');
} else {
to_stdout('E'); to_stdout('R'); to_stdout('R'); to_stdout('\n');
}
acc = 0;
for ( ; i < 7+12; i++) { // zeroes
*fpu = A[i];
*(fpu+1) = B[i];
asm("nop");
res = *fpu;
if (res != C[i])
acc = 1;
}
if (acc == 0) {
to_stdout('z'); to_stdout('e'); to_stdout('r'); to_stdout('\n');
} else {
to_stdout('E'); to_stdout('R'); to_stdout('R'); to_stdout('\n');
}
acc = 0;
for ( ; i < 19+12; i++) { // infinites
*fpu = A[i];
*(fpu+1) = B[i];
asm("nop");
res = *fpu;
if (res != C[i])
acc = 1;
}
if (acc == 0) {
to_stdout('i'); to_stdout('n'); to_stdout('f'); to_stdout('\n');
} else {
to_stdout('E'); to_stdout('R'); to_stdout('R'); to_stdout('\n');
}
acc = 0;
for ( ; i < 21+11; i++) { // NaNs
*fpu = A[i];
*(fpu+1) = B[i];
asm("nop");
res = *fpu;
if (res != C[i])
acc = 1;
}
if (acc == 0) {
to_stdout('N'); to_stdout('a'); to_stdout('N'); to_stdout('\n');
} else {
to_stdout('E'); to_stdout('R'); to_stdout('R'); to_stdout('\n');
}
}
......@@ -231,14 +231,6 @@ read3: tlbr # read TLB at index = 3
.set TAG_MASK, 0xfffff000 # 4Kbyte pages
.set TAG_G, 0x00000000 # mark pages as global
# .set MMU_ini_tag_RAM6, ((x_RAM_PPN_6 & TAG_MASK) | TAG_G)
# .set x_RAM_PPN_6, (x_DATA_BASE_ADDR + 6*PAGE_SZ)
# .set MMU_ini_dat_RAM6, (((x_RAM_PPN_6 >>12) <<6) | 0b000111) # d,v,g=1
# .set x_RAM_PPN_7, (x_DATA_BASE_ADDR + 7*PAGE_SZ)
# .set MMU_ini_dat_RAM7, (((x_RAM_PPN_7 >>12) <<6) | 0b000111) # d,v,g=1
# read from MMU(6)
addi $1, $1, 1
......
This diff is collapsed.
......@@ -855,8 +855,8 @@ begin
waiting <= '0';
when st_na =>
lcd_enable <= '0'; -- disable, stop waiting
lcd_read <= '1'; -- hold inp data for 40ns
lcd_enable <= '0'; -- disable, still waiting
lcd_read <= '1';
waiting <= '0';
when st_nb =>
......
......@@ -55,6 +55,7 @@ package p_WIRES is
subtype reg19 is std_logic_vector(18 downto 0);
subtype reg20 is std_logic_vector(19 downto 0);
subtype reg21 is std_logic_vector(20 downto 0);
subtype reg23 is std_logic_vector(22 downto 0);
subtype reg24 is std_logic_vector(23 downto 0);
subtype reg28 is std_logic_vector(27 downto 0);
subtype reg30 is std_logic_vector(29 downto 0);
......@@ -166,6 +167,10 @@ package p_WIRES is
type t_rimm_mem is array (0 to 31) of t_rimm_type;
-- type for floating point numbers: 'good' number, infinity, NaN, zero
type FP_type is (fp_is_good, fp_is_inf, fp_is_NaN, fp_is_zero);
function log2_ceil(n: natural) return natural;
function CONVERT_BOOLEAN(b: in boolean) return std_logic;
function CONVERT_STRING(s: in string) return std_logic_vector;
......
......@@ -139,6 +139,28 @@ architecture TB of tb_cMIPS is
bit_rt : out std_logic_vector);-- communication speed - TB only
end component simple_uart;
component FPU is
port (rst : in std_logic;
clk : in std_logic;
sel : in std_logic;
rdy : out std_logic;
wr : in std_logic;
addr : in std_logic_vector;
data_inp : in std_logic_vector;
data_out : out std_logic_vector);
end component FPU;
component fake_FPU is
port (rst : in std_logic;
clk : in std_logic;
sel : in std_logic;
rdy : out std_logic;
wr : in std_logic;
addr : in std_logic_vector;
data_inp : in std_logic_vector;
data_out : out std_logic_vector);
end component fake_FPU;
component remota is
generic(OUTPUT_FILE_NAME : string; INPUT_FILE_NAME : string);
port(rst, clk : in std_logic;
......@@ -478,7 +500,7 @@ begin -- TB
cpu_i_wait <= inst_wait;
cpu_d_wait <= data_wait and io_wait;
io_wait <= io_lcd_wait; -- and io_fpu_wait;
io_wait <= io_lcd_wait and io_fpu_wait;
not_waiting <= (inst_wait and data_wait); -- and io_wait);
......@@ -594,8 +616,10 @@ begin -- TB
U_uart_remota: remota generic map ("serial.out","serial.inp")
port map (rst, clk, start_remota, uart_txd, uart_rxd, bit_rt);
-- U_FPU: FPU
-- port map (rst,clk, io_FPU_sel, io_FPU_wait, wr, d_addr, cpu_data);
-- U_FPU: fake_FPU
U_FPU: FPU
port map (rst,clk, io_FPU_sel,io_FPU_wait, wr, d_addr(5 downto 2),
cpu_data,fpu_d_out);
-- U_sys_stats: sys_stats -- CPU reads system counters
-- port map (cpu_reset,clk, io_sstats_sel, wr, d_addr, sstats_d_out,
......@@ -701,7 +725,7 @@ use work.p_wires.all;
use work.p_memory.all;
entity io_addr_decode is -- CPU side triggers access
port (clk,rst : in std_logic;
port (clk,rst : in std_logic; -- clk sparates back-to-back refs
cpu_d_aVal : in std_logic; -- CPU data addr valid (active=0)
addr : in reg32; -- CPU address
dev_select : out reg4; -- select input to CPU
......
......@@ -669,7 +669,7 @@ begin
w_d <= this xor cycle; -- active for ONE cycle only
w <= not(w_d or sel);
w <= w_d and sel;
waiting <= w and will_wait;
......
0% Loading or .
You are about to add 0 people to the discussion. Proceed with caution.
Please register or to comment