diff --git a/vhdl/dsp56k/asm/asm.sh b/vhdl/dsp56k/asm/asm.sh deleted file mode 100755 index 58c4f53..0000000 --- a/vhdl/dsp56k/asm/asm.sh +++ /dev/null @@ -1,6 +0,0 @@ -#!/bin/bash -export DSP_PATH=~/.wine/drive_c/Programme/Motorola/DSP56300/clas - -wine $DSP_PATH/asm56300.exe -b -g -l $1.asm -wine $DSP_PATH/dsplnk.exe $1.cln -wine $DSP_PATH/cldlod.exe $1.cld > $1.lod diff --git a/vhdl/dsp56k/asm/test_agu/test.asm b/vhdl/dsp56k/asm/test_agu/test.asm deleted file mode 100644 index ff0d2b6..0000000 --- a/vhdl/dsp56k/asm/test_agu/test.asm +++ /dev/null @@ -1,13 +0,0 @@ - - move #1,n1 - move #10,r1 - nop - move (r1)+n1 - move #15,m1 - rep #10 - move (r1)+n1 - move #10,n1 - rep #10 - move (r1)+n1 - - diff --git a/vhdl/dsp56k/asm/test_alu/test_abs.asm b/vhdl/dsp56k/asm/test_alu/test_abs.asm deleted file mode 100644 index 9e400e8..0000000 --- a/vhdl/dsp56k/asm/test_alu/test_abs.asm +++ /dev/null @@ -1,12 +0,0 @@ - -; clear CCR - andi #$00,CCR - move #>0.25,a - abs a - move #>-0.25,a - abs a - move #>0,a - abs a - move #>$80,a2 - abs a - diff --git a/vhdl/dsp56k/asm/test_alu/test_adc.asm b/vhdl/dsp56k/asm/test_alu/test_adc.asm deleted file mode 100644 index 0589a4e..0000000 --- a/vhdl/dsp56k/asm/test_alu/test_adc.asm +++ /dev/null @@ -1,11 +0,0 @@ - move #>0,y0 - move #>1,y1 - clr b - move #>1,b0 -; set only carry bit - andi #$00,ccr - ori #$01,ccr - adc y,b - move #>$800000,y1 - move #>$80,b2 - adc y,b diff --git a/vhdl/dsp56k/asm/test_alu/test_add.asm b/vhdl/dsp56k/asm/test_alu/test_add.asm deleted file mode 100644 index ba12582..0000000 --- a/vhdl/dsp56k/asm/test_alu/test_add.asm +++ /dev/null @@ -1,11 +0,0 @@ - move #>0,y0 - move #>1,y1 - clr b - move #>1,b0 -; set only carry bit - andi #$00,ccr - ori #$01,ccr - add y,b - move #>$800000,y1 - move #>$80,b2 - add y,b diff --git a/vhdl/dsp56k/asm/test_alu/test_addl.asm b/vhdl/dsp56k/asm/test_alu/test_addl.asm deleted file mode 100644 index dd80cb5..0000000 --- a/vhdl/dsp56k/asm/test_alu/test_addl.asm +++ /dev/null @@ -1,9 +0,0 @@ - move #>$55,a - clr b - move #>$55,b0 - andi #$00,ccr - addl a,b - move #>$AA,a - addl a,b - move #>$80,b2 - addl a,b diff --git a/vhdl/dsp56k/asm/test_alu/test_addr.asm b/vhdl/dsp56k/asm/test_alu/test_addr.asm deleted file mode 100644 index 7be3b44..0000000 --- a/vhdl/dsp56k/asm/test_alu/test_addr.asm +++ /dev/null @@ -1,9 +0,0 @@ - move #>$55,a - clr b - move #>$55,b0 - andi #$00,ccr - addr a,b - move #>$AA,a - addr a,b - move #>$80,b2 - addr a,b diff --git a/vhdl/dsp56k/asm/test_alu/test_and.asm b/vhdl/dsp56k/asm/test_alu/test_and.asm deleted file mode 100644 index 72aba75..0000000 --- a/vhdl/dsp56k/asm/test_alu/test_and.asm +++ /dev/null @@ -1,12 +0,0 @@ - move #>$000FFF,y0 - move #>$FFFFFF,b - andi #$00,ccr - and y0,b - move #>$FFF000,y0 - move #>$FFFFFF,b - andi #$00,ccr - and y0,b - move #>$000000,y0 - move #>$FFFFFF,b - andi #$00,ccr - and y0,b diff --git a/vhdl/dsp56k/asm/test_alu/test_asl.asm b/vhdl/dsp56k/asm/test_alu/test_asl.asm deleted file mode 100644 index 9a7244b..0000000 --- a/vhdl/dsp56k/asm/test_alu/test_asl.asm +++ /dev/null @@ -1,8 +0,0 @@ -; move #>0,y0 -; move #>1,y1 - clr b - move #>$A5,b0 - move #>$A5,b1 - move #>$A5,b2 - andi #$00,ccr - asl b diff --git a/vhdl/dsp56k/asm/test_alu/test_asr.asm b/vhdl/dsp56k/asm/test_alu/test_asr.asm deleted file mode 100644 index c37a0cc..0000000 --- a/vhdl/dsp56k/asm/test_alu/test_asr.asm +++ /dev/null @@ -1,8 +0,0 @@ -; move #>0,y0 -; move #>1,y1 - clr b - move #>$A5,b0 - move #>$A5,b1 - move #>$A5,b2 - andi #$00,ccr - asr b diff --git a/vhdl/dsp56k/asm/test_alu/test_carry.asm b/vhdl/dsp56k/asm/test_alu/test_carry.asm deleted file mode 100644 index 2fe6ff5..0000000 --- a/vhdl/dsp56k/asm/test_alu/test_carry.asm +++ /dev/null @@ -1,20 +0,0 @@ - clr a - clr b - andi #$00,ccr - move #>$7F,a2 - move #>$7F,b2 - add a,b - - clr a - clr b - andi #$00,ccr - move #>$80,a2 - move #>$7F,b2 - add a,b - - clr a - clr b - andi #$00,ccr - move #>$80,a2 - move #>$80,b2 - add a,b diff --git a/vhdl/dsp56k/asm/test_alu/test_clr.asm b/vhdl/dsp56k/asm/test_alu/test_clr.asm deleted file mode 100644 index 6b2083d..0000000 --- a/vhdl/dsp56k/asm/test_alu/test_clr.asm +++ /dev/null @@ -1,9 +0,0 @@ - -; clear CCR - andi #$00,CCR - move #>0.25,a - clr a - move #>-0.25,a - andi #$00,CCR - ori #$01,CCR - clr a diff --git a/vhdl/dsp56k/asm/test_alu/test_cmp.asm b/vhdl/dsp56k/asm/test_alu/test_cmp.asm deleted file mode 100644 index 978933f..0000000 --- a/vhdl/dsp56k/asm/test_alu/test_cmp.asm +++ /dev/null @@ -1,20 +0,0 @@ - move #$20,b - move #$24,y0 - andi #$00,ccr - cmp y0,b - move #$20,b - move #$20,y0 - andi #$00,ccr - cmp y0,b - move #$24,b - move #$20,y0 - andi #$00,ccr - cmp y0,b - move #$800AAA,b - move #$20,y0 - andi #$00,ccr - cmp y0,b - move #$800AAA,y0 - move #$20,b - andi #$00,ccr - cmp y0,b diff --git a/vhdl/dsp56k/asm/test_alu/test_cmpm.asm b/vhdl/dsp56k/asm/test_alu/test_cmpm.asm deleted file mode 100644 index a63a0d4..0000000 --- a/vhdl/dsp56k/asm/test_alu/test_cmpm.asm +++ /dev/null @@ -1,20 +0,0 @@ - move #$20,b - move #$24,y0 - andi #$00,ccr - cmpm y0,b - move #$20,b - move #$20,y0 - andi #$00,ccr - cmpm y0,b - move #$24,b - move #$20,y0 - andi #$00,ccr - cmpm y0,b - move #$800AAA,b - move #$20,y0 - andi #$00,ccr - cmpm y0,b - move #$800AAA,y0 - move #$20,b - andi #$00,ccr - cmpm y0,b diff --git a/vhdl/dsp56k/asm/test_alu/test_eor.asm b/vhdl/dsp56k/asm/test_alu/test_eor.asm deleted file mode 100644 index 381c5dc..0000000 --- a/vhdl/dsp56k/asm/test_alu/test_eor.asm +++ /dev/null @@ -1,8 +0,0 @@ - move #>$000FFF,y0 - move #>$FF00FF,b - andi #$00,ccr - eor y0,b - move #>$FFFFFF,y0 - move #>$FFFFFF,b - andi #$00,ccr - eor y0,b diff --git a/vhdl/dsp56k/asm/test_alu/test_lsl.asm b/vhdl/dsp56k/asm/test_alu/test_lsl.asm deleted file mode 100644 index 51e845f..0000000 --- a/vhdl/dsp56k/asm/test_alu/test_lsl.asm +++ /dev/null @@ -1,7 +0,0 @@ - - andi #$00,CCR - move #>0.25,a - move #>$AAAAAA,a - move #>$BCDEFA,a0 - rep #24 - lsl a diff --git a/vhdl/dsp56k/asm/test_alu/test_lsr.asm b/vhdl/dsp56k/asm/test_alu/test_lsr.asm deleted file mode 100644 index 87177a9..0000000 --- a/vhdl/dsp56k/asm/test_alu/test_lsr.asm +++ /dev/null @@ -1,7 +0,0 @@ - - andi #$00,CCR - move #>0.25,a - move #>$AAAAAA,a - move #>$BCDEFA,a0 - rep #24 - lsr a diff --git a/vhdl/dsp56k/asm/test_alu/test_mac.asm b/vhdl/dsp56k/asm/test_alu/test_mac.asm deleted file mode 100644 index b97fb6a..0000000 --- a/vhdl/dsp56k/asm/test_alu/test_mac.asm +++ /dev/null @@ -1,17 +0,0 @@ - - andi #$00,CCR - clr a - move #$80,a2 - move #>0.25,x0 - move #>0.50,y0 - mac -x0,y0,a - move #>-0.25,x0 - move #>-0.55,y0 - mac x0,y0,a - move #>-0.20,x0 - move #>+0.55,y0 - mac x0,y0,a - move #>-0.20,x0 - move #>+0.55,y0 - mac -x0,y0,a - diff --git a/vhdl/dsp56k/asm/test_alu/test_macr.asm b/vhdl/dsp56k/asm/test_alu/test_macr.asm deleted file mode 100644 index ebbfdf5..0000000 --- a/vhdl/dsp56k/asm/test_alu/test_macr.asm +++ /dev/null @@ -1,17 +0,0 @@ - - andi #$00,CCR - clr a - move #$100000,a - move #>$123456,x0 - move #>$123456,y0 - macr x0,y0,a - move #$100001,a - move #>$123456,x0 - move #>$123456,y0 - macr x0,y0,a - move #$100000,a - move #$800000,a0 - move #>$123456,x0 - move #>$123456,y0 - macr x0,y0,a - diff --git a/vhdl/dsp56k/asm/test_alu/test_mpy.asm b/vhdl/dsp56k/asm/test_alu/test_mpy.asm deleted file mode 100644 index afde500..0000000 --- a/vhdl/dsp56k/asm/test_alu/test_mpy.asm +++ /dev/null @@ -1,15 +0,0 @@ - - andi #$00,CCR - move #>0.25,x0 - move #>0.50,y0 - mpy x0,y0,a - move #>-0.25,x0 - move #>-0.55,y0 - mpy x0,y0,a - move #>-0.20,x0 - move #>+0.55,y0 - mpy x0,y0,a - move #>-0.20,x0 - move #>+0.55,y0 - mpy -x0,y0,a - diff --git a/vhdl/dsp56k/asm/test_alu/test_mpyr.asm b/vhdl/dsp56k/asm/test_alu/test_mpyr.asm deleted file mode 100644 index 847bccf..0000000 --- a/vhdl/dsp56k/asm/test_alu/test_mpyr.asm +++ /dev/null @@ -1,5 +0,0 @@ - - andi #$00,CCR - move #>$654321,y0 - mpyr -y0,y0,a - diff --git a/vhdl/dsp56k/asm/test_alu/test_neg.asm b/vhdl/dsp56k/asm/test_alu/test_neg.asm deleted file mode 100644 index 9fbc708..0000000 --- a/vhdl/dsp56k/asm/test_alu/test_neg.asm +++ /dev/null @@ -1,10 +0,0 @@ - - andi #$00,CCR - move #>$654321,a - neg a - clr a - move #>$80,a2 - neg a - move #>$800000,a - neg a - diff --git a/vhdl/dsp56k/asm/test_alu/test_norm.asm b/vhdl/dsp56k/asm/test_alu/test_norm.asm deleted file mode 100644 index 50749fe..0000000 --- a/vhdl/dsp56k/asm/test_alu/test_norm.asm +++ /dev/null @@ -1,14 +0,0 @@ - clr a - move #$000001,a1 - tst a - rep #$2F - norm R3,a - clr a - move #$FF0000,a - move #$84,a2 - tst a - rep #$2F - norm R1,a - clr a - rep #$2F - norm R2,a diff --git a/vhdl/dsp56k/asm/test_alu/test_not.asm b/vhdl/dsp56k/asm/test_alu/test_not.asm deleted file mode 100644 index 997fb45..0000000 --- a/vhdl/dsp56k/asm/test_alu/test_not.asm +++ /dev/null @@ -1,8 +0,0 @@ - move #>$000FFF,y0 - move #>$7F00FF,b - andi #$00,ccr - not b - move #>$000000,y0 - move #>$FFFFFF,b - andi #$00,ccr - not b diff --git a/vhdl/dsp56k/asm/test_alu/test_or.asm b/vhdl/dsp56k/asm/test_alu/test_or.asm deleted file mode 100644 index 025991f..0000000 --- a/vhdl/dsp56k/asm/test_alu/test_or.asm +++ /dev/null @@ -1,8 +0,0 @@ - move #>$000FFF,y0 - move #>$FF00FF,b - andi #$00,ccr - or y0,b - move #>$000000,y0 - move #>$000000,b - andi #$00,ccr - or y0,b diff --git a/vhdl/dsp56k/asm/test_alu/test_rnd.asm b/vhdl/dsp56k/asm/test_alu/test_rnd.asm deleted file mode 100644 index 9c7f4bb..0000000 --- a/vhdl/dsp56k/asm/test_alu/test_rnd.asm +++ /dev/null @@ -1,11 +0,0 @@ - - andi #$00,CCR - move #>$123456,a1 - move #>$789ABC,a0 - rnd a - move #>$123456,a1 - move #>$800000,a0 - rnd a - move #>$123455,a1 - move #>$800000,a0 - rnd a diff --git a/vhdl/dsp56k/asm/test_alu/test_rol.asm b/vhdl/dsp56k/asm/test_alu/test_rol.asm deleted file mode 100644 index 4f69ef6..0000000 --- a/vhdl/dsp56k/asm/test_alu/test_rol.asm +++ /dev/null @@ -1,6 +0,0 @@ - - andi #$00,CCR - move #>$AAAAAA,a - move #>$BCDEFA,a0 - rep #24 - rol a diff --git a/vhdl/dsp56k/asm/test_alu/test_ror.asm b/vhdl/dsp56k/asm/test_alu/test_ror.asm deleted file mode 100644 index 4fcca89..0000000 --- a/vhdl/dsp56k/asm/test_alu/test_ror.asm +++ /dev/null @@ -1,6 +0,0 @@ - - andi #$00,CCR - move #>$AAAAAA,a - move #>$BCDEFA,a0 - rep #24 - ror a diff --git a/vhdl/dsp56k/asm/test_alu/test_sbc.asm b/vhdl/dsp56k/asm/test_alu/test_sbc.asm deleted file mode 100644 index 7beb742..0000000 --- a/vhdl/dsp56k/asm/test_alu/test_sbc.asm +++ /dev/null @@ -1,15 +0,0 @@ - move #>0,y0 - move #>1,y1 - clr b - move #>1,b0 -; set only carry bit - andi #$00,ccr - ori #$01,ccr - sbc y,b - move #>$800000,y1 - move #>$80,b2 - sbc y,b - clr b - move #>$80,b2 - move #>$1,y1 - sbc y,b diff --git a/vhdl/dsp56k/asm/test_alu/test_sub.asm b/vhdl/dsp56k/asm/test_alu/test_sub.asm deleted file mode 100644 index fa69320..0000000 --- a/vhdl/dsp56k/asm/test_alu/test_sub.asm +++ /dev/null @@ -1,15 +0,0 @@ - move #>0,y0 - move #>1,y1 - clr b - move #>1,b0 -; set only carry bit - andi #$00,ccr - ori #$01,ccr - sub y,b - move #>$800000,y1 - move #>$80,b2 - sub y,b - clr b - move #>$80,b2 - move #>$1,y1 - sub y1,b diff --git a/vhdl/dsp56k/asm/test_alu/test_subl.asm b/vhdl/dsp56k/asm/test_alu/test_subl.asm deleted file mode 100644 index 4d4a601..0000000 --- a/vhdl/dsp56k/asm/test_alu/test_subl.asm +++ /dev/null @@ -1,15 +0,0 @@ - move #>0,a0 - move #>1,a1 - clr b - move #>1,b0 -; set only carry bit - andi #$00,ccr - ori #$01,ccr - subl a,b - move #>$800000,a1 - move #>$80,b2 - subl a,b - clr b - move #>$80,b2 - move #>$1,a1 - subl a,b diff --git a/vhdl/dsp56k/asm/test_alu/test_subr.asm b/vhdl/dsp56k/asm/test_alu/test_subr.asm deleted file mode 100644 index 989ff9a..0000000 --- a/vhdl/dsp56k/asm/test_alu/test_subr.asm +++ /dev/null @@ -1,15 +0,0 @@ - move #>0,a0 - move #>1,a1 - clr b - move #>1,b0 -; set only carry bit - andi #$00,ccr - ori #$01,ccr - subr a,b - move #>$800000,a1 - move #>$80,b2 - subr a,b - clr b - move #>$80,b2 - move #>$1,a1 - subr a,b diff --git a/vhdl/dsp56k/asm/test_alu/test_tcc.asm b/vhdl/dsp56k/asm/test_alu/test_tcc.asm deleted file mode 100644 index dd471b3..0000000 --- a/vhdl/dsp56k/asm/test_alu/test_tcc.asm +++ /dev/null @@ -1,10 +0,0 @@ - move #20,r1 - move #$ABCDEF,x0 - move #$123456,b - andi #$00,ccr - tcs x0,a r1,r3 - tcc x0,b r1,r2 - ; set Zero Flag - ori #$04,ccr - teq x0,a r1,r3 - tne x0,b r1,r2 diff --git a/vhdl/dsp56k/asm/test_alu/test_tfr.asm b/vhdl/dsp56k/asm/test_alu/test_tfr.asm deleted file mode 100644 index 26fa4c1..0000000 --- a/vhdl/dsp56k/asm/test_alu/test_tfr.asm +++ /dev/null @@ -1,7 +0,0 @@ - move #$ABCDEF,a - move #$123456,b - tfr a,b b,a - move #$555555,x0 - move #$AAAAAA,y1 - tfr x0,a a,x0 - tfr y1,b b,y0 diff --git a/vhdl/dsp56k/asm/test_alu/test_tst.asm b/vhdl/dsp56k/asm/test_alu/test_tst.asm deleted file mode 100644 index b86e4a4..0000000 --- a/vhdl/dsp56k/asm/test_alu/test_tst.asm +++ /dev/null @@ -1,9 +0,0 @@ - clr b - tst b -; set only carry bit - andi #$00,ccr - ori #$01,ccr - move #>$80,b2 - tst b - move #>$7F,b2 - tst b diff --git a/vhdl/dsp56k/asm/test_mem/test.asm b/vhdl/dsp56k/asm/test_mem/test.asm deleted file mode 100644 index 17599e4..0000000 --- a/vhdl/dsp56k/asm/test_mem/test.asm +++ /dev/null @@ -1,8 +0,0 @@ - - move #4,r0 - move #20,r1 - move r1,x:(r0) - move x:(r0),a - move r1,y:(r0) - move l:(r0)+,ab - diff --git a/vhdl/dsp56k/asm/test_pm_l/test.asm b/vhdl/dsp56k/asm/test_pm_l/test.asm deleted file mode 100644 index 821d39b..0000000 --- a/vhdl/dsp56k/asm/test_pm_l/test.asm +++ /dev/null @@ -1,21 +0,0 @@ - - move #>$10,x0 - move #>$11,x1 - move #11,a1 - move #-3,a2 - jclr #0,a,blubb - bset #0,x:(r0)+ - move #>$26,y0 - move #>$27,y1 - move x,L:(r0)+ - move y,L:(r0)+ - move x,L:$0A - move y,L:$1F - move y,L:$00A0 - move x,L:$004F - move L:-(r0),x - move L:-(r0),y - move L:$0A,x - move L:$1F,y -blubb - diff --git a/vhdl/dsp56k/doc/Change.log b/vhdl/dsp56k/doc/Change.log deleted file mode 100644 index 1dc8d5b..0000000 --- a/vhdl/dsp56k/doc/Change.log +++ /dev/null @@ -1,185 +0,0 @@ -Done: -02.01.09 - - Started work on pipeline (FE, FE2, DC, AG, EX) - - Program counter counts linearly - - Initial program memory holds program data - - Started work on instruction decoder -03.01.09 - - Jump instructions work (with flushing of the pipeline) - - First version of AGU implemented - - Detection of double word instructions - - Initial version of global register file -04.01.09 - - Included hardware stack - - Finished support for JSR and JSCC instructions - - RTI/RTS work - - ANDI/ORI work - - Initial work on REP instruction -10.01.09 - - Initial suppurt for X memory accesses. One stall cycle is introduced when - accessing the X memory. - - Finished implementation of REP instruction. Reading number of loops from - registers is still missing. - - Initial support for DO loops. - - Preventing to write the R registers when stalling occurs or a jump is - performed -11.01.09 - - Finished implementation of DO loops (stop looping at the end) - - Nested loops work - - Single instruction loops work - - ENDDO instruction implemented (very much the same as usual end of the loop) -12.01.09 - - Included Y memory and its addressing modes for REP and DO instruction. - - Setup of a sheet showing which types of which instructions have been - implemented and how many clock cycles are needed. -16.01.09 - - Integration of LUA instruction. -24.01.09 - - Integrated different addressing schemes (immediate short, immediate long, - absolute address) - - Integration and test of MOVE(C) instruction. Some modes missing (writing to - memory) - - Testing of Y memory read accesses. -26.01.09 - - Continued testing of different addressing modes. - - Decoding for first parallel move operations. -01.02.09 - - Moved memory components to an extra entity (memory_management) - - Writing to internal X and Y memory supported. Problems are possible for - reading the same address one instruction after writing at the same address! - - Included ALU registers (x,y,a,b) into register file - - Integration of x/y/l bus started -03.02.09 - - Continued testing of parallel moves (there are quite a few cases!) -07.02.09 - - Fixed REP instruction for instructions that are causing a stall due to - a memory read - - Fixed fetching from program data when stalling. - - Fixed detection of double word instruction, when previous instruction - used the AGU as well (forgot instruction word in sensitivity list). - - Continued testing of parallel moves. - - First synthesis run: Changed RAM description to map to BRAMs, removed - latches, and many things are still missing, post-synthesis results: - - Xilinx Spartan3A, Speed-Grade -4 - - 1488 FFs - - 4657 4-Input LUTs - - 3 BRAMs - - 71.08 MHz -08.02.09 - - Implemented second address generation unit in order to access X and Y - memory at the same time - - Implemented reverse carry addressing modes for FFT addressing - - Started implementation of modulo addressing. - - Set M0-M7 to -1 in reset. - - Downloaded the assembler for DSP56300. I hope to use it in order to - generate the content of the program memory automatically, which will - boost the testing speed... - - Encoding each instruction to test by hand just sucks. I think I will - integrate some bootloader in order to use the LOD files from the - assembler to initiate the RAMs. - - Implementation of data shifter and limiter (when accessing a or b and - giving the result to XDB or YDB). Needs testing. - - Integration for L: addressing modes. Needs nesting. -10.02.09 - - Fixed decoding of X: and Y: adressing mode (collided with L: adressing) - - L: adressing modes are working -14.02.09 - - Implemented BCHG,BCLR,BSET,BTST,JCLR,JSCLR,JSET,JSSET. A lot of testing - is still needed. Peripheral register accesses are still missing. - - Second synthesis run: Removed new latches again. - , many things are still missing, post-synthesis results: - - Xilinx Spartan3A, Speed-Grade -4 - - 1519 FFs - - 6210 4-Input LUTs - - 3 BRAMs - - 51.68 MHz - * Critical path for JSCLR/JSSET=> read limited a/b, go through bit modify - unit, test whether condition met, push data to stack. Reading of - limited A/B is probably a bug (DSP56001 UM says CCR is not changed, - in DSP56300 simulator the flag is set when reading a/b!!). -15.02.09 - - Started implementing the ALU. - - ABS works. - - MPY(R), MAC(R) implemented, rounding is missing. - - Clock frequency dropped to 41 MHz, but the critical path is not caused by - the MAC in the ALU! The multiplier is composed of four 18x18 multipliers - and still seems to be very fast! -16.02.09 - - Implemented decoding and controlling of ALU for - ADC, ADD, ADDL, ADDR, AND, ASL, ASR, CLR, CMP, CMPM, EOR, NEG, NOT, OR - Still missing ALU instructions: - DIV, NORM, RND, ROL, ROR, SBC, SUB, SUBL, SUBR, Tcc, TFR, TST - Except for DIV and NORM this will be straight forward. - - Other things that need to be done : - * Adress Generation Unit does not support modulo addressing. - * MOVEP/MOVEM/STOP/WAIT/ILLEGAL/RESET/SWI - * Interrupts - * External memory accesses - * Peripheral devices (SCI, SSI, Host port) -17.02.09 - - Implemented decoding and controlling of ALU instructions for - RND, ROL, ROR, SBC, SUB, SUBL, SUBR, TFR, TST - Still missing ALU instructions: - DIV, NORM, Tcc -08.03.09 - - Forgot integration of LSR and LSL instructions. TBD. - - Started integration of Condition flag generation in ALU. - - New synthesis run with ALU, register balancing: - - Xilinx Spartan3A, Speed-Grade -4 - - 3115 FFs - - 7417 4-Input LUTs - - 3 BRAMs - - 39.47 MHz -13.03.09 - - Integrated decoding of LSL/LSR instructions. - - Integrated rotating function into ALU. - - Included convergent rounding functionality into ALU. - - Implemented Tcc instruction. - - Implemented DIV instruction. -15.03.09 - - Tested ABS,ADC,ADD,ADDL,ADDR,AND,ASL,ASR,CLR,CMP,CMPM,DIV,EOR, - LSL,LSR,MPY,MPYR,MAC,MACR,NEG,NOT,OR - - Bugs fixed: - - Detection of overflow corrected when negating most negative - value $80 000000 000000. - - Decoding of ADC and TFR clarified. - - Overflow flag generation when left shifting of 56 bit values. - - For logical operations the flag generation relied on the adder - output which was wrong. Now relies on the Logical unit output. - - Decoding of CMPM clarified in order not to conflict with NOT. - - Shifter was used for CMP(M) instructions, which is wrong. - - Hopefully calculation of carry and overflow flag work correctly now... - - MPY/MAC write result back. - - Limit Flag is not cleared by the ALU anymore (has to be reset by the - user!). -16.03.09 - - Tested RND - - Bugs fixed: - - Simulator seems to misunderstand the X"1000000" where the first digit - represents a single bit. Comparing against this value fixed! RND works. - -17.03.09 - - Tested ROR,ROL,SBC,SUB,SUBL,SUBR,TCC,TFR,TST,NORM - - Integrated logic for NORM instruction support. - - ALU is complete now! - - Bugs fixed: - - Fixed setting of CCR for ROL/ROR - - TCC didn't read register through ALU - - Known bugs: - - Carry calculation for SBC is still buggy - - New synthesis run with ALU, register balancing: - - Xilinx Spartan3A, Speed-Grade -4 - - 1801 FFs - - 7407 4-Input LUTs - - 3 BRAMs - - 30.84 MHz - Critical path is in the ALU (multiplication, adding, rounding, zero-flag - calculation). I wonder why the values changed like that since the - last synthesis run. -26.03.09 - - Included support for modulo addressing in AGUs. This allows for the - integration of ring buffers. Now 7900 LUTs. -18.05.10 - - Commenting of code. - - Added second memory port for p-mem (needed for movem-instruction) - diff --git a/vhdl/dsp56k/src/adgen_stage.vhd b/vhdl/dsp56k/src/adgen_stage.vhd deleted file mode 100644 index df96c27..0000000 --- a/vhdl/dsp56k/src/adgen_stage.vhd +++ /dev/null @@ -1,291 +0,0 @@ ------------------------------------------------------------------------------- ---! @file ---! @author Matthias Alles ---! @date 01/2009 ---! @brief Address generation logic ---! ------------------------------------------------------------------------------- -library ieee; -use ieee.std_logic_1164.all; -use ieee.numeric_std.all; -library work; -use work.parameter_pkg.all; -use work.types_pkg.all; -use work.constants_pkg.all; - -entity adgen_stage is port( - activate_adgen : in std_logic; - activate_x_mem : in std_logic; - activate_y_mem : in std_logic; - activate_l_mem : in std_logic; - instr_word : in std_logic_vector(23 downto 0); - instr_array : in instructions_type; - optional_ea_word : in std_logic_vector(23 downto 0); - register_file : in register_file_type; - adgen_mode_a : in adgen_mode_type; - adgen_mode_b : in adgen_mode_type; - address_out_x : out unsigned(BW_ADDRESS-1 downto 0); - address_out_y : out unsigned(BW_ADDRESS-1 downto 0); - wr_R_port_A_valid : out std_logic; - wr_R_port_A : out addr_wr_port_type; - wr_R_port_B_valid : out std_logic; - wr_R_port_B : out addr_wr_port_type -); -end entity; - - -architecture rtl of adgen_stage is - - signal address_out_x_int : unsigned(BW_ADDRESS-1 downto 0); - - signal r_reg_local_x : unsigned(BW_ADDRESS-1 downto 0); - signal n_reg_local_x : unsigned(BW_ADDRESS-1 downto 0); - signal m_reg_local_x : unsigned(BW_ADDRESS-1 downto 0); - - signal r_reg_local_y : unsigned(BW_ADDRESS-1 downto 0); - signal n_reg_local_y : unsigned(BW_ADDRESS-1 downto 0); - signal m_reg_local_y : unsigned(BW_ADDRESS-1 downto 0); - - function calculate_modulo_bitmask(m_reg_local : in unsigned ) return std_logic_vector is - variable modulo_bitmask_intern : std_logic_vector(BW_ADDRESS-1 downto 0); - begin - modulo_bitmask_intern(BW_ADDRESS-1) := m_reg_local(BW_ADDRESS-1); - for i in BW_ADDRESS-2 downto 0 loop - modulo_bitmask_intern(i) := modulo_bitmask_intern(i+1) or m_reg_local(i); - end loop; - - return modulo_bitmask_intern; - end function calculate_modulo_bitmask; - - function calculate_new_r_reg(new_r_reg_intermediate, r_reg_local, m_reg_local: in unsigned; - modulo_bitmask: in std_logic_vector ) return unsigned is - variable modulo_result : unsigned(BW_ADDRESS-1 downto 0); - variable new_r_reg_intern : unsigned(BW_ADDRESS-1 downto 0); - begin - -- cut out the bits we are interested in - -- for modulo addressing - for i in 0 to BW_ADDRESS-1 loop - if modulo_bitmask(i) = '1' then - modulo_result(i) := new_r_reg_intermediate(i); - else - modulo_result(i) := '0'; - end if; - end loop; - -- compare whether an overflow occurred and we - -- have to renormalize the result - if modulo_result > m_reg_local then - modulo_result := modulo_result - m_reg_local; - end if; - - -- linear addressing - if m_reg_local = 2**BW_ADDRESS-1 then - new_r_reg_intern := new_r_reg_intermediate; - -- bit reverse operation - elsif m_reg_local = 0 then - for i in 0 to BW_ADDRESS-1 loop - new_r_reg_intern(BW_ADDRESS - 1 - i) := new_r_reg_intermediate(i); - end loop; - -- modulo arithmetic / linear addressing - else - -- only update the bits that are part of the bitmask! - for i in 0 to BW_ADDRESS-1 loop - if modulo_bitmask(i) = '1' then - new_r_reg_intern(i) := modulo_result(i); - else - new_r_reg_intern(i) := r_reg_local(i); - end if; - end loop; - end if; - return new_r_reg_intern; - end function calculate_new_r_reg; - - procedure set_operands(r_reg_local, m_reg_local, addr_mod : in unsigned; op1, op2 : out unsigned) is - begin - -- bit reverse operation - if m_reg_local = 0 then - -- reverse the input to the adder bit wise - -- so we just need to use a single adder - for i in 0 to BW_ADDRESS-1 loop - op1(BW_ADDRESS - 1 - i) := r_reg_local(i); - op2(BW_ADDRESS - 1 - i) := addr_mod(i); - end loop; - -- modulo arithmetic / linear addressing - else - op1 := r_reg_local; - op2 := addr_mod; - end if; - end procedure set_operands; - -begin - - address_out_x <= address_out_x_int; - - r_reg_local_x <= register_file.addr_r(to_integer(unsigned(instr_word(10 downto 8)))); - n_reg_local_x <= register_file.addr_n(to_integer(unsigned(instr_word(10 downto 8)))); - m_reg_local_x <= register_file.addr_m(to_integer(unsigned(instr_word(10 downto 8)))); - - r_reg_local_y <= register_file.addr_r(to_integer(unsigned((not instr_word(10)) & instr_word(14 downto 13)))); - n_reg_local_y <= register_file.addr_n(to_integer(unsigned((not instr_word(10)) & instr_word(14 downto 13)))); - m_reg_local_y <= register_file.addr_m(to_integer(unsigned((not instr_word(10)) & instr_word(14 downto 13)))); - - address_generator_X: process(activate_adgen, instr_word, adgen_mode_a, r_reg_local_x, n_reg_local_x, m_reg_local_x) is - variable op1 : unsigned(BW_ADDRESS-1 downto 0); - variable op2 : unsigned(BW_ADDRESS-1 downto 0); - variable addr_mod : unsigned(BW_ADDRESS-1 downto 0); - variable new_r_reg : unsigned(BW_ADDRESS-1 downto 0); - variable new_r_reg_interm : unsigned(BW_ADDRESS-1 downto 0); - variable modulo_bitmask : std_logic_vector(BW_ADDRESS-1 downto 0); - variable modulo_result : unsigned(BW_ADDRESS-1 downto 0); - begin - - -- select the operands for the calculation - case adgen_mode_a is - -- (Rn) - Nn - when POST_MIN_N => addr_mod := unsigned(- signed(n_reg_local_x)); - -- (Rn) + Nn - when POST_PLUS_N => addr_mod := n_reg_local_x; - -- (Rn)- - when POST_MIN_1 => addr_mod := (others => '1'); -- -1 - -- (Rn)+ - when POST_PLUS_1 => addr_mod := to_unsigned(1, BW_ADDRESS); - -- (Rn) - when NOP => addr_mod := (others => '0'); - -- (Rn + Nn) - when INDEXED_N => addr_mod := n_reg_local_x; - -- -(Rn) - when PRE_MIN_1 => addr_mod := (others => '1'); -- - 1 - -- absolute address (appended to instruction word) - when ABSOLUTE => addr_mod := (others => '0'); - when IMMEDIATE => addr_mod := (others => '0'); - end case; - - ------------------------------------------------ - -- set op1 and op2 according to modulo register - ------------------------------------------------ - set_operands(r_reg_local_x, m_reg_local_x, addr_mod, op1, op2); - - ------------------------- - -- Calculate new address - ------------------------- - new_r_reg_interm := op1 + op2; - - ---------------------------------- - -- Calculate new register content - ----------------------------------- - modulo_bitmask := calculate_modulo_bitmask(m_reg_local_x); - new_r_reg := calculate_new_r_reg(new_r_reg_interm, r_reg_local_x, m_reg_local_x, modulo_bitmask); - - -- store the updated register in the global register file - -- do not store when we do nothing or there is nothing to update - -- LUA instructions DO NOT UPDATE the source register!! - if (adgen_mode_a = NOP or adgen_mode_a = ABSOLUTE or adgen_mode_a = IMMEDIATE or instr_array = INSTR_LUA) then - wr_R_port_A_valid <= '0'; - else - wr_R_port_A_valid <= '1'; - end if; - wr_R_port_A.reg_number <= unsigned(instr_word(10 downto 8)); - wr_R_port_A.reg_value <= new_r_reg; - - -- select the output of the AGU - case adgen_mode_a is - -- (Rn) - Nn - when POST_MIN_N => address_out_x_int <= r_reg_local_x; - -- (Rn) + Nn - when POST_PLUS_N => address_out_x_int <= r_reg_local_x; - -- (Rn)- - when POST_MIN_1 => address_out_x_int <= r_reg_local_x; - -- (Rn)+ - when POST_PLUS_1 => address_out_x_int <= r_reg_local_x; - -- (Rn) - when NOP => address_out_x_int <= r_reg_local_x; - -- (Rn + Nn) - when INDEXED_N => address_out_x_int <= new_r_reg; - -- -(Rn) - when PRE_MIN_1 => address_out_x_int <= new_r_reg; - -- absolute address (appended to instruction word) - when ABSOLUTE => address_out_x_int <= unsigned(optional_ea_word(BW_ADDRESS-1 downto 0)); - when IMMEDIATE => address_out_x_int <= r_reg_local_x; -- Done externally, value never used - end case; - -- LUA instructions only use the updated address! - if instr_array = INSTR_LUA then - address_out_x_int <= new_r_reg; - end if; - - end process address_generator_X; - - - --------------------------------------------------------- - -- Second address generator - -- Used when accessing X and Y memory at the same time - --------------------------------------------------------- - address_generator_Y: process(activate_adgen, activate_x_mem, activate_y_mem, activate_l_mem, instr_word, - register_file, adgen_mode_b, address_out_x_int, r_reg_local_y, n_reg_local_y, m_reg_local_y) is - variable op1 : unsigned(BW_ADDRESS-1 downto 0); - variable op2 : unsigned(BW_ADDRESS-1 downto 0); - variable addr_mod : unsigned(BW_ADDRESS-1 downto 0); - variable new_r_reg : unsigned(BW_ADDRESS-1 downto 0); - variable new_r_reg_interm : unsigned(BW_ADDRESS-1 downto 0); - variable modulo_bitmask : std_logic_vector(BW_ADDRESS-1 downto 0); - variable modulo_result : unsigned(BW_ADDRESS-1 downto 0); - begin - - -- select the operands for the calculation - case adgen_mode_b is - -- (Rn) + Nn - when POST_PLUS_N => addr_mod := n_reg_local_y; - -- (Rn)- - when POST_MIN_1 => addr_mod := (others => '1'); -- -1 - -- (Rn)+ - when POST_PLUS_1 => addr_mod := to_unsigned(1, BW_ADDRESS); - -- (Rn) - when others => addr_mod := (others => '0'); - end case; - - ------------------------------------------------ - -- set op1 and op2 according to modulo register - ------------------------------------------------ - set_operands(r_reg_local_y, m_reg_local_y, addr_mod, op1, op2); - - ------------------------- - -- Calculate new address - ------------------------- - new_r_reg_interm := op1 + op2; - - ---------------------------------- - -- Calculate new register content - ----------------------------------- - modulo_bitmask := calculate_modulo_bitmask(m_reg_local_y); - new_r_reg := calculate_new_r_reg(new_r_reg_interm, r_reg_local_y, m_reg_local_y, modulo_bitmask); - - -- store the updated register in the global register file - -- do not store when we do nothing or there is nothing to update - if adgen_mode_b = NOP then - wr_R_port_B_valid <= '0'; - else - wr_R_port_B_valid <= '1'; - end if; - wr_R_port_B.reg_number <= unsigned((not instr_word(10)) & instr_word(14 downto 13)); - wr_R_port_B.reg_value <= new_r_reg; - - -- the address for the y memory is calculated in the first AGU if the x memory is not accessed! - -- so use the other output as address output for the y memory! - -- Furthermore, use the same address for L memory accesses (X and Y memory access the same address!) - if (activate_y_mem = '1' and activate_x_mem = '0') or activate_l_mem = '1' then - address_out_y <= address_out_x_int; - -- in any other case use the locally computed value - else - -- select the output of the AGU - case adgen_mode_b is - -- (Rn) + Nn - when POST_PLUS_N => address_out_y <= r_reg_local_y; - -- (Rn)- - when POST_MIN_1 => address_out_y <= r_reg_local_y; - -- (Rn)+ - when POST_PLUS_1 => address_out_y <= r_reg_local_y; - -- (Rn) - when others => address_out_y <= r_reg_local_y; - end case; - end if; - end process address_generator_Y; - -end architecture; diff --git a/vhdl/dsp56k/src/constants_pkg.vhd b/vhdl/dsp56k/src/constants_pkg.vhd deleted file mode 100644 index c84a406..0000000 --- a/vhdl/dsp56k/src/constants_pkg.vhd +++ /dev/null @@ -1,74 +0,0 @@ ------------------------------------------------------------------------------- ---! @file ---! @author Matthias Alles ---! @date 01/2009 ---! @brief General constants for decoding pipeline. ---! ------------------------------------------------------------------------------- -library ieee; -use ieee.std_logic_1164.all; -use ieee.numeric_std.all; -library work; -use work.parameter_pkg.all; -use work.types_pkg.all; - - -package constants_pkg is - - - ------------------------- - -- Flags in CCR register - ------------------------- - - constant C_FLAG : natural := 0; - constant V_FLAG : natural := 1; - constant Z_FLAG : natural := 2; - constant N_FLAG : natural := 3; - constant U_FLAG : natural := 4; - constant E_FLAG : natural := 5; - constant L_FLAG : natural := 6; - constant S_FLAG : natural := 7; - - - ------------------- - -- Pipeline stages - ------------------- - - constant ST_FE_FE2 : natural := 0; - constant ST_FE2_DEC : natural := 1; - constant ST_DEC_ADG : natural := 2; - constant ST_ADG_EX : natural := 3; - - - ---------------------- - -- Activation signals - ---------------------- - - constant ACT_ADGEN : natural := 0; -- Run the address generator - constant ACT_ALU : natural := 1; -- Activation of ALU results in modification of the status register - constant ACT_EXEC_BRA : natural := 2; -- Branch (in execute stage) - constant ACT_EXEC_CR_MOD : natural := 3; -- Control Register Modification (in execute stage) - constant ACT_EXEC_LOOP : natural := 4; -- Loop instruction (REP, DO) - constant ACT_X_MEM_RD : natural := 5; -- Init read from X memory - constant ACT_Y_MEM_RD : natural := 6; -- Init read from Y memory - constant ACT_P_MEM_RD : natural := 7; -- Init read from P memory - constant ACT_X_MEM_WR : natural := 8; -- Init write to X memory - constant ACT_Y_MEM_WR : natural := 9; -- Init write to Y memory - constant ACT_P_MEM_WR : natural := 10; -- Init write to P memory - constant ACT_REG_RD : natural := 11; -- Read from register (6 bit addressing) - constant ACT_REG_WR : natural := 12; -- Write to register (6 bit addressing) - constant ACT_IMM_8BIT : natural := 13; -- 8 bit immediate operand (in instruction word) - constant ACT_IMM_12BIT : natural := 14; -- 12 bit immediate operand (in instruction word) - constant ACT_IMM_LONG : natural := 15; -- 24 bit immediate operant (in optional instruction word) - constant ACT_X_BUS_RD : natural := 16; -- Read data via X-bus (from x0,x1,a,b) - constant ACT_X_BUS_WR : natural := 17; -- Write data via X-bus (to x0,x1,a,b) - constant ACT_Y_BUS_RD : natural := 18; -- Read data via Y-bus (from y0,y1,a,b) - constant ACT_Y_BUS_WR : natural := 19; -- Write data via Y-bus (to y0,y1,a,b) - constant ACT_L_BUS_RD : natural := 20; -- Read data via L-bus (from a10, b10,x,y,a,b,ab,ba) - constant ACT_L_BUS_WR : natural := 21; -- Write data via L-bus (to a10, b10,x,y,a,b,ab,ba) - constant ACT_BIT_MOD_WR : natural := 22; -- Bit modify write (to set for BSET, BCLR, BCHG) - constant ACT_REG_WR_CC : natural := 23; -- Write to register file conditionally (Tcc) - constant ACT_ALU_WR_CC : natural := 24; -- Write ALU result conditionally (Tcc) - constant ACT_NORM : natural := 25; -- NORM instruction needs special handling - -end package constants_pkg; diff --git a/vhdl/dsp56k/src/decode_stage.vhd b/vhdl/dsp56k/src/decode_stage.vhd deleted file mode 100644 index 0725c6b..0000000 --- a/vhdl/dsp56k/src/decode_stage.vhd +++ /dev/null @@ -1,1226 +0,0 @@ ------------------------------------------------------------------------------- ---! @file ---! @author Matthias Alles ---! @date 01/2009 ---! @brief Instruction Decoder ---! ---! @details This entity generates multiple flags depending on the instruction ---! word. The flags are used for activation of certain logic units within the ---! subsequent pipeline stages (ALU, AGU, bit modifications, ...). Also the ---! decoder checks whether currently we are processing a double word ---! instruction. ---! ------------------------------------------------------------------------------- -library ieee; -use ieee.std_logic_1164.all; -use ieee.numeric_std.all; -library work; -use work.parameter_pkg.all; -use work.types_pkg.all; -use work.constants_pkg.all; - -entity decode_stage is port( - activate_dec : in std_logic; - instr_word : in std_logic_vector(23 downto 0); - dble_word_instr : out std_logic; - instr_array : out instructions_type; - act_array : out std_logic_vector(NUM_ACT_SIGNALS-1 downto 0); - reg_wr_addr : out std_logic_vector(5 downto 0); - reg_rd_addr : out std_logic_vector(5 downto 0); - x_bus_rd_addr : out std_logic_vector(1 downto 0); - x_bus_wr_addr : out std_logic_vector(1 downto 0); - y_bus_rd_addr : out std_logic_vector(1 downto 0); - y_bus_wr_addr : out std_logic_vector(1 downto 0); - l_bus_addr : out std_logic_vector(2 downto 0); - adgen_mode_a : out adgen_mode_type; - adgen_mode_b : out adgen_mode_type; - alu_ctrl : out alu_ctrl_type -); -end entity; - - -architecture rtl of decode_stage is - - signal instr_array_int : instructions_type; --- signal activate_pm_int : std_logic; - type adgen_bittype_type is (NOP, SINGLE_X, SINGLE_X_SHORT, DOUBLE_X_Y); - -- SINGLE_X : MMMRRR - -- SINGLE_X_SHORT : MMRRR - -- DOUBLE_X_Y : mmrrMMRRR - signal adgen_bittype : adgen_bittype_type; - - signal ea_extension_available : std_logic; - - signal alu_tcc_decoded : std_logic; - signal alu_div_decoded : std_logic; - signal alu_norm_decoded : std_logic; - -begin - - - -- output the decoded instruction - instr_array <= instr_array_int; - - -- calculate whether this is a double word instruction - dble_word_instr <= '1' when ea_extension_available = '1' or - instr_array_int = INSTR_DO or - instr_array_int = INSTR_JCLR or - instr_array_int = INSTR_JSCLR or - instr_array_int = INSTR_JSET or - instr_array_int = INSTR_JSSET else - '0'; - - alu_instruction_decoder: process(instr_word, activate_dec, alu_tcc_decoded, - alu_div_decoded, alu_norm_decoded) is - variable instr_word_var : std_logic_vector(23 downto 0); - begin - if activate_dec = '1' then - instr_word_var := instr_word; - else - instr_word_var := (others => '0'); - end if; - - alu_ctrl.mul_op1 <= (others => '0'); - alu_ctrl.mul_op2 <= (others => '0'); - alu_ctrl.rotate <= '0'; - alu_ctrl.div_instr <= '0'; - alu_ctrl.norm_instr <= '0'; - alu_ctrl.shift_src <= '0'; - alu_ctrl.shift_src_sign <= (others => '0'); - alu_ctrl.shift_mode <= ZEROS; - alu_ctrl.add_src_stage_1 <= (others => '0'); - alu_ctrl.add_src_stage_2 <= (others => '0'); - alu_ctrl.add_src_sign <= (others => '0'); - alu_ctrl.logic_function <= (others => '0'); - alu_ctrl.word_24_update <= '0'; - alu_ctrl.rounding_used <= (others => '0'); - alu_ctrl.store_result <= '0'; - for i in 0 to 7 loop -- by default do not touch any of the ccr flags (L;E;U;N;Z;V;C) - alu_ctrl.ccr_flags_ctrl(i) <= DONT_TOUCH; - end loop; - alu_ctrl.dst_accu <= instr_word_var(3); -- default value for all alu operations - - -- check wether instruction that allows parallel moves - -- has to be decoded, then it is an ALU operation in the 8 LSBs - -- Only exceptions are DIV, NORM, and Tcc - if instr_word_var(23 downto 20) /= "0000" then - -- ABS - if instr_word_var(7 downto 4) = "0010" and instr_word_var(2 downto 0) = "110" then - -- Read accu - alu_ctrl.shift_mode <= NO_SHIFT; - alu_ctrl.shift_src <= instr_word_var(3); -- source/dst are the same register - alu_ctrl.shift_src_sign <= "10"; -- the sign of the operand depends on the operand - -- negative operand will negate the content of the accu as - -- needed by the ABS instruction - alu_ctrl.add_src_stage_2 <= "00"; -- select zero - alu_ctrl.store_result <= '1'; -- store the result - -- set all flags but carry - for i in 1 to 7 loop - alu_ctrl.ccr_flags_ctrl(i) <= MODIFY; - end loop; - end if; - -- ADC - if instr_word_var(7 downto 5) = "001" and instr_word_var(2 downto 0) = "001" then - -- Read accu - alu_ctrl.shift_mode <= NO_SHIFT; - alu_ctrl.shift_src <= instr_word_var(3); -- accumulate to the same register we want to write to - alu_ctrl.shift_src_sign <= "00"; -- with the original sign - -- Read S - alu_ctrl.add_src_stage_1 <= "01" & instr_word_var(4); -- X or Y - alu_ctrl.add_src_stage_2 <= "01"; -- select the register source - alu_ctrl.add_src_sign <= "00"; -- with original sign - alu_ctrl.store_result <= '1'; -- store the result - alu_ctrl.rounding_used <= "10"; -- add carry to result of addition - -- set all flags - for i in 0 to 7 loop - alu_ctrl.ccr_flags_ctrl(i) <= MODIFY; - end loop; - end if; - -- ADD - if instr_word_var(7) = '0' and instr_word_var(2 downto 0) = "000" and instr_word_var(6 downto 4) /= "000" then - -- Read accu - alu_ctrl.shift_mode <= NO_SHIFT; - alu_ctrl.shift_src <= instr_word_var(3); -- accumulate to the same register we want to write to - alu_ctrl.shift_src_sign <= "00"; -- with the original sign - -- Read S - alu_ctrl.add_src_stage_1 <= instr_word_var(6 downto 4); -- source register (JJJ encoding) - alu_ctrl.add_src_stage_2 <= "01"; -- select the register source - alu_ctrl.add_src_sign <= "00"; -- with original sign - alu_ctrl.store_result <= '1'; -- store the result - alu_ctrl.rounding_used <= "00"; -- no rounding needed - -- set all flags - for i in 0 to 7 loop - alu_ctrl.ccr_flags_ctrl(i) <= MODIFY; - end loop; - end if; - -- ADDL - if instr_word_var(7 downto 4) = "0001" and instr_word_var(2 downto 0) = "010" then - -- Read accu - alu_ctrl.shift_mode <= SHIFT_LEFT; - alu_ctrl.shift_src <= instr_word_var(3); -- accumulate to the same register we want to write to - alu_ctrl.shift_src_sign <= "00"; -- with the original sign - -- Read S - alu_ctrl.add_src_stage_1 <= instr_word_var(6 downto 4); -- source register (JJJ encoding) (here: A,B) - alu_ctrl.add_src_stage_2 <= "01"; -- select the register source - alu_ctrl.add_src_sign <= "00"; -- with original sign - alu_ctrl.store_result <= '1'; -- store the result - alu_ctrl.rounding_used <= "00"; -- no rounding needed - -- set all flags - for i in 0 to 7 loop - alu_ctrl.ccr_flags_ctrl(i) <= MODIFY; - end loop; - end if; - -- ADDR - if instr_word_var(7 downto 4) = "0000" and instr_word_var(2 downto 0) = "010" then - -- Read accu - alu_ctrl.shift_mode <= SHIFT_RIGHT; - alu_ctrl.shift_src <= instr_word_var(3); -- accumulate to the same register we want to write to - alu_ctrl.shift_src_sign <= "00"; -- with the original sign - -- Read S - alu_ctrl.add_src_stage_1 <= instr_word_var(6 downto 5) & '1'; -- source register (JJJ encoding) (here: A,B) - alu_ctrl.add_src_stage_2 <= "01"; -- select the register source - alu_ctrl.add_src_sign <= "00"; -- with original sign - alu_ctrl.store_result <= '1'; -- store the result - alu_ctrl.rounding_used <= "00"; -- no rounding needed - -- set all flags - for i in 0 to 7 loop - alu_ctrl.ccr_flags_ctrl(i) <= MODIFY; - end loop; - end if; - -- AND / OR / EOR - if instr_word_var(7 downto 6) = "01" and (instr_word_var(2 downto 0) = "110" or -- and - instr_word_var(2 downto 0) = "010" or -- or - instr_word_var(2 downto 0) = "011") then -- eor - alu_ctrl.logic_function <= instr_word_var(2 downto 0); -- 000: none, 110: and, 010: or, 011: eor, 111: not - alu_ctrl.word_24_update <= '1'; -- only accumulator bits 47 downto 24 affected? - -- Read accu - alu_ctrl.shift_mode <= NO_SHIFT; - alu_ctrl.shift_src <= instr_word_var(3); -- accumulate to the same register we want to write to - alu_ctrl.shift_src_sign <= "00"; -- with the original sign - -- Read S - alu_ctrl.add_src_stage_1 <= instr_word_var(6 downto 4); -- source register (JJJ encoding) (here: A,B) - alu_ctrl.add_src_stage_2 <= "01"; -- select the register source - alu_ctrl.add_src_sign <= "00"; -- with original sign - alu_ctrl.store_result <= '1'; -- store the result - alu_ctrl.rounding_used <= "00"; -- no rounding needed - -- set following flags - alu_ctrl.ccr_flags_ctrl(N_FLAG) <= MODIFY; - alu_ctrl.ccr_flags_ctrl(Z_FLAG) <= MODIFY; - alu_ctrl.ccr_flags_ctrl(V_FLAG) <= CLEAR; - end if; - -- ASL - if instr_word_var(7 downto 4) = "0011" and instr_word_var(2 downto 0) = "010" then - -- Read accu - alu_ctrl.shift_mode <= SHIFT_LEFT; - alu_ctrl.shift_src <= instr_word_var(3); -- accumulate to the same register we want to write to - alu_ctrl.shift_src_sign <= "00"; -- with the original sign - -- Read S - alu_ctrl.add_src_stage_2 <= "00"; -- select zero as operand - alu_ctrl.add_src_sign <= "00"; -- with original sign - alu_ctrl.store_result <= '1'; -- store the result - alu_ctrl.rounding_used <= "00"; -- no rounding needed - -- set all flags - for i in 0 to 7 loop - alu_ctrl.ccr_flags_ctrl(i) <= MODIFY; - end loop; - end if; - -- ASR - if instr_word_var(7 downto 4) = "0010" and instr_word_var(2 downto 0) = "010" then - -- Read accu - alu_ctrl.shift_mode <= SHIFT_RIGHT; - alu_ctrl.shift_src <= instr_word_var(3); -- accumulate to the same register we want to write to - alu_ctrl.shift_src_sign <= "00"; -- with the original sign - -- Read S - alu_ctrl.add_src_stage_2 <= "00"; -- select zero as operand - alu_ctrl.add_src_sign <= "00"; -- with original sign - alu_ctrl.store_result <= '1'; -- store the result - alu_ctrl.rounding_used <= "00"; -- no rounding needed - -- set all flags, V-flag will be cleared due to shifting - for i in 0 to 7 loop - alu_ctrl.ccr_flags_ctrl(i) <= MODIFY; - end loop; - end if; - -- CLR - if instr_word_var(7 downto 4) = "0001" and instr_word_var(2 downto 0) = "011" then - -- Read accu - alu_ctrl.shift_mode <= ZEROS; - -- Read S - alu_ctrl.add_src_stage_2 <= "00"; -- select zero as operand - alu_ctrl.add_src_sign <= "00"; -- with original sign - alu_ctrl.store_result <= '1'; -- store the result - alu_ctrl.rounding_used <= "00"; -- no rounding needed - -- set following flags - alu_ctrl.ccr_flags_ctrl(S_FLAG) <= MODIFY; - alu_ctrl.ccr_flags_ctrl(E_FLAG) <= MODIFY; - alu_ctrl.ccr_flags_ctrl(U_FLAG) <= MODIFY; - alu_ctrl.ccr_flags_ctrl(N_FLAG) <= MODIFY; - alu_ctrl.ccr_flags_ctrl(Z_FLAG) <= MODIFY; - alu_ctrl.ccr_flags_ctrl(V_FLAG) <= CLEAR; - end if; - -- CMP - if instr_word_var(7) = '0' and instr_word_var(6 downto 5) /= "01" and - instr_word_var(2 downto 0) = "101" then - -- Read accu - alu_ctrl.shift_mode <= NO_SHIFT; - alu_ctrl.shift_src <= instr_word_var(3); -- accumulate to the same register we want to write to - alu_ctrl.shift_src_sign <= "00"; -- with the original sign - -- Read S - if instr_word_var(6) = '1' then - alu_ctrl.add_src_stage_1 <= instr_word_var(6 downto 4); -- source register (JJJ encoding) x0,x1,y0,y1 - else - alu_ctrl.add_src_stage_1 <= "001"; -- select opposite accu (JJJ encoding) - end if; - alu_ctrl.add_src_stage_2 <= "01"; -- select the register source - alu_ctrl.add_src_sign <= "01"; -- with negative sign - alu_ctrl.store_result <= '0'; -- do not store the result - alu_ctrl.rounding_used <= "00"; -- no rounding needed - -- set all flags - for i in 0 to 7 loop - alu_ctrl.ccr_flags_ctrl(i) <= MODIFY; - end loop; - end if; - -- CMPM - if instr_word_var(7) = '0' and instr_word_var(6 downto 5) /= "01" and - instr_word_var(2 downto 0) = "111" then - -- Read accu - alu_ctrl.shift_mode <= NO_SHIFT; - alu_ctrl.shift_src <= instr_word_var(3); -- accumulate to the same register we want to write to - alu_ctrl.shift_src_sign <= "10"; -- with the sign dependant sign (magnitude!) - -- Read S - if instr_word_var(6) = '1' then - alu_ctrl.add_src_stage_1 <= instr_word_var(6 downto 4); -- source register (JJJ encoding) x0,x1,y0,y1 - else - alu_ctrl.add_src_stage_1 <= "001"; -- select opposite accu (JJJ encoding) - end if; - alu_ctrl.add_src_stage_2 <= "01"; -- select the register source - alu_ctrl.add_src_sign <= "10"; -- with sign dependant sign (magnitude!) - alu_ctrl.store_result <= '0'; -- do not store the result - alu_ctrl.rounding_used <= "00"; -- no rounding needed - -- set all flags - for i in 0 to 7 loop - alu_ctrl.ccr_flags_ctrl(i) <= MODIFY; - end loop; - end if; - -- LSL - if instr_word_var(7 downto 4) = "0011" and instr_word_var(2 downto 0) = "011" then - alu_ctrl.word_24_update <= '1'; - -- Read accu - alu_ctrl.shift_mode <= SHIFT_LEFT; - alu_ctrl.shift_src <= instr_word_var(3); -- accumulate to the same register we want to write to - alu_ctrl.shift_src_sign <= "00"; -- with normal sign - alu_ctrl.store_result <= '1'; -- store the result - alu_ctrl.rounding_used <= "00"; -- no rounding needed - alu_ctrl.add_src_stage_2 <= "00"; -- select zero as second operand - -- set N,Z,V,C flags - for i in 0 to 3 loop - alu_ctrl.ccr_flags_ctrl(i) <= MODIFY; - end loop; - end if; - -- LSR - if instr_word_var(7 downto 4) = "0010" and instr_word_var(2 downto 0) = "011" then - alu_ctrl.word_24_update <= '1'; - -- Read accu - alu_ctrl.shift_mode <= SHIFT_RIGHT; - alu_ctrl.shift_src <= instr_word_var(3); -- accumulate to the same register we want to write to - alu_ctrl.shift_src_sign <= "00"; -- with normal sign - alu_ctrl.store_result <= '1'; -- store the result - alu_ctrl.rounding_used <= "00"; -- no rounding needed - alu_ctrl.add_src_stage_2 <= "00"; -- select zero as second operand - -- set N,Z,V,C flags - for i in 0 to 3 loop - alu_ctrl.ccr_flags_ctrl(i) <= MODIFY; - end loop; - end if; - -- MPY, MPYR, MAC, MACR - if instr_word_var(7) = '1' then - case instr_word_var(6 downto 4) is - when "000" => alu_ctrl.mul_op1 <= "00"; alu_ctrl.mul_op2 <= "00"; -- x0,x0 - when "001" => alu_ctrl.mul_op1 <= "10"; alu_ctrl.mul_op2 <= "10"; -- y0,y0 - when "010" => alu_ctrl.mul_op1 <= "01"; alu_ctrl.mul_op2 <= "00"; -- x1,x0 - when "011" => alu_ctrl.mul_op1 <= "11"; alu_ctrl.mul_op2 <= "10"; -- y1,y0 - when "100" => alu_ctrl.mul_op1 <= "00"; alu_ctrl.mul_op2 <= "11"; -- x0,y1 - when "101" => alu_ctrl.mul_op1 <= "10"; alu_ctrl.mul_op2 <= "00"; -- y0,x0 - when "110" => alu_ctrl.mul_op1 <= "01"; alu_ctrl.mul_op2 <= "10"; -- x1,y0 - when others => alu_ctrl.mul_op1 <= "11"; alu_ctrl.mul_op2 <= "01"; -- y1,x1 - end case; - alu_ctrl.store_result <= '1'; -- store result in accu - alu_ctrl.add_src_stage_2 <= "10"; -- select mul out for adder! - alu_ctrl.add_src_sign <= '0' & instr_word_var(2); -- select +/- - alu_ctrl.rounding_used <= '0' & instr_word_var(0); -- rounding is determined by that bit! - if instr_word_var(1) = '0' then -- MPY(R) - alu_ctrl.shift_mode <= ZEROS; - else -- MAC(R) - alu_ctrl.shift_mode <= NO_SHIFT; - alu_ctrl.shift_src <= instr_word_var(3); -- accumulate to the same register we want to write to - alu_ctrl.shift_src_sign <= "00"; -- with the original sign - end if; - -- set all flags but carry! - for i in 1 to 7 loop - alu_ctrl.ccr_flags_ctrl(i) <= MODIFY; - end loop; - end if; - -- NEG - if instr_word_var(7 downto 4) = "0011" and instr_word_var(2 downto 0) = "110" then - -- Read accu - alu_ctrl.shift_mode <= ZEROS; --- alu_ctrl.shift_src <= instr_word_var(3); -- accumulate to the same register we want to write to --- alu_ctrl.shift_src_sign <= "01"; -- with negative sign - -- Read Accu - alu_ctrl.add_src_stage_1 <= "000"; -- source register equal to dst_register - alu_ctrl.add_src_stage_2 <= "01"; -- select register as operand - alu_ctrl.add_src_sign <= "01"; -- with negative sign - alu_ctrl.store_result <= '1'; -- store the result - alu_ctrl.rounding_used <= "00"; -- no rounding needed - -- set all flags but carry! - for i in 1 to 7 loop - alu_ctrl.ccr_flags_ctrl(i) <= MODIFY; - end loop; - end if; - -- NOT - if instr_word_var(7 downto 4) = "0001" and instr_word_var(2 downto 0) = "111" then - alu_ctrl.word_24_update <= '1'; - -- Read accu - alu_ctrl.shift_mode <= NO_SHIFT; - alu_ctrl.shift_src <= instr_word_var(3); -- accumulate to the same register we want to write to - alu_ctrl.shift_src_sign <= "00"; -- with normal sign - alu_ctrl.logic_function <= instr_word_var(2 downto 0); -- select not operation - alu_ctrl.store_result <= '1'; -- store the result - alu_ctrl.rounding_used <= "00"; -- no rounding needed - -- set following flags - alu_ctrl.ccr_flags_ctrl(N_FLAG) <= MODIFY; - alu_ctrl.ccr_flags_ctrl(Z_FLAG) <= MODIFY; - alu_ctrl.ccr_flags_ctrl(V_FLAG) <= CLEAR; - end if; - -- RND - if instr_word_var(7 downto 4) = "0001" and instr_word_var(2 downto 0) = "001" then - -- Read accu - alu_ctrl.shift_mode <= NO_SHIFT; - alu_ctrl.shift_src <= instr_word_var(3); -- accumulate to the same register we want to write to - alu_ctrl.shift_src_sign <= "00"; -- with normal sign - alu_ctrl.store_result <= '1'; -- store the result - alu_ctrl.rounding_used <= "01"; -- normal rounding needed - alu_ctrl.add_src_stage_2 <= "00"; -- select zero as second operand - -- set all flags but carry! - for i in 1 to 7 loop - alu_ctrl.ccr_flags_ctrl(i) <= MODIFY; - end loop; - end if; - -- ROL - if instr_word_var(7 downto 4) = "0011" and instr_word_var(2 downto 0) = "111" then - alu_ctrl.word_24_update <= '1'; - alu_ctrl.rotate <= '1'; - -- Read accu - alu_ctrl.shift_mode <= SHIFT_LEFT; - alu_ctrl.shift_src <= instr_word_var(3); -- accumulate to the same register we want to write to - alu_ctrl.shift_src_sign <= "00"; -- with normal sign - alu_ctrl.store_result <= '1'; -- store the result - alu_ctrl.rounding_used <= "00"; -- no rounding needed - alu_ctrl.add_src_stage_2 <= "00"; -- select zero as second operand - -- set the following flags - alu_ctrl.ccr_flags_ctrl(C_FLAG) <= MODIFY; - alu_ctrl.ccr_flags_ctrl(V_FLAG) <= CLEAR; - alu_ctrl.ccr_flags_ctrl(Z_FLAG) <= MODIFY; - alu_ctrl.ccr_flags_ctrl(N_FLAG) <= MODIFY; - end if; - -- ROR - if instr_word_var(7 downto 4) = "0010" and instr_word_var(2 downto 0) = "111" then - alu_ctrl.word_24_update <= '1'; - alu_ctrl.rotate <= '1'; - -- Read accu - alu_ctrl.shift_mode <= SHIFT_RIGHT; - alu_ctrl.shift_src <= instr_word_var(3); -- accumulate to the same register we want to write to - alu_ctrl.shift_src_sign <= "00"; -- with normal sign - alu_ctrl.store_result <= '1'; -- store the result - alu_ctrl.rounding_used <= "00"; -- no rounding needed - alu_ctrl.add_src_stage_2 <= "00"; -- select zero as second operand - -- set the following flags - alu_ctrl.ccr_flags_ctrl(C_FLAG) <= MODIFY; - alu_ctrl.ccr_flags_ctrl(V_FLAG) <= CLEAR; - alu_ctrl.ccr_flags_ctrl(Z_FLAG) <= MODIFY; - alu_ctrl.ccr_flags_ctrl(N_FLAG) <= MODIFY; - end if; - -- SBC - if instr_word_var(7 downto 5) = "001" and instr_word_var(2 downto 0) = "101" then - -- Read accu - alu_ctrl.shift_mode <= NO_SHIFT; - alu_ctrl.shift_src <= instr_word_var(3); -- accumulate to the same register we want to write to - alu_ctrl.shift_src_sign <= "00"; -- with normal sign - -- Read S - alu_ctrl.add_src_stage_1 <= instr_word_var(6 downto 4); -- source register (JJJ encoding) X,Y - alu_ctrl.add_src_stage_2 <= "01"; -- select the register source - alu_ctrl.add_src_sign <= "01"; -- with negative sign - alu_ctrl.rounding_used <= "11"; -- subtract carry - alu_ctrl.store_result <= '1'; -- store the result - -- set all flags! - for i in 0 to 7 loop - alu_ctrl.ccr_flags_ctrl(i) <= MODIFY; - end loop; - end if; - -- SUB - if instr_word_var(7) = '0' and instr_word_var(2 downto 0) = "100" then - -- Read accu - alu_ctrl.shift_mode <= NO_SHIFT; - alu_ctrl.shift_src <= instr_word_var(3); -- accumulate to the same register we want to write to - alu_ctrl.shift_src_sign <= "00"; -- with normal sign - -- Read S - alu_ctrl.add_src_stage_1 <= instr_word_var(6 downto 4); -- source register (JJJ encoding) - alu_ctrl.add_src_stage_2 <= "01"; -- select the register source - alu_ctrl.add_src_sign <= "01"; -- with negative sign - alu_ctrl.rounding_used <= "00"; -- no rounding needed - alu_ctrl.store_result <= '1'; -- store the result - -- set all flags! - for i in 0 to 7 loop - alu_ctrl.ccr_flags_ctrl(i) <= MODIFY; - end loop; - end if; - -- SUBL - if instr_word_var(7 downto 4) = "0001" and instr_word_var(2 downto 0) = "110" then - -- Read accu - alu_ctrl.shift_mode <= SHIFT_LEFT; - alu_ctrl.shift_src <= instr_word_var(3); -- accumulate to the same register we want to write to - alu_ctrl.shift_src_sign <= "00"; -- with normal sign - -- Read S - alu_ctrl.add_src_stage_1 <= instr_word_var(6 downto 4); -- source register (JJJ encoding) - alu_ctrl.add_src_stage_2 <= "01"; -- select the register source - alu_ctrl.add_src_sign <= "01"; -- with negative sign - alu_ctrl.rounding_used <= "00"; -- no rounding needed - alu_ctrl.store_result <= '1'; -- store the result - -- set all flags! - for i in 0 to 7 loop - alu_ctrl.ccr_flags_ctrl(i) <= MODIFY; - end loop; - end if; - -- SUBR - if instr_word_var(7 downto 4) = "0000" and instr_word_var(2 downto 0) = "110" then - -- Read accu - alu_ctrl.shift_mode <= SHIFT_RIGHT; - alu_ctrl.shift_src <= instr_word_var(3); -- accumulate to the same register we want to write to - alu_ctrl.shift_src_sign <= "00"; -- with normal sign - -- Read S - alu_ctrl.add_src_stage_1 <= instr_word_var(6 downto 5) & '1'; -- source register (JJJ encoding) - alu_ctrl.add_src_stage_2 <= "01"; -- select the register source - alu_ctrl.add_src_sign <= "01"; -- with negative sign - alu_ctrl.rounding_used <= "00"; -- no rounding needed - alu_ctrl.store_result <= '1'; -- store the result - -- set all flags! - for i in 0 to 7 loop - alu_ctrl.ccr_flags_ctrl(i) <= MODIFY; - end loop; - end if; - -- TFR - if instr_word_var(7) = '0' and instr_word_var(6 downto 5) /= "01" and - instr_word_var(6 downto 4) /= "001" and instr_word_var(2 downto 0) = "001" then - -- do not read accu - alu_ctrl.shift_mode <= ZEROS; - -- Read S - if instr_word_var(6) = '1' then - alu_ctrl.add_src_stage_1 <= instr_word_var(6 downto 4); -- source register (JJJ encoding) - else - alu_ctrl.add_src_stage_1 <= "001"; -- B,A or A,B (depending on dest. accu) - end if; - alu_ctrl.add_src_stage_2 <= "01"; -- select the register source - alu_ctrl.add_src_sign <= "00"; -- with positive sign - alu_ctrl.rounding_used <= "00"; -- no rounding needed - alu_ctrl.store_result <= '1'; -- store the result - -- do not set any flag at all! - end if; - -- TST - if instr_word_var(7 downto 4) = "0000" and instr_word_var(2 downto 0) = "011" then - -- do not read accu - alu_ctrl.shift_mode <= NO_SHIFT; -- no shift - alu_ctrl.shift_src <= instr_word_var(3); -- read source accu - alu_ctrl.shift_src_sign <= "00"; -- sign unchanged - -- Read S - alu_ctrl.add_src_stage_2 <= "00"; -- select zero - alu_ctrl.add_src_sign <= "00"; -- with positive sign - alu_ctrl.rounding_used <= "00"; -- no rounding needed - alu_ctrl.store_result <= '0'; -- do not store the result - -- set all flags but carry! - for i in 1 to 7 loop - alu_ctrl.ccr_flags_ctrl(i) <= MODIFY; - end loop; - end if; - end if; -- Parallel move ALU instructions - - -- Tcc - if alu_tcc_decoded = '1' then - -- Read source - if instr_word_var(6) = '1' then - alu_ctrl.add_src_stage_1 <= instr_word_var(6 downto 4); -- source register (JJJ encoding) - else - alu_ctrl.add_src_stage_1 <= "001"; -- B,A or A,B (depending on dest. accu) - end if; - alu_ctrl.add_src_stage_2 <= "01"; -- select the registers as source - -- The .store_result flag is generated in the execute stage - -- depending on the condition codes - -- do not set any flag at all! - end if; ---mul_op1 : std_logic_vector(1 downto 0); -- x0,x1,y0,y1 ---mul_op2 : std_logic_vector(1 downto 0); -- x0,x1,y0,y1 ---shift_src : std_logic; -- a,b ---shift_src_sign : std_logic_vector(1 downto 0); -- 00: pos, 01: neg, 10: sign dependant, 11: reserved ---shift_mode : alu_shift_mode; ---add_src_stage_1 : std_logic_vector(2 downto 0); -- x0,x1,y0,y1,x,y,a,b ---add_src_stage_2 : std_logic_vector(1 downto 0); -- 00: 0 , 01: add_src_1, 10: mul_result, 11: reserved ---add_src_sign : std_logic_vector(1 downto 0); -- 00: pos, 01: neg, 10: sign dependant, 11: div instruction! ---logic_function : std_logic_vector(2 downto 0); -- 000: none, 110: and, 010: or, 011: eor, 111: not ---word_24_update : std_logic; -- only accumulator bits 47 downto 24 affected? ---rounding_used : std_logic_vector(1 downto 0); -- 00: no rounding, 01: rounding, 10: add carry, 11: subtract carry ---store_result : std_logic; -- 0: do not update accumulator, 1: update accumulator ---dst_accu : std_logic; -- 0: a, 1: b - -- DIV - if alu_div_decoded = '1' then - alu_ctrl.store_result <= '1'; -- do store the result - -- shifter operation - alu_ctrl.shift_mode <= SHIFT_LEFT; -- shift left - alu_ctrl.shift_src <= instr_word_var(3); -- read source accu - alu_ctrl.div_instr <= '1'; -- this is THE div instruction, special handling needed - -- source operand loading - alu_ctrl.add_src_stage_1 <= instr_word_var(6 downto 4); -- source register (JJJ encoding) - alu_ctrl.add_src_stage_2 <= "01"; -- select the registers as source - alu_ctrl.add_src_sign <= "11"; -- div instruction, sign dependant on D[55] XOR S[23] - -- if 1: positive, if 0: negative - alu_ctrl.ccr_flags_ctrl(C_FLAG) <= MODIFY; - alu_ctrl.ccr_flags_ctrl(V_FLAG) <= MODIFY; - alu_ctrl.ccr_flags_ctrl(L_FLAG) <= MODIFY; - end if; - -- NORM - if alu_norm_decoded = '1' then - -- set all alu-ctrl signals to ASL/ASR already here - -- depending on the condition code registers the flags - -- will be completed in the execute stage - alu_ctrl.norm_instr <= '1'; - -- Read accu - --alu_ctrl.shift_mode <= SHIFT_RIGHT/SHIFT_LEFT/NO_SHIFT; - alu_ctrl.shift_src <= instr_word_var(3); -- accumulate to the same register we want to write to - alu_ctrl.shift_src_sign <= "00"; -- with the original sign - -- Read S - alu_ctrl.add_src_stage_2 <= "00"; -- select zero as operand - alu_ctrl.add_src_sign <= "00"; -- with original sign - alu_ctrl.store_result <= '1'; -- store the result - alu_ctrl.rounding_used <= "00"; -- no rounding needed - -- set all flags, V-flag will be cleared due to shifting - for i in 0 to 7 loop - alu_ctrl.ccr_flags_ctrl(i) <= MODIFY; - end loop; - - end if; - end process; - - - instruction_decoder: process(instr_word, activate_dec) is - variable instr_word_var : std_logic_vector(23 downto 0); - procedure activate_AGU is - begin - -- check for immediate long addressing - if instr_word_var(13 downto 8) = "110100" then - act_array(ACT_IMM_LONG) <= '1'; - act_array(ACT_X_MEM_RD) <= '0'; -- No memory accesses for Immediate addressing! - act_array(ACT_Y_MEM_RD) <= '0'; - act_array(ACT_X_MEM_WR) <= '0'; - act_array(ACT_Y_MEM_WR) <= '0'; - else - act_array(ACT_ADGEN) <= '1'; - end if; - end procedure activate_AGU; - begin - instr_array_int <= INSTR_NOP; - act_array <= (others => '0'); - adgen_bittype <= NOP; - reg_rd_addr <= (others => '0'); - reg_wr_addr <= (others => '0'); - x_bus_rd_addr <= (others => '0'); - x_bus_wr_addr <= (others => '0'); - y_bus_rd_addr <= (others => '0'); - y_bus_wr_addr <= (others => '0'); - l_bus_addr <= instr_word_var(19) & instr_word_var(17 downto 16); - - alu_tcc_decoded <= '0'; - alu_div_decoded <= '0'; - alu_norm_decoded <= '0'; - - -- in case the decoding is not activated we insert a nop - if activate_dec = '1' then - instr_word_var := instr_word; - else - instr_word_var := (others => '0'); - end if; - - if instr_word_var(23 downto 16) = X"00" then - case instr_word_var(15 downto 0) is - when X"0000" => instr_array_int <= INSTR_NOP; - when X"0004" => instr_array_int <= INSTR_RTI; act_array(ACT_EXEC_BRA) <= '1'; - when X"0005" => instr_array_int <= INSTR_ILLEGAL; - when X"0006" => instr_array_int <= INSTR_SWI; - when X"000C" => instr_array_int <= INSTR_RTS; act_array(ACT_EXEC_BRA) <= '1'; - when X"0084" => instr_array_int <= INSTR_RESET; - when X"0086" => instr_array_int <= INSTR_WAIT; - when X"0087" => instr_array_int <= INSTR_STOP; - when X"008C" => instr_array_int <= INSTR_ENDDO; - act_array(ACT_EXEC_LOOP) <= '1'; - when others => - act_array(ACT_EXEC_CR_MOD) <= '1'; -- modify control register - if instr_word_var(7 downto 2) = "101110" then - instr_array_int <= INSTR_ANDI; - elsif instr_word_var(7 downto 2) = "111110" then - instr_array_int <= INSTR_ORI; - end if; - end case; - end if; - --------------------------------------------------------- - -- DIV and NORM - --------------------------------------------------------- - if instr_word_var(23 downto 16) = X"01" then - -- DIV - if instr_word_var(15 downto 6) = "1000000001" and instr_word_var(2 downto 0) = "000" then - alu_div_decoded <= '1'; - act_array(ACT_ALU) <= '1'; -- force ALU to update status register - end if; - -- NORM - if instr_word_var(15 downto 11) = "11011" and instr_word_var(7 downto 4) = "0001" and - instr_word_var(2 downto 0) = "101" then - alu_norm_decoded <= '1'; - act_array(ACT_NORM) <= '1'; -- NORM instruction decoded, - -- special handling in exec-stage is caused - act_array(ACT_REG_RD) <= '1'; - reg_rd_addr <= instr_word_var(13 downto 12) & '0' & instr_word_var(10 downto 8); -- Write same Rn - act_array(ACT_REG_WR) <= '1'; - reg_wr_addr <= instr_word_var(13 downto 12) & '0' & instr_word_var(10 downto 8); -- Write same Rn - end if; - end if; - --------------------------------------------------------- - -- Tcc - --------------------------------------------------------- - if instr_word_var(23 downto 16) = X"02" or instr_word_var(23 downto 16) = X"03" then - -- Tcc S1, D1 S2, D2 (ALU/Reg file) - if instr_word_var(16) = '0' and instr_word_var(11 downto 7) = "00000" and - instr_word_var(2 downto 0) = "000" then - act_array(ACT_ALU_WR_CC) <= '1'; - alu_tcc_decoded <= '1'; - -- Tcc S1, D1 S2, D2 (ALU/Reg file) - elsif instr_word_var(16) = '1' and instr_word_var(11) = '0' and - instr_word_var(7) = '0' then - act_array(ACT_ALU_WR_CC) <= '1'; - alu_tcc_decoded <= '1'; - act_array(ACT_REG_WR_CC) <= '1'; - reg_rd_addr <= "010" & instr_word_var(10 downto 8); -- Read Rn - reg_wr_addr <= "010" & instr_word_var( 2 downto 0); -- Write to other Rn - end if; - end if; - --------------------------------------------------------- - -- MOVEC and LUA instruction with registers - --------------------------------------------------------- - if instr_word_var(23 downto 16) = X"04" then - act_array(ACT_REG_WR) <= '1'; - -- LUA instruction - if instr_word_var(15 downto 13) = "010" and instr_word_var(7 downto 4) = "0001" then - instr_array_int <= INSTR_LUA; - act_array(ACT_ADGEN) <= '1'; - adgen_bittype <= SINGLE_X_SHORT; - reg_wr_addr <= instr_word_var(5 downto 0); - end if; - -- MOVEC instruction (S1, D2) or (S2, D1) - if instr_word_var(14) = '1' and instr_word_var(7 downto 5) = "101" then - instr_array_int <= INSTR_MOVEC; - act_array(ACT_REG_RD) <= '1'; - -- Write D1 - if instr_word_var(15) = '1' then - reg_wr_addr <= instr_word_var(5 downto 0); - reg_rd_addr <= instr_word_var(13 downto 8); - -- Read S1 - else - reg_wr_addr <= instr_word_var(13 downto 8); - reg_rd_addr <= instr_word_var(5 downto 0); - end if; - end if; - end if; - ------------------------------------------------------------------------- - -- MOVEC instruction with memory access/absolute address - ------------------------------------------------------------------------- - if instr_word_var(23 downto 16) = X"05" and - instr_word_var(7) = '0' and instr_word_var(5) = '1' then - - instr_array_int <= INSTR_MOVEC; - -- read from memory, write to register - if instr_word_var(15) = '1' then - act_array(ACT_REG_WR) <= '1'; - reg_wr_addr <= instr_word_var(5 downto 0); - -- X Memory read? - if instr_word_var(6) = '0' then - act_array(ACT_X_MEM_RD) <= '1'; - -- Y Memory read? - else - act_array(ACT_Y_MEM_RD) <= '1'; - end if; - -- write to memory, read register - else - act_array(ACT_REG_RD) <= '1'; - reg_rd_addr <= instr_word_var(5 downto 0); - -- X Memory write? - if instr_word_var(6) = '0' then - act_array(ACT_X_MEM_WR) <= '1'; - -- Y Memory write? - else - act_array(ACT_Y_MEM_WR) <= '1'; - end if; - end if; - -- AGU needed? - if instr_word_var(14) = '1' then - -- detect whether two word instruction! - adgen_bittype <= SINGLE_X; - -- check for immediate long addressing - if instr_word_var(13 downto 8) = "110100" then - act_array(ACT_IMM_LONG) <= '1'; - act_array(ACT_X_MEM_RD) <= '0'; -- No memory accesses for Immediate addressing! - act_array(ACT_Y_MEM_RD) <= '0'; - act_array(ACT_X_MEM_WR) <= '0'; - act_array(ACT_Y_MEM_WR) <= '0'; - else - act_array(ACT_ADGEN) <= '1'; - end if; - else - -- X:/Y:aa short is done in the adgen-stage automatically - end if; - end if; - ------------------------------------------------------------------------- - -- MOVEC instruction with immediate - ------------------------------------------------------------------------- - if instr_word_var(23 downto 16) = X"05" and instr_word_var(7 downto 5) = "101" then - instr_array_int <= INSTR_MOVEC; - act_array(ACT_IMM_8BIT) <= '1'; - act_array(ACT_REG_WR) <= '1'; - reg_wr_addr <= instr_word_var(5 downto 0); - end if; - --------------------------------- - -- REP or DO loop? - --------------------------------- - if instr_word_var(23 downto 16) = X"06" then - -- Instruction encoding is the same for both except of this bit - if instr_word_var(5) = '1' then - instr_array_int <= INSTR_REP; - else - instr_array_int <= INSTR_DO; - end if; - act_array(ACT_EXEC_LOOP) <= '1'; - -- Init reading of loop counter from memory - if instr_word_var(15) = '0' and instr_word_var(7) = '0' then - -- X/Y: ea? - if instr_word_var(14) = '1' then - act_array(ACT_ADGEN) <= '1'; - end if; - -- X/Y: aa? - -- Done automatically in the ADGEN stage by testing whether the ADGEN unit activated or not! - -- If not the absolute address stored in the instruction word is used. - ------- - -- only a single memory access is required - adgen_bittype <= SINGLE_X; - -- X/Y as source? - if instr_word_var(6) = '0' then - act_array(ACT_X_MEM_RD) <= '1'; - else - act_array(ACT_Y_MEM_RD) <= '1'; - end if; - elsif instr_word_var(15) = '1' and instr_word_var(7) = '0' then - -- S (register as source) - reg_rd_addr <= instr_word_var(13 downto 8); - act_array(ACT_REG_RD) <= '1'; - -- #xxx ,12 bit immediate - elsif instr_word_var(7 downto 6) = "10" and instr_word_var(4) = '0' then - act_array(ACT_IMM_12BIT) <= '1'; - end if; - end if; - -------------------------------- - -- MOVEM (Program memory move) - -------------------------------- - if instr_word_var(23 downto 16) = X"07" then - -- read memory, write reg - if instr_word_var(15) = '1' then - act_array(ACT_REG_WR) <= '1'; - reg_wr_addr <= instr_word_var(5 downto 0); - act_array(ACT_P_MEM_RD) <= '1'; - -- read reg, write memory - elsif instr_word_var(15) = '0' then - act_array(ACT_REG_RD) <= '1'; - reg_rd_addr <= instr_word_var(5 downto 0); - act_array(ACT_P_MEM_WR) <= '1'; - end if; - -- AGU needed? - if instr_word_var(14) = '1' and instr_word_var(7 downto 6) = "10" then - adgen_bittype <= SINGLE_X; - -- activate AGU and test whether immediate data is used - activate_AGU; - elsif instr_word_var(14) = '0' and instr_word_var(7 downto 6) = "00" then - -- X:/Y:aa short is done in the adgen-stage automatically - end if; - end if; - -------------------------------- - -- MOVEP (Peripheral memory move) - -------------------------------- - if instr_word_var(23 downto 16) = "0000100-" then - -- TODO?? Why parallel moves in software model?? - case instr_word_var(15 downto 0) is --- when "-1------1-------" => instr_array_int(INSTR_MOVEP) <= '1'; --- when "-1------01------" => instr_array_int(INSTR_MOVEP) <= '1'; --- when "-1------00------" => instr_array_int(INSTR_MOVEP) <= '1'; - when others => - end case; - end if; - -- BSET, BCLR, BCHG, BTST, JCLR, JSET, JSCLR, JSSET, JMP, JCC, JSCC, JSR - if instr_word_var(23 downto 16) = X"0A" or instr_word_var(23 downto 16) = X"0B" then - - reg_rd_addr <= instr_word_var(13 downto 8); - reg_wr_addr <= instr_word_var(13 downto 8); - - if instr_word_var(16) = '0' then - if instr_word_var(7) = '0' and instr_word_var(5) = '0' then - instr_array_int <= INSTR_BCLR; - elsif instr_word_var(7) = '0' and instr_word_var(5) = '1' then - instr_array_int <= INSTR_BSET; - elsif instr_word_var(7) = '1' and instr_word_var(5) = '0' then - instr_array_int <= INSTR_JCLR; - elsif instr_word_var(7) = '1' and instr_word_var(5) = '1' then - instr_array_int <= INSTR_JSET; - end if; - elsif instr_word_var(16) = '1' then - if instr_word_var(7) = '0' and instr_word_var(5) = '0' then - instr_array_int <= INSTR_BCHG; - elsif instr_word_var(7) = '0' and instr_word_var(5) = '1' then - instr_array_int <= INSTR_BTST; - elsif instr_word_var(7) = '1' and instr_word_var(5) = '0' then - instr_array_int <= INSTR_JSCLR; - elsif instr_word_var(7) = '1' and instr_word_var(5) = '1' then - instr_array_int <= INSTR_JSSET; - end if; - end if; - if instr_word_var(7) = '1' then - act_array(ACT_EXEC_BRA) <= '1'; - end if; - - -- memory access? - if instr_word_var(15) = '0' then - -- X: - if instr_word_var(6) = '0' then - act_array(ACT_X_MEM_RD) <= '1'; - -- if not a jump instruction and not BTST write back the result - if instr_word_var(7) = '0' and not(instr_word_var(16) = '1' and instr_word_var(5) = '1') then - act_array(ACT_X_MEM_WR) <= '1'; - end if; - -- Y: - else - act_array(ACT_Y_MEM_RD) <= '1'; - -- if not a jump instruction and not BTST write back the result - if instr_word_var(7) = '0' and not(instr_word_var(16) = '1' and instr_word_var(5) = '1') then - act_array(ACT_Y_MEM_WR) <= '1'; - end if; - end if; - end if; - - case instr_word_var(15 downto 14) is - -- X:/Y: aa - when "00" => - - -- X:/Y: ea - when "01" => - act_array(ACT_ADGEN) <= '1'; - adgen_bittype <= SINGLE_X; - - -- X:/Y: pp - -- TODO! - when "10" => - - when others => -- "11" - if instr_word_var(7 downto 0) = "10000000" then - -- JMP/JSR ea - act_array(ACT_EXEC_BRA) <= '1'; - act_array(ACT_ADGEN) <= '1'; - adgen_bittype <= SINGLE_X; - if instr_word_var(16) = '0' then - instr_array_int <= INSTR_JMP; - elsif instr_word_var(16) = '1' then - instr_array_int <= INSTR_JSR; - end if; - elsif instr_word_var(7 downto 4) = "1010" then - -- JCC/JSCC ea - act_array(ACT_EXEC_BRA) <= '1'; - act_array(ACT_ADGEN) <= '1'; - adgen_bittype <= SINGLE_X; - if instr_word_var(16) = '0' then - instr_array_int <= INSTR_JCC; - elsif instr_word_var(16) = '1' then - instr_array_int <= INSTR_JSCC; - end if; - -- JSCLR,JSET,JCLR,JSSET,BTST,BCLR,BSET,BCHG S/D - else - act_array(ACT_REG_RD) <= '1'; - -- if not a jump instruction and not BTST write back the result - if instr_word_var(7) = '0' and not(instr_word_var(16) = '1' and instr_word_var(5) = '1') then - act_array(ACT_REG_WR) <= '1'; - end if; - end if; - end case; - end if; - -- JMP xxx (absoulute short) - if instr_word_var(23 downto 16) = X"0C" then - if instr_word_var(15 downto 12) = "0000" then - instr_array_int <= INSTR_JMP; - act_array(ACT_EXEC_BRA) <= '1'; - end if; - end if; - -- JSR xxx (absolute short) - if instr_word_var(23 downto 16) = X"0D" then - if instr_word_var(15 downto 12) = "0000" then - instr_array_int <= INSTR_JSR; - act_array(ACT_EXEC_BRA) <= '1'; - end if; - end if; - -- JCC xxx (absolute short) - if instr_word_var(23 downto 16) = X"0E" then - instr_array_int <= INSTR_JCC; - act_array(ACT_EXEC_BRA) <= '1'; - end if; - -- JSCC xxx (absolute short) - if instr_word_var(23 downto 16) = X"0F" then - instr_array_int <= INSTR_JSCC; - act_array(ACT_EXEC_BRA) <= '1'; - end if; - - ------------------------------------------------ - -- PARALLEL MOVE SECTION!! - ------------------------------------------------ - -- Here are the ALU operations that allow for parallel moves - if instr_word_var(23 downto 20) /= "0000" then - act_array(ACT_ALU) <= '1'; -- force ALU to update status register - end if; - -- PM: I - if instr_word_var(23 downto 21) = "001" and instr_word_var(20 downto 18) /= "000" then - act_array(ACT_IMM_8BIT) <= '1'; - act_array(ACT_REG_WR) <= '1'; - reg_wr_addr <= '0' & instr_word_var(20 downto 16); - end if; - -- PM: R - if instr_word_var(23 downto 18) = "001000" then - act_array(ACT_REG_WR) <= '1'; - reg_wr_addr <= '0' & instr_word_var(12 downto 8); - act_array(ACT_REG_RD) <= '1'; - reg_rd_addr <= '0' & instr_word_var(17 downto 13); - end if; - -- PM: U - if instr_word_var(23 downto 13) = "00100000010" then - act_array(ACT_ADGEN) <= '1'; - adgen_bittype <= SINGLE_X_SHORT; - end if; - -- PM: X or PM:Y - if instr_word_var(23 downto 22) = "01" and - -- Check whether L: type parallel move. If so do not enter this branch! - not (instr_word_var(21 downto 20) = "00" and instr_word_var(18) = '0') then - -- read memory, write reg - if instr_word_var(15) = '1' then - act_array(ACT_REG_WR) <= '1'; - reg_wr_addr <= '0' & instr_word_var(21 downto 20) & instr_word_var(18 downto 16); -- TODO: CHECK!! - -- X Memory read? - if instr_word_var(19) = '0' then - act_array(ACT_X_MEM_RD) <= '1'; - -- Y Memory read? - else - act_array(ACT_Y_MEM_RD) <= '1'; - end if; - -- read reg, write memory - elsif instr_word_var(15) = '0' then - act_array(ACT_REG_RD) <= '1'; - reg_rd_addr <= '0' & instr_word_var(21 downto 20) & instr_word_var(18 downto 16); -- TODO: CHECK!! - -- X Memory write? - if instr_word_var(19) = '0' then - act_array(ACT_X_MEM_WR) <= '1'; - -- Y Memory write? - else - act_array(ACT_Y_MEM_WR) <= '1'; - end if; - end if; - -- AGU needed? - if instr_word_var(14) = '1' then - -- detect whether two word instruction! - adgen_bittype <= SINGLE_X; - -- activate AGU and test whether immediate data is used - activate_AGU; - else - -- X:/Y:aa short is done in the adgen-stage automatically - end if; - end if; - -- PM: X:R or R:Y (Class I) - if instr_word_var(23 downto 20) = "0001" then - adgen_bittype <= SINGLE_X; - -- X:R - if instr_word_var(14) = '0' then - x_bus_rd_addr <= instr_word_var(19 downto 18); - x_bus_wr_addr <= instr_word_var(19 downto 18); - y_bus_rd_addr <= '1' & instr_word_var(17); - y_bus_wr_addr <= '0' & instr_word_var(16); -- TODO: Check encoding, manual uses three fs! - -- S2,D2 in any case! - act_array(ACT_Y_BUS_RD) <= '1'; - act_array(ACT_Y_BUS_WR) <= '1'; - -- Write D1? - if instr_word_var(15) = '1' then - act_array(ACT_X_MEM_RD) <= '1'; - act_array(ACT_X_BUS_WR) <= '1'; - else - -- Read S1? - act_array(ACT_X_MEM_WR) <= '1'; - act_array(ACT_X_BUS_RD) <= '1'; - end if; - -- R:Y - elsif instr_word_var(14) = '1' then - x_bus_rd_addr <= '1' & instr_word_var(19); - x_bus_wr_addr <= '0' & instr_word_var(18); - y_bus_rd_addr <= instr_word_var(17 downto 16); - y_bus_wr_addr <= instr_word_var(17 downto 16); - -- S1,D1 in any case! - act_array(ACT_X_BUS_RD) <= '1'; - act_array(ACT_X_BUS_WR) <= '1'; - -- Write D1? - if instr_word_var(15) = '1' then - act_array(ACT_Y_MEM_RD) <= '1'; - act_array(ACT_Y_BUS_WR) <= '1'; - else - -- Read S1? - act_array(ACT_Y_MEM_WR) <= '1'; - act_array(ACT_Y_BUS_RD) <= '1'; - end if; - - end if; - -- detect whether two word instruction! - adgen_bittype <= SINGLE_X; - -- activate AGU and test whether immediate data is used - activate_AGU; - end if; - -- PM: X:R or R:Y (Class II) - if instr_word_var(23 downto 17) = "0000100" and instr_word_var(14) = '0' then - act_array(ACT_REG_RD) <= '1'; - -- X:R - if instr_word_var(15) = '0' then - reg_rd_addr <= "00111" & instr_word_var(16); -- read A or B - act_array(ACT_X_MEM_WR) <= '1'; -- and store it in X memory - x_bus_rd_addr <= "00"; -- read x0 - x_bus_wr_addr <= '1' & instr_word_var(16); -- and write to A or B - act_array(ACT_X_BUS_RD) <= '1'; - act_array(ACT_X_BUS_WR) <= '1'; - -- R:Y - elsif instr_word_var(15) = '1' then - reg_rd_addr <= "00111" & instr_word_var(16); -- read A or B - act_array(ACT_Y_MEM_WR) <= '1'; -- and store it in Y memory - y_bus_rd_addr <= "00"; -- read y0 - y_bus_wr_addr <= '1' & instr_word_var(16); -- and write to A or B - act_array(ACT_Y_BUS_RD) <= '1'; - act_array(ACT_Y_BUS_WR) <= '1'; - end if; - -- detect whether two word instruction! - adgen_bittype <= SINGLE_X; - -- activate AGU and test whether immediate data is used - activate_AGU; - end if; - -- PM: L: - l_bus_addr <= instr_word_var(19) & instr_word_var(17 downto 16); - if instr_word_var(23 downto 20) = "0100" and instr_word_var(18) = '0' then - -- Read S? - if instr_word_var(15) = '0' then - act_array(ACT_L_BUS_RD) <= '1'; - act_array(ACT_X_MEM_WR) <= '1'; - act_array(ACT_Y_MEM_WR) <= '1'; - else -- Write D - act_array(ACT_L_BUS_WR) <= '1'; - act_array(ACT_X_MEM_RD) <= '1'; - act_array(ACT_Y_MEM_RD) <= '1'; - end if; - if instr_word_var(14) = '1' then - adgen_bittype <= SINGLE_X; - activate_AGU; - else - -- L:aa automatically performed in ADGEN stage - end if; - end if; - -- PM: X: Y: - if instr_word_var(23) = '1' then - adgen_bittype <= DOUBLE_X_Y; - -- No immediate value allowed, so activate in any case! - act_array(ACT_ADGEN) <= '1'; - -- S1, X: - if instr_word_var(15) = '0' then - act_array(ACT_X_BUS_RD) <= '1'; - x_bus_rd_addr <= instr_word_var(19 downto 18); - act_array(ACT_X_MEM_WR) <= '1'; - -- X:, D1 - else - act_array(ACT_X_BUS_WR) <= '1'; - x_bus_wr_addr <= instr_word_var(19 downto 18); - act_array(ACT_X_MEM_RD) <= '1'; - end if; - -- S2, Y: - if instr_word_var(22) = '0' then - act_array(ACT_Y_BUS_RD) <= '1'; - y_bus_rd_addr <= instr_word_var(17 downto 16); - act_array(ACT_Y_MEM_WR) <= '1'; - -- Y:, D2 - else - act_array(ACT_Y_BUS_WR) <= '1'; - y_bus_wr_addr <= instr_word_var(17 downto 16); - act_array(ACT_Y_MEM_RD) <= '1'; - end if; - end if; - end process; - - adgen_decoder: process(adgen_bittype, instr_word) is - begin - adgen_mode_a <= NOP; - adgen_mode_b <= NOP; - ea_extension_available <= '0'; - - case adgen_bittype is - when SINGLE_X => - case instr_word(13 downto 11) is - when "000" => adgen_mode_a <= POST_MIN_N; - when "001" => adgen_mode_a <= POST_PLUS_N; - when "010" => adgen_mode_a <= POST_MIN_1; - when "011" => adgen_mode_a <= POST_PLUS_1; - when "100" => adgen_mode_a <= NOP; - when "101" => adgen_mode_a <= INDEXED_N; - when "111" => adgen_mode_a <= PRE_MIN_1; - when "110" => - if instr_word(10 downto 8) = "000" then - adgen_mode_a <= ABSOLUTE; - ea_extension_available <= '1'; - elsif instr_word(10 downto 8) = "100" then - adgen_mode_a <= IMMEDIATE; - ea_extension_available <= '1'; - else - adgen_mode_a <= NOP; -- INVALID OPCODE! - end if; - when others => - end case; - when SINGLE_X_SHORT => - case instr_word(12 downto 11) is - when "00" => adgen_mode_a <= POST_MIN_N; - when "01" => adgen_mode_a <= POST_PLUS_N; - when "10" => adgen_mode_a <= POST_MIN_1; - when "11" => adgen_mode_a <= POST_PLUS_1; - when others => - end case; - when DOUBLE_X_Y => - case instr_word(12 downto 11) is - when "00" => adgen_mode_a <= NOP; - when "01" => adgen_mode_a <= POST_PLUS_N; - when "10" => adgen_mode_a <= POST_MIN_1; - when "11" => adgen_mode_a <= POST_PLUS_1; - when others => - end case; - case instr_word(21 downto 20) is - when "00" => adgen_mode_b <= NOP; - when "01" => adgen_mode_b <= POST_PLUS_N; - when "10" => adgen_mode_b <= POST_MIN_1; - when "11" => adgen_mode_b <= POST_PLUS_1; - when others => - end case; - when others => - end case; - end process adgen_decoder; - -end architecture rtl; - diff --git a/vhdl/dsp56k/src/dsp56k.vhd b/vhdl/dsp56k/src/dsp56k.vhd deleted file mode 100644 index c8be35c..0000000 --- a/vhdl/dsp56k/src/dsp56k.vhd +++ /dev/null @@ -1,117 +0,0 @@ ------------------------------------------------------------------------------- ---! @file ---! @author Matthias Alles ---! @date 01/2009 ---! @brief Top entity of DSP ---! ------------------------------------------------------------------------------- -library ieee; -use ieee.std_logic_1164.all; -use ieee.numeric_std.all; -library work; -use work.parameter_pkg.all; -use work.types_pkg.all; -use work.constants_pkg.all; - -entity dsp56k is port ( - clk, rst : in std_logic; - -- put register file here for synthesis! - register_file : out register_file_type --- port_a_in : in port_a_in_type; --- port_a_out : out port_a_out_type; --- port_b_in : in port_b_in_type; --- port_b_out : out port_b_out_type; --- port_c_in : in port_c_in_type; --- port_c_out : out port_c_out_type; - -); -end dsp56k; - - -architecture rtl of dsp56k is - - component pipeline is port ( - clk, rst : in std_logic; - register_file_out : out register_file_type; - stall_flags_out : out std_logic_vector(PIPELINE_DEPTH-1 downto 0); - memory_stall : in std_logic; - data_rom_enable: out std_logic; - pmem_ctrl_in : out mem_ctrl_type_in; - pmem_ctrl_out : in mem_ctrl_type_out; - pmem2_ctrl_in : out mem_ctrl_type_in; - pmem2_ctrl_out : in mem_ctrl_type_out; - xmem_ctrl_in : out mem_ctrl_type_in; - xmem_ctrl_out : in mem_ctrl_type_out; - ymem_ctrl_in : out mem_ctrl_type_in; - ymem_ctrl_out : in mem_ctrl_type_out - - ); - end component pipeline; - - component memory_management is port ( - clk, rst : in std_logic; - stall_flags : in std_logic_vector(PIPELINE_DEPTH-1 downto 0); - memory_stall : out std_logic; - data_rom_enable: in std_logic; - pmem_ctrl_in : in mem_ctrl_type_in; - pmem_ctrl_out : out mem_ctrl_type_out; - pmem2_ctrl_in : in mem_ctrl_type_in; - pmem2_ctrl_out : out mem_ctrl_type_out; - xmem_ctrl_in : in mem_ctrl_type_in; - xmem_ctrl_out : out mem_ctrl_type_out; - ymem_ctrl_in : in mem_ctrl_type_in; - ymem_ctrl_out : out mem_ctrl_type_out - ); - end component memory_management; - - signal stall_flags : std_logic_vector(PIPELINE_DEPTH-1 downto 0); - signal memory_stall : std_logic; - signal data_rom_enable : std_logic; - signal pmem_ctrl_in : mem_ctrl_type_in; - signal pmem_ctrl_out : mem_ctrl_type_out; - signal pmem2_ctrl_in : mem_ctrl_type_in; - signal pmem2_ctrl_out : mem_ctrl_type_out; - signal xmem_ctrl_in : mem_ctrl_type_in; - signal xmem_ctrl_out : mem_ctrl_type_out; - signal ymem_ctrl_in : mem_ctrl_type_in; - signal ymem_ctrl_out : mem_ctrl_type_out; - -begin - - pipeline_inst : pipeline port map( - clk => clk, - rst => rst, - register_file_out => register_file, - stall_flags_out => stall_flags, - memory_stall => memory_stall, - data_rom_enable => data_rom_enable, - pmem_ctrl_in => pmem_ctrl_in, - pmem_ctrl_out => pmem_ctrl_out, - pmem2_ctrl_in => pmem2_ctrl_in, - pmem2_ctrl_out => pmem2_ctrl_out, - xmem_ctrl_in => xmem_ctrl_in, - xmem_ctrl_out => xmem_ctrl_out, - ymem_ctrl_in => ymem_ctrl_in, - ymem_ctrl_out => ymem_ctrl_out - ); - - --------------------- - -- MEMORY MANAGEMENT - --------------------- - MMU_inst: memory_management port map ( - clk => clk, - rst => rst, - stall_flags => stall_flags, - memory_stall => memory_stall, - data_rom_enable => data_rom_enable, - pmem_ctrl_in => pmem_ctrl_in, - pmem_ctrl_out => pmem_ctrl_out, - pmem2_ctrl_in => pmem2_ctrl_in, - pmem2_ctrl_out => pmem2_ctrl_out, - xmem_ctrl_in => xmem_ctrl_in, - xmem_ctrl_out => xmem_ctrl_out, - ymem_ctrl_in => ymem_ctrl_in, - ymem_ctrl_out => ymem_ctrl_out - ); - -end architecture rtl; diff --git a/vhdl/dsp56k/src/exec_stage_alu.vhd b/vhdl/dsp56k/src/exec_stage_alu.vhd deleted file mode 100644 index 249be3c..0000000 --- a/vhdl/dsp56k/src/exec_stage_alu.vhd +++ /dev/null @@ -1,611 +0,0 @@ ------------------------------------------------------------------------------- ---! @file ---! @author Matthias Alles ---! @date 01/2009 ---! @brief ALU, including shifter, MAC unit, etc. ---! ------------------------------------------------------------------------------- -library ieee; -use ieee.std_logic_1164.all; -use ieee.numeric_std.all; -library work; -use work.parameter_pkg.all; -use work.types_pkg.all; -use work.constants_pkg.all; - -entity exec_stage_alu is port( - alu_activate : in std_logic; - instr_word : in std_logic_vector(23 downto 0); - alu_ctrl : in alu_ctrl_type; - register_file : in register_file_type; - addr_r_in : in unsigned(BW_ADDRESS-1 downto 0); - addr_r_out : out unsigned(BW_ADDRESS-1 downto 0); - modify_accu : out std_logic; - dst_accu : out std_logic; - modified_accu : out signed(55 downto 0); - modify_sr : out std_logic; - modified_sr : out std_logic_vector(15 downto 0) -); -end entity; - -architecture rtl of exec_stage_alu is - - signal alu_shifter_out : signed(55 downto 0); - signal alu_shifter_carry_out : std_logic; - signal alu_shifter_overflow_out : std_logic; - - signal alu_logic_conj : signed(55 downto 0); - signal alu_multiplier_out : signed(55 downto 0); - signal alu_src_op : signed(55 downto 0); - signal alu_add_result : signed(56 downto 0); - signal alu_add_carry_out : std_logic; - signal alu_post_adder_result : signed(56 downto 0); - - signal scaling_mode : std_logic_vector(1 downto 0); - - signal modified_accu_int : signed(55 downto 0); - - signal norm_instr_asl : std_logic; - signal norm_instr_asr : std_logic; - signal norm_instr_nop : std_logic; - signal norm_update_ccr : std_logic; - -begin - - - -- store calculated value? - modify_accu <= alu_ctrl.store_result; - modified_accu <= modified_accu_int; - -- for the norm instruction we first need to determine whether we have to - -- update the CCR register or not - modify_sr <= alu_activate when alu_ctrl.norm_instr = '0' else - norm_update_ccr; - dst_accu <= alu_ctrl.dst_accu; - - scaling_mode <= register_file.sr(11 downto 10); - - - calcule_ccr_flags: process(register_file, alu_ctrl, alu_shifter_carry_out, - alu_post_adder_result, modified_accu_int, alu_add_carry_out) is - begin - -- by default do not modify the flags in the status register - modified_sr <= register_file.sr; - - -- Carry flag generation - ------------------------- - case alu_ctrl.ccr_flags_ctrl(C_FLAG) is - when CLEAR => modified_sr(C_FLAG) <= '0'; - when SET => modified_sr(C_FLAG) <= '1'; - when MODIFY => - -- the carry flag can stem from the shifter or from the post adder - -- in case we shift and add only a zero to the shift result (ASL, ASR, LSL, LSR, ROL, ROR) - -- take the carry flag from the shifter, else from the post adder - if (alu_ctrl.shift_mode = SHIFT_LEFT or alu_ctrl.shift_mode = SHIFT_RIGHT) and - alu_ctrl.add_src_stage_2 = "00" then -- add zero after shifting? - modified_sr(C_FLAG) <= alu_shifter_carry_out; - elsif alu_ctrl.div_instr = '1' then - modified_sr(C_FLAG) <= not std_logic(alu_post_adder_result(55)); - else --- modified_sr(C_FLAG) <= std_logic(alu_post_adder_result(57)); - modified_sr(C_FLAG) <= alu_add_carry_out; - end if; - when others => -- Don't touch - end case; - - -- Overflow flag generation - ---------------------------- - case alu_ctrl.ccr_flags_ctrl(V_FLAG) is - when CLEAR => modified_sr(V_FLAG) <= '0'; - when SET => modified_sr(V_FLAG) <= '1'; - when MODIFY => - -- There are two sources for the overflow flag: - -- 1) - -- in case the result cannot be represented using 56 bits set - -- the overflow flag. this is the case when the two MSBs of - -- the 57 bit result are different - -- 2) - -- The shifter circuit performs a 56 bit left shift. In case the - -- two MSBs of the operand are different set the overflow flag as well - if (alu_ctrl.div_instr = '0' and alu_post_adder_result(56) /= alu_post_adder_result(55)) or - (alu_ctrl.shift_mode = SHIFT_LEFT and alu_ctrl.word_24_update = '0' and - alu_shifter_overflow_out = '1' ) then - modified_sr(V_FLAG) <= '1'; - else - modified_sr(V_FLAG) <= '0'; - end if; - when others => -- Don't touch - end case; - - -- Zero flag generation - ---------------------------- - case alu_ctrl.ccr_flags_ctrl(Z_FLAG) is - when CLEAR => modified_sr(Z_FLAG) <= '0'; - when SET => modified_sr(Z_FLAG) <= '1'; - when MODIFY => - -- in case the result is zero set this flag - -- distinguish between 24 bit and 56 bit ALU operations - -- 24 bit instructions are LSL, LSR, ROR, ROL, OR, EOR, NOT, AND - if (alu_ctrl.word_24_update = '1' and modified_accu_int(47 downto 24) = 0) or - (alu_ctrl.word_24_update = '0' and modified_accu_int(55 downto 0) = 0) then - modified_sr(Z_FLAG) <= '1'; - else - modified_sr(Z_FLAG) <= '0'; - end if; - when others => -- Don't touch - end case; - - -- Negative flag generation - ---------------------------- - case alu_ctrl.ccr_flags_ctrl(N_FLAG) is - when CLEAR => modified_sr(N_FLAG) <= '0'; - when SET => modified_sr(N_FLAG) <= '1'; - when MODIFY => - -- in case the result is negative set this flag - -- distinguish between 24 bit and 56 bit ALU operations - -- 24 bit instructions are LSL, LSR, ROR, ROL, OR, EOR, NOT, AND - if alu_ctrl.word_24_update = '1' then - modified_sr(N_FLAG) <= std_logic(modified_accu_int(47)); - else - modified_sr(N_FLAG) <= std_logic(modified_accu_int(55)); - end if; - when others => -- Don't touch - end case; - - -- Unnormalized flag generation - ---------------------------- - case alu_ctrl.ccr_flags_ctrl(U_FLAG) is - when CLEAR => modified_sr(U_FLAG) <= '0'; - when SET => modified_sr(U_FLAG) <= '1'; - when MODIFY => - -- Set unnormalized bit according to the scaling mode - if (scaling_mode = "00" and alu_post_adder_result(47) = alu_post_adder_result(46)) or - (scaling_mode = "01" and alu_post_adder_result(48) = alu_post_adder_result(47)) or - (scaling_mode = "10" and alu_post_adder_result(46) = alu_post_adder_result(45)) then - modified_sr(U_FLAG) <= '1'; - else - modified_sr(U_FLAG) <= '0'; - end if; - when others => -- Don't touch - end case; - - -- Extension flag generation - ---------------------------- - case alu_ctrl.ccr_flags_ctrl(E_FLAG) is - when CLEAR => modified_sr(E_FLAG) <= '0'; - when SET => modified_sr(E_FLAG) <= '1'; - when MODIFY => - -- Set extension flag by default - modified_sr(E_FLAG) <= '1'; - -- Clear extension flag according to the scaling mode - case scaling_mode is - when "00" => - if alu_post_adder_result(55 downto 47) = "111111111" or alu_post_adder_result(55 downto 47) = "000000000" then - modified_sr(E_FLAG) <= '0'; - end if; - when "01" => - if alu_post_adder_result(55 downto 48) = "11111111" or alu_post_adder_result(55 downto 48) = "00000000" then - modified_sr(E_FLAG) <= '0'; - end if; - when "10" => - if alu_post_adder_result(55 downto 46) = "1111111111" or alu_post_adder_result(55 downto 46) = "0000000000" then - modified_sr(E_FLAG) <= '0'; - end if; - when others => - modified_sr(E_FLAG) <= '0'; - end case; - when others => -- Don't touch - end case; - - -- Limit flag generation (equals overflow flag generaton!) - -- Clearing of the Limit flag has to be done by the user! - ----------------------------------------------------------- - case alu_ctrl.ccr_flags_ctrl(L_FLAG) is - when CLEAR => modified_sr(L_FLAG) <= '0'; - when SET => modified_sr(L_FLAG) <= '1'; - when MODIFY => - -- There are two sources for the overflow flag: - -- 1) - -- in case the result cannot be represented using 56 bits set - -- the overflow flag. this is the case when the two MSBs of - -- the 57 bit result are different - -- 2) - -- The shifter circuit performs a 56 bit left shift. In case the - -- two MSBs of the operand are different set the overflow flag as well - if (alu_ctrl.div_instr = '0' and alu_post_adder_result(56) /= alu_post_adder_result(55)) or - (alu_ctrl.shift_mode = SHIFT_LEFT and alu_ctrl.word_24_update = '0' and - alu_shifter_overflow_out = '1' ) then - modified_sr(L_FLAG) <= '1'; - end if; - when others => -- Don't touch - end case; - - -- Scaling flag generation (DSP56002 and up) - -------------------------------------------- - -- Scaling flag is not generated in the ALU, but when A or B are read to the XDB or YDB - - end process; - - - src_operand_select: process(register_file, alu_ctrl) is - begin - -- decoding according similar to JJJ representation - case alu_ctrl.add_src_stage_1 is - when "000" => - -- select depending on destination accu - if alu_ctrl.dst_accu = '0' then - alu_src_op <= register_file.a; - else - alu_src_op <= register_file.b; - end if; - when "001" => -- A,B or B,A - -- select depending on destination accu - if alu_ctrl.dst_accu = '0' then - alu_src_op <= register_file.b; - else - alu_src_op <= register_file.a; - end if; - when "010" => -- X - alu_src_op(55 downto 48) <= (others => register_file.x1(23)); - alu_src_op(47 downto 0) <= register_file.x1 & register_file.x0; - when "011" => -- Y - alu_src_op(55 downto 48) <= (others => register_file.y1(23)); - alu_src_op(47 downto 0) <= register_file.y1 & register_file.y0; - when "100" => -- x0 - alu_src_op(55 downto 48) <= (others => register_file.x0(23)); - alu_src_op(47 downto 24) <= register_file.x0; - alu_src_op(23 downto 0) <= (others => '0'); - when "101" => -- y0 - alu_src_op(55 downto 48) <= (others => register_file.y0(23)); - alu_src_op(47 downto 24) <= register_file.y0; - alu_src_op(23 downto 0) <= (others => '0'); - when "110" => -- x1 - alu_src_op(55 downto 48) <= (others => register_file.x1(23)); - alu_src_op(47 downto 24) <= register_file.x1; - alu_src_op(23 downto 0) <= (others => '0'); - when "111" => -- y1 - alu_src_op(55 downto 48) <= (others => register_file.y1(23)); - alu_src_op(47 downto 24) <= register_file.y1; - alu_src_op(23 downto 0) <= (others => '0'); - when others => - end case; - end process; - - alu_logical_functions: process(alu_ctrl, alu_src_op, alu_shifter_out) is - begin - alu_logic_conj <= alu_shifter_out; - case alu_ctrl.logic_function is - when "110" => - alu_logic_conj(47 downto 24) <= alu_shifter_out(47 downto 24) and alu_src_op(47 downto 24); - when "010" => - alu_logic_conj(47 downto 24) <= alu_shifter_out(47 downto 24) or alu_src_op(47 downto 24); - when "011" => - alu_logic_conj(47 downto 24) <= alu_shifter_out(47 downto 24) xor alu_src_op(47 downto 24); - when "111" => - alu_logic_conj(47 downto 24) <= not alu_shifter_out(47 downto 24); - when others => - end case; - end process; - - alu_adder : process(alu_ctrl, alu_src_op, alu_multiplier_out, alu_shifter_out) is - variable add_src_op_1 : signed(56 downto 0); - variable add_src_op_2 : signed(56 downto 0); - variable carry_const : signed(56 downto 0); - variable alu_shifter_out_57 : signed(56 downto 0); - variable alu_add_result_58 : signed(57 downto 0); - variable alu_add_result_interm : signed(56 downto 0); - variable invert_carry_flag : std_logic; - begin - - -- by default do not invert the carry - invert_carry_flag := '0'; - - -- determine whether to use multiplier output, the operand defined above, or zeros! - -- resizing is done here already. Like that we can see whether an overflow - -- occurs due to negating the source operand - case alu_ctrl.add_src_stage_2 is - when "00" => add_src_op_1 := (others => '0'); - when "10" => add_src_op_1 := resize(alu_multiplier_out, 57); - when others => add_src_op_1 := resize(alu_src_op, 57); - end case; - - -- determine the sign for the 1st operand! - case alu_ctrl.add_src_sign is - -- normal operation - when "00" => add_src_op_1 := add_src_op_1; - -- negative sign - when "01" => add_src_op_1 := - add_src_op_1; - invert_carry_flag := not invert_carry_flag; - -- change according to sign - -- performs - | accu | for the CMPM instruction - when "10" => - -- we subtract in any case, so invert the carry! - invert_carry_flag := not invert_carry_flag; - if add_src_op_1(55) = '0' then - add_src_op_1 := - add_src_op_1; - else - add_src_op_1 := add_src_op_1; - end if; - -- div instruction! - -- sign dependant of D[55] XOR S[23], if 1 => positive , if 0 => negative - -- add_src_op_1 holds S[23] (sign extension!) - when others => - if (alu_ctrl.shift_src = '0' and add_src_op_1(55) /= register_file.a(55)) or - (alu_ctrl.shift_src = '1' and add_src_op_1(55) /= register_file.b(55)) then - add_src_op_1 := add_src_op_1; - else - add_src_op_1 := - add_src_op_1; --- invert_carry_flag := not invert_carry_flag; - end if; - end case; - - alu_shifter_out_57 := resize(alu_shifter_out, 57); - - -- determine the sign for the 2nd operand (coming from the shifter)! - case alu_ctrl.shift_src_sign is - -- negative sign - when "01" => - add_src_op_2 := - alu_shifter_out_57; - -- change according to sign - -- this allows to build the magnitude (ABS, CMPM) - when "10" => - if alu_shifter_out(55) = '1' then - add_src_op_2 := - alu_shifter_out_57; - else - add_src_op_2 := alu_shifter_out_57; - end if; - when others => - add_src_op_2 := alu_shifter_out_57; - end case; - - -- determine whether carry flag has to be added or subtracted - if alu_ctrl.rounding_used = "10" then - carry_const := (others => '0'); - -- add carry flag - carry_const(0) := register_file.sr(C_FLAG); - elsif alu_ctrl.rounding_used = "11" then - -- subtract carry flag - carry_const := (others => register_file.sr(0)); -- carry flag - else - carry_const := (others => '0'); - end if; - - -- add the values and calculate the carry bit - alu_add_result_interm := ('0' & add_src_op_1(55 downto 0)) + - ('0' & add_src_op_2(55 downto 0)) + - ('0' & carry_const(55 downto 0)); - - -- here pops the new carry out of the adder - if invert_carry_flag = '0' then - alu_add_carry_out <= alu_add_result_interm(56); - else - alu_add_carry_out <= not alu_add_result_interm(56); - end if; - - -- calculate the last bit (56), in order to test for overflow later on - alu_add_result(55 downto 0) <= alu_add_result_interm(55 downto 0); --- alu_add_result(56) <= add_src_op_1(56) xor add_src_op_2(56) xor alu_add_result_interm(56); - alu_add_result(56) <= add_src_op_1(56) xor add_src_op_2(56) - xor carry_const(56) xor alu_add_result_interm(56); - - end process alu_adder; - - - -- Adder after the normal arithmetic adder - -- This adder is responsible for --- -- 1) carry addition --- -- 2) carry subtration - -- 3) convergent rounding - alu_post_adder: process(alu_add_result, scaling_mode, alu_ctrl) is - variable post_adder_constant : signed(56 downto 0); - variable testing_constant : signed(24 downto 0); - begin - -- by default add nothing - post_adder_constant := (others => '0'); - - case alu_ctrl.rounding_used is - -- rounding dependant on scaling bits - when "01" => - case scaling_mode is - -- no scaling - when "00" => testing_constant := alu_add_result(23 downto 0) & '0'; - -- scale down - when "01" => testing_constant := alu_add_result(24 downto 0); - -- scale up - when "10" => testing_constant := alu_add_result(22 downto 0) & "00"; - when others => - testing_constant := alu_add_result(23 downto 0) & '0'; - end case; - - -- Special case! - if testing_constant(24) = '1' and testing_constant(23 downto 0) = X"000000" then - -- add depending on bit left to the rounding position - case scaling_mode is - -- no scaling - when "00" => post_adder_constant(23) := alu_add_result(24); - -- scale down - when "01" => post_adder_constant(24) := alu_add_result(25); - -- scale up - when "10" => post_adder_constant(22) := alu_add_result(23); - when others => - end case; - else -- testing_constant /= X"1000000" - -- add rounding constant depending on scaling mode - -- results in round up if MSB of testing constant is set, else nothing happens - case scaling_mode is - -- no scaling - when "00" => post_adder_constant(23) := '1'; - -- scale down - when "01" => post_adder_constant(24) := '1'; - -- scale up - when "10" => post_adder_constant(22) := '1'; - when others => - end case; - end if; - -- no rounding - when others => - post_adder_constant := (others => '0'); - - end case; - - -- Add the result of the first adder to the constant (e.g., carry flag) - alu_post_adder_result <= alu_add_result + post_adder_constant; - - -- When rounding is used set 24 LSBs to zero! - if alu_ctrl.rounding_used = "01" then - alu_post_adder_result(23 downto 0) <= (others => '0'); - end if; - end process; - - - - alu_select_new_accu: process(alu_post_adder_result, alu_logic_conj, alu_ctrl) is - begin - if alu_ctrl.logic_function /= "000" then - modified_accu_int <= alu_logic_conj; - else - modified_accu_int <= alu_post_adder_result(55 downto 0); - end if; - end process; - - - -- contains the 24*24 bit fractional multiplier - alu_multiplier : process(register_file, alu_ctrl) is - variable src_op1: signed(23 downto 0); - variable src_op2: signed(23 downto 0); - variable mul_result_interm : signed(47 downto 0); - begin - -- select source operands for multiplication - case alu_ctrl.mul_op1 is - when "00" => src_op1 := register_file.x0; - when "01" => src_op1 := register_file.x1; - when "10" => src_op1 := register_file.y0; - when others => src_op1 := register_file.y1; - end case; - case alu_ctrl.mul_op2 is - when "00" => src_op2 := register_file.x0; - when "01" => src_op2 := register_file.x1; - when "10" => src_op2 := register_file.y0; - when others => src_op2 := register_file.y1; - end case; - - -- perform integer multiplication - mul_result_interm := src_op1 * src_op2; - - -- sign extension of result - alu_multiplier_out(55 downto 48) <= (others => mul_result_interm(47)); - -- convert from two's complement representation to fractional format - -- signed integer multiplication delivers twice the sign bit, but only one is needed for the - -- fractional multiplication, so remove one and append a zero to the result - alu_multiplier_out(47 downto 0) <= mul_result_interm(46 downto 0) & '0'; - - end process alu_multiplier; - - - -- contains the data shifter - alu_shifter: process(register_file, alu_ctrl, norm_instr_asl, norm_instr_asr) is - variable src_accu : signed(55 downto 0); - variable shift_to_perform : alu_shift_mode; - begin - -- read source accumulator - if alu_ctrl.shift_src = '0' then - src_accu := register_file.a; - else - src_accu := register_file.b; - end if; - - alu_shifter_carry_out <= '0'; - alu_shifter_overflow_out <= '0'; - - -- NORM instruction determines the shift value just - -- in time, so overwrite the flag from the alu_ctrl - -- for this instruction by the calculated value - if alu_ctrl.norm_instr = '0' then - shift_to_perform := alu_ctrl.shift_mode; - else - if norm_instr_asl = '1' then - shift_to_perform := SHIFT_LEFT; - elsif norm_instr_asr = '1' then - shift_to_perform := SHIFT_RIGHT; - else - shift_to_perform := NO_SHIFT; - end if; - end if; - - case shift_to_perform is - when NO_SHIFT => - alu_shifter_out <= src_accu; - when SHIFT_LEFT => - -- ASL, ADDL, DIV? - if alu_ctrl.word_24_update = '0' then - -- special handling for div instruction required - if alu_ctrl.div_instr = '1' then - alu_shifter_out <= src_accu(54 downto 0) & register_file.sr(C_FLAG); - else - alu_shifter_out <= src_accu(54 downto 0) & '0'; - end if; - alu_shifter_carry_out <= src_accu(55); - -- detect overflow that results from left shifting - -- Needed for ASL, ADDL, DIV instructions - if src_accu(55) /= src_accu(54) then - alu_shifter_overflow_out <= '1'; - end if; - -- LSL/ROL? - elsif alu_ctrl.word_24_update = '1' then - alu_shifter_out(55 downto 48) <= src_accu(55 downto 48); - alu_shifter_out(23 downto 0) <= src_accu(23 downto 0); - alu_shifter_carry_out <= src_accu(47); - if alu_ctrl.rotate = '0' then -- LSL ? - alu_shifter_out(47 downto 24) <= src_accu(46 downto 24) & '0'; - else -- ROL ? - alu_shifter_out(47 downto 24) <= src_accu(46 downto 24) & register_file.sr(C_FLAG); - end if; - end if; - when SHIFT_RIGHT => - -- ASR? - if alu_ctrl.word_24_update = '0' then - alu_shifter_out <= src_accu(55) & src_accu(55 downto 1); - alu_shifter_carry_out <= src_accu(0); - -- LSR/ROR? - elsif alu_ctrl.word_24_update = '1' then - alu_shifter_out(55 downto 48) <= src_accu(55 downto 48); - alu_shifter_out(23 downto 0) <= src_accu(23 downto 0); - alu_shifter_carry_out <= src_accu(24); - if alu_ctrl.rotate = '0' then -- LSR - alu_shifter_out(47 downto 24) <= '0' & src_accu(47 downto 25); - else -- ROR - alu_shifter_out(47 downto 24) <= register_file.sr(C_FLAG) & src_accu(47 downto 25); - end if; - end if; - when ZEROS => - alu_shifter_out <= (others => '0'); - end case; - end process alu_shifter; - - - -- Special handling for NORM instruction - -- Determine which case occurs (see User's Manual for more information) - norm_instr_logic: process(register_file, addr_r_in) is - begin - norm_instr_asl <= '0'; - norm_instr_asr <= '0'; - - -- Either left shift - if register_file.sr(E_FLAG) = '0' and - register_file.sr(U_FLAG) = '1' and - register_file.sr(Z_FLAG) = '0' then - norm_instr_asl <= '1'; - norm_update_ccr <= '1'; - addr_r_out <= addr_r_in - 1; - -- Or right shift - elsif register_file.sr(E_FLAG) = '1' then - norm_instr_asr <= '1'; - norm_update_ccr <= '1'; - addr_r_out <= addr_r_in + 1; - -- Or do nothing! - else - norm_update_ccr <= '0'; - addr_r_out <= addr_r_in; - end if; - end process; - -end architecture; diff --git a/vhdl/dsp56k/src/exec_stage_bit_modify.vhd b/vhdl/dsp56k/src/exec_stage_bit_modify.vhd deleted file mode 100644 index 0bd69cd..0000000 --- a/vhdl/dsp56k/src/exec_stage_bit_modify.vhd +++ /dev/null @@ -1,86 +0,0 @@ ------------------------------------------------------------------------------ ---! @file ---! @author Matthias Alles ---! @date 01/2009 ---! @brief Bit modify (BCLR, BSET, J(S)CLR, J(S)SET) ---! ------------------------------------------------------------------------------- -library ieee; -use ieee.std_logic_1164.all; -use ieee.numeric_std.all; -library work; -use work.parameter_pkg.all; -use work.types_pkg.all; -use work.constants_pkg.all; - -entity exec_stage_bit_modify is port( - instr_word : in std_logic_vector(23 downto 0); - instr_array : in instructions_type; - src_operand : in std_logic_vector(23 downto 0); - register_file : in register_file_type; - dst_operand : out std_logic_vector(23 downto 0); - bit_cond_met : out std_logic; - modify_sr : out std_logic; - modified_sr : out std_logic_vector(15 downto 0) -); -end entity; - - -architecture rtl of exec_stage_bit_modify is - - signal operand_bit : std_logic; - signal src_operand_32 : std_logic_vector(31 downto 0); - -begin - - -- this is just a helper signal to prevent the simulator - -- to stop when accessing a bit > 23. - src_operand_32 <= "00000000" & src_operand; - -- read the bit we want to test (and modify) - operand_bit <= src_operand_32(to_integer(unsigned(instr_word(4 downto 0)))); - - -- modify the Carry flag only for the bit modify instructions! - modify_sr <= '1' when instr_array = INSTR_BCLR or instr_array = INSTR_BSET or instr_array = INSTR_BCHG or instr_array = INSTR_BTST else '0'; - modified_sr <= register_file.sr(15 downto 1) & operand_bit; - - bit_operation: process(instr_word, instr_array, src_operand, operand_bit) is - variable new_bit : std_logic; - begin - -- do nothing by default! - dst_operand <= src_operand; - bit_cond_met <= '0'; - - -- determine which bit to write - if instr_array = INSTR_BCLR then - new_bit := '0'; - elsif instr_array = INSTR_BSET then - new_bit := '1'; - else -- BCHG - new_bit := not operand_bit; - end if; - - if instr_array = INSTR_BCLR or instr_array = INSTR_BSET or instr_array = INSTR_BCHG then - dst_operand(to_integer(unsigned(instr_word(4 downto 0)))) <= new_bit; - end if; - - - -- check for the jump instructions whether condition is met or not! - if instr_array = INSTR_JCLR or instr_array = INSTR_JSCLR then - if operand_bit = '0' then - bit_cond_met <= '1'; - else - bit_cond_met <= '0'; - end if; - end if; - if instr_array = INSTR_JSET or instr_array = INSTR_JSSET then - if operand_bit = '0' then - bit_cond_met <= '0'; - else - bit_cond_met <= '1'; - end if; - end if; - - end process; - - -end architecture; diff --git a/vhdl/dsp56k/src/exec_stage_branch.vhd b/vhdl/dsp56k/src/exec_stage_branch.vhd deleted file mode 100644 index f59cc09..0000000 --- a/vhdl/dsp56k/src/exec_stage_branch.vhd +++ /dev/null @@ -1,124 +0,0 @@ ------------------------------------------------------------------------------ ---! @file ---! @author Matthias Alles ---! @date 01/2009 ---! @brief Branch control ---! ------------------------------------------------------------------------------- -library ieee; -use ieee.std_logic_1164.all; -use ieee.numeric_std.all; -library work; -use work.parameter_pkg.all; -use work.types_pkg.all; -use work.constants_pkg.all; - -entity exec_stage_branch is port( - activate_exec_bra : in std_logic; - instr_word : in std_logic_vector(23 downto 0); - instr_array : in instructions_type; - register_file : in register_file_type; - jump_address : in unsigned(BW_ADDRESS-1 downto 0); - bit_cond_met : in std_logic; - cc_flag_set : in std_logic; - push_stack : out push_stack_type; - pop_stack : out pop_stack_type; - modify_pc : out std_logic; - modified_pc : out unsigned(BW_ADDRESS-1 downto 0); - modify_sr : out std_logic; - modified_sr : out std_logic_vector(15 downto 0) -); -end entity; - - -architecture rtl of exec_stage_branch is - - signal branch_condition_met : std_logic; - signal modify_pc_int : std_logic; - -begin - - modify_pc_int <= '1' when activate_exec_bra = '1' and branch_condition_met = '1' else '0'; - modify_pc <= modify_pc_int; - - calculate_branch_condition : process(instr_word, instr_array, register_file, bit_cond_met) - begin - branch_condition_met <= '0'; - - -- unconditional jumps - if instr_array = INSTR_JMP or - instr_array = INSTR_JSR or - instr_array = INSTR_RTI or - instr_array = INSTR_RTS then - -- jump always - branch_condition_met <= '1'; - end if; - -- then see whether the branch condition is satisfied - if instr_array = INSTR_JCC or instr_array = INSTR_JSCC then - branch_condition_met <= cc_flag_set; - end if; - -- jmp that is executed according to a certain bit condition - if instr_array = INSTR_JCLR or instr_array = INSTR_JSCLR or - instr_array = INSTR_JSET or instr_array = INSTR_JSSET then - branch_condition_met <= bit_cond_met; - end if; - end process calculate_branch_condition; - - - calculate_branch_target : process(instr_array, instr_word, jump_address) - begin - modified_pc <= jump_address; - - -- address calculation is the same for the following instructions - if instr_array = INSTR_JMP or - instr_array = INSTR_JCC or - instr_array = INSTR_JSCC or - instr_array = INSTR_JSR then - if instr_word(18) = '1' then - -- short jump address included in opcode (bits 11 downto 0) - modified_pc(11 downto 0) <= unsigned(instr_word(11 downto 0)); - elsif instr_word(18) = '0' then - -- effective address defined by opcode and coming from address generator unit - modified_pc <= jump_address; - end if; - end if; - - -- jump address contains the obligatory address of the second - -- instruction word - if instr_array = INSTR_JCLR or - instr_array = INSTR_JSET or - instr_array = INSTR_JSCLR or - instr_array = INSTR_JSSET then - modified_pc <= jump_address; - end if; - - -- target address is stored on the stack - if instr_array = INSTR_RTS or - instr_array = INSTR_RTI then - modified_pc <= unsigned(register_file.current_ssh); - end if; - end process calculate_branch_target; - - -- Subroutine functions need to store PC and SR on the stack - push_stack.valid <= '1' when modify_pc_int = '1' and (instr_array = INSTR_JSCC or instr_array = INSTR_JSR or - instr_array = INSTR_JSCLR or instr_array = INSTR_JSSET) else '0'; - push_stack.content <= PC_AND_SR; - -- pc is set externally! - push_stack.pc <= (others => '0'); - - -- RTI/RTS instructions need to read from the stack - pop_stack.valid <= '1' when modify_pc_int = '1' and (instr_array = INSTR_RTI or instr_array = INSTR_RTS) else '0'; - - -- some instructions require to set the SR - calculate_status_register : process(instr_array) - begin - modify_sr <= '0'; - modified_sr <= (others => '0'); - if instr_array = INSTR_RTI then - modify_sr <= '1'; - modified_sr <= register_file.current_ssl; - end if; - end process calculate_status_register; - - -end architecture rtl; diff --git a/vhdl/dsp56k/src/exec_stage_cc_flag_calc.vhd b/vhdl/dsp56k/src/exec_stage_cc_flag_calc.vhd deleted file mode 100644 index 2f69230..0000000 --- a/vhdl/dsp56k/src/exec_stage_cc_flag_calc.vhd +++ /dev/null @@ -1,82 +0,0 @@ ------------------------------------------------------------------------------ ---! @file ---! @author Matthias Alles ---! @date 01/2009 ---! @brief Calculate whether cc flag condition is true ---! ------------------------------------------------------------------------------- -library ieee; -use ieee.std_logic_1164.all; -use ieee.numeric_std.all; -library work; -use work.parameter_pkg.all; -use work.types_pkg.all; -use work.constants_pkg.all; - -entity exec_stage_cc_flag_calc is port( - instr_word : in std_logic_vector(23 downto 0); - instr_array : in instructions_type; - register_file : in register_file_type; - cc_flag_set : out std_logic -); -end entity; - - -architecture rtl of exec_stage_cc_flag_calc is - - -begin - - calculate_cc_flag : process(instr_word, instr_array, register_file) - - variable cc_select : std_logic_vector(3 downto 0); - - procedure calculate_cc_flag(cc: std_logic_vector(3 downto 0)) is - variable c_flag : std_logic := register_file.ccr(0); - variable v_flag : std_logic := register_file.ccr(1); - variable z_flag : std_logic := register_file.ccr(2); - variable n_flag : std_logic := register_file.ccr(3); - variable u_flag : std_logic := register_file.ccr(4); - variable e_flag : std_logic := register_file.ccr(5); - variable l_flag : std_logic := register_file.ccr(6); - - begin - if (cc = "0000" and c_flag = '0') or -- CC: carry clear - (cc = "1000" and c_flag = '1') or -- CS: carry set - (cc = "0101" and e_flag = '0') or -- EC: extension clear - (cc = "1010" and z_flag = '1') or -- EQ: equal - (cc = "1101" and e_flag = '1') or -- ES: extension set - (cc = "0001" and (n_flag = v_flag)) or -- GE: greater than or equal - (cc = "0001" and ((n_flag xor v_flag) or z_flag) = '0') or -- GT: greater than - (cc = "0110" and l_flag = '0') or -- LC: limit clear - (cc = "1111" and ((n_flag xor v_flag) or z_flag ) = '1') or -- LE: less or equal - (cc = "1110" and l_flag = '1') or -- LS: limit set - (cc = "1001" and (n_flag /= v_flag)) or -- LT: less than - (cc = "1011" and n_flag = '1') or -- MI: minus - (cc = "0010" and z_flag = '0') or -- NE: not equal - (cc = "1100" and (( not u_flag and not e_flag) or z_flag) = '1') or -- NR: normalized - (cc = "0011" and n_flag = '0') or -- PL: plus - (cc = "0100" and (( not u_flag and not e_flag ) or z_flag) = '0') -- NN: not normalized - then - cc_flag_set <= '1'; - end if; - end procedure; - - begin - - cc_flag_set <= '0'; - - -- Rip the flags we have to test for from the instruction word - if (instr_array = INSTR_JCC and instr_word(18) = '0') or - (instr_array = INSTR_JSCC) then - cc_select := instr_word(3 downto 0); - else - cc_select := instr_word(15 downto 12); - end if; - - calculate_cc_flag(cc_select); - - end process; - - -end architecture; diff --git a/vhdl/dsp56k/src/exec_stage_cr_mod.vhd b/vhdl/dsp56k/src/exec_stage_cr_mod.vhd deleted file mode 100644 index 2465125..0000000 --- a/vhdl/dsp56k/src/exec_stage_cr_mod.vhd +++ /dev/null @@ -1,79 +0,0 @@ ------------------------------------------------------------------------------ ---! @file ---! @author Matthias Alles ---! @date 01/2009 ---! @brief ---! ------------------------------------------------------------------------------- -library ieee; -use ieee.std_logic_1164.all; -use ieee.numeric_std.all; -library work; -use work.parameter_pkg.all; -use work.types_pkg.all; -use work.constants_pkg.all; - -entity exec_stage_cr_mod is port ( - activate_exec_cr_mod : in std_logic; - instr_word : in std_logic_vector(23 downto 0); - instr_array : in instructions_type; - register_file : in register_file_type; - modify_sr : out std_logic; - modified_sr : out std_logic_vector(15 downto 0); - modify_omr : out std_logic; - modified_omr : out std_logic_vector(7 downto 0) -); -end exec_stage_cr_mod; - - -architecture rtl of exec_stage_cr_mod is - -begin - - process(activate_exec_cr_mod, instr_word, instr_array, register_file) is - variable imm8 : std_logic_vector(7 downto 0); - variable op8 : std_logic_vector(7 downto 0); - variable res8 : std_logic_vector(7 downto 0); - begin - modify_sr <= '0'; - modify_omr <= '0'; - modified_sr <= (others => '0'); - modified_omr <= (others => '0'); - - imm8 := instr_word(15 downto 8); - if instr_word(1 downto 0) = "00" then - -- read MR - op8 := register_file.mr; - elsif instr_word(1 downto 0) = "01" then - -- read CCR - op8 := register_file.ccr; - else -- instr_word(1 downto 0) = "10" - -- read OMR - op8 := register_file.omr; - end if; - - if instr_array = INSTR_ANDI then - res8 := imm8 and op8; - else -- instr_array = INSTR_ORI - res8 := imm8 or op8; - end if; - - -- only write the result when activated - if activate_exec_cr_mod = '1' then - if instr_word(1 downto 0) = "00" then - -- update MR - modify_sr <= '1'; - modified_sr <= res8 & register_file.ccr; - elsif instr_word(1 downto 0) = "01" then - -- update CCR - modify_sr <= '1'; - modified_sr <= register_file.mr & res8; - elsif instr_word(1 downto 0) = "10" then - -- update OMR - modify_omr <= '1'; - modified_omr <= res8; - end if; - end if; - end process; - -end architecture; diff --git a/vhdl/dsp56k/src/exec_stage_loops.vhd b/vhdl/dsp56k/src/exec_stage_loops.vhd deleted file mode 100644 index 3472636..0000000 --- a/vhdl/dsp56k/src/exec_stage_loops.vhd +++ /dev/null @@ -1,207 +0,0 @@ ------------------------------------------------------------------------------- ---! @file ---! @author Matthias Alles ---! @date 01/2009 ---! @brief Loop control (REP, DO, ENDDO) ---! ------------------------------------------------------------------------------- -library ieee; -use ieee.std_logic_1164.all; -use ieee.numeric_std.all; -library work; -use work.parameter_pkg.all; -use work.types_pkg.all; -use work.constants_pkg.all; - -entity exec_stage_loop is port( - clk, rst : in std_logic; - activate_exec_loop : in std_logic; - instr_word : in std_logic_vector(23 downto 0); - instr_array : in instructions_type; - loop_iterations : in unsigned(15 downto 0); - loop_address : in unsigned(BW_ADDRESS-1 downto 0); - loop_start_address: in unsigned(BW_ADDRESS-1 downto 0); - register_file : in register_file_type; - fetch_perform_enddo: in std_logic; - memory_stall : in std_logic; - push_stack : out push_stack_type; - pop_stack : out pop_stack_type; - stall_rep : out std_logic; - stall_do : out std_logic; - decrement_lc : out std_logic; - modify_lc : out std_logic; - modified_lc : out unsigned(15 downto 0); - modify_la : out std_logic; - modified_la : out unsigned(15 downto 0); - modify_pc : out std_logic; - modified_pc : out unsigned(BW_ADDRESS-1 downto 0); - modify_sr : out std_logic; - modified_sr : out std_logic_vector(15 downto 0) -); -end entity; - - -architecture rtl of exec_stage_loop is - - signal rep_loop_polling : std_logic; - signal do_loop_polling : std_logic; - signal enddo_polling : std_logic; - signal lc_temp : unsigned(15 downto 0); - signal rf_lc_eq_1 : std_logic; - signal memory_stall_t : std_logic; - -begin - - modified_pc <= loop_start_address; - - - -- loop counter in register file equal to 1? - rf_lc_eq_1 <= '1' when register_file.lc = 1 else '0'; - - process(activate_exec_loop, instr_array, register_file, fetch_perform_enddo, - rep_loop_polling, loop_iterations, rf_lc_eq_1, loop_start_address) is - begin - stall_rep <= '0'; - stall_do <= '0'; - - modify_la <= '0'; - modify_lc <= '0'; - modify_pc <= '0'; - modify_sr <= '0'; - modified_la <= loop_address; - modified_lc <= loop_iterations; -- default - -- set the loop flag LF (bit 15) of Status register - modified_sr(15) <= '1'; - modified_sr(14 downto 0) <= register_file.sr(14 downto 0); - - push_stack.valid <= '0'; -- push PC and SR on the stack - push_stack.pc <= loop_start_address; - push_stack.content <= LA_AND_LC; - - pop_stack.valid <= '0'; - decrement_lc <= '0'; - ------------------ - -- DO instruction - ------------------ - if activate_exec_loop = '1' and instr_array = INSTR_DO then - -- first instruction of the do loop instruction? - if do_loop_polling = '0' then - stall_do <= '1'; - modify_lc <= '1'; -- store the new loop counter - modify_la <= '1'; -- store the new loop address - push_stack.valid <= '1'; -- push LA and LC on the stack - push_stack.content <= LA_AND_LC; - else -- second clock cycle of the do loop instruction ? - push_stack.valid <= '1'; -- push PC and SR on the stack - push_stack.pc <= loop_start_address; - push_stack.content <= PC_AND_SR; - -- set the PC to the first instruction of the loop - -- the already fetched instruction are flushed from the pipeline - -- this prevents problems, when the loop consists of only one or two instructions - modify_pc <= '1'; - -- set the loop flag - modify_sr <= '1'; - end if; - end if; - ----------------------------------------------- - -- ENDDO instruction / loop end in fetch stage - ----------------------------------------------- - if (activate_exec_loop = '1' and instr_array = INSTR_ENDDO) or fetch_perform_enddo = '1' or enddo_polling = '1' then - pop_stack.valid <= '1'; - if enddo_polling = '0' then - -- only restore the LF from the stack - modified_sr(15) <= register_file.current_ssl(15); - modify_sr <= '1'; - stall_do <= '1'; -- stall one clock cycle - else - -- restore loop counter and loop address in second clock cycle - modified_lc <= unsigned(register_file.current_ssl); - modify_lc <= '1'; - modified_la <= unsigned(register_file.current_ssh); - modify_la <= '1'; - end if; - end if; - ------------------- - -- REP instruction - ------------------- - if activate_exec_loop = '1' and instr_array = INSTR_REP then - -- only do something when there are more than 1 iterations - -- the first execution is already on the way - if loop_iterations /= 1 then - stall_rep <= '1'; -- stall the fetch and decode stages - modify_lc <= '1'; -- store the loop counter - modified_lc <= loop_iterations - 1; - end if; - end if; - - -- keep processing the single instruction - if rep_loop_polling = '1' then - stall_rep <= '1'; - -- if the REP instruction caused a stall do not modify the lc! - if memory_stall_t = '0' then - if rf_lc_eq_1 = '0' then - decrement_lc <= '1'; - -- when the instruction to repeat caused a memory stall - -- do not continue! - else - -- finish the REP instruction by restoring the LC - stall_rep <= '0'; - modify_lc <= '1'; - modified_lc <= lc_temp; - end if; - end if; - end if; - end process; - - - -- process that allows to remember that we are processing a REP/DO instruction - -- even though the REP instruction is not available in the pipeline anymore - -- also store the old loop counter - process(clk) is - begin - if rising_edge(clk) then - if rst = '1' then - rep_loop_polling <= '0'; - do_loop_polling <= '0'; - enddo_polling <= '0'; - lc_temp <= (others => '0'); - memory_stall_t <= '0'; - else - memory_stall_t <= memory_stall; - - if activate_exec_loop = '1' and instr_array = INSTR_REP then - -- only do something when there are more than 1 iterations - -- the first execution is already on the way - if loop_iterations /= 1 then - rep_loop_polling <= '1'; - lc_temp <= register_file.lc; - end if; - end if; - -- test whether the REP instruction has been executed - if rep_loop_polling = '1' and rf_lc_eq_1 = '1' and memory_stall_t = '0' then - rep_loop_polling <= '0'; - end if; - - -- do loop execution takes two clock cycles - -- in the first clock cycle we store loop address and loop counter on the stack - -- in the second clock cycle we store programm counter and status register on the stack - if activate_exec_loop = '1' and instr_array = INSTR_DO then - do_loop_polling <= '1'; - end if; - -- clear the flag immediately again (only two cycles execution time!) - if do_loop_polling = '1' then - do_loop_polling <= '0'; - end if; - - -- ENDDO instructions take two clock cycles as well! - if (activate_exec_loop = '1' and instr_array = INSTR_ENDDO) or fetch_perform_enddo = '1' then - enddo_polling <= '1'; - end if; - if enddo_polling = '1' then - enddo_polling <= '0'; - end if; - end if; - end if; - end process; - -end architecture; diff --git a/vhdl/dsp56k/src/fetch_stage.vhd b/vhdl/dsp56k/src/fetch_stage.vhd deleted file mode 100644 index 0848bf8..0000000 --- a/vhdl/dsp56k/src/fetch_stage.vhd +++ /dev/null @@ -1,67 +0,0 @@ ------------------------------------------------------------------------------- ---! @file ---! @author Matthias Alles ---! @date 01/2009 ---! @brief Fetching from program memory ---! ------------------------------------------------------------------------------- -library ieee; -use ieee.std_logic_1164.all; -use ieee.numeric_std.all; -library work; -use work.parameter_pkg.all; -use work.types_pkg.all; - - -entity fetch_stage is port( - - pc_old : in unsigned(BW_ADDRESS-1 downto 0); - pc_new : out unsigned(BW_ADDRESS-1 downto 0); - modify_pc : in std_logic; - modified_pc : in unsigned(BW_ADDRESS-1 downto 0); - register_file : in register_file_type; - decrement_lc : out std_logic; - perform_enddo : out std_logic - -); -end fetch_stage; - - -architecture rtl of fetch_stage is - - -begin - - pc_calculation: process(pc_old, modify_pc, modified_pc, register_file) is - begin - decrement_lc <= '0'; - perform_enddo <= '0'; - - -- by default increment pc by one - pc_new <= pc_old + 1; - if modify_pc = '1' then - pc_new <= modified_pc; - end if; - -- Loop Flag set? - if register_file.sr(15) = '1' then - if register_file.la = pc_old then - -- Loop not finished? - -- => start from the beginning if necessary - if register_file.lc /= 1 then - -- if the last address was LA and the loop is not finished yet, we have to - -- read now from the beginning of the loop again - pc_new <= unsigned(register_file.current_ssh(BW_ADDRESS-1 downto 0)); - -- decrement loop counter - decrement_lc <= '1'; - else - -- loop done! - -- => tell the loop controller in the exec stage to perform the enddo operation - -- (without flushing of the pipeline!) - perform_enddo <= '1'; - end if; - end if; - end if; - end process pc_calculation; - -end architecture rtl; - diff --git a/vhdl/dsp56k/src/mem_control.vhd b/vhdl/dsp56k/src/mem_control.vhd deleted file mode 100644 index 02c70eb..0000000 --- a/vhdl/dsp56k/src/mem_control.vhd +++ /dev/null @@ -1,1543 +0,0 @@ ------------------------------------------------------------------------------- ---! @file ---! @author Matthias Alles ---! @date 01/2009 ---! @brief Internal DSP RAM ---! ------------------------------------------------------------------------------- -library ieee; -use ieee.std_logic_1164.all; -use ieee.numeric_std.all; -library work; -use work.parameter_pkg.all; -use work.types_pkg.all; - -entity mem_control is - generic( - mem_type : memory_type := P_MEM - ); - port( - clk, rst : in std_logic; - rd_addr : in unsigned(BW_ADDRESS-1 downto 0); - rd_en : in std_logic; - data_out : out std_logic_vector(23 downto 0); - data_out_valid : out std_logic; - wr_addr : in unsigned(BW_ADDRESS-1 downto 0); - wr_en : in std_logic; - wr_accomplished : out std_logic; - data_in : in std_logic_vector(23 downto 0) - ); -end entity mem_control; - - -architecture rtl of mem_control is - - signal int_mem_rd_addr : std_logic_vector(7 downto 0); - type int_mem_type is array(0 to 255) of std_logic_vector(23 downto 0); - signal int_mem : int_mem_type; - signal int_pmem : int_mem_type := ( --- AGU testing -X"390100", -X"310A00", -X"000000", -X"204900", -X"050FA1", -X"060AA0", -X"204900", -X"390A00", -X"060AA0", -X"204900", -X"000000", -X"000000", -X"000000", -X"000000", --- AGU testing - --- ABS begin ---X"0000B9", ---X"56F400", ---X"200000", ---X"200026", ---X"56F400", ---X"E00000", ---X"200026", ---X"56F400", ---X"000000", ---X"200026", ---X"52F400", ---X"000080", ---X"200026", --- ABS end - --- ADC begin ---X"46F400", ---X"000000", ---X"47F400", ---X"000001", ---X"20001B", ---X"51F400", ---X"000001", ---X"0000B9", ---X"0001F9", ---X"200039", ---X"47F400", ---X"800000", ---X"53F400", ---X"000080", ---X"200039", --- ADC end - --- ADD begin ---X"46F400", ---X"000000", ---X"47F400", ---X"000001", ---X"20001B", ---X"51F400", ---X"000001", ---X"0000B9", ---X"0001F9", ---X"200038", ---X"47F400", ---X"800000", ---X"53F400", ---X"000080", ---X"200038", --- ADD end - --- ADDL begin ---X"56F400", ---X"000055", ---X"20001B", ---X"51F400", ---X"000055", ---X"0000B9", ---X"20001A", ---X"56F400", ---X"0000AA", ---X"20001A", ---X"53F400", ---X"000080", ---X"20001A", --- ADDL end - --- ADDR begin ---X"56F400", ---X"000055", ---X"20001B", ---X"51F400", ---X"000055", ---X"0000B9", ---X"20000A", ---X"56F400", ---X"0000AA", ---X"20000A", ---X"53F400", ---X"000080", ---X"20000A", --- ADDR end - --- AND begin ---X"46F400", ---X"000FFF", ---X"57F400", ---X"FFFFFF", ---X"0000B9", ---X"20005E", ---X"46F400", ---X"FFF000", ---X"57F400", ---X"FFFFFF", ---X"0000B9", ---X"20005E", ---X"46F400", ---X"000000", ---X"57F400", ---X"FFFFFF", ---X"0000B9", ---X"20005E", --- AND end - --- EOR begin ---X"46F400", ---X"000FFF", ---X"57F400", ---X"FF00FF", ---X"0000B9", ---X"20005B", ---X"46F400", ---X"FFFFFF", ---X"57F400", ---X"FFFFFF", ---X"0000B9", ---X"20005B", --- EOR end - --- OR begin ---X"46F400", ---X"000FFF", ---X"57F400", ---X"FF00FF", ---X"0000B9", ---X"20005A", ---X"46F400", ---X"000000", ---X"57F400", ---X"000000", ---X"0000B9", ---X"20005A", --- OR end - --- NOT begin ---X"46F400", ---X"000FFF", ---X"57F400", ---X"7F00FF", ---X"0000B9", ---X"20001F", ---X"46F400", ---X"000000", ---X"57F400", ---X"FFFFFF", ---X"0000B9", ---X"20001F", --- NOT end - --- ASL begin ---X"20001B", ---X"51F400", ---X"0000A5", ---X"55F400", ---X"0000A5", ---X"53F400", ---X"0000A5", ---X"0000B9", ---X"20003A", --- ASL end - --- ASR begin ---X"20001B", ---X"51F400", ---X"0000A5", ---X"55F400", ---X"0000A5", ---X"53F400", ---X"0000A5", ---X"0000B9", ---X"20002A", --- ASR end - --- CLR begin ---X"0000B9", ---X"56F400", ---X"200000", ---X"200013", ---X"56F400", ---X"E00000", ---X"0000B9", ---X"0001F9", ---X"200013", --- CLR end - --- CMP begin ---X"2F2000", ---X"262400", ---X"0000B9", ---X"20005D", ---X"2F2000", ---X"262000", ---X"0000B9", ---X"20005D", ---X"2F2400", ---X"262000", ---X"0000B9", ---X"20005D", ---X"57F400", ---X"800AAA", ---X"262000", ---X"0000B9", ---X"20005D", ---X"46F400", ---X"800AAA", ---X"2F2000", ---X"0000B9", ---X"20005D", --- CMP end - --- CMPM begin ---X"2F2000", ---X"262400", ---X"0000B9", ---X"20005F", ---X"2F2000", ---X"262000", ---X"0000B9", ---X"20005F", ---X"2F2400", ---X"262000", ---X"0000B9", ---X"20005F", ---X"57F400", ---X"800AAA", ---X"262000", ---X"0000B9", ---X"20005F", ---X"46F400", ---X"800AAA", ---X"2F2000", ---X"0000B9", ---X"20005F", --- CMPM end - --- DIV begin ---X"00FEB9", ---X"44F400", ---X"600000", ---X"56F400", ---X"200000", ---X"0618A0", ---X"018040", ---X"210E00", --- DIV end - --- LSL begin ---X"0000B9", ---X"56F400", ---X"200000", ---X"56F400", ---X"AAAAAA", ---X"50F400", ---X"BCDEFA", ---X"0618A0", ---X"200033", --- LSL end - --- LSR begin ---X"0000B9", ---X"56F400", ---X"200000", ---X"56F400", ---X"AAAAAA", ---X"50F400", ---X"BCDEFA", ---X"0618A0", ---X"200023", --- LSR end - --- MPY begin ---X"0000B9", ---X"44F400", ---X"200000", ---X"46F400", ---X"400000", ---X"2000D0", ---X"44F400", ---X"E00000", ---X"46F400", ---X"B9999A", ---X"2000D0", ---X"44F400", ---X"E66666", ---X"46F400", ---X"466666", ---X"2000D0", ---X"44F400", ---X"E66666", ---X"46F400", ---X"466666", ---X"2000D4", --- MPY end - --- MAC begin ---X"0000B9", ---X"200013", ---X"2A8000", ---X"44F400", ---X"200000", ---X"46F400", ---X"400000", ---X"2000D6", ---X"44F400", ---X"E00000", ---X"46F400", ---X"B9999A", ---X"2000D2", ---X"44F400", ---X"E66666", ---X"46F400", ---X"466666", ---X"2000D2", ---X"44F400", ---X"E66666", ---X"46F400", ---X"466666", ---X"2000D6", --- MAC end - --- MACR begin ---X"0000B9", ---X"200013", ---X"2E1000", ---X"44F400", ---X"123456", ---X"46F400", ---X"123456", ---X"2000D3", ---X"56F400", ---X"100001", ---X"44F400", ---X"123456", ---X"46F400", ---X"123456", ---X"2000D3", ---X"2E1000", ---X"50F400", ---X"800000", ---X"44F400", ---X"123456", ---X"46F400", ---X"123456", ---X"2000D3", --- MACR end - --- MPYR begin ---X"0000B9", ---X"46F400", ---X"654321", ---X"200095", --- MPYR end - --- NEG begin ---X"0000B9", ---X"56F400", ---X"654321", ---X"200036", ---X"200013", ---X"52F400", ---X"000080", ---X"200036", ---X"56F400", ---X"800000", ---X"200036", --- NEG end - --- NORM begin ---X"200013", ---X"2C0100", ---X"200003", ---X"062FA0", ---X"01DB15", ---X"200013", ---X"2EFF00", ---X"2A8400", ---X"200003", ---X"062FA0", ---X"01D915", ---X"200013", ---X"062FA0", ---X"01DA15", --- NORM end - --- RND begin ---X"0000B9", ---X"54F400", ---X"123456", ---X"50F400", ---X"789ABC", ---X"200011", ---X"54F400", ---X"123456", ---X"50F400", ---X"800000", ---X"200011", ---X"54F400", ---X"123455", ---X"50F400", ---X"800000", ---X"200011", --- RND end - --- ROR begin ---X"0000B9", ---X"56F400", ---X"AAAAAA", ---X"50F400", ---X"BCDEFA", ---X"0618A0", ---X"200027", --- ROR end - --- ROL begin ---X"0000B9", ---X"56F400", ---X"AAAAAA", ---X"50F400", ---X"BCDEFA", ---X"0618A0", ---X"200037", --- ROL end - - --- SUB begin ---X"46F400", ---X"000000", ---X"47F400", ---X"000001", ---X"20001B", ---X"51F400", ---X"000001", ---X"0000B9", ---X"0001F9", ---X"20003C", ---X"47F400", ---X"800000", ---X"53F400", ---X"000080", ---X"20003C", ---X"20001B", ---X"53F400", ---X"000080", ---X"47F400", ---X"000001", ---X"20007C", --- SUB end - --- SUBL begin ---X"50F400", ---X"000000", ---X"54F400", ---X"000001", ---X"20001B", ---X"51F400", ---X"000001", ---X"0000B9", ---X"0001F9", ---X"20001E", ---X"54F400", ---X"800000", ---X"53F400", ---X"000080", ---X"20001E", ---X"20001B", ---X"53F400", ---X"000080", ---X"54F400", ---X"000001", ---X"20001E", --- SUBL end - --- SUBR begin ---X"50F400", ---X"000000", ---X"54F400", ---X"000001", ---X"20001B", ---X"51F400", ---X"000001", ---X"0000B9", ---X"0001F9", ---X"20000E", ---X"54F400", ---X"800000", ---X"53F400", ---X"000080", ---X"20000E", ---X"20001B", ---X"53F400", ---X"000080", ---X"54F400", ---X"000001", ---X"20000E", --- SUBR end - --- SBC begin ---X"46F400", ---X"000000", ---X"47F400", ---X"000001", ---X"20001B", ---X"51F400", ---X"000001", ---X"0000B9", ---X"0001F9", ---X"20003D", ---X"47F400", ---X"800000", ---X"53F400", ---X"000080", ---X"20003D", ---X"20001B", ---X"53F400", ---X"000080", ---X"47F400", ---X"000001", ---X"20003D", --- SBC end - --- TCC begin ---X"311400", ---X"44F400", ---X"ABCDEF", ---X"57F400", ---X"123456", ---X"0000B9", ---X"038143", ---X"03014A", ---X"0004F9", ---X"03A143", ---X"03214A", --- TCC end - --- TFR begin ---X"56F400", ---X"ABCDEF", ---X"57F400", ---X"123456", ---X"21EE09", ---X"44F400", ---X"555555", ---X"47F400", ---X"AAAAAA", ---X"21C441", ---X"21E679", --- TFR end - --- TST begin ---X"20001B", ---X"20000B", ---X"0000B9", ---X"0001F9", ---X"53F400", ---X"000080", ---X"20000B", ---X"53F400", ---X"00007F", ---X"20000B", --- TST end - - ---X"2AFF00", ---X"54F400", ---X"FFFFFF", ---X"50F400", ---X"FFFFF2", ---X"200026", ---X"000000", ---X"000000", ---X"000000", ---X"000000", ---X"000000", ---X"000000", ---X"000000", ---X"000000", ---X"000000", ---X"000000", -X"000000", -X"000000", -X"000000", -X"000000", -X"000000", -X"000000", -X"000000", -X"000000", -X"000000", ---X"44F400", ---X"100010", ---X"45F400", ---X"100011", ---X"0B5880", ---X"000017", ---X"46F400", ---X"100026", ---X"47F400", ---X"100027", ---X"425800", ---X"435800", ---X"420A00", ---X"431F00", ---X"437000", ---X"0000A0", ---X"427000", ---X"00004F", --- X"42F800", --- X"43F800", --- X"428A00", --- X"439F00", --- "001100000100100000000000", -- 0 move #72,r0 --- "001110000000100000000000", -- 1 move #8,n0 --- "000001010000000010100000", -- 2 move #0,m0 --- "000001010001000010100001", -- 3 move #16,m1 --- "000001101110000100100000", -- 4 rep m1 --- "010001001100100000000000", -- 5 move x:(r0)+n0,x0 --- "000000000000000000000000", -- 6 --- "000000000000000000000000", -- 7 --- "000000000000000000000000", -- 8 --- "000000000000000000000000", -- 9 --- "000000000000000000000000", -- 10 --- "000000000000000000000000", -- 11 --- "000000000000000000000000", -- 12 --- "000000000000000000000000", -- 13 --- "000000000000000000000000", -- 14 --- "000000000000000000000000", -- 15 --- "000000000000000000000000", -- 16 --- "000000000000000000000000", -- 17 --- "000000000000000000000000", -- 18 --- "000000000000000000000000", -- 19 --- "000010101101101010000000", -- 20 -- JMP (r2)+ --- "000000000000000000000000", -- 20 --- "000000000000000000000000", -- 21 --- "000000000000000000000000", -- 22 - "000000000000000000000000", -- 23 - "000000000000000000000000", -- 24 - "000000000000000000000000", -- 25 - "000000000000000000000000", -- 26 - "000000000000000000000000", -- 27 - "000000000000000000000000", -- 28 - "000000000000000000000000", -- 29 - "000000000000000000000000", -- 30 - "000000000000000000000000", -- 31 --- "000000000000000000000000", -- 32 --- "000011010000000000000000", -- 32 -- JSR #0 - "000010111111000010000000", -- 32 -- JSR absolute - "000000000000000001000000", -- 33 -- #64 - "000000000000000000000000", -- 34 - "000000000000000000000000", -- 35 - "000000000000000000000000", -- 36 - "000000000000000000000000", -- 37 - "000000000000000000000000", -- 38 - "000000000000000000000000", -- 39 - "000000000000000000000000", -- 40 - "000000000000000000000000", -- 41 - "000000000000000000000000", -- 42 - "000000000000000000000000", -- 43 - "000000000000000000000000", -- 44 - "000000000000000000000000", -- 45 - "000000000000000000000000", -- 46 - "000000000000000000000000", -- 47 - "000000000000000000000000", -- 48 - "000000000000000000000000", -- 49 - "000000000000000000000000", -- 50 - "000000000000000000000000", -- 51 - "000000000000000000000000", -- 52 - "000000000000000000000000", -- 53 - "000000000000000000000000", -- 54 - "000000000000000000000000", -- 55 - "000000000000000000000000", -- 56 - "000000000000000000000000", -- 57 - "000000000000000000000000", -- 58 - "000000000000000000000000", -- 59 - "000000000000000000000000", -- 60 - "000000000000000000000000", -- 61 - "000000000000000000000000", -- 62 - "000000000000000000000000", -- 63 - "000000000000000000000000", -- 64 - "000000000000000000000000", -- 65 - "000000000000000000000000", -- 66 - "000000000000000000000000", -- 67 - "000000000000000000000000", -- 68 - "000000000000000000000000", -- 69 - "000000000000000000000100", -- 70 -- RTI - "000000000000000000000000", -- 71 - "000000000000000000000000", -- 72 - "000000000000000000000000", -- 73 - "000000000000000000000000", -- 74 - "000000000000000000000000", -- 75 - "000000000000000000000000", -- 76 - "000000000000000000000000", -- 77 - "000000000000000000000000", -- 78 - "000000000000000000000000", -- 79 - "000000000000000000000000", -- 80 - "000000000000000000000000", -- 81 - "000000000000000000000000", -- 82 - "000000000000000000000000", -- 83 - "000000000000000000000000", -- 84 - "000000000000000000000000", -- 85 - "000000000000000000000000", -- 86 - "000000000000000000000000", -- 87 - "000000000000000000000000", -- 88 - "000000000000000000000000", -- 89 - "000000000000000000000000", -- 90 - "000000000000000000000000", -- 91 - "000000000000000000000000", -- 92 - "000000000000000000000000", -- 93 - "000000000000000000000000", -- 94 - "000000000000000000000000", -- 95 - "000000000000000000000000", -- 96 - "000000000000000000000000", -- 97 - "000000000000000000000000", -- 98 - "000000000000000000000000", -- 99 - "000000000000000000000000", -- 100 - "000000000000000000000000", -- 101 - "000000000000000000000000", -- 102 - "000000000000000000000000", -- 103 - "000000000000000000000000", -- 104 - "000000000000000000000000", -- 105 - "000000000000000000000000", -- 106 - "000000000000000000000000", -- 107 - "000000000000000000000000", -- 108 - "000000000000000000000000", -- 109 - "000000000000000000000000", -- 110 - "000000000000000000000000", -- 111 - "000000000000000000000000", -- 112 - "000000000000000000000000", -- 113 - "000000000000000000000000", -- 114 - "000000000000000000000000", -- 115 - "000000000000000000000000", -- 116 - "000000000000000000000000", -- 117 - "000000000000000000000000", -- 118 - "000000000000000000000000", -- 119 - "000000000000000000000000", -- 120 - "000000000000000000000000", -- 121 - "000000000000000000000000", -- 122 - "000000000000000000000000", -- 123 - "000000000000000000000000", -- 124 - "000000000000000000000000", -- 125 - "000000000000000000000000", -- 126 - "000000000000000000000000", -- 127 - "000000000000000000000000", -- 128 - "000000000000000000000000", -- 129 - "000000000000000000000000", -- 130 - "000000000000000000000000", -- 131 - "000000000000000000000000", -- 132 - "000000000000000000000000", -- 133 - "000000000000000000000000", -- 134 - "000000000000000000000000", -- 135 - "000000000000000000000000", -- 136 - "000000000000000000000000", -- 137 - "000000000000000000000000", -- 138 - "000000000000000000000000", -- 139 - "000000000000000000000000", -- 140 - "000000000000000000000000", -- 141 - "000000000000000000000000", -- 142 - "000000000000000000000000", -- 143 - "000000000000000000000000", -- 144 - "000000000000000000000000", -- 145 - "000000000000000000000000", -- 146 - "000000000000000000000000", -- 147 - "000000000000000000000000", -- 148 - "000000000000000000000000", -- 149 - "000000000000000000000000", -- 150 - "000000000000000000000000", -- 151 - "000000000000000000000000", -- 152 - "000000000000000000000000", -- 153 - "000000000000000000000000", -- 154 - "000000000000000000000000", -- 155 - "000000000000000000000000", -- 156 - "000000000000000000000000", -- 157 - "000000000000000000000000", -- 158 - "000000000000000000000000", -- 159 - "000000000000000000000000", -- 160 - "000000000000000000000000", -- 161 - "000000000000000000000000", -- 162 - "000000000000000000000000", -- 163 - "000000000000000000000000", -- 164 - "000000000000000000000000", -- 165 - "000000000000000000000000", -- 166 - "000000000000000000000000", -- 167 - "000000000000000000000000", -- 168 - "000000000000000000000000", -- 169 - "000000000000000000000000", -- 170 - "000000000000000000000000", -- 171 - "000000000000000000000000", -- 172 - "000000000000000000000000", -- 173 - "000000000000000000000000", -- 174 - "000000000000000000000000", -- 175 - "000000000000000000000000", -- 176 - "000000000000000000000000", -- 177 - "000000000000000000000000", -- 178 - "000000000000000000000000", -- 179 - "000000000000000000000000", -- 180 - "000000000000000000000000", -- 181 - "000000000000000000000000", -- 182 - "000000000000000000000000", -- 183 - "000000000000000000000000", -- 184 - "000000000000000000000000", -- 185 - "000000000000000000000000", -- 186 - "000000000000000000000000", -- 187 - "000000000000000000000000", -- 188 - "000000000000000000000000", -- 189 - "000000000000000000000000", -- 190 - "000000000000000000000000", -- 191 - "000000000000000000000000", -- 192 - "000000000000000000000000", -- 193 - "000000000000000000000000", -- 194 - "000000000000000000000000", -- 195 - "000000000000000000000000", -- 196 - "000000000000000000000000", -- 197 - "000000000000000000000000", -- 198 - "000000000000000000000000", -- 199 - "000000000000000000000000", -- 200 - "000000000000000000000000", -- 201 - "000000000000000000000000", -- 202 - "000000000000000000000000", -- 203 - "000000000000000000000000", -- 204 - "000000000000000000000000", -- 205 - "000000000000000000000000", -- 206 - "000000000000000000000000", -- 207 - "000000000000000000000000", -- 208 - "000000000000000000000000", -- 209 - "000000000000000000000000", -- 210 - "000000000000000000000000", -- 211 - "000000000000000000000000", -- 212 - "000000000000000000000000", -- 213 - "000000000000000000000000", -- 214 - "000000000000000000000000", -- 215 - "000000000000000000000000", -- 216 - "000000000000000000000000", -- 217 - "000000000000000000000000", -- 218 - "000000000000000000000000", -- 219 - "000000000000000000000000", -- 220 - "000000000000000000000000", -- 221 - "000000000000000000000000", -- 222 - "000000000000000000000000", -- 223 - "000000000000000000000000", -- 224 - "000000000000000000000000", -- 225 - "000000000000000000000000", -- 226 - "000000000000000000000000", -- 227 - "000000000000000000000000", -- 228 - "000000000000000000000000", -- 229 - "000000000000000000000000", -- 230 - "000000000000000000000000", -- 231 - "000000000000000000000000", -- 232 - "000000000000000000000000", -- 233 - "000000000000000000000000", -- 234 - "000000000000000000000000", -- 235 - "000000000000000000000000", -- 236 - "000000000000000000000000", -- 237 - "000000000000000000000000", -- 238 - "000000000000000000000000", -- 239 - "000000000000000000000000", -- 240 - "000000000000000000000000", -- 241 - "000000000000000000000000", -- 242 - "000000000000000000000000", -- 243 - "000000000000000000000000", -- 244 - "000000000000000000000000", -- 245 - "000000000000000000000000", -- 246 - "000000000000000000000000", -- 247 - "000000000000000000000000", -- 248 - "000000000000000000000000", -- 249 - "000000000000000000000000", -- 250 - "000000000000000000000000", -- 251 - "000000000000000000000000", -- 252 - "000000000000000000000000", -- 253 - "000000000000000000000000", -- 254 - "000000000000000000000000"); -- 255 - signal int_xmem : int_mem_type := ( --- when "11------10000000" => instr_array(JMP_INSTR) <= '1'; --- "000000000000111011111001", -- 0 -- ORI #$0E, CCR - "000000000000000000001100", -- 0 -- REP - "000000000000000000000101", -- 1 -- ORI #$0E, MR - "000000000000111011111010", -- 2 -- ORI #$0E, OMR - "000000000000100010111010", -- 3 -- ANDI #$08, OMR --- "000010101111000010000000", -- 1 -- JMP absolute --- "000000000000000000011111", -- 2 -- #31 --- "000011000000000000010000", -- 3 -- JMP #16 - "000000000000000000000000", -- 4 - "000000000000000000000000", -- 5 - "000000000000000000000000", -- 6 - "000000000000000000000000", -- 7 - "000000000000000000000000", -- 8 - "000000000000000000000000", -- 9 - "000000000000000000000000", -- 10 - "000000000000000000000000", -- 11 - "000000000000000000000000", -- 12 - "000000000000000000000000", -- 13 - "000000000000000000000000", -- 14 - "000000000000000000000000", -- 15 - "000000000000000000000000", -- 16 --- "000000000000000000000000", -- 17 - "000010101101010110100000", -- 17 -- JCC (r5)- - "000000000000000000000000", -- 18 - "000000000000000000000000", -- 19 - "000010101101101010000000", -- 20 -- JMP (r2)+ - "000000000000000000000000", -- 21 - "000000000000000000000000", -- 22 - "000000000000000000000000", -- 23 - "000000000000000000000000", -- 24 - "000000000000000000000000", -- 25 - "000000000000000000000000", -- 26 - "000000000000000000000000", -- 27 - "000000000000000000000000", -- 28 - "000000000000000000000000", -- 29 - "000000000000000000000000", -- 30 - "000000000000000000000000", -- 31 --- "000000000000000000000000", -- 32 --- "000011010000000000000000", -- 32 -- JSR #0 - "000010111111000010000000", -- 32 -- JSR absolute - "000000000000000001000000", -- 33 -- #64 - "000000000000000000000000", -- 34 - "000000000000000000000000", -- 35 - "000000000000000000000000", -- 36 - "000000000000000000000000", -- 37 - "000000000000000000000000", -- 38 - "000000000000000000000000", -- 39 - "000000000000000000000000", -- 40 - "000000000000000000000000", -- 41 - "000000000000000000000000", -- 42 - "000000000000000000000000", -- 43 - "000000000000000000000000", -- 44 - "000000000000000000000000", -- 45 - "000000000000000000000000", -- 46 - "000000000000000000000000", -- 47 - "000000000000000000000000", -- 48 - "000000000000000000000000", -- 49 - "000000000000000000000000", -- 50 - "000000000000000000000000", -- 51 - "000000000000000000000000", -- 52 - "000000000000000000000000", -- 53 - "000000000000000000000000", -- 54 - "000000000000000000000000", -- 55 - "000000000000000000000000", -- 56 - "000000000000000000000000", -- 57 - "000000000000000000000000", -- 58 - "000000000000000000000000", -- 59 - "000000000000000000000000", -- 60 - "000000000000000000000000", -- 61 - "000000000000000000000000", -- 62 - "000000000000000000000000", -- 63 - "000000000000000000000000", -- 64 - "000000000000000000000000", -- 65 - "000000000000000000000000", -- 66 - "000000000000000000000000", -- 67 - "000000000000000000000000", -- 68 - "000000000000000000000000", -- 69 - "000000000000000000000100", -- 70 -- RTI - "000000000000000000000000", -- 71 - "000000000000000000000000", -- 72 - "000000000000000000000000", -- 73 - "000000000000000000000000", -- 74 - "000000000000000000000000", -- 75 - "000000000000000000000000", -- 76 - "000000000000000000000000", -- 77 - "000000000000000000000000", -- 78 - "000000000000000000000000", -- 79 - "000000000000000000000000", -- 80 - "000000000000000000000000", -- 81 - "000000000000000000000000", -- 82 - "000000000000000000000000", -- 83 - "000000000000000000000000", -- 84 - "000000000000000000000000", -- 85 - "000000000000000000000000", -- 86 - "000000000000000000000000", -- 87 - "000000000000000000000000", -- 88 - "000000000000000000000000", -- 89 - "000000000000000000000000", -- 90 - "000000000000000000000000", -- 91 - "000000000000000000000000", -- 92 - "000000000000000000000000", -- 93 - "000000000000000000000000", -- 94 - "000000000000000000000000", -- 95 - "000000000000000000000000", -- 96 - "000000000000000000000000", -- 97 - "000000000000000000000000", -- 98 - "000000000000000000000000", -- 99 - "000000000000000000000000", -- 100 - "000000000000000000000000", -- 101 - "000000000000000000000000", -- 102 - "000000000000000000000000", -- 103 - "000000000000000000000000", -- 104 - "000000000000000000000000", -- 105 - "000000000000000000000000", -- 106 - "000000000000000000000000", -- 107 - "000000000000000000000000", -- 108 - "000000000000000000000000", -- 109 - "000000000000000000000000", -- 110 - "000000000000000000000000", -- 111 - "000000000000000000000000", -- 112 - "000000000000000000000000", -- 113 - "000000000000000000000000", -- 114 - "000000000000000000000000", -- 115 - "000000000000000000000000", -- 116 - "000000000000000000000000", -- 117 - "000000000000000000000000", -- 118 - "000000000000000000000000", -- 119 - "000000000000000000000000", -- 120 - "000000000000000000000000", -- 121 - "000000000000000000000000", -- 122 - "000000000000000000000000", -- 123 - "000000000000000000000000", -- 124 - "000000000000000000000000", -- 125 - "000000000000000000000000", -- 126 - "000000000000000000000000", -- 127 - "000000000000000000000000", -- 128 - "000000000000000000000000", -- 129 - "000000000000000000000000", -- 130 - "000000000000000000000000", -- 131 - "000000000000000000000000", -- 132 - "000000000000000000000000", -- 133 - "000000000000000000000000", -- 134 - "000000000000000000000000", -- 135 - "000000000000000000000000", -- 136 - "000000000000000000000000", -- 137 - "000000000000000000000000", -- 138 - "000000000000000000000000", -- 139 - "000000000000000000000000", -- 140 - "000000000000000000000000", -- 141 - "000000000000000000000000", -- 142 - "000000000000000000000000", -- 143 - "000000000000000000000000", -- 144 - "000000000000000000000000", -- 145 - "000000000000000000000000", -- 146 - "000000000000000000000000", -- 147 - "000000000000000000000000", -- 148 - "000000000000000000000000", -- 149 - "000000000000000000000000", -- 150 - "000000000000000000000000", -- 151 - "000000000000000000000000", -- 152 - "000000000000000000000000", -- 153 - "000000000000000000000000", -- 154 - "000000000000000000000000", -- 155 - "000000000000000000000000", -- 156 - "000000000000000000000000", -- 157 - "000000000000000000000000", -- 158 - "000000000000000000000000", -- 159 - "000000000000000000000000", -- 160 - "000000000000000000000000", -- 161 - "000000000000000000000000", -- 162 - "000000000000000000000000", -- 163 - "000000000000000000000000", -- 164 - "000000000000000000000000", -- 165 - "000000000000000000000000", -- 166 - "000000000000000000000000", -- 167 - "000000000000000000000000", -- 168 - "000000000000000000000000", -- 169 - "000000000000000000000000", -- 170 - "000000000000000000000000", -- 171 - "000000000000000000000000", -- 172 - "000000000000000000000000", -- 173 - "000000000000000000000000", -- 174 - "000000000000000000000000", -- 175 - "000000000000000000000000", -- 176 - "000000000000000000000000", -- 177 - "000000000000000000000000", -- 178 - "000000000000000000000000", -- 179 - "000000000000000000000000", -- 180 - "000000000000000000000000", -- 181 - "000000000000000000000000", -- 182 - "000000000000000000000000", -- 183 - "000000000000000000000000", -- 184 - "000000000000000000000000", -- 185 - "000000000000000000000000", -- 186 - "000000000000000000000000", -- 187 - "000000000000000000000000", -- 188 - "000000000000000000000000", -- 189 - "000000000000000000000000", -- 190 - "000000000000000000000000", -- 191 - "000000000000000000000000", -- 192 - "000000000000000000000000", -- 193 - "000000000000000000000000", -- 194 - "000000000000000000000000", -- 195 - "000000000000000000000000", -- 196 - "000000000000000000000000", -- 197 - "000000000000000000000000", -- 198 - "000000000000000000000000", -- 199 - "000000000000000000000000", -- 200 - "000000000000000000000000", -- 201 - "000000000000000000000000", -- 202 - "000000000000000000000000", -- 203 - "000000000000000000000000", -- 204 - "000000000000000000000000", -- 205 - "000000000000000000000000", -- 206 - "000000000000000000000000", -- 207 - "000000000000000000000000", -- 208 - "000000000000000000000000", -- 209 - "000000000000000000000000", -- 210 - "000000000000000000000000", -- 211 - "000000000000000000000000", -- 212 - "000000000000000000000000", -- 213 - "000000000000000000000000", -- 214 - "000000000000000000000000", -- 215 - "000000000000000000000000", -- 216 - "000000000000000000000000", -- 217 - "000000000000000000000000", -- 218 - "000000000000000000000000", -- 219 - "000000000000000000000000", -- 220 - "000000000000000000000000", -- 221 - "000000000000000000000000", -- 222 - "000000000000000000000000", -- 223 - "000000000000000000000000", -- 224 - "000000000000000000000000", -- 225 - "000000000000000000000000", -- 226 - "000000000000000000000000", -- 227 - "000000000000000000000000", -- 228 - "000000000000000000000000", -- 229 - "000000000000000000000000", -- 230 - "000000000000000000000000", -- 231 - "000000000000000000000000", -- 232 - "000000000000000000000000", -- 233 - "000000000000000000000000", -- 234 - "000000000000000000000000", -- 235 - "000000000000000000000000", -- 236 - "000000000000000000000000", -- 237 - "000000000000000000000000", -- 238 - "000000000000000000000000", -- 239 - "000000000000000000000000", -- 240 - "000000000000000000000000", -- 241 - "000000000000000000000000", -- 242 - "000000000000000000000000", -- 243 - "000000000000000000000000", -- 244 - "000000000000000000000000", -- 245 - "000000000000000000000000", -- 246 - "000000000000000000000000", -- 247 - "000000000000000000000000", -- 248 - "000000000000000000000000", -- 249 - "000000000000000000000000", -- 250 - "000000000000000000000000", -- 251 - "000000000000000000000000", -- 252 - "000000000000000000000000", -- 253 - "000000000000000000000000", -- 254 - "000000000000000000000000"); -- 255 - signal int_ymem : int_mem_type := ( --- when "11------10000000" => instr_array(JMP_INSTR) <= '1'; --- "000000000000111011111001", -- 0 -- ORI #$0E, CCR - "000000000000000000000001", -- 0 -- REP - "000000000000000000000010", -- 1 -- ORI #$0E, MR - "000000000000000000000011", -- 2 -- ORI #$0E, OMR - "000000000000000000000100", -- 3 -- ANDI #$08, OMR --- "000010101111000010000000", -- 1 -- JMP absolute --- "000000000000000000011111", -- 2 -- #31 --- "000011000000000000010000", -- 3 -- JMP #16 - "000000000000000000000101", -- 4 - "000000000000000000000110", -- 5 - "000000000000000000000111", -- 6 - "000000000000000000001000", -- 7 - "000000000000000000001001", -- 8 - "000000000000000000001010", -- 9 - "000000000000000000001011", -- 10 - "000000000000000000001100", -- 11 - "000000000000000000001101", -- 12 - "000000000000000000001110", -- 13 - "000000000000000000001111", -- 14 - "000000000000000000010000", -- 15 - "000000000000000000010001", -- 16 --- "000000000000000000000000", -- 17 - "000010101101010110100000", -- 17 -- JCC (r5)- - "000000000000000000000000", -- 18 - "000000000000000000000000", -- 19 - "000010101101101010000000", -- 20 -- JMP (r2)+ - "000000000000000000000000", -- 21 - "000000000000000000000000", -- 22 - "000000000000000000000000", -- 23 - "000000000000000000000000", -- 24 - "000000000000000000000000", -- 25 - "000000000000000000000000", -- 26 - "000000000000000000000000", -- 27 - "000000000000000000000000", -- 28 - "000000000000000000000000", -- 29 - "000000000000000000000000", -- 30 - "000000000000000000000000", -- 31 --- "000000000000000000000000", -- 32 --- "000011010000000000000000", -- 32 -- JSR #0 - "000010111111000010000000", -- 32 -- JSR absolute - "000000000000000001000000", -- 33 -- #64 - "000000000000000000000000", -- 34 - "000000000000000000000000", -- 35 - "000000000000000000000000", -- 36 - "000000000000000000000000", -- 37 - "000000000000000000000000", -- 38 - "000000000000000000000000", -- 39 - "000000000000000000000000", -- 40 - "000000000000000000000000", -- 41 - "000000000000000000000000", -- 42 - "000000000000000000000000", -- 43 - "000000000000000000000000", -- 44 - "000000000000000000000000", -- 45 - "000000000000000000000000", -- 46 - "000000000000000000000000", -- 47 - "000000000000000000000000", -- 48 - "000000000000000000000000", -- 49 - "000000000000000000000000", -- 50 - "000000000000000000000000", -- 51 - "000000000000000000000000", -- 52 - "000000000000000000000000", -- 53 - "000000000000000000000000", -- 54 - "000000000000000000000000", -- 55 - "000000000000000000000000", -- 56 - "000000000000000000000000", -- 57 - "000000000000000000000000", -- 58 - "000000000000000000000000", -- 59 - "000000000000000000000000", -- 60 - "000000000000000000000000", -- 61 - "000000000000000000000000", -- 62 - "000000000000000000000000", -- 63 - "000000000000000000000000", -- 64 - "000000000000000000000000", -- 65 - "000000000000000000000000", -- 66 - "000000000000000000000000", -- 67 - "000000000000000000000000", -- 68 - "000000000000000000000000", -- 69 - "000000000000000000000100", -- 70 -- RTI - "000000000000000000000000", -- 71 - "000000000000000000000000", -- 72 - "000000000000000000000000", -- 73 - "000000000000000000000000", -- 74 - "000000000000000000000000", -- 75 - "000000000000000000000000", -- 76 - "000000000000000000000000", -- 77 - "000000000000000000000000", -- 78 - "000000000000000000000000", -- 79 - "000000000000000000000000", -- 80 - "000000000000000000000000", -- 81 - "000000000000000000000000", -- 82 - "000000000000000000000000", -- 83 - "000000000000000000000000", -- 84 - "000000000000000000000000", -- 85 - "000000000000000000000000", -- 86 - "000000000000000000000000", -- 87 - "000000000000000000000000", -- 88 - "000000000000000000000000", -- 89 - "000000000000000000000000", -- 90 - "000000000000000000000000", -- 91 - "000000000000000000000000", -- 92 - "000000000000000000000000", -- 93 - "000000000000000000000000", -- 94 - "000000000000000000000000", -- 95 - "000000000000000000000000", -- 96 - "000000000000000000000000", -- 97 - "000000000000000000000000", -- 98 - "000000000000000000000000", -- 99 - "000000000000000000000000", -- 100 - "000000000000000000000000", -- 101 - "000000000000000000000000", -- 102 - "000000000000000000000000", -- 103 - "000000000000000000000000", -- 104 - "000000000000000000000000", -- 105 - "000000000000000000000000", -- 106 - "000000000000000000000000", -- 107 - "000000000000000000000000", -- 108 - "000000000000000000000000", -- 109 - "000000000000000000000000", -- 110 - "000000000000000000000000", -- 111 - "000000000000000000000000", -- 112 - "000000000000000000000000", -- 113 - "000000000000000000000000", -- 114 - "000000000000000000000000", -- 115 - "000000000000000000000000", -- 116 - "000000000000000000000000", -- 117 - "000000000000000000000000", -- 118 - "000000000000000000000000", -- 119 - "000000000000000000000000", -- 120 - "000000000000000000000000", -- 121 - "000000000000000000000000", -- 122 - "000000000000000000000000", -- 123 - "000000000000000000000000", -- 124 - "000000000000000000000000", -- 125 - "000000000000000000000000", -- 126 - "000000000000000000000000", -- 127 - "000000000000000000000000", -- 128 - "000000000000000000000000", -- 129 - "000000000000000000000000", -- 130 - "000000000000000000000000", -- 131 - "000000000000000000000000", -- 132 - "000000000000000000000000", -- 133 - "000000000000000000000000", -- 134 - "000000000000000000000000", -- 135 - "000000000000000000000000", -- 136 - "000000000000000000000000", -- 137 - "000000000000000000000000", -- 138 - "000000000000000000000000", -- 139 - "000000000000000000000000", -- 140 - "000000000000000000000000", -- 141 - "000000000000000000000000", -- 142 - "000000000000000000000000", -- 143 - "000000000000000000000000", -- 144 - "000000000000000000000000", -- 145 - "000000000000000000000000", -- 146 - "000000000000000000000000", -- 147 - "000000000000000000000000", -- 148 - "000000000000000000000000", -- 149 - "000000000000000000000000", -- 150 - "000000000000000000000000", -- 151 - "000000000000000000000000", -- 152 - "000000000000000000000000", -- 153 - "000000000000000000000000", -- 154 - "000000000000000000000000", -- 155 - "000000000000000000000000", -- 156 - "000000000000000000000000", -- 157 - "000000000000000000000000", -- 158 - "000000000000000000000000", -- 159 - "000000000000000000000000", -- 160 - "000000000000000000000000", -- 161 - "000000000000000000000000", -- 162 - "000000000000000000000000", -- 163 - "000000000000000000000000", -- 164 - "000000000000000000000000", -- 165 - "000000000000000000000000", -- 166 - "000000000000000000000000", -- 167 - "000000000000000000000000", -- 168 - "000000000000000000000000", -- 169 - "000000000000000000000000", -- 170 - "000000000000000000000000", -- 171 - "000000000000000000000000", -- 172 - "000000000000000000000000", -- 173 - "000000000000000000000000", -- 174 - "000000000000000000000000", -- 175 - "000000000000000000000000", -- 176 - "000000000000000000000000", -- 177 - "000000000000000000000000", -- 178 - "000000000000000000000000", -- 179 - "000000000000000000000000", -- 180 - "000000000000000000000000", -- 181 - "000000000000000000000000", -- 182 - "000000000000000000000000", -- 183 - "000000000000000000000000", -- 184 - "000000000000000000000000", -- 185 - "000000000000000000000000", -- 186 - "000000000000000000000000", -- 187 - "000000000000000000000000", -- 188 - "000000000000000000000000", -- 189 - "000000000000000000000000", -- 190 - "000000000000000000000000", -- 191 - "000000000000000000000000", -- 192 - "000000000000000000000000", -- 193 - "000000000000000000000000", -- 194 - "000000000000000000000000", -- 195 - "000000000000000000000000", -- 196 - "000000000000000000000000", -- 197 - "000000000000000000000000", -- 198 - "000000000000000000000000", -- 199 - "000000000000000000000000", -- 200 - "000000000000000000000000", -- 201 - "000000000000000000000000", -- 202 - "000000000000000000000000", -- 203 - "000000000000000000000000", -- 204 - "000000000000000000000000", -- 205 - "000000000000000000000000", -- 206 - "000000000000000000000000", -- 207 - "000000000000000000000000", -- 208 - "000000000000000000000000", -- 209 - "000000000000000000000000", -- 210 - "000000000000000000000000", -- 211 - "000000000000000000000000", -- 212 - "000000000000000000000000", -- 213 - "000000000000000000000000", -- 214 - "000000000000000000000000", -- 215 - "000000000000000000000000", -- 216 - "000000000000000000000000", -- 217 - "000000000000000000000000", -- 218 - "000000000000000000000000", -- 219 - "000000000000000000000000", -- 220 - "000000000000000000000000", -- 221 - "000000000000000000000000", -- 222 - "000000000000000000000000", -- 223 - "000000000000000000000000", -- 224 - "000000000000000000000000", -- 225 - "000000000000000000000000", -- 226 - "000000000000000000000000", -- 227 - "000000000000000000000000", -- 228 - "000000000000000000000000", -- 229 - "000000000000000000000000", -- 230 - "000000000000000000000000", -- 231 - "000000000000000000000000", -- 232 - "000000000000000000000000", -- 233 - "000000000000000000000000", -- 234 - "000000000000000000000000", -- 235 - "000000000000000000000000", -- 236 - "000000000000000000000000", -- 237 - "000000000000000000000000", -- 238 - "000000000000000000000000", -- 239 - "000000000000000000000000", -- 240 - "000000000000000000000000", -- 241 - "000000000000000000000000", -- 242 - "000000000000000000000000", -- 243 - "000000000000000000000000", -- 244 - "000000000000000000000000", -- 245 - "000000000000000000000000", -- 246 - "000000000000000000000000", -- 247 - "000000000000000000000000", -- 248 - "000000000000000000000000", -- 249 - "000000000000000000000000", -- 250 - "000000000000000000000000", -- 251 - "000000000000000000000000", -- 252 - "000000000000000000000000", -- 253 - "000000000000000000000000", -- 254 - "000000000000000000000000"); -- 255 - -begin - --- int_mem <= int_pmem when mem_type = P_MEM else --- int_xmem when mem_type = X_MEM else --- int_ymem when mem_type = Y_MEM; - - wr_accomplished <= wr_en; - - PMEM_GEN: if mem_type = P_MEM generate - data_out <= int_pmem(to_integer(unsigned(int_mem_rd_addr))); - process(clk) is - begin - if rising_edge(clk) then --- if rst = '1' then --- data_out_valid <= '0'; --- int_mem_rd_addr <= (others => '0'); --- else - int_mem_rd_addr <= std_logic_vector(rd_addr(7 downto 0)); - data_out_valid <= rd_en; - if wr_en = '1' then - int_pmem(to_integer(wr_addr)) <= data_in; - end if; --- end if; - end if; - end process; - end generate; - - XMEM_GEN: if mem_type = X_MEM generate - data_out <= int_xmem(to_integer(unsigned(int_mem_rd_addr))); - process(clk) is - begin - if rising_edge(clk) then --- if rst = '1' then --- data_out_valid <= '0'; --- int_mem_rd_addr <= (others => '0'); --- else - int_mem_rd_addr <= std_logic_vector(rd_addr(7 downto 0)); - data_out_valid <= rd_en; - if wr_en = '1' then - int_xmem(to_integer(wr_addr)) <= data_in; - end if; --- end if; - end if; - end process; - end generate; - - YMEM_GEN: if mem_type = Y_MEM generate - data_out <= int_ymem(to_integer(unsigned(int_mem_rd_addr))); - process(clk) is - begin - if rising_edge(clk) then --- if rst = '1' then --- data_out_valid <= '0'; --- int_mem_rd_addr <= (others => '0'); --- else - int_mem_rd_addr <= std_logic_vector(rd_addr(7 downto 0)); - data_out_valid <= rd_en; - if wr_en = '1' then - int_ymem(to_integer(wr_addr)) <= data_in; - end if; --- end if; - end if; - end process; - end generate; --- process(clk, rst) is --- begin --- if rising_edge(clk) then --- if rst = '1' then --- data_out_valid <= '0'; --- int_mem_rd_addr <= (others => '0'); --- else --- int_mem_rd_addr <= std_logic_vector(rd_addr(7 downto 0)); --- data_out_valid <= rd_en; --- if wr_en = '1' then --- if mem_type = P_MEM then --- int_pmem(to_integer(wr_addr)) <= data_in; --- elsif mem_type = X_MEM then --- int_xmem(to_integer(wr_addr)) <= data_in; --- elsif mem_type = Y_MEM then --- int_ymem(to_integer(wr_addr)) <= data_in; --- end if; --- end if; --- end if; --- end if; --- end process; - -end architecture rtl; - diff --git a/vhdl/dsp56k/src/memory_management.vhd b/vhdl/dsp56k/src/memory_management.vhd deleted file mode 100644 index 215fe66..0000000 --- a/vhdl/dsp56k/src/memory_management.vhd +++ /dev/null @@ -1,223 +0,0 @@ ------------------------------------------------------------------------------- ---! @file ---! @author Matthias Alles ---! @date 01/2009 ---! @brief Memory controller ---! ---! @details This entity contains the internal memories. These are: ---! - pmem ---! - xmem ---! - ymem ---! - ROM tables ---! - Bootup code ---! All memory requests are collected here. Only when they are all finished ---! the memory_stall-flag is released. External memory accesses are given to ---! the external interface. ---! ------------------------------------------------------------------------------- -library ieee; -use ieee.std_logic_1164.all; -use ieee.numeric_std.all; -library work; -use work.parameter_pkg.all; -use work.types_pkg.all; -use work.constants_pkg.all; - -entity memory_management is port ( - clk, rst : in std_logic; - stall_flags : in std_logic_vector(PIPELINE_DEPTH-1 downto 0); - memory_stall : out std_logic; - data_rom_enable: in std_logic; - pmem_ctrl_in : in mem_ctrl_type_in; - pmem_ctrl_out : out mem_ctrl_type_out; - pmem2_ctrl_in : in mem_ctrl_type_in; - pmem2_ctrl_out : out mem_ctrl_type_out; - xmem_ctrl_in : in mem_ctrl_type_in; - xmem_ctrl_out : out mem_ctrl_type_out; - ymem_ctrl_in : in mem_ctrl_type_in; - ymem_ctrl_out : out mem_ctrl_type_out -); -end memory_management; - - -architecture rtl of memory_management is - - component mem_control is - generic( - mem_type : memory_type - ); - port( - clk, rst : in std_logic; - rd_addr : in unsigned(BW_ADDRESS-1 downto 0); - rd_en : in std_logic; - data_out : out std_logic_vector(23 downto 0); - data_out_valid : out std_logic; - wr_addr : in unsigned(BW_ADDRESS-1 downto 0); - wr_en : in std_logic; - wr_accomplished : out std_logic; - data_in : in std_logic_vector(23 downto 0) - ); - end component mem_control; - - signal pmem_data_out : std_logic_vector(23 downto 0); - signal pmem_data_out_valid : std_logic; - - signal pmem_rd_addr : unsigned(BW_ADDRESS-1 downto 0); - signal pmem_rd_en : std_logic; - - signal xmem_rd_en : std_logic; - signal xmem_data_out : std_logic_vector(23 downto 0); - signal xmem_data_out_valid : std_logic; - signal xmem_rd_polling : std_logic; - - signal ymem_rd_en : std_logic; - signal ymem_data_out : std_logic_vector(23 downto 0); - signal ymem_data_out_valid : std_logic; - signal ymem_rd_polling : std_logic; - - signal pmem_stall_buffer : std_logic_vector(23 downto 0); - signal pmem_stall_buffer_valid : std_logic; - signal xmem_stall_buffer : std_logic_vector(23 downto 0); - signal ymem_stall_buffer : std_logic_vector(23 downto 0); - - signal stall_flags_d : std_logic_vector(PIPELINE_DEPTH-1 downto 0); - -begin - - -- here it is necessary to store the output of the pmem/xmem/ymem when the pipeline enters a stall - -- when the pipeline wakes up, this temporal result is inserted into the pipeline - stall_buffer: process(clk) is - begin - if rising_edge(clk) then - if rst = '1' then - pmem_stall_buffer <= (others => '0'); - pmem_stall_buffer_valid <= '0'; - xmem_stall_buffer <= (others => '0'); - ymem_stall_buffer <= (others => '0'); - stall_flags_d <= (others => '0'); - else - stall_flags_d <= stall_flags; - if stall_flags(ST_FE2_DEC) = '1' and stall_flags_d(ST_FE2_DEC) = '0' then - if pmem_data_out_valid = '1' then - pmem_stall_buffer <= pmem_data_out; - pmem_stall_buffer_valid <= '1'; - end if; - end if; - if stall_flags(ST_FE2_DEC) = '0' and stall_flags_d(ST_FE2_DEC) = '1' then - pmem_stall_buffer_valid <= '0'; - end if; - - end if; - end if; - end process stall_buffer; - - memory_stall <= '1' when ( xmem_rd_en = '1' or (xmem_rd_polling = '1' and xmem_data_out_valid = '0') ) or - ( ymem_rd_en = '1' or (ymem_rd_polling = '1' and ymem_data_out_valid = '0') ) else - '0'; - - ------------------------------- - -- PMEM CONTROLLER - ------------------------------- - inst_pmem_ctrl : mem_control - generic map( - mem_type => P_MEM - ) - port map( - clk => clk, - rst => rst, - rd_addr => pmem_ctrl_in.rd_addr, - rd_en => pmem_ctrl_in.rd_en, - data_out => pmem_data_out, - data_out_valid => pmem_data_out_valid, - wr_addr => pmem_ctrl_in.wr_addr, - wr_en => pmem_ctrl_in.wr_en, - data_in => pmem_ctrl_in.data_in - ); - - -- In case we wake up from a stall use the buffered value - pmem_ctrl_out.data_out <= pmem_stall_buffer when stall_flags(ST_FE2_DEC) = '0' and - stall_flags_d(ST_FE2_DEC) = '1' and - pmem_stall_buffer_valid = '1' else - pmem_data_out; - - pmem_ctrl_out.data_out_valid <= pmem_stall_buffer_valid when stall_flags(ST_FE2_DEC) = '0' and - stall_flags_d(ST_FE2_DEC) = '1' else - '0' when stall_flags(ST_FE2_DEC) = '1' else - pmem_data_out_valid; - - ------------------------------- - -- XMEM CONTROLLER - ------------------------------- - inst_xmem_ctrl : mem_control - generic map( - mem_type => X_MEM - ) - port map( - clk => clk, - rst => rst, - rd_addr => xmem_ctrl_in.rd_addr, - rd_en => xmem_rd_en, - data_out => xmem_data_out, - data_out_valid => xmem_data_out_valid, - wr_addr => xmem_ctrl_in.wr_addr, - wr_en => xmem_ctrl_in.wr_en, - data_in => xmem_ctrl_in.data_in - ); - - xmem_rd_en <= '1' when xmem_rd_polling = '0' and xmem_ctrl_in.rd_en = '1' else '0'; - - xmem_ctrl_out.data_out <= xmem_data_out; - xmem_ctrl_out.data_out_valid <= xmem_data_out_valid; - - ------------------------------- - -- YMEM CONTROLLER - ------------------------------- - inst_ymem_ctrl : mem_control - generic map( - mem_type => Y_MEM - ) - port map( - clk => clk, - rst => rst, - rd_addr => ymem_ctrl_in.rd_addr, - rd_en => ymem_rd_en, - data_out => ymem_data_out, - data_out_valid => ymem_data_out_valid, - wr_addr => ymem_ctrl_in.wr_addr, - wr_en => ymem_ctrl_in.wr_en, - data_in => ymem_ctrl_in.data_in - ); - - ymem_rd_en <= '1' when ymem_rd_polling = '0' and ymem_ctrl_in.rd_en = '1' else '0'; - - ymem_ctrl_out.data_out <= ymem_data_out; - ymem_ctrl_out.data_out_valid <= ymem_data_out_valid; - - mem_stall_control: process(clk) is - begin - if rising_edge(clk) then - if rst = '1' then - xmem_rd_polling <= '0'; - ymem_rd_polling <= '0'; - else - if xmem_rd_en = '1' then - xmem_rd_polling <= '1'; - end if; - - if xmem_data_out_valid = '1' then - xmem_rd_polling <= '0'; - end if; - - if ymem_rd_en = '1' then - ymem_rd_polling <= '1'; - end if; - - if ymem_data_out_valid = '1' then - ymem_rd_polling <= '0'; - end if; - - end if; - end if; - end process; -end architecture; - diff --git a/vhdl/dsp56k/src/parameter_pkg.vhd b/vhdl/dsp56k/src/parameter_pkg.vhd deleted file mode 100644 index f06c000..0000000 --- a/vhdl/dsp56k/src/parameter_pkg.vhd +++ /dev/null @@ -1,18 +0,0 @@ ------------------------------------------------------------------------------- ---! @file ---! @author Matthias Alles ---! @date 01/2009 ---! @brief Global parameters ---! ------------------------------------------------------------------------------- - -package parameter_pkg is - - constant BW_ADDRESS : natural := 16; - - -- number of pipeline register stages - constant PIPELINE_DEPTH : natural := 4; - - constant NUM_ACT_SIGNALS : natural := 26; - -end package; diff --git a/vhdl/dsp56k/src/pipeline.vhd b/vhdl/dsp56k/src/pipeline.vhd deleted file mode 100644 index f00db65..0000000 --- a/vhdl/dsp56k/src/pipeline.vhd +++ /dev/null @@ -1,1007 +0,0 @@ ------------------------------------------------------------------------------- ---! @file ---! @author Matthias Alles ---! @date 01/2009 ---! @brief DSP 56k pipeline ---! ---! @details This is the computational part of the DSP core. The pipeline ---! consists of five stages: ---! - FE : Initiate read access to program memory ---! - FE2: Retrieve data from program memory ---! - DEC: Instruction decode ---! - ADG: Address generation units - also inits of xmem, ymem, and pmem reads ---! - EX : Execute stage, contains ALU, loop controls, writes to xmem, ymem, ---! pmem ---! ------------------------------------------------------------------------------- -library ieee; -use ieee.std_logic_1164.all; -use ieee.numeric_std.all; -library work; -use work.parameter_pkg.all; -use work.types_pkg.all; -use work.constants_pkg.all; - -entity pipeline is port ( - clk, rst : in std_logic; - register_file_out : out register_file_type; - stall_flags_out : out std_logic_vector(PIPELINE_DEPTH-1 downto 0); - memory_stall : in std_logic; - data_rom_enable: out std_logic; - pmem_ctrl_in : out mem_ctrl_type_in; - pmem_ctrl_out : in mem_ctrl_type_out; - pmem2_ctrl_in : out mem_ctrl_type_in; - pmem2_ctrl_out : in mem_ctrl_type_out; - xmem_ctrl_in : out mem_ctrl_type_in; - xmem_ctrl_out : in mem_ctrl_type_out; - ymem_ctrl_in : out mem_ctrl_type_in; - ymem_ctrl_out : in mem_ctrl_type_out - -); -end pipeline; - --- TODOs: --- External memory accesses --- ROM tables --- Reading from SSH flag has to modify stack pointer --- Memory access (x,y,p) and stalling accordingly - --- List of known BUGS: --- - Reading from address one clock cycle after writing to the same address might result in corrupted data!! --- - SBC instruction has errorneous carry flag calculation - --- List of probable issues: --- - Reading from XMEM/YMEM with stalls probably results in corrupted data --- - ENDDO instruction probably has to flush the pipeline afterwards --- - Writing to memory occurs twice, when stalls occur - --- Things to optimize: --- - RTS/RTI could be executed in the ADGEN Stage already --- - DO loops always flush the pipeline. This is necessary in case we have a very short loop. --- The single instruction of the loop then has passed the fetch stage already without the branch - - -architecture rtl of pipeline is - - signal pipeline_regs : pipeline_type; - signal stall_flags : std_logic_vector(PIPELINE_DEPTH-1 downto 0); - - component fetch_stage is port( - pc_old : in unsigned(BW_ADDRESS-1 downto 0); - pc_new : out unsigned(BW_ADDRESS-1 downto 0); - modify_pc : in std_logic; - modified_pc : in unsigned(BW_ADDRESS-1 downto 0); - register_file : in register_file_type; - decrement_lc : out std_logic; - perform_enddo : out std_logic - ); - end component fetch_stage; - - signal pc_old, pc_new : unsigned(BW_ADDRESS-1 downto 0); - signal fetch_modify_pc : std_logic; - signal fetch_modified_pc : unsigned(BW_ADDRESS-1 downto 0); - signal fetch_perform_enddo: std_logic; - signal fetch_decrement_lc: std_logic; - - - component decode_stage is port( - activate_dec : in std_logic; - instr_word : in std_logic_vector(23 downto 0); - dble_word_instr : out std_logic; - instr_array : out instructions_type; - act_array : out std_logic_vector(NUM_ACT_SIGNALS-1 downto 0); - reg_wr_addr : out std_logic_vector(5 downto 0); - reg_rd_addr : out std_logic_vector(5 downto 0); - x_bus_rd_addr : out std_logic_vector(1 downto 0); - x_bus_wr_addr : out std_logic_vector(1 downto 0); - y_bus_rd_addr : out std_logic_vector(1 downto 0); - y_bus_wr_addr : out std_logic_vector(1 downto 0); - l_bus_addr : out std_logic_vector(2 downto 0); - adgen_mode_a : out adgen_mode_type; - adgen_mode_b : out adgen_mode_type; - alu_ctrl : out alu_ctrl_type - ); - end component decode_stage; - - signal dec_activate : std_logic; - signal dec_instr_word : std_logic_vector(23 downto 0); - signal dec_dble_word_instr : std_logic; - signal dec_instr_array : instructions_type; - signal dec_act_array : std_logic_vector(NUM_ACT_SIGNALS-1 downto 0); - signal dec_reg_wr_addr : std_logic_vector(5 downto 0); - signal dec_reg_rd_addr : std_logic_vector(5 downto 0); - signal dec_x_bus_wr_addr : std_logic_vector(1 downto 0); - signal dec_x_bus_rd_addr : std_logic_vector(1 downto 0); - signal dec_y_bus_wr_addr : std_logic_vector(1 downto 0); - signal dec_y_bus_rd_addr : std_logic_vector(1 downto 0); - signal dec_l_bus_addr : std_logic_vector(2 downto 0); - signal dec_adgen_mode_a : adgen_mode_type; - signal dec_adgen_mode_b : adgen_mode_type; - signal dec_alu_ctrl : alu_ctrl_type; - - component adgen_stage is port( - activate_adgen : in std_logic; - activate_x_mem : in std_logic; - activate_y_mem : in std_logic; - activate_l_mem : in std_logic; - instr_word : in std_logic_vector(23 downto 0); - instr_array : in instructions_type; - optional_ea_word : in std_logic_vector(23 downto 0); - register_file : in register_file_type; - adgen_mode_a : in adgen_mode_type; - adgen_mode_b : in adgen_mode_type; - address_out_x : out unsigned(BW_ADDRESS-1 downto 0); - address_out_y : out unsigned(BW_ADDRESS-1 downto 0); - wr_R_port_A_valid : out std_logic; - wr_R_port_A : out addr_wr_port_type; - wr_R_port_B_valid : out std_logic; - wr_R_port_B : out addr_wr_port_type - ); - end component adgen_stage; - - signal adgen_activate : std_logic; - signal adgen_activate_x_mem : std_logic; - signal adgen_activate_y_mem : std_logic; - signal adgen_activate_l_mem : std_logic; - signal adgen_instr_word : std_logic_vector(23 downto 0); - signal adgen_instr_array : instructions_type; - signal adgen_optional_ea_word : std_logic_vector(23 downto 0); - signal adgen_register_file : register_file_type; - signal adgen_mode_a : adgen_mode_type; - signal adgen_mode_b : adgen_mode_type; - signal adgen_address_out_x : unsigned(BW_ADDRESS-1 downto 0); - signal adgen_address_out_y : unsigned(BW_ADDRESS-1 downto 0); - signal adgen_wr_R_port_A_valid : std_logic; - signal adgen_wr_R_port_A : addr_wr_port_type; - signal adgen_wr_R_port_B_valid : std_logic; - signal adgen_wr_R_port_B : addr_wr_port_type; - - component exec_stage_bit_modify is port( - instr_word : in std_logic_vector(23 downto 0); - instr_array : in instructions_type; - src_operand : in std_logic_vector(23 downto 0); - register_file : in register_file_type; - dst_operand : out std_logic_vector(23 downto 0); - bit_cond_met : out std_logic; - modify_sr : out std_logic; - modified_sr : out std_logic_vector(15 downto 0) - ); - end component exec_stage_bit_modify; - - signal exec_bit_modify_instr_word : std_logic_vector(23 downto 0); - signal exec_bit_modify_instr_array : instructions_type; - signal exec_bit_modify_src_operand : std_logic_vector(23 downto 0); - signal exec_bit_modify_dst_operand : std_logic_vector(23 downto 0); - signal exec_bit_modify_bit_cond_met : std_logic; - signal exec_bit_modify_modify_sr : std_logic; - signal exec_bit_modify_modified_sr : std_logic_vector(15 downto 0); - - component exec_stage_branch is port( - activate_exec_bra : in std_logic; - instr_word : in std_logic_vector(23 downto 0); - instr_array : in instructions_type; - register_file : in register_file_type; - jump_address : in unsigned(BW_ADDRESS-1 downto 0); - bit_cond_met : in std_logic; - cc_flag_set : in std_logic; - push_stack : out push_stack_type; - pop_stack : out pop_stack_type; - modify_pc : out std_logic; - modified_pc : out unsigned(BW_ADDRESS-1 downto 0); - modify_sr : out std_logic; - modified_sr : out std_logic_vector(15 downto 0) - ); - end component exec_stage_branch; - - signal exec_bra_activate : std_logic; - signal exec_bra_instr_word : std_logic_vector(23 downto 0); - signal exec_bra_instr_array : instructions_type; - signal exec_bra_jump_address : unsigned(BW_ADDRESS-1 downto 0); - signal exec_bra_bit_cond_met : std_logic; - signal exec_bra_push_stack : push_stack_type; - signal exec_bra_pop_stack : pop_stack_type; - signal exec_bra_modify_pc : std_logic; - signal exec_bra_modified_pc : unsigned(BW_ADDRESS-1 downto 0); - signal exec_bra_modify_sr : std_logic; - signal exec_bra_modified_sr : std_logic_vector(15 downto 0); - - component exec_stage_cr_mod is port( - activate_exec_cr_mod : in std_logic; - instr_word : in std_logic_vector(23 downto 0); - instr_array : in instructions_type; - register_file : in register_file_type; - modify_sr : out std_logic; - modified_sr : out std_logic_vector(15 downto 0); - modify_omr : out std_logic; - modified_omr : out std_logic_vector(7 downto 0) - ); - end component exec_stage_cr_mod; - - signal exec_cr_mod_activate : std_logic; - signal exec_cr_mod_instr_word : std_logic_vector(23 downto 0); - signal exec_cr_mod_instr_array : instructions_type; - signal exec_cr_mod_modify_sr : std_logic; - signal exec_cr_mod_modified_sr : std_logic_vector(15 downto 0); - signal exec_cr_mod_modify_omr : std_logic; - signal exec_cr_mod_modified_omr : std_logic_vector(7 downto 0); - - component exec_stage_loop is port( - clk, rst : in std_logic; - activate_exec_loop : in std_logic; - instr_word : in std_logic_vector(23 downto 0); - instr_array : in instructions_type; - loop_iterations : in unsigned(15 downto 0); - loop_address : in unsigned(BW_ADDRESS-1 downto 0); - loop_start_address: in unsigned(BW_ADDRESS-1 downto 0); - register_file : in register_file_type; - fetch_perform_enddo: in std_logic; - memory_stall : in std_logic; - push_stack : out push_stack_type; - pop_stack : out pop_stack_type; - stall_rep : out std_logic; - stall_do : out std_logic; - decrement_lc : out std_logic; - modify_lc : out std_logic; - modified_lc : out unsigned(15 downto 0); - modify_la : out std_logic; - modified_la : out unsigned(15 downto 0); - modify_pc : out std_logic; - modified_pc : out unsigned(BW_ADDRESS-1 downto 0); - modify_sr : out std_logic; - modified_sr : out std_logic_vector(15 downto 0) - ); - end component exec_stage_loop; - - signal exec_loop_activate : std_logic; - signal exec_loop_instr_word : std_logic_vector(23 downto 0); - signal exec_loop_instr_array : instructions_type; - signal exec_loop_iterations : unsigned(15 downto 0); - signal exec_loop_address : unsigned(BW_ADDRESS-1 downto 0); - signal exec_loop_start_address : unsigned(BW_ADDRESS-1 downto 0); - signal exec_loop_register_file : register_file_type; - signal exec_loop_push_stack : push_stack_type; - signal exec_loop_pop_stack : pop_stack_type; - signal exec_loop_stall_rep : std_logic; - signal exec_loop_stall_do : std_logic; - signal exec_loop_decrement_lc : std_logic; - signal exec_loop_modify_lc : std_logic; - signal exec_loop_modified_lc : unsigned(15 downto 0); - signal exec_loop_modify_la : std_logic; - signal exec_loop_modified_la : unsigned(BW_ADDRESS-1 downto 0); - signal exec_loop_modify_pc : std_logic; - signal exec_loop_modified_pc : unsigned(BW_ADDRESS-1 downto 0); - signal exec_loop_modify_sr : std_logic; - signal exec_loop_modified_sr : std_logic_vector(BW_ADDRESS-1 downto 0); - - component exec_stage_alu is port( - alu_activate : in std_logic; - instr_word : in std_logic_vector(23 downto 0); - alu_ctrl : in alu_ctrl_type; - register_file : in register_file_type; - addr_r_in : in unsigned(BW_ADDRESS-1 downto 0); - addr_r_out : out unsigned(BW_ADDRESS-1 downto 0); - modify_accu : out std_logic; - dst_accu : out std_logic; - modified_accu : out signed(55 downto 0); - modify_sr : out std_logic; - modified_sr : out std_logic_vector(15 downto 0) - ); - end component exec_stage_alu; - - signal exec_alu_activate : std_logic; - signal exec_alu_instr_word : std_logic_vector(23 downto 0); - signal exec_alu_ctrl : alu_ctrl_type; - signal exec_alu_addr_r_in : unsigned(BW_ADDRESS-1 downto 0); - signal exec_alu_addr_r_out : unsigned(BW_ADDRESS-1 downto 0); - signal exec_alu_modify_accu : std_logic; - signal exec_alu_dst_accu : std_logic; - signal exec_alu_modified_accu : signed(55 downto 0); - signal exec_alu_modify_sr : std_logic; - signal exec_alu_modified_sr : std_logic_vector(15 downto 0); - - signal exec_imm_8bit : std_logic_vector(23 downto 0); - signal exec_imm_12bit : std_logic_vector(23 downto 0); - signal exec_src_operand : std_logic_vector(23 downto 0); - signal exec_dst_operand : std_logic_vector(23 downto 0); - - component exec_stage_cc_flag_calc is port( - instr_word : in std_logic_vector(23 downto 0); - instr_array : in instructions_type; - register_file : in register_file_type; - cc_flag_set : out std_logic - ); - end component exec_stage_cc_flag_calc; - - signal exec_cc_flag_calc_instr_word : std_logic_vector(23 downto 0); - signal exec_cc_flag_calc_instr_array : instructions_type; - signal exec_cc_flag_set : std_logic; - - component reg_file is port( - clk, rst : in std_logic; - register_file : out register_file_type; - wr_R_port_A_valid : in std_logic; - wr_R_port_A : in addr_wr_port_type; - wr_R_port_B_valid : in std_logic; - wr_R_port_B : in addr_wr_port_type; - alu_wr_valid : in std_logic; - alu_wr_addr : in std_logic; - alu_wr_data : in signed(55 downto 0); - reg_wr_addr : in std_logic_vector(5 downto 0); - reg_wr_addr_valid : in std_logic; - reg_wr_data : in std_Logic_vector(23 downto 0); - reg_rd_addr : in std_logic_vector(5 downto 0); - reg_rd_data : out std_Logic_vector(23 downto 0); - X_bus_rd_addr : in std_logic_vector(1 downto 0); - X_bus_data_out : out std_logic_vector(23 downto 0); - X_bus_wr_addr : in std_logic_vector(1 downto 0); - X_bus_wr_valid : in std_logic; - X_bus_data_in : in std_logic_vector(23 downto 0); - Y_bus_rd_addr : in std_logic_vector(1 downto 0); - Y_bus_data_out : out std_logic_vector(23 downto 0); - Y_bus_wr_addr : in std_logic_vector(1 downto 0); - Y_bus_wr_valid : in std_logic; - Y_bus_data_in : in std_logic_vector(23 downto 0); - L_bus_rd_addr : in std_logic_vector(2 downto 0); - L_bus_rd_valid : in std_logic; - L_bus_wr_addr : in std_logic_vector(2 downto 0); - L_bus_wr_valid : in std_logic; - push_stack : in push_stack_type; - pop_stack : in pop_stack_type; - set_sr : in std_logic; - new_sr : in std_logic_vector(15 downto 0); - set_omr : in std_logic; - new_omr : in std_logic_vector(7 downto 0); - set_lc : in std_logic; - new_lc : in unsigned(15 downto 0); - dec_lc : in std_logic; - set_la : in std_logic; - new_la : in unsigned(BW_ADDRESS-1 downto 0) - ); - end component reg_file; - - signal register_file : register_file_type; - signal rf_wr_R_port_A_valid : std_logic; - signal rf_wr_R_port_B_valid : std_logic; - signal rf_reg_wr_addr : std_logic_vector(5 downto 0); - signal rf_reg_wr_addr_valid : std_logic; - signal rf_reg_wr_data : std_logic_vector(23 downto 0); - signal rf_reg_rd_addr : std_logic_vector(5 downto 0); - signal rf_reg_rd_data : std_logic_vector(23 downto 0); - signal rf_X_bus_rd_addr : std_logic_vector(1 downto 0); - signal rf_X_bus_data_out : std_logic_vector(23 downto 0); - signal rf_X_bus_wr_addr : std_logic_vector(1 downto 0); - signal rf_X_bus_wr_valid : std_logic; - signal rf_X_bus_data_in : std_logic_vector(23 downto 0); - signal rf_Y_bus_rd_addr : std_logic_vector(1 downto 0); - signal rf_Y_bus_data_out : std_logic_vector(23 downto 0); - signal rf_Y_bus_wr_addr : std_logic_vector(1 downto 0); - signal rf_Y_bus_wr_valid : std_logic; - signal rf_Y_bus_data_in : std_logic_vector(23 downto 0); - signal rf_L_bus_rd_addr : std_logic_vector(2 downto 0); - signal rf_L_bus_rd_valid : std_logic; - signal rf_L_bus_wr_addr : std_logic_vector(2 downto 0); - signal rf_L_bus_wr_valid : std_logic; - signal push_stack : push_stack_type; - signal pop_stack : pop_stack_type; - signal rf_set_sr : std_logic; - signal rf_new_sr : std_logic_vector(15 downto 0); - signal rf_set_omr : std_logic; - signal rf_new_omr : std_logic_vector(7 downto 0); - signal rf_dec_lc : std_logic; - signal rf_set_lc : std_logic; - signal rf_new_lc : unsigned(15 downto 0); - signal rf_set_la : std_logic; - signal rf_new_la : unsigned(BW_ADDRESS-1 downto 0); - signal rf_alu_wr_valid : std_logic; - - signal pmem_data_out : std_logic_vector(23 downto 0); - signal pmem_data_out_valid : std_logic; - signal pmem2_data_out : std_logic_vector(23 downto 0); - signal pmem2_data_out_valid : std_logic; - -begin - - register_file_out <= register_file; - stall_flags_out <= stall_flags; - - -- merge all stall sources - stall_flags(ST_FE_FE2) <= '1' when exec_loop_stall_rep = '1' or - memory_stall = '1' or - exec_loop_stall_do = '1' else '0'; - stall_flags(ST_FE2_DEC) <= '1' when exec_loop_stall_rep = '1' or - memory_stall = '1' or - exec_loop_stall_do = '1' else '0'; - stall_flags(ST_DEC_ADG) <= '1' when exec_loop_stall_rep = '1' or - memory_stall = '1' or - exec_loop_stall_do = '1' else '0'; - stall_flags(ST_ADG_EX) <= exec_loop_stall_do; - - - shift_pipeline: process(clk, rst) is - procedure flush_pipeline_stage(stage: natural) is - begin - pipeline_regs(stage).pc <= (others => '1'); - pipeline_regs(stage).instr_word <= (others => '0'); - pipeline_regs(stage).act_array <= (others => '0'); - pipeline_regs(stage).instr_array <= INSTR_NOP; - pipeline_regs(stage).dble_word_instr <= '0'; - pipeline_regs(stage).dec_activate <= '0'; - pipeline_regs(stage).adgen_mode_a <= NOP; - pipeline_regs(stage).adgen_mode_b <= NOP; - pipeline_regs(stage).reg_wr_addr <= (others => '0'); - pipeline_regs(stage).reg_rd_addr <= (others => '0'); - pipeline_regs(stage).x_bus_rd_addr <= (others => '0'); - pipeline_regs(stage).x_bus_wr_addr <= (others => '0'); - pipeline_regs(stage).y_bus_rd_addr <= (others => '0'); - pipeline_regs(stage).y_bus_wr_addr <= (others => '0'); - pipeline_regs(stage).l_bus_addr <= (others => '0'); - pipeline_regs(stage).adgen_address_x <= (others => '0'); - pipeline_regs(stage).adgen_address_y <= (others => '0'); - pipeline_regs(stage).RAM_out_x <= (others => '0'); - pipeline_regs(stage).RAM_out_y <= (others => '0'); - pipeline_regs(stage).alu_ctrl.store_result <= '0'; - end procedure flush_pipeline_stage; - begin - if rising_edge(clk) then - if rst = '1' then - for i in 0 to PIPELINE_DEPTH-1 loop - flush_pipeline_stage(i); - end loop; - else - -- shift the pipeline registers when no stall applies - for i in 1 to PIPELINE_DEPTH-1 loop - if stall_flags(i) = '0' then - -- The following situations have to be considered: - -- 1) Do not copy the pipeline registers from a stalled pipeline stage. - -- Instead insert NOPs into the pipeline, except for the REP instruction. - -- 2) Flushing of the ST_ADG_EX-stage is required when a memory access causes - -- a stall. In this case the EX-stage will perform its task and the pipeline - -- stage has to be flushed. Otherwise the instruction would be executed twice. --- TODO: --- What happens when memory writes cause a stall? => Flushing of ST_ADG_EX not allowed!? - if (stall_flags(i-1) = '1' and exec_loop_stall_rep = '0') or - (i = ST_ADG_EX and memory_stall = '1' and exec_loop_stall_rep = '1') then - flush_pipeline_stage(i); - else - pipeline_regs(i) <= pipeline_regs(i-1); - end if; - end if; - end loop; - -- FE_FE2 Pipeline Registers - if stall_flags(ST_FE_FE2) = '0' then - pipeline_regs(ST_FE_FE2).pc <= pc_new; - pipeline_regs(ST_FE_FE2).dec_activate <= '1'; - end if; - - -- FE2_DEC Pipeline Registers - if stall_flags(ST_FE2_DEC) = '0' then - -- Normal pipeline operation? - -- Buffering of RAM output when stalling is performed in the memory management - if pmem_data_out_valid = '1' then - pipeline_regs(ST_FE2_DEC).instr_word <= pmem_data_out; - end if; - end if; - - -- DEC_ADG Pipeline registers - if stall_flags(ST_DEC_ADG) = '0' then - pipeline_regs(ST_DEC_ADG).act_array <= dec_act_array; - pipeline_regs(ST_DEC_ADG).instr_array <= dec_instr_array; - pipeline_regs(ST_DEC_ADG).dble_word_instr <= dec_dble_word_instr; - pipeline_regs(ST_DEC_ADG).reg_wr_addr <= dec_reg_wr_addr; - pipeline_regs(ST_DEC_ADG).reg_rd_addr <= dec_reg_rd_addr; - pipeline_regs(ST_DEC_ADG).x_bus_wr_addr <= dec_x_bus_wr_addr; - pipeline_regs(ST_DEC_ADG).x_bus_rd_addr <= dec_x_bus_rd_addr; - pipeline_regs(ST_DEC_ADG).y_bus_wr_addr <= dec_y_bus_wr_addr; - pipeline_regs(ST_DEC_ADG).y_bus_rd_addr <= dec_y_bus_rd_addr; - pipeline_regs(ST_DEC_ADG).l_bus_addr <= dec_l_bus_addr; - pipeline_regs(ST_DEC_ADG).adgen_mode_a <= dec_adgen_mode_a; - pipeline_regs(ST_DEC_ADG).adgen_mode_b <= dec_adgen_mode_b; - pipeline_regs(ST_DEC_ADG).alu_ctrl <= dec_alu_ctrl; - end if; - - -- ADG_EX Pipeline registers - if stall_flags(ST_ADG_EX) = '0' then - pipeline_regs(ST_ADG_EX).adgen_address_x <= adgen_address_out_x; - pipeline_regs(ST_ADG_EX).adgen_address_y <= adgen_address_out_y; - end if; - --- TODO: memory_stall neu eingebaut, noch nicht getestet. Hier evtl. wie oben direkt auf --- stall_flags zugreifen (ST_ADG_EX)? - -- Copying to the pipeline register should only happen, when the stall is released. - -- Otherwise the content could be deleted before it is actually used (when x and y - -- content are not valid at the same time). - if xmem_ctrl_out.data_out_valid = '1' and memory_stall = '0' then - pipeline_regs(ST_ADG_EX).RAM_out_x <= xmem_ctrl_out.data_out; - end if; - if ymem_ctrl_out.data_out_valid = '1'and memory_stall = '0' then - pipeline_regs(ST_ADG_EX).RAM_out_y <= ymem_ctrl_out.data_out; - end if; - - -- EXECUTE Pipeline stuff - if exec_bra_modify_pc = '1' or exec_loop_modify_pc = '1' then - -- clear the following pipeline stages, - -- since we modified the pc. - -- Do not flush ST_FE_FE2 - it will hold the correct pc. - flush_pipeline_stage(ST_FE2_DEC); - flush_pipeline_stage(ST_DEC_ADG); - flush_pipeline_stage(ST_ADG_EX); - end if; - end if; - end if; - end process shift_pipeline; - - - ------------------------------- - -- FETCH STAGE INSTANTIATION - ------------------------------- - - inst_fetch_stage: fetch_stage port map( - pc_old => pc_old, - pc_new => pc_new, - modify_pc => fetch_modify_pc, - modified_pc => fetch_modified_pc, - register_file => register_file, - decrement_lc => fetch_decrement_lc, - perform_enddo => fetch_perform_enddo - ); - - pc_old <= pipeline_regs(ST_FE_FE2).pc; - - fetch_modify_pc <= '1' when exec_bra_modify_pc = '1' or exec_loop_modify_pc = '1' else '0'; - fetch_modified_pc <= exec_bra_modified_pc when exec_bra_modify_pc = '1' else - exec_loop_modified_pc; - - - ------------------------------- - -- DECODE STAGE INSTANTIATION - ------------------------------- - - inst_decode_stage : decode_stage port map( - activate_dec => dec_activate, - instr_word => dec_instr_word, - dble_word_instr => dec_dble_word_instr, - instr_array => dec_instr_array, - act_array => dec_act_array, - reg_wr_addr => dec_reg_wr_addr, - reg_rd_addr => dec_reg_rd_addr, - x_bus_wr_addr => dec_x_bus_wr_addr, - x_bus_rd_addr => dec_x_bus_rd_addr, - y_bus_wr_addr => dec_y_bus_wr_addr, - y_bus_rd_addr => dec_y_bus_rd_addr, - l_bus_addr => dec_l_bus_addr, - adgen_mode_a => dec_adgen_mode_a, - adgen_mode_b => dec_adgen_mode_b, - alu_ctrl => dec_alu_ctrl - ); - - dec_instr_word <= pipeline_regs(ST_FE2_DEC).instr_word; - -- do not decode, when we have no valid instruction. This can happen when - -- 1) the pipeline just started its operation - -- 2) the pipeline was flushed due to a jump - -- 3) we are processing an instruction that consists of two words - dec_activate <= '1' when pipeline_regs(ST_FE2_DEC).dec_activate = '1' and pipeline_regs(ST_DEC_ADG).dble_word_instr = '0' else '0'; - - - ------------------------------- - -- AGU STAGE INSTANTIATION - ------------------------------- - - inst_adgen_stage: adgen_stage port map( - activate_adgen => adgen_activate, - activate_x_mem => adgen_activate_x_mem, - activate_y_mem => adgen_activate_y_mem, - activate_l_mem => adgen_activate_l_mem, - instr_word => adgen_instr_word, - instr_array => adgen_instr_array, - optional_ea_word => adgen_optional_ea_word, - register_file => register_file, - adgen_mode_a => adgen_mode_a, - adgen_mode_b => adgen_mode_b, - address_out_x => adgen_address_out_x, - address_out_y => adgen_address_out_y, - wr_R_port_A_valid => adgen_wr_R_port_A_valid, - wr_R_port_A => adgen_wr_R_port_A, - wr_R_port_B_valid => adgen_wr_R_port_B_valid, - wr_R_port_B => adgen_wr_R_port_B - ); - - adgen_activate <= pipeline_regs(ST_DEC_ADG).act_array(ACT_ADGEN); - adgen_activate_x_mem <= '1' when pipeline_regs(ST_DEC_ADG).act_array(ACT_X_MEM_RD) = '1' or - pipeline_regs(ST_DEC_ADG).act_array(ACT_X_MEM_WR) = '1' else '0'; - adgen_activate_y_mem <= '1' when pipeline_regs(ST_DEC_ADG).act_array(ACT_Y_MEM_RD) = '1' or - pipeline_regs(ST_DEC_ADG).act_array(ACT_Y_MEM_WR) = '1' else '0'; - adgen_activate_l_mem <= '1' when pipeline_regs(ST_DEC_ADG).act_array(ACT_L_BUS_RD) = '1' or - pipeline_regs(ST_DEC_ADG).act_array(ACT_L_BUS_WR) = '1' else '0'; - adgen_instr_word <= pipeline_regs(ST_DEC_ADG).instr_word; - adgen_instr_array <= pipeline_regs(ST_DEC_ADG).instr_array; - adgen_optional_ea_word <= pipeline_regs(ST_DEC_ADG-1).instr_word; - adgen_mode_a <= pipeline_regs(ST_DEC_ADG).adgen_mode_a; - adgen_mode_b <= pipeline_regs(ST_DEC_ADG).adgen_mode_b; - - - ------------------------------- - -- EXECUTE STAGE INSTANTIATIONS - ------------------------------- - - -- Data ALU (MPY, MAC, ADD, shift, ...) - inst_exec_stage_alu: exec_stage_alu port map( - alu_activate => exec_alu_activate, - instr_word => exec_alu_instr_word, - alu_ctrl => exec_alu_ctrl, - register_file => register_file, - addr_r_in => exec_alu_addr_r_in, - addr_r_out => exec_alu_addr_r_out, - modify_accu => exec_alu_modify_accu, - dst_accu => exec_alu_dst_accu, - modified_accu => exec_alu_modified_accu, - modify_sr => exec_alu_modify_sr, - modified_sr => exec_alu_modified_sr - ); - - exec_alu_activate <= pipeline_regs(ST_ADG_EX).act_array(ACT_ALU); - exec_alu_instr_word <= pipeline_regs(ST_ADG_EX).instr_word; - exec_alu_ctrl <= pipeline_regs(ST_ADG_EX).alu_ctrl; - - exec_alu_addr_r_in <= unsigned(rf_reg_rd_data(BW_ADDRESS-1 downto 0)); - - -- Bit modification unit (BCLR, BSET, BCHG, ...) - inst_exec_stage_bit_modify: exec_stage_bit_modify port map( - instr_word => exec_bit_modify_instr_word, - instr_array => exec_bit_modify_instr_array, - src_operand => exec_bit_modify_src_operand, - register_file => register_file, - dst_operand => exec_bit_modify_dst_operand, - bit_cond_met => exec_bit_modify_bit_cond_met, - modify_sr => exec_bit_modify_modify_sr, - modified_sr => exec_bit_modify_modified_sr - ); - - exec_bit_modify_instr_word <= pipeline_regs(ST_ADG_EX).instr_word; - exec_bit_modify_instr_array <= pipeline_regs(ST_ADG_EX).instr_array; - exec_bit_modify_src_operand <= exec_src_operand; - - -- Writing to the register file using the 6 bit addressing scheme - -- sources are: - -- 1) X-RAM output - -- 2) Y-RAM output - -- 3) register file itself - -- 4) short immediate value (8 bit stored in instruction word) - -- 5) long immediate value (from optional effective address extension) - -- 6) address generated by the address generation unit (LUA instr) - exec_src_operand <= pipeline_regs(ST_ADG_EX).RAM_out_x when pipeline_regs(ST_ADG_EX).act_array(ACT_X_MEM_RD) = '1' else - pipeline_regs(ST_ADG_EX).RAM_out_y when pipeline_regs(ST_ADG_EX).act_array(ACT_Y_MEM_RD) = '1' else - rf_reg_rd_data when pipeline_regs(ST_ADG_EX).act_array(ACT_REG_RD) = '1' else - exec_imm_8bit when pipeline_regs(ST_ADG_EX).act_array(ACT_IMM_8BIT) = '1' else - exec_imm_12bit when pipeline_regs(ST_ADG_EX).act_array(ACT_IMM_12BIT) = '1' else - pipeline_regs(ST_ADG_EX-1).instr_word when pipeline_regs(ST_ADG_EX).act_array(ACT_IMM_LONG) = '1' else - std_logic_vector(resize(pipeline_regs(ST_ADG_EX).adgen_address_x, 24)); -- for LUA instr. - - -- Destination for the register file using the 6 bit addressing scheme. - -- Either read the bit modified version of the read value - -- or the output of a p-memory read - -- or use the modified Rn in case of a NORM instruction - exec_dst_operand <= exec_bit_modify_dst_operand when pipeline_regs(ST_ADG_EX).act_array(ACT_NORM) = '0' else - pmem2_data_out when pipeline_regs(ST_ADG_EX).act_array(ACT_P_MEM_RD) = '1' else - std_logic_vector(resize(exec_alu_addr_r_out,24)); - - -- Unit to check whether cc (in Jcc, JScc, Tcc, ...) is true - inst_exec_stage_cc_flag_calc: exec_stage_cc_flag_calc port map( - instr_word => exec_cc_flag_calc_instr_word, - instr_array => exec_cc_flag_calc_instr_array, - register_file => register_file, - cc_flag_set => exec_cc_flag_set - ); - - exec_cc_flag_calc_instr_word <= pipeline_regs(ST_ADG_EX).instr_word; - exec_cc_flag_calc_instr_array <= pipeline_regs(ST_ADG_EX).instr_array; - - -- Branch calculation unit - inst_exec_stage_branch : exec_stage_branch port map( - activate_exec_bra => exec_bra_activate, - instr_word => exec_bra_instr_word, - instr_array => exec_bra_instr_array, - register_file => register_file, - jump_address => exec_bra_jump_address, - bit_cond_met => exec_bra_bit_cond_met, - cc_flag_set => exec_cc_flag_set, - push_stack => exec_bra_push_stack, - pop_stack => exec_bra_pop_stack, - modify_pc => exec_bra_modify_pc, - modified_pc => exec_bra_modified_pc, - modify_sr => exec_bra_modify_sr, - modified_sr => exec_bra_modified_sr - ); - - exec_bra_activate <= pipeline_regs(ST_ADG_EX).act_array(ACT_EXEC_BRA); - exec_bra_instr_word <= pipeline_regs(ST_ADG_EX).instr_word; - exec_bra_instr_array <= pipeline_regs(ST_ADG_EX).instr_array; - exec_bra_jump_address <= pipeline_regs(ST_ADG_EX).adgen_address_x when pipeline_regs(ST_ADG_EX).dble_word_instr = '0' else - unsigned(pipeline_regs(ST_ADG_EX-1).instr_word(BW_ADDRESS-1 downto 0)); - exec_bra_bit_cond_met <= exec_bit_modify_bit_cond_met; - - -- Control register modifications - inst_exec_stage_cr_mod : exec_stage_cr_mod port map( - activate_exec_cr_mod => exec_cr_mod_activate, - instr_word => exec_cr_mod_instr_word, - instr_array => exec_cr_mod_instr_array, - register_file => register_file, - modify_sr => exec_cr_mod_modify_sr, - modified_sr => exec_cr_mod_modified_sr, - modify_omr => exec_cr_mod_modify_omr, - modified_omr => exec_cr_mod_modified_omr - ); - - exec_cr_mod_activate <= pipeline_regs(ST_ADG_EX).act_array(ACT_EXEC_CR_MOD); - exec_cr_mod_instr_word <= pipeline_regs(ST_ADG_EX).instr_word; - exec_cr_mod_instr_array <= pipeline_regs(ST_ADG_EX).instr_array; - - -- Loop control - inst_exec_stage_loop: exec_stage_loop port map( - clk => clk, - rst => rst, - activate_exec_loop => exec_loop_activate, - instr_word => exec_loop_instr_word, - instr_array => exec_loop_instr_array, - loop_iterations => exec_loop_iterations, - loop_address => exec_loop_address, - loop_start_address => exec_loop_start_address, - register_file => register_file, - fetch_perform_enddo=> fetch_perform_enddo, - memory_stall => memory_stall, - push_stack => exec_loop_push_stack, - pop_stack => exec_loop_pop_stack, - stall_rep => exec_loop_stall_rep, - stall_do => exec_loop_stall_do, - modify_lc => exec_loop_modify_lc, - decrement_lc => exec_loop_decrement_lc, - modified_lc => exec_loop_modified_lc, - modify_la => exec_loop_modify_la, - modified_la => exec_loop_modified_la, - modify_pc => exec_loop_modify_pc, - modified_pc => exec_loop_modified_pc, - modify_sr => exec_loop_modify_sr, - modified_sr => exec_loop_modified_sr - ); - - exec_loop_activate <= pipeline_regs(ST_ADG_EX).act_array(ACT_EXEC_LOOP); - exec_loop_instr_word <= pipeline_regs(ST_ADG_EX).instr_word; - exec_loop_instr_array <= pipeline_regs(ST_ADG_EX).instr_array; - exec_loop_iterations <= unsigned(exec_src_operand(15 downto 0)); - - -- Loop address is given by the second instruction word of the DO instruction. - -- This address is available one previous stage within the pipeline - exec_loop_address <= unsigned(pipeline_regs(ST_ADG_EX-1).instr_word(BW_ADDRESS-1 downto 0)) - 1; - -- one more stage before we find the programm counter of the first instruction to be executed in a DO loop - exec_loop_start_address <= unsigned(pipeline_regs(ST_ADG_EX-2).pc); - - -- For the 8 bit immediate is can be either a fractional (registers x0,x1,y0,y1,a,b) or an unsigned (the rest) - exec_imm_8bit(23 downto 16) <= (others => '0') when rf_reg_wr_addr(5 downto 2) /= "0001" and rf_reg_wr_addr(5 downto 1) /= "00111" else - pipeline_regs(ST_ADG_EX).instr_word(15 downto 8); - exec_imm_8bit(15 downto 8) <= (others => '0'); - exec_imm_8bit( 7 downto 0) <= (others => '0') when rf_reg_wr_addr(5 downto 2) = "0001" or rf_reg_wr_addr(5 downto 1) = "00111" else - pipeline_regs(ST_ADG_EX).instr_word(15 downto 8); - -- The 12 bit immediate stems from the instruction word - exec_imm_12bit(23 downto 12) <= (others => '0'); - exec_imm_12bit(11 downto 0) <= pipeline_regs(ST_ADG_EX).instr_word(3 downto 0) & pipeline_regs(ST_ADG_EX).instr_word(15 downto 8); - - - ----------------- - -- REGISTER FILE - ----------------- - - inst_reg_file: reg_file port map( - clk => clk, - rst => rst, - - -- Output for reading when needed - register_file => register_file, - - -- AGU write ports - wr_R_port_A_valid => rf_wr_R_port_A_valid, - wr_R_port_A => adgen_wr_R_port_A, - wr_R_port_B_valid => rf_wr_R_port_B_valid, - wr_R_port_B => adgen_wr_R_port_B, - - -- register read/write port - reg_wr_addr => rf_reg_wr_addr, - reg_wr_addr_valid => rf_reg_wr_addr_valid, - reg_wr_data => rf_reg_wr_data, - reg_rd_addr => rf_reg_rd_addr, - reg_rd_data => rf_reg_rd_data, - - -- ALU result write port - alu_wr_valid => rf_alu_wr_valid, - alu_wr_addr => exec_alu_dst_accu, - alu_wr_data => exec_alu_modified_accu, - - -- Bus read and write ports (X/Y/L) - X_bus_rd_addr => rf_X_bus_rd_addr, - X_bus_data_out => rf_X_bus_data_out, - X_bus_wr_addr => rf_X_bus_wr_addr , - X_bus_wr_valid => rf_X_bus_wr_valid, - X_bus_data_in => rf_X_bus_data_in , - Y_bus_rd_addr => rf_Y_bus_rd_addr , - Y_bus_data_out => rf_Y_bus_data_out, - Y_bus_wr_addr => rf_Y_bus_wr_addr , - Y_bus_wr_valid => rf_Y_bus_wr_valid, - Y_bus_data_in => rf_Y_bus_data_in , - L_bus_rd_addr => rf_L_bus_rd_addr , - L_bus_rd_valid => rf_L_bus_rd_valid, - L_bus_wr_addr => rf_L_bus_wr_addr , - L_bus_wr_valid => rf_L_bus_wr_valid, - - -- Stack modifications - push_stack => push_stack, - pop_stack => pop_stack, - - -- Control register modifications - set_sr => rf_set_sr, - new_sr => rf_new_sr, - set_omr => rf_set_omr, - new_omr => rf_new_omr, - set_la => rf_set_la, - new_la => rf_new_la, - dec_lc => rf_dec_lc, - set_lc => rf_set_lc, - new_lc => rf_new_lc - ); - - -- writing to the R registers within the ADGEN stage has to be prevented when - -- 1) a jump is currently being executed (which is detected in the exec stage) - -- 2) stall cycles occur. In this case the write will happen in the last cycle, when we stop stalling. - -- 3) a memory access results in a stall (e.g. caused by the instruction to REP) - rf_wr_R_port_A_valid <= '0' when stall_flags(ST_ADG_EX) = '1' or - exec_bra_modify_pc = '1' or - memory_stall = '1' else - adgen_wr_R_port_A_valid; - rf_wr_R_port_B_valid <= '0' when stall_flags(ST_ADG_EX) = '1' or - exec_bra_modify_pc = '1' or - memory_stall = '1' else - adgen_wr_R_port_B_valid; - - - rf_reg_wr_addr <= pipeline_regs(ST_ADG_EX).reg_wr_addr; - -- can be set due to - -- 1) normal write operation (e.g., move) - -- 2) conditional move (Tcc) - rf_reg_wr_addr_valid <= '1' when pipeline_regs(ST_ADG_EX).act_array(ACT_REG_WR) = '1' else - exec_cc_flag_set when pipeline_regs(ST_ADG_EX).act_array(ACT_REG_WR_CC) = '1' else '0'; - rf_reg_wr_data <= exec_dst_operand; - - rf_reg_rd_addr <= pipeline_regs(ST_ADG_EX).reg_rd_addr; - - -- Writing from the ALU can depend on the condition code (Tcc) instruction - rf_alu_wr_valid <= exec_cc_flag_set when pipeline_regs(ST_ADG_EX).act_array(ACT_ALU_WR_CC) = '1' else - exec_alu_modify_accu; - - push_stack.valid <= '1' when exec_bra_push_stack.valid = '1' or exec_loop_push_stack.valid = '1' else '0'; - push_stack.content <= exec_bra_push_stack.content when exec_bra_push_stack.valid = '1' else - exec_loop_push_stack.content; - -- for jump to subroutine store the pc of the subsequent instruction - push_stack.pc <= pipeline_regs(ST_ADG_EX-1).pc when exec_bra_push_stack.valid = '1' and pipeline_regs(ST_ADG_EX).dble_word_instr = '0' else - pipeline_regs(ST_ADG_EX-2).pc when exec_bra_push_stack.valid = '1' and pipeline_regs(ST_ADG_EX).dble_word_instr = '1' else - exec_loop_push_stack.pc when exec_loop_push_stack.valid = '1' else - (others => '0'); - - pop_stack.valid <= '1' when exec_bra_pop_stack.valid = '1' or exec_loop_pop_stack.valid = '1' else '0'; - - rf_set_sr <= '1' when exec_bra_modify_sr = '1' or - exec_cr_mod_modify_sr = '1' or - exec_loop_modify_sr = '1' or - exec_alu_modify_sr = '1' or - exec_bit_modify_modify_sr = '1' else '0'; - rf_new_sr <= exec_bra_modified_sr when exec_bra_modify_sr = '1' else - exec_cr_mod_modified_sr when exec_cr_mod_modify_sr = '1' else - exec_loop_modified_sr when exec_loop_modify_sr = '1' else - exec_alu_modified_sr when exec_alu_modify_sr = '1' else - exec_bit_modify_modified_sr; -- when exec_bit_modify_modify_sr = '1' else - - rf_set_omr <= exec_cr_mod_modify_omr; - rf_new_omr <= exec_cr_mod_modified_omr; - rf_set_lc <= exec_loop_modify_lc; - rf_new_lc <= exec_loop_modified_lc; - rf_set_la <= exec_loop_modify_la; - rf_new_la <= exec_loop_modified_la; - - rf_dec_lc <= '1' when exec_loop_decrement_lc = '1' or fetch_decrement_lc = '1' else '0'; - - ----------------- - -- BUSES (X,Y,L) - ----------------- - - rf_X_bus_wr_valid <= pipeline_regs(ST_ADG_EX).act_array(ACT_X_BUS_WR); - rf_X_bus_wr_addr <= pipeline_regs(ST_ADG_EX).x_bus_wr_addr; - rf_X_bus_rd_addr <= pipeline_regs(ST_ADG_EX).x_bus_rd_addr; - rf_X_bus_data_in <= rf_X_bus_data_out when pipeline_regs(ST_ADG_EX).act_array(ACT_X_BUS_RD) = '1' else - pipeline_regs(ST_ADG_EX).RAM_out_x; -- when pipeline_regs(ST_ADG_EX).act_array(ACT_X_MEM_RD) = '1' else - - rf_Y_bus_wr_valid <= pipeline_regs(ST_ADG_EX).act_array(ACT_Y_BUS_WR); - rf_Y_bus_wr_addr <= pipeline_regs(ST_ADG_EX).y_bus_wr_addr; - rf_Y_bus_rd_addr <= pipeline_regs(ST_ADG_EX).y_bus_rd_addr; - rf_Y_bus_data_in <= rf_Y_bus_data_out when pipeline_regs(ST_ADG_EX).act_array(ACT_Y_BUS_RD) = '1' else - pipeline_regs(ST_ADG_EX).RAM_out_y; -- when pipeline_regs(ST_ADG_EX).act_array(ACT_Y_MEM_RD) = '1' else - - rf_L_bus_wr_valid <= pipeline_regs(ST_ADG_EX).act_array(ACT_L_BUS_WR); - rf_L_bus_rd_valid <= pipeline_regs(ST_ADG_EX).act_array(ACT_L_BUS_RD); - rf_L_bus_wr_addr <= pipeline_regs(ST_ADG_EX).l_bus_addr; -- equal to bits in instruction word - rf_L_bus_rd_addr <= pipeline_regs(ST_ADG_EX).l_bus_addr; -- could be simplified by taking these bits.. - - - data_rom_enable <= register_file.omr(2); - - - ------------------------- - -- Program Memory Port 1 - -------------------------- - - -- pmem port 1 is only for instruction fetch - pmem_ctrl_in.rd_addr <= pc_new; - pmem_ctrl_in.rd_en <= '1' when stall_flags(ST_FE_FE2) = '0' else '0'; - - -- never write to this port - pmem_ctrl_in.wr_addr <= (others => '0'); - pmem_ctrl_in.wr_en <= '0'; - pmem_ctrl_in.data_in <= (others => '0'); - - pmem_data_out <= pmem_ctrl_out.data_out; - pmem_data_out_valid <= pmem_ctrl_out.data_out_valid; - - - ------------------------- - -- Program Memory Port 2 - -------------------------- --- TODO: This is untested! - - -- pmem port 2 is for movem instructions - - -- take x memory address as address - pmem2_ctrl_in.rd_addr <= adgen_address_out_x when pipeline_regs(ST_DEC_ADG).act_array(ACT_ADGEN) = '1' else - "0000000000" & unsigned(pipeline_regs(ST_DEC_ADG).instr_word(13 downto 8)); - pmem2_ctrl_in.rd_en <= pipeline_regs(ST_DEC_ADG).act_array(ACT_P_MEM_RD); - - - -- Either take the result of the AGU or use the absolute value stored in the instruction word - pmem2_ctrl_in.wr_addr <= pipeline_regs(ST_ADG_EX).adgen_address_x when pipeline_regs(ST_ADG_EX).act_array(ACT_ADGEN) = '1' else - "0000000000" & unsigned(pipeline_regs(ST_ADG_EX).instr_word(13 downto 8)); - pmem2_ctrl_in.wr_en <= pipeline_regs(ST_ADG_EX).act_array(ACT_P_MEM_WR); - - -- only the register file read value is allowed here - pmem2_ctrl_in.data_in <= rf_reg_rd_data; - - pmem2_data_out <= pmem2_ctrl_out.data_out; - pmem2_data_out_valid <= pmem2_ctrl_out.data_out_valid; - - ------------------ - -- X Memory - ------------------ - - -- Either take the result of the AGU or use the short absolute value stored in the instruction word - xmem_ctrl_in.rd_addr <= adgen_address_out_x when pipeline_regs(ST_DEC_ADG).act_array(ACT_ADGEN) = '1' else - "0000000000" & unsigned(pipeline_regs(ST_DEC_ADG).instr_word(13 downto 8)); - xmem_ctrl_in.rd_en <= '1' when pipeline_regs(ST_DEC_ADG).act_array(ACT_X_MEM_RD) = '1' else '0'; - -- Either take the result of the AGU or use the absolute value stored in the instruction word - xmem_ctrl_in.wr_addr <= pipeline_regs(ST_ADG_EX).adgen_address_x when pipeline_regs(ST_ADG_EX).act_array(ACT_ADGEN) = '1' else - "0000000000" & unsigned(pipeline_regs(ST_ADG_EX).instr_word(13 downto 8)); - xmem_ctrl_in.wr_en <= '1' when pipeline_regs(ST_ADG_EX).act_array(ACT_X_MEM_WR) = '1' else '0'; - xmem_ctrl_in.data_in <= rf_X_bus_data_out when pipeline_regs(ST_ADG_EX).act_array(ACT_X_BUS_RD) = '1' or - pipeline_regs(ST_ADG_EX).act_array(ACT_L_BUS_RD) = '1' else - exec_dst_operand; - - - ------------------ - -- Y Memory - ------------------ - - -- Either take the result of the AGU or use the absolute value stored in the instruction word - ymem_ctrl_in.rd_addr <= adgen_address_out_y when pipeline_regs(ST_DEC_ADG).act_array(ACT_ADGEN) = '1' else - "0000000000" & unsigned(pipeline_regs(ST_DEC_ADG).instr_word(13 downto 8)); - ymem_ctrl_in.rd_en <= '1' when pipeline_regs(ST_DEC_ADG).act_array(ACT_Y_MEM_RD) = '1' else '0'; - -- Either take the result of the AGU or use the absolute value stored in the instruction word - ymem_ctrl_in.wr_addr <= pipeline_regs(ST_ADG_EX).adgen_address_y when pipeline_regs(ST_ADG_EX).act_array(ACT_ADGEN) = '1' else - "0000000000" & unsigned(pipeline_regs(ST_ADG_EX).instr_word(13 downto 8)); - ymem_ctrl_in.wr_en <= '1' when pipeline_regs(ST_ADG_EX).act_array(ACT_Y_MEM_WR) = '1' else '0'; - ymem_ctrl_in.data_in <= rf_Y_bus_data_out when pipeline_regs(ST_ADG_EX).act_array(ACT_Y_BUS_RD) = '1' or - pipeline_regs(ST_ADG_EX).act_array(ACT_L_BUS_RD) = '1' else - exec_dst_operand; - -end architecture rtl; diff --git a/vhdl/dsp56k/src/reg_file.vhd b/vhdl/dsp56k/src/reg_file.vhd deleted file mode 100644 index afeeda0..0000000 --- a/vhdl/dsp56k/src/reg_file.vhd +++ /dev/null @@ -1,686 +0,0 @@ ------------------------------------------------------------------------------- ---! @file ---! @author Matthias Alles ---! @date 01/2009 ---! @brief Global register file, including scaler and limiter ---! ------------------------------------------------------------------------------- -library ieee; -use ieee.std_logic_1164.all; -use ieee.numeric_std.all; -library work; -use work.parameter_pkg.all; -use work.types_pkg.all; -use work.constants_pkg.all; - -entity reg_file is port( - clk, rst : in std_logic; - register_file : out register_file_type; - wr_R_port_A_valid : in std_logic; - wr_R_port_A : in addr_wr_port_type; - wr_R_port_B_valid : in std_logic; - wr_R_port_B : in addr_wr_port_type; - alu_wr_valid : in std_logic; - alu_wr_addr : in std_logic; - alu_wr_data : in signed(55 downto 0); - reg_wr_addr : in std_logic_vector(5 downto 0); - reg_wr_addr_valid : in std_logic; - reg_wr_data : in std_Logic_vector(23 downto 0); - reg_rd_addr : in std_logic_vector(5 downto 0); - reg_rd_data : out std_Logic_vector(23 downto 0); - X_bus_rd_addr : in std_logic_vector(1 downto 0); - X_bus_data_out : out std_logic_vector(23 downto 0); - X_bus_wr_addr : in std_logic_vector(1 downto 0); - X_bus_wr_valid : in std_logic; - X_bus_data_in : in std_logic_vector(23 downto 0); - Y_bus_rd_addr : in std_logic_vector(1 downto 0); - Y_bus_data_out : out std_logic_vector(23 downto 0); - Y_bus_wr_addr : in std_logic_vector(1 downto 0); - Y_bus_wr_valid : in std_logic; - Y_bus_data_in : in std_logic_vector(23 downto 0); - L_bus_rd_addr : in std_logic_vector(2 downto 0); - L_bus_rd_valid : in std_logic; - L_bus_wr_addr : in std_logic_vector(2 downto 0); - L_bus_wr_valid : in std_logic; - push_stack : in push_stack_type; - pop_stack : in pop_stack_type; - set_sr : in std_logic; - new_sr : in std_logic_vector(15 downto 0); - set_omr : in std_logic; - new_omr : in std_logic_vector(7 downto 0); - dec_lc : in std_logic; - set_lc : in std_logic; - new_lc : in unsigned(15 downto 0); - set_la : in std_logic; - new_la : in unsigned(BW_ADDRESS-1 downto 0) -); -end entity; - - -architecture rtl of reg_file is - - signal addr_r : addr_array; - signal addr_m : addr_array; - signal addr_n : addr_array; - - signal loop_address : unsigned(BW_ADDRESS-1 downto 0); - signal loop_counter : unsigned(15 downto 0); - - -- condition code register - signal ccr : std_logic_vector(7 downto 0); - -- mode register - signal mr : std_logic_vector(7 downto 0); - -- status register = mode register + condition code register - signal sr : std_logic_vector(15 downto 0); - -- operation mode register - signal omr : std_logic_vector(7 downto 0); - - signal stack_pointer : unsigned(5 downto 0); - signal system_stack_ssh : stack_array_type; - signal system_stack_ssl : stack_array_type; - - signal x0 : signed(23 downto 0); - signal x1 : signed(23 downto 0); - signal y0 : signed(23 downto 0); - signal y1 : signed(23 downto 0); - - signal a0 : signed(23 downto 0); - signal a1 : signed(23 downto 0); - signal a2 : signed(7 downto 0); - - signal b0 : signed(23 downto 0); - signal b1 : signed(23 downto 0); - signal b2 : signed(7 downto 0); - - signal limited_a1 : signed(23 downto 0); - signal limited_b1 : signed(23 downto 0); - signal limited_a0 : signed(23 downto 0); - signal limited_b0 : signed(23 downto 0); - signal set_limiting_flag : std_logic; - signal X_bus_rd_limited_a : std_logic; - signal X_bus_rd_limited_b : std_logic; - signal Y_bus_rd_limited_a : std_logic; - signal Y_bus_rd_limited_b : std_logic; - signal reg_rd_limited_a : std_logic; - signal reg_rd_limited_b : std_logic; - signal rd_limited_a : std_logic; - signal rd_limited_b : std_logic; - -begin - - - - sr <= mr & ccr; - - register_file.addr_r <= addr_r; - register_file.addr_n <= addr_n; - register_file.addr_m <= addr_m; - register_file.lc <= loop_counter; - register_file.la <= loop_address; - register_file.ccr <= ccr; - register_file.mr <= mr; - register_file.sr <= sr; - register_file.omr <= omr; - register_file.stack_pointer <= stack_pointer; - register_file.current_ssh <= system_stack_ssh(to_integer(stack_pointer(3 downto 0))); - register_file.current_ssl <= system_stack_ssl(to_integer(stack_pointer(3 downto 0))); - register_file.a <= a2 & a1 & a0; - register_file.b <= b2 & b1 & b0; - register_file.x0 <= x0; - register_file.x1 <= x1; - register_file.y0 <= y0; - register_file.y1 <= y1; - - - global_register_file: process(clk) is - variable stack_pointer_plus_1 : unsigned(3 downto 0); - variable reg_addr : integer range 0 to 7; - begin - if rising_edge(clk) then - if rst = '1' then - addr_r <= (others => (others => '0')); - addr_n <= (others => (others => '0')); - addr_m <= (others => (others => '1')); - ccr <= (others => '0'); - mr <= (others => '0'); - omr <= (others => '0'); - system_stack_ssl <= (others => (others => '0')); - system_stack_ssh <= (others => (others => '0')); - stack_pointer <= (others => '0'); - loop_counter <= (others => '0'); - loop_address <= (others => '0'); - x0 <= (others => '0'); - x1 <= (others => '0'); - y0 <= (others => '0'); - y1 <= (others => '0'); - a0 <= (others => '0'); - a1 <= (others => '0'); - a2 <= (others => '0'); - b0 <= (others => '0'); - b1 <= (others => '0'); - b2 <= (others => '0'); - else - reg_addr := to_integer(unsigned(reg_wr_addr(2 downto 0))); - ----------------------------------------------------------------------- - -- General write port to register file using 6 bit addressing scheme - ----------------------------------------------------------------------- - if reg_wr_addr_valid = '1' then - case reg_wr_addr(5 downto 3) is - -- X0, X1, Y0, Y1 - when "000" => - case reg_wr_addr(2 downto 0) is - when "100" => - x0 <= signed(reg_wr_data); - when "101" => - x1 <= signed(reg_wr_data); - when "110" => - y0 <= signed(reg_wr_data); - when "111" => - y1 <= signed(reg_wr_data); - when others => - end case; - - -- A0, B0, A2, B2, A1, B1, A, B - when "001" => - case reg_wr_addr(2 downto 0) is - when "000" => - a0 <= signed(reg_wr_data); - when "001" => - b0 <= signed(reg_wr_data); - when "010" => - a2 <= signed(reg_wr_data(7 downto 0)); - when "011" => - b2 <= signed(reg_wr_data(7 downto 0)); - when "100" => - a1 <= signed(reg_wr_data); - when "101" => - b1 <= signed(reg_wr_data); - when "110" => - a2 <= (others => reg_wr_data(23)); - a1 <= signed(reg_wr_data); - a0 <= (others => '0'); - when "111" => - b2 <= (others => reg_wr_data(23)); - b1 <= signed(reg_wr_data); - b0 <= (others => '0'); - when others => - end case; - - -- R0-R7 - when "010" => - addr_r(reg_addr) <= unsigned(reg_wr_data(BW_ADDRESS-1 downto 0)); - - -- N0-N7 - when "011" => - addr_n(reg_addr) <= unsigned(reg_wr_data(BW_ADDRESS-1 downto 0)); - - -- M0-M7 - when "100" => - addr_m(reg_addr) <= unsigned(reg_wr_data(BW_ADDRESS-1 downto 0)); - - -- SR, OMR, SP, SSH, SSL, LA, LC - when "111" => - case reg_wr_addr(2 downto 0) is - -- SR - when "001" => - mr <= reg_wr_data(15 downto 8); - ccr <= reg_wr_data( 7 downto 0); - - -- OMR - when "010" => - omr <= reg_wr_data(7 downto 0); - - -- SP - when "011" => - stack_pointer <= unsigned(reg_wr_data(5 downto 0)); - - -- SSH - when "100" => - system_stack_ssh(to_integer(stack_pointer_plus_1)) <= reg_wr_data(BW_ADDRESS-1 downto 0); - -- increase stack after writing - stack_pointer(3 downto 0) <= stack_pointer_plus_1; - -- test whether stack is full, if so set the stack error flag (SE) - if stack_pointer(3 downto 0) = "1111" then - stack_pointer(4) <= '1'; - end if; - - -- SSL - when "101" => - system_stack_ssl(to_integer(stack_pointer)) <= reg_wr_data(BW_ADDRESS-1 downto 0); - - -- LA - when "110" => - loop_address <= unsigned(reg_wr_data(BW_ADDRESS-1 downto 0)); - - -- LC - when "111" => - loop_counter <= unsigned(reg_wr_data(15 downto 0)); - - when others => - end case; - when others => - end case; - end if; - - ---------------- - -- X BUS Write - ---------------- - if X_bus_wr_valid = '1' then - case X_bus_wr_addr is - when "00" => - x0 <= signed(X_bus_data_in); - when "01" => - x1 <= signed(X_bus_data_in); - when "10" => - a2 <= (others => X_bus_data_in(23)); - a1 <= signed(X_bus_data_in); - a0 <= (others => '0'); - when others => - b2 <= (others => X_bus_data_in(23)); - b1 <= signed(X_bus_data_in); - b0 <= (others => '0'); - end case; - end if; - ---------------- - -- Y BUS Write - ---------------- - if Y_bus_wr_valid = '1' then - case Y_bus_wr_addr is - when "00" => - y0 <= signed(Y_bus_data_in); - when "01" => - y1 <= signed(Y_bus_data_in); - when "10" => - a2 <= (others => Y_bus_data_in(23)); - a1 <= signed(Y_bus_data_in); - a0 <= (others => '0'); - when others => - b2 <= (others => Y_bus_data_in(23)); - b1 <= signed(Y_bus_data_in); - b0 <= (others => '0'); - end case; - end if; - ------------------ - -- L BUS Write - ------------------ - if L_bus_wr_valid = '1' then - case L_bus_wr_addr is - -- A10 - when "000" => - a1 <= signed(X_bus_data_in); - a0 <= signed(Y_bus_data_in); - -- B10 - when "001" => - b1 <= signed(X_bus_data_in); - b0 <= signed(Y_bus_data_in); - -- X - when "010" => - x1 <= signed(X_bus_data_in); - x0 <= signed(Y_bus_data_in); - -- Y - when "011" => - y1 <= signed(X_bus_data_in); - y0 <= signed(Y_bus_data_in); - -- A - when "100" => - a2 <= (others => X_bus_data_in(23)); - a1 <= signed(X_bus_data_in); - a0 <= signed(Y_bus_data_in); - -- B - when "101" => - b2 <= (others => X_bus_data_in(23)); - b1 <= signed(X_bus_data_in); - b0 <= signed(Y_bus_data_in); - -- AB - when "110" => - a2 <= (others => X_bus_data_in(23)); - a1 <= signed(X_bus_data_in); - a0 <= (others => '0'); - b2 <= (others => Y_bus_data_in(23)); - b1 <= signed(Y_bus_data_in); - b0 <= (others => '0'); - -- BA - when others => - a2 <= (others => Y_bus_data_in(23)); - a1 <= signed(Y_bus_data_in); - a0 <= (others => '0'); - b2 <= (others => X_bus_data_in(23)); - b1 <= signed(X_bus_data_in); - b0 <= (others => '0'); - end case; - end if; - - --------------------- - -- STATUS REGISTERS - --------------------- - if set_sr = '1' then - ccr <= new_sr( 7 downto 0); - mr <= new_sr(15 downto 8); - end if; - if set_omr = '1' then - omr <= new_omr; - end if; - -- data limiter active? - -- listing this statement after the set_sr test results - -- in the correct behaviour for ALU operations with parallel move - if set_limiting_flag = '1' then - ccr(6) <= '1'; - end if; - - -------------------- - -- LOOP REGISTERS - -------------------- - if set_la = '1' then - loop_address <= new_la; - end if; - if set_lc = '1' then - loop_counter <= new_lc; - end if; - if dec_lc = '1' then - loop_counter <= loop_counter - 1; - end if; - - --------------------- - -- ADDRESS REGISTER - --------------------- - if wr_R_port_A_valid = '1' then - addr_r(to_integer(wr_R_port_A.reg_number)) <= wr_R_port_A.reg_value; - end if; - if wr_R_port_B_valid = '1' then - addr_r(to_integer(wr_R_port_B.reg_number)) <= wr_R_port_B.reg_value; - end if; - - ------------------------- - -- ALU ACCUMULATOR WRITE - ------------------------- - if alu_wr_valid = '1' then - if alu_wr_addr = '0' then - a2 <= alu_wr_data(55 downto 48); - a1 <= alu_wr_data(47 downto 24); - a0 <= alu_wr_data(23 downto 0); - else - b2 <= alu_wr_data(55 downto 48); - b1 <= alu_wr_data(47 downto 24); - b0 <= alu_wr_data(23 downto 0); - end if; - end if; - - --------------------- - -- STACK CONTROLLER - --------------------- - stack_pointer_plus_1 := stack_pointer(3 downto 0) + 1; - if push_stack.valid = '1' then - -- increase stack after writing - stack_pointer(3 downto 0) <= stack_pointer_plus_1; - -- test whether stack is full, if so set the stack error flag (SE) - if stack_pointer(3 downto 0) = "1111" then - stack_pointer(4) <= '1'; - end if; - case push_stack.content is - when PC => - system_stack_ssh(to_integer(stack_pointer_plus_1)) <= std_logic_vector(push_stack.pc); - - when PC_AND_SR => - system_stack_ssh(to_integer(stack_pointer_plus_1)) <= std_logic_vector(push_stack.pc); - system_stack_ssl(to_integer(stack_pointer_plus_1)) <= SR; - - when LA_AND_LC => - system_stack_ssh(to_integer(stack_pointer_plus_1)) <= std_logic_vector(loop_address); - system_stack_ssl(to_integer(stack_pointer_plus_1)) <= std_logic_vector(loop_counter); - - end case; - end if; - - -- decrease stack pointer - if pop_stack.valid = '1' then - stack_pointer(3 downto 0) <= stack_pointer(3 downto 0) - 1; - -- if stack is empty set the underflow flag (bit 5, UF) and the stack error flag (bit 4, SE) - if stack_pointer(3 downto 0) = "0000" then - stack_pointer(5) <= '1'; - stack_pointer(4) <= '1'; - end if; - end if; - end if; - end if; - end process; - - - x_bus_rd_port: process(X_bus_rd_addr,x0,x1,a1,b1,limited_a1,limited_b1, - L_bus_rd_addr,L_bus_rd_valid,y1) is - begin - X_bus_rd_limited_a <= '0'; - X_bus_rd_limited_b <= '0'; - case X_bus_rd_addr is - when "00" => X_bus_data_out <= std_logic_vector(x0); - when "01" => X_bus_data_out <= std_logic_vector(x1); - when "10" => X_bus_data_out <= std_logic_vector(limited_a1); X_bus_rd_limited_a <= '1'; - when others => X_bus_data_out <= std_logic_vector(limited_b1); X_bus_rd_limited_b <= '1'; - end case; - if L_bus_rd_valid = '1' then - case L_bus_rd_addr is - when "000" => X_bus_data_out <= std_logic_vector(a1); - when "001" => X_bus_data_out <= std_logic_vector(b1); - when "010" => X_bus_data_out <= std_logic_vector(x1); - when "011" => X_bus_data_out <= std_logic_vector(y1); - when "100" => X_bus_data_out <= std_logic_vector(limited_a1); X_bus_rd_limited_a <= '1'; - when "101" => X_bus_data_out <= std_logic_vector(limited_b1); X_bus_rd_limited_b <= '1'; - when "110" => X_bus_data_out <= std_logic_vector(limited_a1); X_bus_rd_limited_a <= '1'; - when others => X_bus_data_out <= std_logic_vector(limited_b1); X_bus_rd_limited_b <= '1'; - end case; - end if; - end process x_bus_rd_port; - - y_bus_rd_port: process(Y_bus_rd_addr,y0,y1,a1,b1,limited_a1,limited_b1, - L_bus_rd_addr,L_bus_rd_valid,a0,b0,x0,limited_a0,limited_b0) is - begin - Y_bus_rd_limited_a <= '0'; - Y_bus_rd_limited_b <= '0'; - case Y_bus_rd_addr is - when "00" => Y_bus_data_out <= std_logic_vector(y0); - when "01" => Y_bus_data_out <= std_logic_vector(y1); - when "10" => Y_bus_data_out <= std_logic_vector(limited_a1); Y_bus_rd_limited_a <= '1'; - when others => Y_bus_data_out <= std_logic_vector(limited_b1); Y_bus_rd_limited_b <= '1'; - end case; - if L_bus_rd_valid = '1' then - case L_bus_rd_addr is - when "000" => Y_bus_data_out <= std_logic_vector(a0); - when "001" => Y_bus_data_out <= std_logic_vector(b0); - when "010" => Y_bus_data_out <= std_logic_vector(x0); - when "011" => Y_bus_data_out <= std_logic_vector(y0); - when "100" => Y_bus_data_out <= std_logic_vector(limited_a0); Y_bus_rd_limited_a <= '1'; - when "101" => Y_bus_data_out <= std_logic_vector(limited_b0); Y_bus_rd_limited_b <= '1'; - when "110" => Y_bus_data_out <= std_logic_vector(limited_b1); Y_bus_rd_limited_b <= '1'; - when others => Y_bus_data_out <= std_logic_vector(limited_a1); Y_bus_rd_limited_a <= '1'; - end case; - end if; - end process y_bus_rd_port; - - - reg_rd_port: process(reg_rd_addr, x0,x1,y0,y1,a0,a1,a2,b0,b1,b2, - omr,ccr,mr,addr_r,addr_n,addr_m,stack_pointer, - loop_address,loop_counter,system_stack_ssl,system_stack_ssh) is - variable reg_addr : integer range 0 to 7; - begin - reg_addr := to_integer(unsigned(reg_rd_addr(2 downto 0))); - reg_rd_data <= (others => '0'); - reg_rd_limited_a <= '0'; - reg_rd_limited_b <= '0'; - - case reg_rd_addr(5 downto 3) is - -- X0, X1, Y0, Y1 - when "000" => - case reg_rd_addr(2 downto 0) is - when "100" => - reg_rd_data <= std_logic_vector(x0); - when "101" => - reg_rd_data <= std_logic_vector(x1); - when "110" => - reg_rd_data <= std_logic_vector(y0); - when "111" => - reg_rd_data <= std_logic_vector(y1); - when others => - end case; - - -- A0, B0, A2, B2, A1, B1, A, B - when "001" => - case reg_rd_addr(2 downto 0) is - when "000" => - reg_rd_data <= std_logic_vector(a0); - when "001" => - reg_rd_data <= std_logic_vector(b0); - when "010" => - -- MSBs are read as zero! - reg_rd_data(23 downto 8) <= (others => '0'); - reg_rd_data(7 downto 0) <= std_logic_vector(a2); - when "011" => - -- MSBs are read as zero! - reg_rd_data(23 downto 8) <= (others => '0'); - reg_rd_data(7 downto 0) <= std_logic_vector(b2); - when "100" => - reg_rd_data <= std_logic_vector(a1); - when "101" => - reg_rd_data <= std_logic_vector(b1); - when "110" => - reg_rd_data <= std_logic_vector(limited_a1); - reg_rd_limited_a <= '1'; - when "111" => - reg_rd_data <= std_logic_vector(limited_b1); - reg_rd_limited_b <= '1'; - when others => - end case; - - -- R0-R7 - when "010" => - reg_rd_data <= std_logic_vector(resize(addr_r(reg_addr), 24)); - - -- N0-N7 - when "011" => - reg_rd_data <= std_logic_vector(resize(addr_n(reg_addr), 24)); - - -- M0-M7 - when "100" => - reg_rd_data <= std_logic_vector(resize(addr_m(reg_addr), 24)); - - -- SR, OMR, SP, SSH, SSL, LA, LC - when "111" => - case reg_wr_addr(2 downto 0) is - -- SR - when "001" => - reg_rd_data(23 downto 16) <= (others => '0'); - reg_rd_data(15 downto 0) <= mr & ccr; - - -- OMR - when "010" => - reg_rd_data(23 downto 8) <= (others => '0'); - reg_rd_data( 7 downto 0) <= omr; - - -- SP - when "011" => - reg_rd_data(23 downto 6) <= (others => '0'); - reg_rd_data(5 downto 0) <= std_logic_vector(stack_pointer); - - -- SSH - when "100" => --- TODO! --- system_stack_ssh(to_integer(stack_pointer_plus_1)) <= reg_wr_data(BW_ADDRESS-1 downto 0); --- -- increase stack after writing --- stack_pointer(3 downto 0) <= stack_pointer_plus_1; --- -- test whether stack is full, if so set the stack error flag (SE) --- if stack_pointer(3 downto 0) = "1111" then --- stack_pointer(4) <= '1'; --- end if; - - -- SSL - when "101" => - reg_rd_data <= (others => '0'); - reg_rd_data(BW_ADDRESS-1 downto 0) <= std_logic_vector(system_stack_ssl(to_integer(stack_pointer))); - - -- LA - when "110" => - reg_rd_data <= (others => '0'); - reg_rd_data(BW_ADDRESS-1 downto 0) <= std_logic_vector(loop_address); - - -- LC - when "111" => - reg_rd_data <= (others => '0'); - reg_rd_data(15 downto 0) <= std_logic_vector(loop_counter); - - when others => - end case; - when others => - end case; - end process; - - rd_limited_a <= '1' when reg_rd_limited_a = '1' or X_bus_rd_limited_a = '1' or Y_bus_rd_limited_a = '1' else '0'; - rd_limited_b <= '1' when reg_rd_limited_b = '1' or X_bus_rd_limited_b = '1' or Y_bus_rd_limited_b = '1' else '0'; - - data_shifter_limiter: process(a2,a1,a0,b2,b1,b0,sr,rd_limited_a,rd_limited_b) is - variable scaled_a : signed(55 downto 0); - variable scaled_b : signed(55 downto 0); - begin - - set_limiting_flag <= '0'; - ----------------- - -- DATA SCALING - ----------------- - -- test against scaling bits S1, S0 - case sr(11 downto 10) is - -- scale down (right shift) - when "01" => - scaled_a := a2(7) & a2 & a1 & a0(23 downto 1); - scaled_b := b2(7) & b2 & b1 & b0(23 downto 1); - -- scale up (arithmetic left shift) - when "10" => - scaled_a := a2(6 downto 0) & a1 & a0 & '0'; - scaled_b := b2(6 downto 0) & b1 & b0 & '0'; - -- "00" do not scale! - when others => - scaled_a := a2 & a1 & a0; - scaled_b := b2 & b1 & b0; - end case; - - -- only sign extension stored in a2? - -- Yes: No limiting needed! - if scaled_a(55 downto 47) = "111111111" or scaled_a(55 downto 47) = "000000000" then - limited_a1 <= scaled_a(47 downto 24); - limited_a0 <= scaled_a(23 downto 0); - else - -- positive value in a? - if scaled_a(55) = '0' then - limited_a1 <= X"7FFFFF"; - limited_a0 <= X"FFFFFF"; - -- negative value in a? - else - limited_a1 <= X"800000"; - limited_a0 <= X"000000"; - end if; - -- set the limit flag in the status register - if rd_limited_a = '1' then - set_limiting_flag <= '1'; - end if; - end if; - -- only sign extension stored in b2? - -- Yes: No limiting needed! - if scaled_b(55 downto 47) = "111111111" or scaled_b(55 downto 47) = "000000000" then - limited_b1 <= scaled_b(47 downto 24); - limited_b0 <= scaled_b(23 downto 0); - else - -- positive value in b? - if scaled_b(55) = '0' then - limited_b1 <= X"7FFFFF"; - limited_b0 <= X"FFFFFF"; - -- negative value in b? - else - limited_b1 <= X"800000"; - limited_b0 <= X"000000"; - end if; - -- set the limit flag in the status register - if rd_limited_b = '1' then - set_limiting_flag <= '1'; - end if; - end if; - - end process; - - -end architecture rtl; diff --git a/vhdl/dsp56k/src/types_pkg.vhd b/vhdl/dsp56k/src/types_pkg.vhd deleted file mode 100644 index f0f1175..0000000 --- a/vhdl/dsp56k/src/types_pkg.vhd +++ /dev/null @@ -1,182 +0,0 @@ ------------------------------------------------------------------------------- ---! @file ---! @author Matthias Alles ---! @date 01/2009 ---! @brief Global types ---! ------------------------------------------------------------------------------- -library ieee; -use ieee.std_logic_1164.all; -use ieee.numeric_std.all; -library work; -use work.parameter_pkg.all; - - - -package types_pkg is - - -- the different addressing modes - type ADGen_mode_type is (NOP, - POST_MIN_N, - POST_PLUS_N, - POST_MIN_1, - POST_PLUS_1, - INDEXED_N, - PRE_MIN_1, - ABSOLUTE, - IMMEDIATE); - - ------------------------ - -- Decoded instructions - ------------------------ - type instructions_type is ( - INSTR_NOP , - INSTR_RTI , - INSTR_ILLEGAL , - INSTR_SWI , - INSTR_RTS , - INSTR_RESET , - INSTR_WAIT , - INSTR_STOP , - INSTR_ENDDO , - INSTR_ANDI , - INSTR_ORI , - INSTR_DIV , - INSTR_NORM , - INSTR_LUA , - INSTR_MOVEC , - INSTR_REP , - INSTR_DO , - INSTR_MOVEM , - INSTR_MOVEP , - INSTR_PM_MOVEM, - INSTR_BCLR , - INSTR_BSET , - INSTR_JCLR , - INSTR_JSET , - INSTR_JMP , - INSTR_JCC , - INSTR_BCHG , - INSTR_BTST , - INSTR_JSCLR , - INSTR_JSSET , - INSTR_JSR , - INSTR_JSCC ); - - type addr_array is array(0 to 7) of unsigned(BW_ADDRESS-1 downto 0); - - type alu_shift_mode is (NO_SHIFT, SHIFT_LEFT, SHIFT_RIGHT, ZEROS); - type alu_ccr_flag is (DONT_TOUCH, CLEAR, MODIFY, SET); - type alu_ccr_flag_array is array(7 downto 0) of alu_ccr_flag; - - type alu_ctrl_type is record - mul_op1 : std_logic_vector(1 downto 0); -- x0,x1,y0,y1 - mul_op2 : std_logic_vector(1 downto 0); -- x0,x1,y0,y1 - shift_src : std_logic; -- a,b - shift_src_sign : std_logic_vector(1 downto 0); -- 00: pos, 01: neg, 10: sign dependant, 11: reserved - shift_mode : alu_shift_mode; - rotate : std_logic; -- 0: logical shift, 1: rotate shift - add_src_stage_1 : std_logic_vector(2 downto 0); -- x0,x1,y0,y1,x,y,a,b - add_src_stage_2 : std_logic_vector(1 downto 0); -- 00: 0 , 01: add_src_1, 10: mul_result, 11: reserved - add_src_sign : std_logic_vector(1 downto 0); -- 00: pos, 01: neg, 10: sign dependant, 11: reserved - logic_function : std_logic_vector(2 downto 0); -- 000: none, 001: and, 010: or, 011: eor, 100: not - word_24_update : std_logic; -- only accumulator bits 47 downto 24 affected? - rounding_used : std_logic_vector(1 downto 0); -- 00: no rounding, 01: rounding, 10: add carry, 11: subtract carry - store_result : std_logic; -- 0: do not update accumulator, 1: update accumulator - dst_accu : std_logic; -- 0: a, 1: b - div_instr : std_logic; -- DIV instruction? Special ALU operations needed! - norm_instr : std_logic; -- NORM instruction? Special ALU operations needed! - ccr_flags_ctrl : alu_ccr_flag_array; - end record; - - type pipeline_signals is record - instr_word: std_logic_vector(23 downto 0); - pc : unsigned(BW_ADDRESS-1 downto 0); - dble_word_instr : std_logic; - instr_array : instructions_type; - act_array : std_logic_vector(NUM_ACT_SIGNALS-1 downto 0); - dec_activate : std_logic; - adgen_mode_a : adgen_mode_type; - adgen_mode_b : adgen_mode_type; - reg_wr_addr : std_logic_vector(5 downto 0); - reg_rd_addr : std_logic_vector(5 downto 0); - x_bus_rd_addr : std_logic_vector(1 downto 0); - x_bus_wr_addr : std_logic_vector(1 downto 0); - y_bus_rd_addr : std_logic_vector(1 downto 0); - y_bus_wr_addr : std_logic_vector(1 downto 0); - l_bus_addr : std_logic_vector(2 downto 0); - adgen_address_x : unsigned(BW_ADDRESS-1 downto 0); - adgen_address_y : unsigned(BW_ADDRESS-1 downto 0); - RAM_out_x : std_logic_vector(23 downto 0); - RAM_out_y : std_logic_vector(23 downto 0); - alu_ctrl : alu_ctrl_type; - end record; - - type pipeline_type is array(0 to PIPELINE_DEPTH-1) of pipeline_signals; - - - type register_file_type is record - a : signed(55 downto 0); - b : signed(55 downto 0); - x0 : signed(23 downto 0); - x1 : signed(23 downto 0); - y0 : signed(23 downto 0); - y1 : signed(23 downto 0); - la : unsigned(BW_ADDRESS-1 downto 0); - lc : unsigned(15 downto 0); - addr_r : addr_array; - addr_n : addr_array; - addr_m : addr_array; - ccr : std_logic_vector(7 downto 0); - mr : std_logic_vector(7 downto 0); - sr : std_logic_vector(15 downto 0); - omr : std_logic_vector(7 downto 0); - stack_pointer : unsigned(5 downto 0); --- system_stack_ssh : stack_array_type; --- system_stack_ssl : stack_array_type; - current_ssh : std_logic_vector(BW_ADDRESS-1 downto 0); - current_ssl : std_logic_vector(BW_ADDRESS-1 downto 0); - - end record; - - type addr_wr_port_type is record --- write_valid : std_logic; - reg_number : unsigned(2 downto 0); - reg_value : unsigned(15 downto 0); - end record; - - type mem_ctrl_type_in is record - rd_addr : unsigned(BW_ADDRESS-1 downto 0); - rd_en : std_logic; - wr_addr : unsigned(BW_ADDRESS-1 downto 0); - wr_en : std_logic; - data_in : std_logic_vector(23 downto 0); - end record; - - type mem_ctrl_type_out is record - data_out : std_logic_vector(23 downto 0); - data_out_valid : std_logic; - end record; - - type memory_type is (X_MEM, Y_MEM, P_MEM); - --------------- - -- STACK TYPES - --------------- - type stack_array_type is array(0 to 15) of std_logic_vector(BW_ADDRESS-1 downto 0); - - type push_stack_content_type is (PC, PC_AND_SR, LA_AND_LC); - - type push_stack_type is record - valid : std_logic; - pc : unsigned(BW_ADDRESS-1 downto 0); - content : push_stack_content_type; - end record; - - --- type pop_stack_type is std_logic; - type pop_stack_type is record - valid : std_logic; --- content : pop_stack_content_type; - end record; - -end package types_pkg; diff --git a/vhdl/dsp56k/testbench/tb_pipeline.vhd b/vhdl/dsp56k/testbench/tb_pipeline.vhd deleted file mode 100644 index e4ed829..0000000 --- a/vhdl/dsp56k/testbench/tb_pipeline.vhd +++ /dev/null @@ -1,49 +0,0 @@ -library ieee; -use ieee.std_logic_1164.all; -use ieee.numeric_std.all; -library work; -use work.parameter_pkg.all; -use work.types_pkg.all; - -entity tb_pipeline is generic ( - clk_period : time := 10 ns - ); - - -end entity tb_pipeline; - - -architecture uut of tb_pipeline is - - signal clk : std_logic := '0'; - signal rst : std_logic; - - component pipeline is port( - clk, rst : std_logic - ); - end component pipeline; - -begin - - - - uut: pipeline port map( - clk => clk, - rst => rst - ); - - clk_gen: process - begin - wait for clk_period/2; - clk <= not clk; - end process clk_gen; - - rst_gen : process - begin - rst <= '1'; - wait for 10 * clk_period; - rst <= '0'; - wait; - end process rst_gen; - -end architecture uut;