X-Git-Url: http://wien.tomnetworks.com/gitweb/?a=blobdiff_plain;f=src%2Fparser.vhd;h=e9778da86dc854f58c84f4016e1727e92fa7f2e5;hb=83b5b662c8e556783f8c02088f8c72003e38ee24;hp=6e41837ade3e3eaf1783d3a84df288b6de2845e1;hpb=6744ad83ff2e2715a4775ee08594f47cf1633c2e;p=hwmod.git diff --git a/src/parser.vhd b/src/parser.vhd index 6e41837..e9778da 100644 --- a/src/parser.vhd +++ b/src/parser.vhd @@ -33,26 +33,42 @@ entity parser is end entity parser; architecture beh of parser is - type PARSER_STATE is (SIDLE, SREAD_CHAR1, SREAD_CHAR2, SWRITE_CHAR); + type PARSER_STATE is (SIDLE, SREAD_NEWNUMBER, SREAD_NEXTBYTE, + SREAD_CALCNUMBER1, SREAD_CALCNUMBER2, SCALC_1, SCALC_2, SWRITE_CHAR1, SWRITE_CHAR2, SDONE); signal state_int, state_next : PARSER_STATE; - signal z_int, z_next : csigned; + signal z_int, z_next, strich_int, strich_next, wtmp_int, wtmp_next : csigned; signal rbyte_int, rbyte_next : hbyte; signal p_write_int, p_write_next : hbyte; signal p_rget_int, p_rget_next : std_logic; signal p_wtake_int, p_wtake_next : std_logic; signal p_finished_int, p_finished_next : std_logic; + signal aktop_int, aktop_next : alu_ops; + signal opp_int, opp_next : alu_ops; + signal opcode_int, opcode_next : alu_ops; + signal op1_int, op1_next : csigned; + signal op2_int, op2_next : csigned; + signal do_calc_int, do_calc_next : std_logic; begin p_write <= p_write_int; p_rget <= p_rget_int; p_wtake <= p_wtake_int; p_finished <= p_finished_int; + opcode <= opcode_int; + op1 <= op1_int; + op2 <= op2_int; + do_calc <= do_calc_int; + process(sys_clk, sys_res_n) begin if sys_res_n = '0' then state_int <= SIDLE; z_int <= (others => '0'); + strich_int <= (others => '0'); + wtmp_int <= (others => '0'); rbyte_int <= (others => '0'); + aktop_int <= ALU_NOP; + opp_int <= ALU_NOP; -- out ports p_rw <= '0'; p_spalte <= (others => '0'); @@ -60,80 +76,211 @@ begin p_write_int <= (others => '0'); p_wtake_int <= '0'; p_finished_int <= '0'; - opcode <= ALU_NOP; - op1 <= (others => '0'); - op2 <= (others => '0'); - do_calc <= '0'; + opcode_int <= ALU_NOP; + op1_int <= (others => '0'); + op2_int <= (others => '0'); + do_calc_int <= '0'; finished <= '0'; elsif rising_edge(sys_clk) then -- internal state_int <= state_next; z_int <= z_next; + strich_int <= strich_next; + wtmp_int <= wtmp_next; rbyte_int <= rbyte_next; + aktop_int <= aktop_next; + opp_int <= opp_next; -- out ports p_rget_int <= p_rget_next; p_write_int <= p_write_next; p_wtake_int <= p_wtake_next; p_finished_int <= p_finished_next; + opcode_int <= opcode_next; + op1_int <= op1_next; + op2_int <= op2_next; + do_calc_int <= do_calc_next; end if; end process; -- next state - process(state_int, do_it, p_rdone, p_wdone, p_read) + process(state_int, do_it, p_rdone, p_wdone, p_read, aktop_int, strich_int, + strich_next, calc_done, wtmp_int) begin state_next <= state_int; case state_int is when SIDLE => if do_it = '1' then - state_next <= SREAD_CHAR1; + state_next <= SREAD_NEWNUMBER; end if; - when SREAD_CHAR1 => + when SREAD_NEWNUMBER => + state_next <= SREAD_NEXTBYTE; + when SREAD_NEXTBYTE => if p_rdone = '1' then - state_next <= SREAD_CHAR2; + state_next <= SREAD_CALCNUMBER1; end if; - when SREAD_CHAR2 => - if p_wdone = '1' then - state_next <= SWRITE_CHAR; + when SREAD_CALCNUMBER1 => + state_next <= SREAD_CALCNUMBER2; + when SREAD_CALCNUMBER2 => + if aktop_int /= ALU_NOP then + state_next <= SCALC_1; + else + state_next <= SREAD_NEXTBYTE; end if; - when SWRITE_CHAR => - if rbyte_int = hbyte(to_unsigned(character'pos(character'val(0)), 8)) then - if do_it = '0' then - state_next <= SIDLE; - end if; + when SCALC_1 => + if calc_done = '1' then + state_next <= SCALC_2; + end if; + when SCALC_2 => + if aktop_int = ALU_DONE then + state_next <= SWRITE_CHAR1; else - state_next <= SREAD_CHAR1; + state_next <= SREAD_NEWNUMBER; + end if; + when SWRITE_CHAR1 => + if p_wdone = '1' then + if strich_int < 10 then + state_next <= SDONE; + else + state_next <= SWRITE_CHAR2; + end if; + end if; + when SWRITE_CHAR2 => + if p_wdone = '0' then + state_next <= SWRITE_CHAR1; + end if; + when SDONE => + if p_wdone = '0' and do_it = '0' then + state_next <= SIDLE; end if; end case; end process; - process(state_int, p_read, p_write_int, z_int, rbyte_int, p_rget_int) + -- out + process(state_int, p_read, p_write_int, z_int, rbyte_int, p_rget_int, + strich_int, aktop_int, opp_int, opcode_int, op1_int, op2_int, op3, + do_calc_int) + function hbyte2csigned (x : hbyte) return csigned is + variable y : csigned; + begin + case x is + when x"30" => y := to_signed(0, CBITS); + when x"31" => y := to_signed(1, CBITS); + when x"32" => y := to_signed(2, CBITS); + when x"33" => y := to_signed(3, CBITS); + when x"34" => y := to_signed(4, CBITS); + when x"35" => y := to_signed(5, CBITS); + when x"36" => y := to_signed(6, CBITS); + when x"37" => y := to_signed(7, CBITS); + when x"38" => y := to_signed(8, CBITS); + when x"39" => y := to_signed(9, CBITS); + when others => assert(false) report "hbyte2csigned: shouldn't happen"; + end case; + return y; + end function hbyte2csigned; + + function csigned2hbyte (x : csigned) return hbyte is + variable y : hbyte; + begin + case x is + when x"00000000" => y := x"30"; + when x"00000001" => y := x"31"; + when x"00000002" => y := x"32"; + when x"00000003" => y := x"33"; + when x"00000004" => y := x"34"; + when x"00000005" => y := x"35"; + when x"00000006" => y := x"36"; + when x"00000007" => y := x"37"; + when x"00000008" => y := x"38"; + when x"00000009" => y := x"39"; + when others => assert(false) report "csigned2hbyte: shouldn't happen"; + end case; + return y; + end function csigned2hbyte; + + variable multmp : signed(((2*CBITS)-1) downto 0); + variable tmp : csigned; begin -- internal z_next <= z_int; + strich_next <= strich_int; + wtmp_next <= wtmp_int; rbyte_next <= rbyte_int; + aktop_next <= aktop_int; + opp_next <= opp_int; -- signals p_rget_next <= '0'; p_write_next <= p_write_int; p_wtake_next <= '0'; p_finished_next <= '0'; + opcode_next <= opcode_int; + op1_next <= op1_int; + op2_next <= op2_int; + do_calc_next <= '0'; case state_int is when SIDLE => + strich_next <= (others => '0'); + opp_next <= ALU_NOP; + when SREAD_NEWNUMBER => z_next <= (others => '0'); rbyte_next <= (others => '0'); p_write_next <= (others => '0'); - when SREAD_CHAR1 => + aktop_next <= ALU_NOP; + when SREAD_NEXTBYTE => p_rget_next <= '1'; - p_write_next <= (others => '0'); - when SREAD_CHAR2 => - rbyte_next <= p_read; + when SREAD_CALCNUMBER1 => + case p_read is + -- '+' + when x"2B" => + aktop_next <= ALU_ADD; + + -- '\0' + when x"00" => + aktop_next <= ALU_DONE; + + when others => + -- TODO: check auf overflow + multmp := (z_int * 10) + hbyte2csigned(p_read); + z_next <= multmp((CBITS-1) downto 0); + end case; + when SREAD_CALCNUMBER2 => + null; + + when SCALC_1 => + case opp_int is + when ALU_NOP | ALU_ADD => + op1_next <= z_int; + case aktop_int is + when ALU_ADD | ALU_SUB | ALU_NOP | ALU_DONE => + opcode_next <= ALU_ADD; + op2_next <= strich_int; + when ALU_MUL | ALU_DIV => + opcode_next <= ALU_MUL; + op2_next <= strich_int; + when others => assert(false) report "SCALC_1/ALU_NOP: not implemented yet"; + end case; + do_calc_next <= '1'; + when others => assert(false) report "SCALC_1: not implemented yet"; + end case; + when SCALC_2 => + case opp_int is + when ALU_NOP | ALU_ADD => + strich_next <= op3; + when others => assert (false) report "SCALC_2: not implemented yet"; + end case; + opp_next <= aktop_int; + + when SWRITE_CHAR1 => p_wtake_next <= '1'; - p_write_next <= p_read; - when SWRITE_CHAR => - if rbyte_int = hbyte(to_unsigned(character'pos(character'val(0)), 8)) then - p_finished_next <= '1'; - end if; + tmp := strich_int mod 10; + p_write_next <= csigned2hbyte(tmp); + wtmp_next <= strich_int / 10; + when SWRITE_CHAR2 => + strich_next <= wtmp_int; + + when SDONE => + p_finished_next <= '1'; end case; end process; end architecture beh;