LIBRARY IEEE; USE IEEE.std_logic_1164.ALL; USE IEEE.std_arith.ALL; -- LIBRARY parwan_s; USE parwan_s.ALL; USE parwan_s.synthesis_parameters.ALL; USE parwan_s.synthesis_utilities.ALL; -- ENTITY quad_adrdcd IS GENERIC (addresses : twelve := "111111111100"); PORT (adbus : IN twelve; active : OUT std_logic; selects : OUT nibble); END quad_adrdcd; -- ARCHITECTURE behavioral OF quad_adrdcd IS BEGIN PROCESS (adbus) BEGIN IF TO_BITVECTOR(addresses AND adbus) = TO_BITVECTOR(addresses) THEN active <= '1'; CASE adbus (1 DOWNTO 0) IS WHEN "00" => selects <= "0001"; WHEN "01" => selects <= "0010"; WHEN "10" => selects <= "0100"; WHEN "11" => selects <= "1000"; WHEN OTHERS => selects <= "0000"; END CASE; ELSE active <= '0'; selects <= "0000"; END IF; END PROCESS; -- PROCESS (adbus) -- VARIABLE addr : twelve; -- BEGIN -- FOR i IN addr'RANGE LOOP -- IF adbus(i) = '1' THEN addr (i) := '1'; -- ELSE addr(i) := '0'; END IF; -- END LOOP; -- IF (addr AND addresses) = addresses THEN -- active <= '1'; -- selects (TO_INTEGER (NOT addresses AND addr)) <= '1'; -- ELSE -- active <= '0'; -- selects <= "0000"; -- END IF; -- END PROCESS; END behavioral; LIBRARY IEEE; USE IEEE.std_logic_1164.ALL; -- LIBRARY parwan_s; USE parwan_s.ALL; USE parwan_s.synthesis_parameters.ALL; USE parwan_s.synthesis_utilities.ALL; -- ENTITY arbitrator IS GENERIC (wait_states : natural_vector (3 DOWNTO 0) := (OTHERS => 1); clock_period : TIME := 1 US); PORT (read_request, write_request : IN nibble; grant : BUFFER nibble; clock, skip_wait : IN std_logic; memsel, rwbar, ready : OUT std_logic); END arbitrator; -- ARCHITECTURE behavioral OF arbitrator IS BEGIN -- Works with consecuitive requests wait_cycle: PROCESS BEGIN IF clock = '0' THEN WAIT FOR 20 NS; FOR i IN read_request'RANGE LOOP IF read_request(i) = '1' OR write_request(i) = '1' THEN grant <= "0000"; grant (i) <= '1'; memsel <= '1'; rwbar <= read_request (i); ready <= '0'; IF wait_states (i) /= 0 THEN FOR j IN 1 TO wait_states (i) LOOP EXIT WHEN skip_wait = '1'; WAIT FOR clock_period; END LOOP; END IF; ready <= '1'; EXIT; ELSE grant (i) <= '0'; memsel <= '0'; END IF; END LOOP; END IF; WAIT ON clock; END PROCESS wait_cycle; END behavioral; -- LIBRARY IEEE; USE IEEE.std_logic_1164.ALL; USE IEEE.std_arith.ALL; -- LIBRARY parwan_s; USE parwan_s.ALL; USE parwan_s.synthesis_parameters.ALL; USE parwan_s.synthesis_utilities.ALL; -- ENTITY cache_system IS PORT (clk : IN std_logic; -- memory signals read_mem, write_mem : OUT std_logic; grant_mem, ready_mem : IN std_logic; mem_databus : INOUT byte := "ZZZZZZZZ"; mem_adbus : INOUT twelve := "ZZZZZZZZZZZZ"; -- cpu signals read, write : IN std_logic; grant, ready : OUT std_logic; databus : INOUT byte := "ZZZZZZZZ"; adbus : INOUT twelve := "ZZZZZZZZZZZZ" ); END cache_system; -- ARCHITECTURE control_and_memory OF cache_system IS SUBTYPE ways IS INTEGER RANGE 0 TO 1; SUBTYPE sets IS INTEGER RANGE 0 TO 31; TYPE line IS ARRAY (0 TO 0) OF byte; SUBTYPE tags IS std_logic_vector (6 DOWNTO 0); TYPE lru_type IS ARRAY (sets) OF ways; TYPE entry IS RECORD valid : BOOLEAN; tag : tags; data : line; END RECORD; TYPE each_cache IS ARRAY (sets) OF entry; TYPE cache_type IS ARRAY (ways) OF each_cache; SIGNAL cache : cache_type; SIGNAL lru : lru_type; BEGIN PROCESS VARIABLE s : sets; VARIABLE hit : BOOLEAN; VARIABLE w, free : ways; TYPE ww IS ARRAY(ways) OF ways; CONSTANT nw : ww := (1, 0); ALIAS set_value : std_logic_vector (4 DOWNTO 0) IS adbus (4 DOWNTO 0); ALIAS tag_value : tags IS adbus (11 DOWNTO 5); BEGIN grant <= '1'; ready <= '0'; WAIT UNTIL clk = '0'; s := TO_INTEGER (set_value); hit := FALSE; FOR i IN ways LOOP IF cache(i)(s).tag = tag_value AND cache(i)(s).valid THEN hit := TRUE; w := i; END IF; END LOOP; IF hit THEN ready <= '1'; lru (s) <= nw (w); IF read = '1' THEN databus <= cache(w)(s).data(0); WAIT UNTIL read = '0'; databus <= "ZZZZZZZZ"; ELSIF write = '1' THEN cache(w)(s).data(0) <= databus; cache(w)(s).valid <= TRUE; write_mem <= '1'; WAIT UNTIL grant_mem = '1'; mem_databus <= databus; mem_adbus <= adbus; WAIT UNTIL ready_mem = '1'; mem_databus <= "ZZZZZZZZ"; mem_adbus <= "ZZZZZZZZZZZZ"; write_mem <= '0'; ready <= '1'; WAIT UNTIL write = '0'; END IF; ready <= '0'; ELSE free := lru (s); lru (s) <= nw (lru (s)); IF write = '1' THEN cache(free)(s).tag <= tag_value; cache(free)(s).data(0) <= databus; cache(free)(s).valid <= TRUE; write_mem <= '1'; WAIT UNTIL grant_mem = '1'; mem_databus <= databus; mem_adbus <= adbus; WAIT UNTIL ready_mem = '1'; mem_databus <= "ZZZZZZZZ"; mem_adbus <= "ZZZZZZZZZZZZ"; write_mem <= '0'; ready <= '1'; WAIT UNTIL write = '0'; ready <= '0'; ELSIF read = '1' THEN read_mem <= '1'; WAIT UNTIL grant_mem = '1'; mem_adbus <= adbus; WAIT UNTIL ready_mem = '1'; cache(free)(s).tag <= tag_value; cache(free)(s).data(0) <= mem_databus; cache(free)(s).valid <= TRUE; databus <= mem_databus; mem_adbus <= "ZZZZZZZZZZZZ"; read_mem <= '0'; ready <= '1'; WAIT UNTIL read = '0'; ready <= '0'; END IF; END IF; WAIT UNTIL (read OR write) = '1'; END PROCESS; END control_and_memory; LIBRARY IEEE; USE IEEE.std_logic_1164.ALL; USE IEEE.std_arith.ALL; -- LIBRARY parwan_s; USE parwan_s.ALL; USE parwan_s.synthesis_parameters.ALL; USE parwan_s.synthesis_utilities.ALL; -- ENTITY dma_controller IS PORT (clk : IN std_logic; -- memory signals read_mem, write_mem : OUT std_logic := '0'; databus : INOUT byte := "ZZZZZZZZ"; adbus : INOUT twelve := "ZZZZZZZZZZZZ"; ready, grant : IN std_logic; -- cpu signals select_reg : IN nibble; status_rd, status_wr : IN std_logic; --device signals error1, error2, dev_rdy : IN std_logic; dev_rcv : OUT std_logic; dev_data : IN byte ); END dma_controller; -- ARCHITECTURE behavioral OF dma_controller IS SIGNAL done : std_logic := '0'; TYPE r4 IS ARRAY (0 TO 3) OF byte; SIGNAL rfile : r4 REGISTER := (OTHERS => zero_8); ALIAS go : std_logic IS rfile(3)(0); ALIAS rd : std_logic IS rfile(3)(1); ALIAS wr : std_logic IS rfile(3)(2); ALIAS ie : std_logic IS rfile(3)(3); BEGIN get_put : PROCESS VARIABLE buff : byte := zero_8; VARIABLE pntr : twelve; VARIABLE numb : byte; BEGIN WAIT UNTIL go = '1'; done <= '0'; numb := rfile(2); pntr := rfile(1)(3 DOWNTO 0) & rfile(0); IF wr = '1' THEN writing : WHILE TO_INTEGER(numb) > 0 LOOP numb := numb - 1; -- get data IF dev_rdy /= '1' THEN WAIT UNTIL dev_rdy = '1'; END IF; buff := dev_data; WAIT UNTIL clk = '1'; dev_rcv <= '1'; WAIT UNTIL clk = '0'; dev_rcv <= '0'; -- write to mem write_mem <= '1'; WAIT UNTIL grant = '1'; databus <= buff; adbus <= pntr; pntr := pntr + 1; WAIT UNTIL ready = '1'; databus <= "ZZZZZZZZ"; adbus <= "ZZZZZZZZZZZZ"; write_mem <= '0'; END LOOP writing; done <= '1'; END IF; END PROCESS get_put; -- cpu_direct : FOR i IN 0 TO 3 GENERATE databus <= rfile(i) WHEN select_reg(i) = '1' AND status_rd = '1' ELSE "ZZZZZZZZ"; r0to3 : BLOCK ((clk'EVENT AND clk = '0') AND select_reg(i) = '1' AND status_wr = '1') BEGIN rfile (i) <= GUARDED databus; END BLOCK; END GENERATE cpu_direct; r3 : BLOCK ((clk'EVENT AND clk = '0') AND done = '1') BEGIN rfile (3)(7 DOWNTO 4) <= GUARDED ('1', ie, error2, error1); END BLOCK; END behavioral; LIBRARY IEEE; USE IEEE.std_logic_1164.ALL; USE IEEE.std_arith.ALL; -- LIBRARY parwan_s; USE parwan_s.ALL; USE parwan_s.synthesis_parameters.ALL; USE parwan_s.synthesis_utilities.ALL; -- ENTITY dma_serial_device IS PORT (clk : IN std_logic; -- memory signals read_mem, write_mem : OUT std_logic := '0'; databus : INOUT byte := "ZZZZZZZZ"; adbus : INOUT twelve; ready, grant : IN std_logic; status_rd, status_wr : IN std_logic; status_sel : OUT std_logic; serial_in : IN std_logic); END dma_serial_device; -- ARCHITECTURE structural OF dma_serial_device IS COMPONENT dma IS PORT (clk : IN std_logic; read_mem, write_mem : OUT std_logic; databus : INOUT byte := "ZZZZZZZZ"; adbus : INOUT twelve; ready, grant : IN std_logic; select_reg : IN nibble; status_rd, status_wr : IN std_logic; error1, error2, dev_rdy : IN std_logic; dev_rcv : OUT std_logic; dev_data : IN byte ); END COMPONENT dma; FOR c1 : dma USE ENTITY parwan_s.dma_controller(behavioral); COMPONENT dcd IS GENERIC (addresses : twelve := "1111111111XX"); PORT (adbus : IN twelve; active : OUT std_logic; selects : OUT nibble); END COMPONENT dcd; FOR c2 : dcd USE ENTITY parwan_s.quad_adrdcd(behavioral); COMPONENT s2p IS GENERIC (bps : INTEGER := 9600); PORT (serial, received : IN std_logic; dataready : BUFFER std_logic; overrun, frame_error : OUT std_logic; parallel_out : BUFFER std_logic_vector (7 DOWNTO 0)); END COMPONENT s2p; FOR c3 : s2p USE ENTITY parwan_s.serial2parallel(waiting); SIGNAL s2p_rdy, s2p_rcv, s2p_er1, s2p_er2 : std_logic; SIGNAL s2p_par : byte; SIGNAL cpu_mem_data : byte; SIGNAL cpu_mem_addr : twelve; SIGNAL select_reg : nibble; BEGIN c1 : dma PORT MAP (clk, read_mem, write_mem, databus, adbus, ready, grant, select_reg, status_rd, status_wr, s2p_er1, s2p_er2, s2p_rdy, s2p_rcv, s2p_par); c2 : dcd PORT MAP (adbus, status_sel, select_reg); c3 : s2p PORT MAP (serial_in, s2p_rcv, s2p_rdy, s2p_er1, s2p_er2, s2p_par); END structural; LIBRARY IEEE; USE IEEE.std_logic_1164.ALL; USE IEEE.std_arith.ALL; -- LIBRARY parwan_s; USE parwan_s.ALL; USE parwan_s.synthesis_parameters.ALL; USE parwan_s.synthesis_utilities.ALL; -- ENTITY parwan_memory IS PORT (cs : IN std_logic; rwbar : IN std_logic; databus : INOUT byte := "ZZZZZZZZ"; adbus : IN twelve ); END parwan_memory; -- ARCHITECTURE behavioral OF parwan_memory IS TYPE byte_memory IS ARRAY ( INTEGER RANGE <> ) OF std_logic_vector ( 7 DOWNTO 0 ); BEGIN mem : PROCESS VARIABLE memory : byte_memory ( 0 TO 63 ) := (00 => "00000000", 01 => "00111000", 02 => "10100000", 03 => "00111001", --00: lda 56, sta 57 04 => "00100000", 05 => "00111010", 06 => "01000000", 07 => "00111011", --04: and 58, add 59 08 => "10000000", 09 => "00010100", --08: jmp 20, 20 => "00000000", 21 => "00111100", 22 => "10101111", 23 => "11111100", --20: lda 60, sta DMA 0 24 => "00000000", 25 => "00111101", 26 => "10101111", 27 => "11111101", --24: lda 61, sta DMA 1 28 => "00000000", 29 => "00111110", 30 => "10101111", 31 => "11111110", --28: lda 62, sta DMA 2 32 => "00000000", 33 => "00111111", 34 => "10101111", 35 => "11111111", --32: lda 63, sta DMA 3 36 => "10000000", 37 => "00101000", 38 => "11100000", 39 => "11100000", --36: jmp 40, nop, nop 40 => "10000000", 41 => "00100100", --40: jmp 36 56 => "01011100", 57 => "00000000", 58 => "01110000", 59 => "00010010", --56: (56, 57, 58, 59) 60 => "00110000", 61 => "00000000", 62 => "00000100", 63 => "00001101", --60: #44, #00, #4, #13 OTHERS => "00000000" ); VARIABLE ia : INTEGER; BEGIN databus <= "ZZZZZZZZ"; IF cs = '1' THEN WAIT FOR 70 NS; ia := TO_INTEGER (adbus); IF rwbar = '1' THEN IF ia >= 64 THEN databus <= "ZZZZZZZZ"; ELSE databus <= memory (ia); END IF; ELSIF rwbar = '0' THEN IF ia < 64 THEN memory (ia) := databus; END IF; END IF; END IF; WAIT ON cs, adbus; WAIT FOR 50 NS; END PROCESS mem; END behavioral; LIBRARY IEEE; USE IEEE.std_logic_1164.ALL; -- LIBRARY parwan_s; USE parwan_s.ALL; USE parwan_s.synthesis_parameters.ALL; USE parwan_s.synthesis_utilities.ALL; -- ENTITY parwan_system IS PORT (clk : IN std_logic; interrupt : IN std_logic; mem_cs, mem_rw : OUT std_logic; databus : INOUT byte := "ZZZZZZZZ"; adbus : OUT twelve; halted : OUT std_logic := '0'; ready, grant : IN std_logic ); END parwan_system; -- ARCHITECTURE wiring OF parwan_system IS COMPONENT parwan PORT (clk : IN std_logic; interrupt : IN std_logic; read_mem, write_mem : OUT std_logic; databus : INOUT byte; adbus : OUT twelve; halted : OUT std_logic := '0'; ready, grant : IN std_logic := '1' ); END COMPONENT; FOR cpu : parwan USE ENTITY parwan_s.par_central_processing_unit(dataflow_synthesizable); COMPONENT serial IS PORT (clk : IN std_logic; read_mem, write_mem : OUT std_logic; databus : INOUT byte := "ZZZZZZZZ"; adbus : INOUT twelve; ready, grant : IN std_logic; status_rd, status_wr : IN std_logic; status_sel : OUT std_logic; serial_in : IN std_logic ); END COMPONENT; FOR dev : serial USE ENTITY WORK.dma_serial_device(structural); COMPONENT arbitr GENERIC (wait_states : natural_vector (3 DOWNTO 0); clock_period : TIME); PORT (read_request, write_request : IN nibble; grant : BUFFER nibble; clock, skip_wait : IN std_logic; memsel, rwbar, ready : OUT std_logic ); END COMPONENT; FOR arb : arbitr USE ENTITY parwan_s.arbitrator(behavioral); SIGNAL clock, interrupt, halted : std_logic := '0'; SIGNAL skip_wait, cs, rwbar, ready : std_logic := '0'; SIGNAL data : byte := "ZZZZZZZZ"; SIGNAL address : twelve; SIGNAL rd_req, wr_req, grant_mem : nibble := "0000"; CONSTANT duty : TIME := 0.5 US; CONSTANT period : TIME := duty * 2; CONSTANT wait_state : INTEGER := 3; BEGIN int : interrupt <= '1', '0' AFTER 4500 NS; clk : clock <= NOT clock AFTER duty WHEN halted = '0' ELSE clock; arb : arbitr GENERIC MAP ((OTHERS => 2), period) PORT MAP (rd_req, wr_req, grant_mem, clock, skip_wait, cs, rwbar, ready); dev : serial PORT MAP (clock, rd_req(0), wr_req(0), data, address, ready, grant_mem(0), rd_req(1), wr_req(1), skip_wait, serial_in); cpu : parwan PORT MAP (clock, interrupt, rd_req(1), wr_req(1), data, address, halted, grant_mem(1)); END synthesizable; LIBRARY IEEE; USE IEEE.std_logic_1164.ALL; USE IEEE.std_arith.ALL; -- ENTITY serial2parallel IS GENERIC (bps : INTEGER); PORT (serial, received : IN std_logic; dataready : BUFFER std_logic; overrun, frame_error : OUT std_logic; parallel_out : BUFFER std_logic_vector (7 DOWNTO 0)); END serial2parallel; -- ARCHITECTURE waiting OF serial2parallel IS BEGIN collect : PROCESS VARIABLE buff : std_logic_vector (7 DOWNTO 0); CONSTANT half_bit : TIME := (1000000.0/REAL(bps))/2.0 * 1 US; CONSTANT full_bit : TIME := (1000000.0/REAL(bps)) * 1 US; BEGIN WAIT UNTIL serial = '0'; WAIT FOR half_bit; FOR count IN 0 TO 7 LOOP WAIT FOR full_bit; buff (count) := serial; END LOOP; WAIT FOR full_bit; IF serial = '0' THEN frame_error <= '1'; WAIT UNTIL serial = '1'; ELSE frame_error <= '0'; dataready <= '1'; parallel_out <= buff; WAIT UNTIL received = '1'; WAIT UNTIL received = '0'; dataready <= '0'; END IF; END PROCESS collect; -- too_fast : PROCESS BEGIN IF dataready = '1' THEN WAIT UNTIL serial = '0'; IF dataready = '1' THEN overrun <= '1'; END IF; ELSE overrun <= '0'; END IF; WAIT ON dataready; END PROCESS too_fast; END waiting; LIBRARY IEEE; USE IEEE.std_logic_1164.ALL; -- ENTITY serial_generator IS GENERIC (rate : INTEGER := 9600); PORT (serial_out : OUT std_logic); END serial_generator; -- ARCHITECTURE behavioral OF serial_generator IS CONSTANT fb : TIME := (1000000.0/REAL(rate)) * 1 US; BEGIN serial_out <= '1', '0' AFTER 2*fb, '1' AFTER 3*fb, '0' AFTER 4*fb, '1' AFTER 06*fb, '0' AFTER 09*fb, '1' AFTER 13*fb, '0' AFTER 15*fb, '1' AFTER 17*fb, '0' AFTER 20*fb, '1' AFTER 22*fb, '0' AFTER 25*fb, '1' AFTER 27*fb, '0' AFTER 30*fb, '1' AFTER 34*fb, '0' AFTER 35*fb, '1' AFTER 36*fb, '0' AFTER 39*fb, '1' AFTER 43*fb, '0' AFTER 45*fb, '1' AFTER 47*fb, '0' AFTER 50*fb, '1' AFTER 52*fb, '0' AFTER 55*fb, '1' AFTER 57*fb, '0' AFTER 60*fb, '1' AFTER 64*fb; END behavioral; LIBRARY IEEE; USE IEEE.std_logic_1164.ALL; -- LIBRARY parwan_s; USE parwan_s.synthesis_parameters.ALL; USE parwan_s.synthesis_utilities.ALL; USE parwan_s.alu_operations.ALL; -- ENTITY par_control_unit IS PORT (clk : IN std_logic; -- register control signals: load_ac, zero_ac, load_ir, increment_pc, load_page_pc, load_offset_pc, reset_pc, load_page_mar, load_offset_mar, load_sr, cm_carry_sr, -- bus connection control signals: pc_on_mar_page_bus, ir_on_mar_page_bus, pc_on_mar_offset_bus, dbus_on_mar_offset_bus, pc_offset_on_dbus, obus_on_dbus, databus_on_dbus, mar_on_adbus, dbus_on_databus, -- logic unit function control outputs: arith_shift_left, arith_shift_right : OUT std_logic; alu_code : OUT std_logic_vector (2 DOWNTO 0); -- inputs from the data section: ir_lines : IN byte; status : IN nibble; -- memory control and other external signals: read_mem, write_mem : OUT std_logic; interrupt : IN std_logic; halted : OUT std_logic := '0'; ready, grant : IN std_logic ); END par_control_unit; -- ARCHITECTURE dataflow_synthesizable OF par_control_unit IS TYPE cpu_states IS (initial, instr_fetch, do_one_bytes, opnd_fetch, do_indirect, do_two_bytes, do_jsr, continue_jsr, do_branch); SIGNAL present_state, next_state : cpu_states; BEGIN clocking : PROCESS (clk, interrupt) BEGIN IF (interrupt = '1') THEN present_state <= initial; ELSIF clk'EVENT AND clk = '0' THEN present_state <= next_state; END IF; END PROCESS clocking; -- sequencing : PROCESS ( present_state, ir_lines, status, interrupt, ready ) BEGIN load_ac <= '0'; zero_ac <= '0'; load_ir <= '0'; increment_pc <= '0'; load_page_pc <= '0'; load_offset_pc <= '0'; reset_pc <= '0'; load_page_mar <= '0'; load_offset_mar <= '0'; load_sr <= '0'; cm_carry_sr <= '0'; -- bus connection control signals: pc_on_mar_page_bus <= '0'; ir_on_mar_page_bus <= '0'; pc_on_mar_offset_bus <= '0'; dbus_on_mar_offset_bus <= '0'; pc_offset_on_dbus <= '0'; obus_on_dbus <= '0'; databus_on_dbus <= '0'; mar_on_adbus <= '0'; dbus_on_databus <= '0'; -- logic unit function control outputs: arith_shift_left <= '0'; arith_shift_right <= '0'; alu_code <= "000"; -- memory control and other external signals: read_mem <= '0'; write_mem <= '0'; halted <= '0'; CASE present_state IS WHEN initial => -------------------------------------------1 IF (interrupt = '1') THEN reset_pc <= '1'; next_state <= initial; ELSE -- pc to mar pc_on_mar_page_bus <= '1'; pc_on_mar_offset_bus <= '1'; load_page_mar <= '1'; load_offset_mar <= '1'; next_state <= instr_fetch; END IF; WHEN instr_fetch => ---------------------------------------2 -- read memory into ir read_mem <= '1'; IF grant = '1' THEN mar_on_adbus <= '1'; IF ready = '1' THEN databus_on_dbus <= '1'; alu_code <= a_input; load_ir <= '1'; increment_pc <= '1'; next_state <= do_one_bytes; ELSE next_state <= instr_fetch; END IF; ELSE next_state <= instr_fetch; END IF; WHEN do_one_bytes => --------------------------------------3 pc_on_mar_page_bus <= '1'; pc_on_mar_offset_bus <= '1'; load_page_mar <= '1'; load_offset_mar <= '1'; IF (ir_lines (7 DOWNTO 4) /= single_byte_instructions) THEN next_state <= opnd_fetch; ELSE CASE ir_lines (3 DOWNTO 0) IS WHEN cla => zero_ac <= '1'; load_ac <= '1'; WHEN cma => alu_code <= b_compl; load_sr <= '1'; load_ac <= '1'; WHEN cmc => cm_carry_sr <= '1'; WHEN asl => alu_code <= b_input; arith_shift_left <= '1'; load_sr <= '1'; load_ac <= '1'; WHEN asr => alu_code <= b_input; arith_shift_right <= '1'; load_sr <= '1'; load_ac <= '1'; WHEN hlt => halted <= '1'; WHEN OTHERS => NULL; END CASE; next_state <= instr_fetch; END IF; WHEN opnd_fetch => ----------------------------------------4 -- read memory into mar offset read_mem <= '1'; IF grant = '1' THEN mar_on_adbus <= '1'; IF ready = '1' THEN databus_on_dbus <= '1'; dbus_on_mar_offset_bus <= '1'; load_offset_mar <= '1'; IF ( ir_lines (7 DOWNTO 6) /= jsr_or_bra ) THEN ir_on_mar_page_bus <= '1'; load_page_mar <= '1'; IF ( ir_lines (4) = indirect ) THEN next_state <= do_indirect; ELSE next_state <= do_two_bytes; END IF; ELSE --jsr or bra, do not alter mar page IF ( ir_lines (5) = '0' ) THEN -- jsr next_state <= do_jsr; ELSE next_state <= do_branch; END IF; END IF; increment_pc <= '1'; ELSE next_state <= opnd_fetch; END IF; ELSE next_state <= opnd_fetch; END IF; WHEN do_indirect => ---------------------------------------5 -- read actual operand from memory into mar offset read_mem <= '1'; IF grant = '1' THEN mar_on_adbus <= '1'; IF ready = '1' THEN databus_on_dbus <= '1'; dbus_on_mar_offset_bus <= '1'; load_offset_mar <= '1'; next_state <= do_two_bytes; ELSE next_state <= do_indirect; END IF; ELSE next_state <= do_indirect; END IF; WHEN do_two_bytes => --------------------------------------6 IF ( ir_lines (7 DOWNTO 5) = jmp ) THEN load_page_pc <= '1'; load_offset_pc <= '1'; next_state <= instr_fetch; ELSIF ( ir_lines (7 DOWNTO 5) = sta ) THEN write_mem <= '1'; IF grant = '1' THEN -- mar on adbus, ac on databus, write to memory mar_on_adbus <= '1'; alu_code <= b_input; obus_on_dbus <= '1'; dbus_on_databus <= '1'; IF ready = '1' THEN next_state <= initial; ELSE next_state <= do_two_bytes; END IF; ELSE next_state <= do_two_bytes; END IF; ELSIF ( ir_lines (7) = '0' ) THEN ------ lda, and, add, sub read_mem <= '1'; IF grant = '1' THEN -- mar on adbus, read memory for operand, perform operation mar_on_adbus <= '1'; IF ready = '1' THEN databus_on_dbus <= '1'; IF ( ir_lines (6) = '0' ) THEN ---- lda, and IF ( ir_lines (5) = '0' ) THEN -- lda alu_code<= a_input; ELSE -- and alu_code<= a_and_b; END IF; ELSE ---- add, sub IF ( ir_lines (5) = '0' ) THEN -- add alu_code<= a_add_b; ELSE -- sub alu_code<= a_sub_b; END IF; END IF; load_sr <= '1'; load_ac <= '1'; next_state <= initial; ELSE next_state <= do_two_bytes; END IF; ELSE next_state <= do_two_bytes; END IF; ELSE next_state <= initial; --never happens END IF; WHEN do_jsr => --------------------------------------------7 write_mem <= '1'; IF grant = '1' THEN -- write pc offset to top of subroutine mar_on_adbus <= '1'; pc_offset_on_dbus <= '1'; dbus_on_databus <= '1'; IF ready = '1' THEN -- address of subroutine to pc load_offset_pc <= '1'; next_state <= continue_jsr; ELSE next_state <= do_jsr; END IF; ELSE next_state <= do_jsr; END IF; WHEN continue_jsr => --------------------------------------8 increment_pc <= '1'; next_state <= initial; WHEN do_branch => -----------------------------------------9 IF ( all_or (status AND ir_lines (3 DOWNTO 0)) = '1') THEN load_offset_pc <= '1'; END IF; next_state <= initial; END CASE; END PROCESS; END dataflow_synthesizable; ENTITY tester IS END tester; -- ARCHITECTURE io OF tester IS CONSTANT rate : INTEGER := 9600; CONSTANT fb : TIME := (1000000.0/REAL(rate)) * 1 US; SIGNAL serial, received : BIT; SIGNAL dataready, overrun, frame_error : BIT; SIGNAL parallel_out : BIT_VECTOR (7 DOWNTO 0); BEGIN s2p : ENTITY WORK.serial2parallel (waiting) GENERIC MAP (rate) PORT MAP (serial, received, dataready, overrun, frame_error, parallel_out); serial <= '1', '0' AFTER 2*fb, '1' AFTER 3*fb, '0' AFTER 4*fb, '1' AFTER 06*fb, '0' AFTER 20*fb, '1' AFTER 23*fb, '0' AFTER 25*fb, '1' AFTER 26*fb, '0' AFTER 27*fb, '1' AFTER 28*fb, '0' AFTER 33*fb; received <= '0', '1' AFTER 1.6 MS, '0' AFTER 1.6001 MS, '1' AFTER 3.5 MS, '0' AFTER 3.5001 MS; END io; USE WORK.waiting.ALL; ENTITY arbtest IS END arbtest; -- ARCHITECTURE io OF arbtest IS USE WORK.waiting.ALL; CONSTANT source_delays : natural_vector := (12, 10, 9, 14); SIGNAL clk, sel, rwb, rdy : BIT; SIGNAL r, w, g : BIT_VECTOR (3 DOWNTO 0); CONSTANT t : TIME := 1 US; BEGIN arb : ENTITY WORK.arbitrator (behavioral) GENERIC MAP (wait_states => (3 => 0, 2 => 1, 1 => 2, 0 => 3), clock_period => t) PORT MAP (r, w, g, clk, '0', sel, rwb, rdy); -- PORT MAP (r, g, clk); clk <= NOT clk AFTER t / 2 WHEN NOW < 400 US ELSE clk; sources : FOR i IN r'RANGE GENERATE PROCESS BEGIN WAIT FOR source_delays (i) * 1 US; r(i) <= '1'; WAIT UNTIL g(i) = '1'; WAIT UNTIL rdy = '1'; WAIT UNTIL clk = '0'; r(i) <= '0'; END PROCESS; END GENERATE; --r <= (r1, r2, r3, r4); --(g1, g2, g3, g4) <= g; END io; 1