mirror of
https://github.com/MiSTer-devel/Archie_MiSTer.git
synced 2026-04-19 03:04:04 +00:00
added more regs to reset for other modules added simulation some changes to be standard conform, mostly reordering of wire/reg defines
390 lines
12 KiB
VHDL
390 lines
12 KiB
VHDL
library ieee;
|
|
use ieee.std_logic_1164.all;
|
|
use ieee.numeric_std.all;
|
|
use STD.textio.all;
|
|
|
|
use work.globals.all;
|
|
|
|
entity estringprocessor is
|
|
generic
|
|
(
|
|
clk_speed : integer := 50000000
|
|
);
|
|
port
|
|
(
|
|
ready : in std_logic;
|
|
tx_command : out std_logic_vector(31 downto 0);
|
|
tx_bytes : out integer range 0 to 4;
|
|
tx_enable : out std_logic := '0';
|
|
rx_command : in std_logic_vector(31 downto 0);
|
|
rx_valid : in std_logic
|
|
);
|
|
end entity;
|
|
|
|
architecture arch of estringprocessor is
|
|
|
|
constant proc_busadr : integer := 28;
|
|
constant proc_buswidth : integer := 32;
|
|
|
|
constant clk_period : time := (1000000000 / clk_speed) * 1 ns;
|
|
|
|
signal string_command : string(1 to 3);
|
|
|
|
type t_internal_variables is array(0 to 256) of integer;
|
|
signal internal_variables : t_internal_variables := (others => 0);
|
|
|
|
type r_thread_record is record
|
|
id : integer;
|
|
waittime : integer;
|
|
waitcommand : line;
|
|
end record;
|
|
|
|
type t_thread_buffers is array(0 to 255) of r_thread_record;
|
|
|
|
|
|
procedure find_id
|
|
(
|
|
variable t_buf : inout t_thread_buffers;
|
|
variable id : in integer;
|
|
variable slot : out integer
|
|
) is
|
|
begin
|
|
for i in 0 to 255 loop
|
|
if (t_buf(i).id = id) then
|
|
slot := i;
|
|
exit;
|
|
elsif (t_buf(i).id = -1) then
|
|
t_buf(i).id := id;
|
|
slot := i;
|
|
exit;
|
|
end if;
|
|
end loop;
|
|
end procedure;
|
|
|
|
|
|
|
|
begin
|
|
|
|
|
|
process
|
|
|
|
file infile : text;
|
|
file outfile : text;
|
|
variable f_status : FILE_OPEN_STATUS;
|
|
variable newdat : LINE;
|
|
variable endfound : boolean;
|
|
variable buf : LINE;
|
|
variable run : boolean := true;
|
|
|
|
variable line_out : line;
|
|
variable debugline_out : line;
|
|
variable command : string(1 to 3);
|
|
|
|
variable dev_null_str3 : string (1 to 3);
|
|
variable dev_null_str6 : string (1 to 6);
|
|
variable OK : boolean := FALSE;
|
|
variable para_int1 : integer;
|
|
variable para_int2 : integer;
|
|
variable para_int3 : integer;
|
|
variable para_int4 : integer;
|
|
|
|
variable address : integer;
|
|
variable data : integer;
|
|
variable count : integer;
|
|
|
|
variable thread_buffers : t_thread_buffers := (others => (-1, 0, null));
|
|
|
|
variable freerun : boolean := false;
|
|
|
|
begin
|
|
|
|
file_open(f_status, outfile, "input.txt", write_mode);
|
|
file_close(outfile);
|
|
file_open(f_status, outfile, "output.txt", write_mode);
|
|
file_close(outfile);
|
|
|
|
file_open(f_status, infile, "input.txt", read_mode);
|
|
|
|
wait for 1000 ns;
|
|
|
|
while (run) loop
|
|
|
|
if not endfile(infile) then
|
|
|
|
endfound := false;
|
|
buf := null;
|
|
while (endfound = false) loop
|
|
if not endfile(infile) then
|
|
readline(infile,newdat);
|
|
for i in 1 to newdat'length loop
|
|
write(buf, newdat(i to i));
|
|
if (newdat(i to i) = "&") then
|
|
endfound := true;
|
|
end if;
|
|
end loop;
|
|
end if;
|
|
end loop;
|
|
|
|
command := buf(1 to 3);
|
|
string_command <= command;
|
|
|
|
line_out := null;
|
|
buf(buf'length) := ' ';
|
|
write(line_out, buf(1 to buf'length));
|
|
write(line_out, string'("# "));
|
|
|
|
if (command(1 to 3) = String'("set")) then
|
|
-- command
|
|
Read(buf, dev_null_str6);
|
|
-- command nr
|
|
Read(buf, para_int1, OK);
|
|
Read(buf, dev_null_str3);
|
|
-- process id
|
|
Read(buf, para_int1, OK);
|
|
Read(buf, dev_null_str3);
|
|
-- target for reading
|
|
Read(buf, para_int2, OK);
|
|
Read(buf, dev_null_str3);
|
|
-- count
|
|
Read(buf, count, OK);
|
|
Read(buf, dev_null_str3);
|
|
-- address in target space
|
|
Read(buf, address, OK);
|
|
Read(buf, dev_null_str3);
|
|
|
|
-- write address
|
|
if (ready = '0') then
|
|
wait until ready = '1';
|
|
end if;
|
|
tx_command <= "0000" & std_logic_vector(to_unsigned(address,proc_busadr));
|
|
if (count > 1) then
|
|
tx_command(31) <= '1';
|
|
end if;
|
|
tx_bytes <= 4;
|
|
tx_enable <= '1';
|
|
wait for clk_period*2;
|
|
tx_enable <= '0';
|
|
|
|
-- write block size
|
|
if (count > 1) then
|
|
if (ready = '0') then
|
|
wait until ready = '1';
|
|
end if;
|
|
tx_command <= std_logic_vector(to_unsigned(count - 1,32));
|
|
tx_bytes <= 4;
|
|
tx_enable <= '1';
|
|
wait for clk_period*2;
|
|
tx_enable <= '0';
|
|
end if;
|
|
|
|
for i in 1 to count loop
|
|
|
|
-- value to write
|
|
Read(buf, data, OK);
|
|
if (i < count) then
|
|
Read(buf, dev_null_str3);
|
|
end if;
|
|
|
|
-- write data
|
|
if (ready = '0') then
|
|
wait until ready = '1';
|
|
end if;
|
|
tx_command <= std_logic_vector(to_signed(data,proc_buswidth));
|
|
tx_bytes <= 4;
|
|
tx_enable <= '1';
|
|
wait for clk_period*2;
|
|
tx_enable <= '0';
|
|
wait for 20*clk_period; -- this is required, because there is no answer for write commands
|
|
|
|
address := address + 1;
|
|
|
|
end loop;
|
|
|
|
write(line_out, string'("&"));
|
|
file_open(f_status, outfile, "output.txt", append_mode);
|
|
writeline(outfile, line_out);
|
|
file_close(outfile);
|
|
end if;
|
|
|
|
if (command(1 to 3) = String'("get")) then
|
|
-- command
|
|
Read(buf, dev_null_str6);
|
|
-- command nr
|
|
Read(buf, para_int1, OK);
|
|
Read(buf, dev_null_str3);
|
|
-- process id
|
|
Read(buf, para_int1, OK);
|
|
Read(buf, dev_null_str3);
|
|
-- target for reading
|
|
Read(buf, para_int1, OK);
|
|
Read(buf, dev_null_str3);
|
|
-- count
|
|
Read(buf, count, OK);
|
|
Read(buf, dev_null_str3);
|
|
-- address in target space
|
|
Read(buf, address, OK);
|
|
|
|
-- write address
|
|
if (ready = '0') then
|
|
wait until ready = '1';
|
|
end if;
|
|
tx_command <= "0100" & std_logic_vector(to_unsigned(address,proc_busadr));
|
|
if (count > 1) then
|
|
tx_command(31) <= '1';
|
|
end if;
|
|
tx_bytes <= 4;
|
|
tx_enable <= '1';
|
|
wait for clk_period*2;
|
|
tx_enable <= '0';
|
|
|
|
-- write block size
|
|
if (count > 1) then
|
|
if (ready = '0') then
|
|
wait until ready = '1';
|
|
end if;
|
|
tx_command <= std_logic_vector(to_unsigned(count - 1,32));
|
|
tx_bytes <= 4;
|
|
tx_enable <= '1';
|
|
wait for clk_period*2;
|
|
tx_enable <= '0';
|
|
end if;
|
|
|
|
for i in 1 to count loop
|
|
|
|
if (rx_valid = '0') then
|
|
wait until rx_valid = '1';
|
|
end if;
|
|
data := to_integer(signed(rx_command(31 downto 0)));
|
|
wait until rx_valid = '0';
|
|
|
|
write(line_out, data);
|
|
write(line_out, string'("#"));
|
|
|
|
address := address + 1;
|
|
|
|
end loop;
|
|
|
|
write(line_out, string'("&"));
|
|
file_open(f_status, outfile, "output.txt", append_mode);
|
|
writeline(outfile, line_out);
|
|
file_close(outfile);
|
|
end if;
|
|
|
|
if (command(1 to 3) = String'("fil")) then
|
|
-- command
|
|
Read(buf, dev_null_str6);
|
|
-- command nr
|
|
Read(buf, para_int1, OK);
|
|
Read(buf, dev_null_str3);
|
|
-- process id
|
|
Read(buf, para_int1, OK);
|
|
Read(buf, dev_null_str3);
|
|
-- endianess
|
|
Read(buf, para_int2, OK);
|
|
Read(buf, dev_null_str3);
|
|
-- address in target space
|
|
Read(buf, address, OK);
|
|
Read(buf, dev_null_str3);
|
|
|
|
COMMAND_FILE_NAME <= (others => ' ');
|
|
COMMAND_FILE_NAME(1 to buf'length) <= buf(1 to buf'length);
|
|
COMMAND_FILE_NAMELEN <= buf'length;
|
|
COMMAND_FILE_TARGET <= address;
|
|
if (para_int2 = 1) then
|
|
COMMAND_FILE_ENDIAN <= '1';
|
|
else
|
|
COMMAND_FILE_ENDIAN <= '0';
|
|
end if;
|
|
COMMAND_FILE_START <= '1';
|
|
wait until COMMAND_FILE_ACK = '1';
|
|
COMMAND_FILE_START <= '0';
|
|
wait for 20 ns;
|
|
|
|
write(line_out, string'("&"));
|
|
file_open(f_status, outfile, "output.txt", append_mode);
|
|
writeline(outfile, line_out);
|
|
file_close(outfile);
|
|
end if;
|
|
|
|
if (command(1 to 3) = String'("brk")) then
|
|
run := false;
|
|
end if;
|
|
|
|
if (command(1 to 3) = String'("wtn")) then
|
|
-- command
|
|
Read(buf, dev_null_str6);
|
|
-- command nr
|
|
Read(buf, para_int1, OK);
|
|
Read(buf, dev_null_str3);
|
|
-- process id
|
|
Read(buf, para_int1, OK);
|
|
Read(buf, dev_null_str3);
|
|
-- time to wait
|
|
Read(buf, para_int2, OK);
|
|
|
|
|
|
write(line_out, string'("&"));
|
|
if (para_int2 = -1) then
|
|
freerun := true;
|
|
find_id(thread_buffers, para_int1, para_int3);
|
|
thread_buffers(para_int3).waittime := 2;
|
|
thread_buffers(para_int3).waitcommand := line_out;
|
|
else
|
|
find_id(thread_buffers, para_int1, para_int3);
|
|
thread_buffers(para_int3).waittime := para_int2;
|
|
thread_buffers(para_int3).waitcommand := line_out;
|
|
end if;
|
|
|
|
end if;
|
|
|
|
wait for 1 ps;
|
|
|
|
end if;
|
|
|
|
OK := false;
|
|
for i in 0 to 255 loop
|
|
if (thread_buffers(i).id /= -1) then
|
|
if (thread_buffers(i).waittime = 1) then
|
|
file_open(f_status, outfile, "output.txt", append_mode);
|
|
writeline(outfile, thread_buffers(i).waitcommand);
|
|
file_close(outfile);
|
|
end if;
|
|
if (thread_buffers(i).waittime > 0) then
|
|
OK := true;
|
|
thread_buffers(i).waittime := thread_buffers(i).waittime - 1;
|
|
end if;
|
|
end if;
|
|
end loop;
|
|
|
|
if (OK = true or freerun = true) then
|
|
wait for 1 ns;
|
|
end if;
|
|
|
|
end loop;
|
|
|
|
file_close(infile);
|
|
|
|
wait;
|
|
|
|
end process;
|
|
|
|
|
|
|
|
|
|
end architecture;
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|