From f16479b66808d7d2a5d29787c4271381cb66f6eb Mon Sep 17 00:00:00 2001 From: J Date: Thu, 26 Sep 2019 21:15:44 -0400 Subject: [PATCH] some more instruction colation --- decode_body.vhd | 8 +- decode_table_simple.vhd | 272 +-- ram.img | Bin 7004 -> 18912 bytes ram_init.vhd | 3455 ++++++++++++++++++++++++++++++++++++--- simple_ram.vhd | 2 +- testrom/Makefile | 4 +- testrom/startup/sh32.x | 4 +- 7 files changed, 3278 insertions(+), 467 deletions(-) diff --git a/decode_body.vhd b/decode_body.vhd index e37f6fa..fc6c9c5 100644 --- a/decode_body.vhd +++ b/decode_body.vhd @@ -39,10 +39,10 @@ package body decode_pack is ret.fmt := MX; end if; - ret.rm := code(11 downto 8); - ret.rn := code(7 downto 4); - if code(15 downto 10) = "100000" then ret.rm := code(7 downto 4); end if; - if ret.fmt = MX then ret.rn := code(11 downto 8); end if; + ret.rn := code(11 downto 8); + ret.rm := code(7 downto 4); + if code(15 downto 10) = "100000" then ret.rm := code(11 downto 8); end if; + if ret.fmt = MX then ret.rn := code( 7 downto 4); end if; if ret.fmt = I12 then ret.imm := code(11 downto 0); elsif ret.fmt = N8 or ret.fmt = X8 then ret.imm := x"0" & code( 7 downto 0); diff --git a/decode_table_simple.vhd b/decode_table_simple.vhd index e5b0061..2cfa880 100644 --- a/decode_table_simple.vhd +++ b/decode_table_simple.vhd @@ -111,30 +111,72 @@ begin imm_enum <= IMM_ZERO; mac_busy <= NOT_BUSY; - if fmt.fmt = NMX and fmt.ln = "0000" and fmt.op(0) = '1' and cond(1 downto 0) /= "11" then +-- if fmt.fmt = NMX and +-- ((fmt.ln = "0000" and fmt.op(0) = '1') or +-- ((fmt.ln = "0010" or fmt.ln = "0110") and fmt.op(1 downto 0) = "00")) + if (std_match(cond, "00000---------1--") or std_match(cond, "00-10--------00--")) + and cond(1 downto 0) /= "11" then + -- MOV.BWL Rm, @Rn [2nm0] + -- MOV.BWL @Rm, Rn [6nm0] -- MOV.BWL Rm, @(R0, Rn) [0nm4] -- MOV.BWL @(R0, Rm), Rn [0nmC] -- (R0 +Rm)->sign extension -> Rn -- X = Rm ex.xbus_sel <= SEL_REG; - if cond(3) = '1' then ex.regnum_x <= '0' & fmt.rn; else - ex.regnum_x <= '0' & fmt.rm; end if; + if (cond(3) or cond(14)) = '1' then ex.regnum_x <= '0' & fmt.rm; else + ex.regnum_x <= '0' & fmt.rn; end if; -- Y = Rm ex.ybus_sel <= SEL_REG; - ex.regnum_y <= '0' & fmt.rn; + ex.regnum_y <= '0' & fmt.rm; -- Z = X + R0 - ex.aluiny_sel <= SEL_R0; + if cond(13) = '1' then ex.aluiny_sel <= SEL_IMM; ex.arith_func <= SUB; + else ex.aluiny_sel <= SEL_R0; end if; ex_stall.zbus_sel <= SEL_ARITH; - ex.arith_func <= ADD; - -- W = MEM[Z] byte + if cond(1 downto 0) = "00" then imm_enum <= IMM_P1; + elsif cond(1 downto 0) = "01" then imm_enum <= IMM_P2; + else imm_enum <= IMM_P4; end if; + -- ex.arith_func <= ADD; + -- W = MEM[Z] or MEM[X] ex_stall.ma_issue <= '1'; - ex.ma_wr <= not cond(3); - ex_stall.mem_addr_sel <= SEL_ZBUS; + ex.ma_wr <= not (cond(3) or cond(14)); + if cond(13) = '0' then ex_stall.mem_addr_sel <= SEL_ZBUS; else + ex_stall.mem_addr_sel <= SEL_XBUS; end if; ex_stall.mem_wdata_sel <= SEL_YBUS; ex.mem_size <= fmt.sz; -- Rn = W - if cond(3) = '1' then wb_stall.wrreg_w <= '1'; end if; - wb.regnum_w <= '0' & fmt.rm; + if (cond(2) and cond(13)) = '1' then ex_stall.wrreg_z <= '1'; + elsif (cond(3) or cond(14)) = '1' then wb_stall.wrreg_w <= '1'; end if; + ex.regnum_z <= '0' & fmt.rn; + wb.regnum_w <= '0' & fmt.rn; + id.incpc <= '1'; + dispatch <= '1'; + id.if_issue <= '1'; + + elsif std_match(cond, "00010--------01--") and cond(1 downto 0) /= "11" then + -- MOV.B Rm,@-Rn [2nm4] + -- Rn - 1 -> Rn, Rm -> (Rn) + -- X = Rn + ex.xbus_sel <= SEL_REG; + ex.regnum_x <= '0' & op.code(11 downto 8); + -- Y = Rm + ex.ybus_sel <= SEL_REG; + ex.regnum_y <= '0' & op.code(7 downto 4); + -- Z = X - 1 + ex.aluiny_sel <= SEL_IMM; + ex_stall.zbus_sel <= SEL_ARITH; + ex.arith_func <= SUB; + if cond(1 downto 0) = "00" then imm_enum <= IMM_P1; + elsif cond(1 downto 0) = "01" then imm_enum <= IMM_P2; + else imm_enum <= IMM_P4; end if; + -- MEM[Z] = Y byte + ex_stall.ma_issue <= '1'; + ex.ma_wr <= '1'; + ex_stall.mem_addr_sel <= SEL_ZBUS; + ex_stall.mem_wdata_sel <= SEL_YBUS; + ex.mem_size <= fmt.sz; + -- Rn = Z + ex_stall.wrreg_z <= '1'; + ex.regnum_z <= '0' & op.code(11 downto 8); id.incpc <= '1'; dispatch <= '1'; id.if_issue <= '1'; @@ -2087,134 +2129,6 @@ begin dispatch <= '1'; id.if_issue <= '1'; - elsif std_match(cond, "00010--------0000") then - -- MOV.B Rm, @Rn [2nm0] - -- Rm -> (Rn) - -- X = Rn - ex.xbus_sel <= SEL_REG; - ex.regnum_x <= '0' & op.code(11 downto 8); - -- Y = Rm - ex.ybus_sel <= SEL_REG; - ex.regnum_y <= '0' & op.code(7 downto 4); - -- Z = X + 0 - ex.aluiny_sel <= SEL_IMM; - ex_stall.zbus_sel <= SEL_ARITH; - ex.arith_func <= ADD; - imm_enum <= IMM_ZERO; - -- MEM[Z] = Y byte - ex_stall.ma_issue <= '1'; - ex.ma_wr <= '1'; - ex_stall.mem_addr_sel <= SEL_ZBUS; - ex_stall.mem_wdata_sel <= SEL_YBUS; - ex.mem_size <= BYTE; - id.incpc <= '1'; - dispatch <= '1'; - id.if_issue <= '1'; - - elsif std_match(cond, "00010--------0001") then - -- MOV.W Rm, @Rn [2nm1] - -- Rm -> (Rn) - -- X = Rn - ex.xbus_sel <= SEL_REG; - ex.regnum_x <= '0' & op.code(11 downto 8); - -- Y = Rm - ex.ybus_sel <= SEL_REG; - ex.regnum_y <= '0' & op.code(7 downto 4); - -- Z = X + 0 - ex.aluiny_sel <= SEL_IMM; - ex_stall.zbus_sel <= SEL_ARITH; - ex.arith_func <= ADD; - imm_enum <= IMM_ZERO; - -- MEM[Z] = Y word - ex_stall.ma_issue <= '1'; - ex.ma_wr <= '1'; - ex_stall.mem_addr_sel <= SEL_ZBUS; - ex_stall.mem_wdata_sel <= SEL_YBUS; - ex.mem_size <= WORD; - id.incpc <= '1'; - dispatch <= '1'; - id.if_issue <= '1'; - - elsif std_match(cond, "00010--------0010") then - -- MOV.L Rm, @Rn [2nm2] - -- Rm -> (Rn) - -- X = Rn - ex.xbus_sel <= SEL_REG; - ex.regnum_x <= '0' & op.code(11 downto 8); - -- Y = Rm - ex.ybus_sel <= SEL_REG; - ex.regnum_y <= '0' & op.code(7 downto 4); - -- Z = X + 0 - ex.aluiny_sel <= SEL_IMM; - ex_stall.zbus_sel <= SEL_ARITH; - ex.arith_func <= ADD; - imm_enum <= IMM_ZERO; - -- MEM[Z] = Y long - ex_stall.ma_issue <= '1'; - ex.ma_wr <= '1'; - ex_stall.mem_addr_sel <= SEL_ZBUS; - ex_stall.mem_wdata_sel <= SEL_YBUS; - ex.mem_size <= LONG; - id.incpc <= '1'; - dispatch <= '1'; - id.if_issue <= '1'; - - elsif std_match(cond, "00110--------0000") then - -- MOV.B @Rm, Rn [6nm0] - -- (Rm) -> sign extension -> Rn - -- Y = Rm - ex.ybus_sel <= SEL_REG; - ex.regnum_y <= '0' & op.code(7 downto 4); - ex_stall.zbus_sel <= SEL_YBUS; - -- W = MEM[Z] byte - ex_stall.ma_issue <= '1'; - ex.ma_wr <= '0'; - ex_stall.mem_addr_sel <= SEL_ZBUS; - ex.mem_size <= BYTE; - -- Rn = W - wb_stall.wrreg_w <= '1'; - wb.regnum_w <= '0' & op.code(11 downto 8); - id.incpc <= '1'; - dispatch <= '1'; - id.if_issue <= '1'; - - elsif std_match(cond, "00110--------0001") then - -- MOV.W @Rm, Rn [6nm1] - -- (Rm) -> sign extension -> Rn - -- Y = Rm - ex.ybus_sel <= SEL_REG; - ex.regnum_y <= '0' & op.code(7 downto 4); - ex_stall.zbus_sel <= SEL_YBUS; - -- W = MEM[Z] word - ex_stall.ma_issue <= '1'; - ex.ma_wr <= '0'; - ex_stall.mem_addr_sel <= SEL_ZBUS; - ex.mem_size <= WORD; - -- Rn = W - wb_stall.wrreg_w <= '1'; - wb.regnum_w <= '0' & op.code(11 downto 8); - id.incpc <= '1'; - dispatch <= '1'; - id.if_issue <= '1'; - - elsif std_match(cond, "00110--------0010") then - -- MOV.L @Rm, Rn [6nm2] - -- (Rm)-> Rn - -- Y = Rm - ex.ybus_sel <= SEL_REG; - ex.regnum_y <= '0' & op.code(7 downto 4); - ex_stall.zbus_sel <= SEL_YBUS; - -- W = MEM[Z] long - ex_stall.ma_issue <= '1'; - ex.ma_wr <= '0'; - ex_stall.mem_addr_sel <= SEL_ZBUS; - ex.mem_size <= LONG; - -- Rn = W - wb_stall.wrreg_w <= '1'; - wb.regnum_w <= '0' & op.code(11 downto 8); - id.incpc <= '1'; - dispatch <= '1'; - id.if_issue <= '1'; elsif std_match(cond, "00000--------1111") then -- MAC.L @Rm+, @Rn+ [0nmF] @@ -2445,86 +2359,6 @@ begin when others => end case; - elsif std_match(cond, "00010--------0100") then - -- MOV.B Rm,@-Rn [2nm4] - -- Rn - 1 -> Rn, Rm -> (Rn) - -- X = Rn - ex.xbus_sel <= SEL_REG; - ex.regnum_x <= '0' & op.code(11 downto 8); - -- Y = Rm - ex.ybus_sel <= SEL_REG; - ex.regnum_y <= '0' & op.code(7 downto 4); - -- Z = X - 1 - ex.aluiny_sel <= SEL_IMM; - ex_stall.zbus_sel <= SEL_ARITH; - ex.arith_func <= SUB; - imm_enum <= IMM_P1; - -- MEM[Z] = Y byte - ex_stall.ma_issue <= '1'; - ex.ma_wr <= '1'; - ex_stall.mem_addr_sel <= SEL_ZBUS; - ex_stall.mem_wdata_sel <= SEL_YBUS; - ex.mem_size <= BYTE; - -- Rn = Z - ex_stall.wrreg_z <= '1'; - ex.regnum_z <= '0' & op.code(11 downto 8); - id.incpc <= '1'; - dispatch <= '1'; - id.if_issue <= '1'; - - elsif std_match(cond, "00010--------0101") then - -- MOV.W Rm,@-Rn [2nm5] - -- Rn - 2 -> Rn, Rm -> (Rn) - -- X = Rn - ex.xbus_sel <= SEL_REG; - ex.regnum_x <= '0' & op.code(11 downto 8); - -- Y = Rm - ex.ybus_sel <= SEL_REG; - ex.regnum_y <= '0' & op.code(7 downto 4); - -- Z = X - 2 - ex.aluiny_sel <= SEL_IMM; - ex_stall.zbus_sel <= SEL_ARITH; - ex.arith_func <= SUB; - imm_enum <= IMM_P2; - -- MEM[Z] = Y word - ex_stall.ma_issue <= '1'; - ex.ma_wr <= '1'; - ex_stall.mem_addr_sel <= SEL_ZBUS; - ex_stall.mem_wdata_sel <= SEL_YBUS; - ex.mem_size <= WORD; - -- Rn = Z - ex_stall.wrreg_z <= '1'; - ex.regnum_z <= '0' & op.code(11 downto 8); - id.incpc <= '1'; - dispatch <= '1'; - id.if_issue <= '1'; - - elsif std_match(cond, "00010--------0110") then - -- MOV.L Rm,@-Rn [2nm6] - -- Rn - 4 -> Rn, Rm -> (Rn) - -- X = Rn - ex.xbus_sel <= SEL_REG; - ex.regnum_x <= '0' & op.code(11 downto 8); - -- Y = Rm - ex.ybus_sel <= SEL_REG; - ex.regnum_y <= '0' & op.code(7 downto 4); - -- Z = X - 4 - ex.aluiny_sel <= SEL_IMM; - ex_stall.zbus_sel <= SEL_ARITH; - ex.arith_func <= SUB; - imm_enum <= IMM_P4; - -- MEM[Z] = Y long - ex_stall.ma_issue <= '1'; - ex.ma_wr <= '1'; - ex_stall.mem_addr_sel <= SEL_ZBUS; - ex_stall.mem_wdata_sel <= SEL_YBUS; - ex.mem_size <= LONG; - -- Rn = Z - ex_stall.wrreg_z <= '1'; - ex.regnum_z <= '0' & op.code(11 downto 8); - id.incpc <= '1'; - dispatch <= '1'; - id.if_issue <= '1'; elsif std_match(cond, "010000100--------") then diff --git a/ram.img b/ram.img index 06d7f8fe528daba79f686893f531d6be7e261b5f..c8bef62247b526304984b03ca8d59ca1e6642a1b 100755 GIT binary patch literal 18912 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 L4`rMpeIfGiv<0b& delta 1224 zcmb`FUr1AN6vxl+w?F9I+})ktt6s@%E*%y$r^y^rEB}qC6x>4(dk|4Ek&++?5hU;- zs|WGdV-G7LghmPTVGmM+Bzg(9@}Y-4h(z=du}86ieSc03dJAOx@H^++bHDd{&$-)z z6}lFPn4PGp^!Ic$5ZU*Lj?RO)4Y|Ztz9wrY!h#gq0H49H6B7Lob3XfCu0F4MIaN`m z{N-x$s+Z@KDDu3Lb9uSA$3iytl*kgmkVq6+>*+wwG~|;lLoJ6lk`k3so?SX~AVlt% z=;3pmt%?kP&9$hQGDSF>5id-4s@V(?-y+hYP+Sy#^PZKh5-EP+w>&()TKiLWq&F2DR2tVQ<7URgWP zz~Z$`S;O%_T9CTwSz9&p9lM-DPrR(HDTr&z+Lk~%S#_OhvQNH=)Rz9_oE#Bhb_`nV zL`FsoJKl0*G_6$oSjb2c{U)L%@CXz^Ql9&09VJ>rjF8>~10M#2#+}nvdC5qME$8Hw za_EmOu{?M6=lRjVrLrTEw~V=bfhF@7^T_#T?+$srM+=f_Ml#2uhYPAKh()E%+JFfd z39+t>SfY6UfUvs;SwO^HAGnegjp~X`$-epoH&l}n8MTWWSy5D{xjHKn?m25+Baxa& z7u=`VfRd%k)_0J*irOr|K-G^J&OA;GRzvQNAx;pv%-}IYIP`kKmY_mc%^@5L2gZ32OB`fS+EJ@17)5AUqJzE16li*AE*_F