Commit 7ec22859 authored by Marc's avatar Marc
Browse files

saturated mult and tidiness improvements

parent 67a5a9e1
......@@ -498,10 +498,19 @@ $(SIMTOP): gnu
# Run testbench SIMTOP
.PHONY: ghdl-run
ghdl-run: $(SIMTOP)
./$(SIMTOP) $(GHDLRUNOPT)
./$(SIMTOP) $(GHDLRUNOPT)
ghdl-wave: $(SIMTOP)
./$(SIMTOP) $(GHDLRUNOPT) --wave=$(SIMTOP).ghw
ghdl-vcd: $(SIMTOP)
./$(SIMTOP) $(GHDLRUNOPT) --vcd=$(SIMTOP).vcd
ghdl-time: $(SIMTOP)
./$(SIMTOP) $(GHDLRUNOPT)
ghdl-clean:
-rm -rf gnu $(SIMTOP) make.ghdl
-rm -rf gnu $(SIMTOP) make.ghdl *.ghw *.vcd
######### NcSim targets ############
......
......@@ -12,6 +12,8 @@ XCFLAGS0=-O0 -g -msoft-float -mcpu=v8
bin_change:
g++ -o bin_change bin_change.cc
make.x:
g++ -o make.x make_simd_op.cc
systest:
cp systest.srec test.srec
......@@ -35,4 +37,4 @@ mat_mul: mat_mul.o
cp mat_mul.srec test.srec
clean:
rm -f *.exe *.o *.dump
rm -f *.exe *.o *.dump bin_change make.x
Directory containing the testing utilities for the leon3mp design
The executed program, must be found in test.srec file in the .srec format
A makefile is provided with the commands to generate this srec file
execute "make _test_name" to generate all the necessary files
To use instructions not included in the compiler the bin_change and make_simd_op
programs are included. Use make_sim_op (whose executable is make.x) to
generate the hex codification for the simd instructions.
--TODO-- allow input to be operation name
Include a list of all the new instructions, just the ones not included in the
compiler, in the corresponding order. This list must be in _test_name.list
When calling bin_change pass this list together with the output file, usually
test.srec, and the dummy instruction used in the C code to compile.
For existing test all this mechanisms are included when executing "make _test_name"
-- to compile the program
make prog_name
-- this compiles and moves the file data to test.srec
-- which is used by the testbench
#include<iostream>
#include<string>
#include<bitset>
using namespace std;
......@@ -8,19 +9,28 @@ int main(){
const bitset<1> imm ("0");
int input;
cout<<"Input destination register:\n";
cout<<"Use default addresses?(1/0)\n";
cin>>input;
bitset<5> rd(input);
cout<<"Input source1 register:\n";
cin>>input;
bitset<5> rs1(input);
cout<<"Input source2 register:\n";
cin>>input;
bitset<5> rs2(input);
bitset<5> rd(1);
bitset<5> rs1(2);
bitset<5> rs2(1);
if(!input){
cout<<"Input destination register:\n";
cin>>input;
bitset<5> rd(input);
cout<<"Input source1 register:\n";
cin>>input;
bitset<5> rs1(input);
cout<<"Input source2 register:\n";
cin>>input;
bitset<5> rs2(input);
}
cout<<"Input stage1 op:\n";
cin>>input;
bitset<5> op1(input);
cout<<"Input stage2 op:\n";
cout<<"NOP = 0 MAX = 2 XOR = 4 MAX = 6\n";
cout<<"SUM = 1 MIN = 3 USUM = 5 MIN = 7\n";
cin>>input;
bitset<3> op2(input);
bitset<32> instr(op.to_string()+rd.to_string()+opcode.to_string()+rs1.to_string()+imm.to_string()+op2.to_string()+op1.to_string()+rs2.to_string());
......
This diff is collapsed.
......@@ -234,6 +234,28 @@ int main()
__asm__("st %g1, [ %fp + -12 ]");
printf("dot product2: c=%#010x, expected result 0xfffffffc\n", c);
//test saturated mul
a=0x7f7ffdff;
b=0x7fff7f80;
//c=0x7f81807f
__asm__("ld [%fp + -4], %g2");
__asm__("ld [%fp + -8], %g1");
__asm__("nop");
__asm__("nop");
__asm__("nop");
__asm__("nop");
__asm__("nop");
__asm__("nop");
__asm__("sll %g2, %g1, %g1");
__asm__("nop");
__asm__("nop");
__asm__("nop");
__asm__("nop");
__asm__("nop");
__asm__("nop");
__asm__("st %g1, [ %fp + -12 ]");
printf("saturate mul: c=%#010x, expected result 0x7f81807f\n",c);
//test div
a=0x40404040;
b=0x01020040;
......
......@@ -9,6 +9,7 @@
82488CC1
82488461
82488461
824881E1
82488081
82488081
82488142
......
This source diff could not be displayed because it is too large. You can view the blob instead.
This diff is collapsed.
This source diff could not be displayed because it is too large. You can view the blob instead.
......@@ -312,21 +312,26 @@ end;
-- saturate multiplication
function saturate_mul(a,b : std_logic_vector; sign : std_logic) return std_logic_vector is
variable z : std_logic_vector(a'length+b'length-1 downto 0);
constant U_MAX : integer := 2**(a'length)-1;
constant S_MAX : integer := 2**(a'length-1)-1;
constant S_MIN : integer := -2**(a'length-1);
begin
return a;
--variable a1 : std_logic_vector(a'left*2 downto 0) := (a'left*2 downto a'left+1 => (sign and a(a'left))) & a;
--variable b1 : std_logic_vector(b'left*2 downto 0) := (b'left*2 downto b'left+1 => (sign and b(b'left))) & b;
--constant U_MAX : std_logic_vector(a'left downto 0) := (others => '1');
--constant S_MAX : std_logic_vector(a'left*2 downto 0) := (a'left*2 downto a'left => '0') & (a'left-1 downto 0 => '1');
--constant S_MIN : std_logic_vector(a'left*2 downto 0) := (a'left*2 downto a'left => '1') & (a'left-1 downto 0 => '0');
--begin
-- if sign = '0' then
-- a1 := unsigned_mul(a1,b1)(a1'left downto 0);
-- return unsigned_min(a1,U_MAX)(a'left downto 0);
-- else
-- a1 := signed_mul(a1,b1)(a1'left downto 0);
-- return signed_max(signed_min(S_MAX, a1), S_MIN)(a'left downto 0);
-- end if;
-- pragma translate_off
if notx(a&b) then
-- pragma translate_on
if sign = '0' then
z := unsigned_mul(a,b)(z'left downto 0);
return unsigned_min(std_logic_vector(to_unsigned(U_MAX, z'length)), z);
else
z := signed_mul(a,b)(z'left downto 0);
return signed_max(std_logic_vector(to_signed(S_MIN, z'length)), signed_min(std_logic_vector(to_signed(S_MAX,z'length)), z));
end if;
-- pragma translate_off
else
z := (others =>'X'); return(z);
end if;
-- pragma translate_on
end;
--signed division
......
......@@ -17,13 +17,13 @@ build:
ghdl -m -fexplicit --ieee=synopsys --mb-comments -O2 --workdir=gnu/work --work=work -Pgnu -Pgnu/grlib -Pgnu/marcmod -Pgnu/work simd_test
sim:
./simd_test --vcd=simd.vcd --assert-level=error
./simd_test --wave=simd.ghw --assert-level=error
view:
gtkwave simd.vcd &
gtkwave simd.ghw &
clean:
rm -f *.o *.vcd *.cf
rm -f *.o *.ghw *.cf
rm -rf gnu/
......@@ -217,12 +217,12 @@ architecture rtl of simd is
when S1_SMUL =>
for i in 0 to (XLEN/VLEN)-1 loop
rc.data(VLEN*i+VLEN-1 downto VLEN*i) <= saturate_mul(ra.data(VLEN*i+VLEN-1 downto VLEN*i),
rb.data(VLEN*i+VLEN-1 downto VLEN*i),'1');
rb.data(VLEN*i+VLEN-1 downto VLEN*i),'1')(VLEN-1 downto 0);
end loop;
when S1_USMUL =>
for i in 0 to (XLEN/VLEN)-1 loop
rc.data(VLEN*i+VLEN-1 downto VLEN*i) <= saturate_mul(ra.data(VLEN*i+VLEN-1 downto VLEN*i),
rb.data(VLEN*i+VLEN-1 downto VLEN*i),'0');
rb.data(VLEN*i+VLEN-1 downto VLEN*i),'0')(VLEN-1 downto 0);
end loop;
when S1_UMUL =>
for i in 0 to (XLEN/VLEN)-1 loop
......
Supports Markdown
0% or .
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment