diff --git a/cMIPS/bin/compile.sh b/cMIPS/bin/compile.sh index 89ef9cfd7c8de23553223d4cd25ef0971d88723a..b02825febf9e7a2b83deff79b681007d2ab27258 100755 --- a/cMIPS/bin/compile.sh +++ b/cMIPS/bin/compile.sh @@ -5,7 +5,7 @@ if [ ! -v tree ] ; then # you must set the location of the cMIPS root directory in the variable tree # tree=${HOME}/cMIPS - # tree=${HOME}/cmips-code/cMIPS + # tree=${HOME}/cmips/cMIPS export tree="$(echo $PWD | sed -e 's:^\(/.*/cMIPS\)/.*:\1:')" fi diff --git a/cMIPS/bin/run.sh b/cMIPS/bin/run.sh index 17daa4d7f3aa743f8459eba18d252ea95335d6d4..0e0a33cb5be5be98652c84843871d72b9faa773f 100755 --- a/cMIPS/bin/run.sh +++ b/cMIPS/bin/run.sh @@ -1,7 +1,7 @@ #!/bin/bash ## ------------------------------------------------------------------------ -## classicalMIPS, Roberto Hexsel, 23nov2012 +## classicalMIPS, Roberto Hexsel, 23nov2012-12nov2015 ## ------------------------------------------------------------------------ # set -x @@ -10,7 +10,7 @@ if [ ! -v tree ] ; then # you must set the location of the cMIPS root directory in the variable tree # tree=${HOME}/cMIPS - # tree=${HOME}/cmips-code/cMIPS + # tree=${HOME}/cmips/cMIPS export tree="$(echo $PWD | sed -e 's:\(/.*/cMIPS\)/.*:\1:')" fi @@ -25,7 +25,7 @@ unset WAVE length=1 unit=m -gtkwconf=v +gtkwconf=pipe touch input.data input.txt serial.inp @@ -77,19 +77,23 @@ gfile=${gtkwconf%%.sav} sav="${tree}"/${gfile}.sav -"${bin}"/build.sh || ( usage ; exit 1) +"${bin}"/build.sh || exit 1 options="--ieee-asserts=disable --stop-time=${length}${unit}s --vcd=${visual}" if [ -v $WAVE ] ; then + ## simulator must be exec'd so it can read from the standard input exec "${simulator}" $options else - "${simulator}" $options || gtkwave -O /dev/null ${visual} ${sav} + ## this echo is for testing the reads from stdin + ## echo -en "abc\n%" | + "${simulator}" $options ; gtkwave -O /dev/null ${visual} ${sav} fi -# --wave=${visual%.vcd}.ghw \ No newline at end of file +# --wave=${visual%.vcd}.ghw + diff --git a/cMIPS/tests/echo.c b/cMIPS/tests/echo.c new file mode 100644 index 0000000000000000000000000000000000000000..c56ea34007f8a63d1a1cb07dcd49a4bd2a729574 --- /dev/null +++ b/cMIPS/tests/echo.c @@ -0,0 +1,32 @@ +// Test stdin and stdout -- echo characters read from stdin to stdout +// test ends when '%' (percent) is read. +// from_stdin() returns EOT (0x04) the there is nothing on stdin +// +// Keep in mind that the terminal itself does echoing -- characters are +// displayed AFTER a second NewLine because of the terminal also echoes +// what you just typed in :( + +#include "cMIPS.h" + +void main(void) { + + char c; + + // the first read by the simulator is from an ampty line, + // thus the model returns a '\n' + + do { + + c = (char)from_stdin(); + + if (c != (char)0x04) { // EOT + to_stdout(c); + } + + } while (c != '%'); + + to_stdout('\n'); + + exit(0); + +} diff --git a/cMIPS/tests/stdin_out.s b/cMIPS/tests/stdin_out.s new file mode 100644 index 0000000000000000000000000000000000000000..8a8a54cb893b9fef5ea1c1f7d5556d75977505fe --- /dev/null +++ b/cMIPS/tests/stdin_out.s @@ -0,0 +1,38 @@ + .include "cMIPS.s" + .text + .align 2 + .set noreorder + .globl _start + .ent _start + + .set HW_stdout_addr,(x_IO_BASE_ADDR + 1 * x_IO_ADDR_RANGE) + .set HW_stdin_addr, (x_IO_BASE_ADDR + 2 * x_IO_ADDR_RANGE) + + +_start: nop + la $10, HW_stdin_addr + la $20, HW_stdout_addr + li $4, '%' + nop + +snd: lw $3, 0($10) # get char from STDIN + nop + sw $3, 0($20) # send it to STDOUT + + beq $3, $0, end # got NUL? go to end + nop + + beq $3, $4, end # got '%'? go to end + nop + + j snd + nop + +end: nop + nop + nop + nop + wait 0 + nop + nop + .end _start diff --git a/cMIPS/vhdl/io.vhd b/cMIPS/vhdl/io.vhd index 08946e906ac39b7982bf1ba62a2e302dffc520c1..728fd1df909b53cf6d33ca82d87d430e3c06ed73 100644 --- a/cMIPS/vhdl/io.vhd +++ b/cMIPS/vhdl/io.vhd @@ -17,41 +17,53 @@ ---++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++ --- peripheral: print_data --- print an integer to stdout, 32bit hexadecimal ---++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++ +--+++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++ +-- peripheral: from_stdin +-- read a signle character from stdout +-- returns LF ('\n'=0x0a) if there are no charachters on input +-- on the first ever read, returna LF on the empty line read +--+++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++ library IEEE; use IEEE.std_logic_1164.all; use IEEE.numeric_std.all; use std.textio.all; use work.p_wires.all; -entity print_data is +entity from_stdin is port (rst : in std_logic; clk : in std_logic; sel : in std_logic; wr : in std_logic; - data : in reg32); -end print_data; - -architecture behavioral of print_data is + data : out std_logic_vector); +end from_stdin; - file output : text open write_mode is "STD_OUTPUT"; +architecture behavioral of from_stdin is begin - U_WRITE_OUT: process(sel,clk) - variable msg : line; + U_READ_IN: process(clk,sel) + variable L : line; + variable this : character; + variable good : boolean := FALSE; begin + if falling_edge(clk) and sel = '0' then - write ( msg, string'(SLV32HEX(data)) ); - writeline( output, msg ); - end if; - end process U_WRITE_OUT; + read(L, this, good); + + if not(good) then + readline(input, L); + this := LF; + end if; + + data <= x"000000" & std_logic_vector(to_signed(character'pos(this),8)); + -- assert FALSE report "STD_IOrd= " & this; + + end if; + end process U_READ_IN; + end behavioral; --- ++ print_data +++++++++++++++++++++++++++++++++++++++++++++++++++++++++ +-- ++ from_stdin +++++++++++++++++++++++++++++++++++++++++++++++++++++++++ --++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++ @@ -91,7 +103,45 @@ begin end process U_WRITE_OUT; end behavioral; --- ++ to_stdout +++++++++++++++++++++++++++++++++++++++++++++++++++++++++ +-- ++ to_stdout +++++++++++++++++++++++++++++++++++++++++++++++++++++++++* + + + +--++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++ +-- peripheral: print_data +-- print an integer to stdout, 32bit hexadecimal +--++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++ +library IEEE; +use IEEE.std_logic_1164.all; +use IEEE.numeric_std.all; +use std.textio.all; +use work.p_wires.all; + +entity print_data is + port (rst : in std_logic; + clk : in std_logic; + sel : in std_logic; + wr : in std_logic; + data : in reg32); +end print_data; + +architecture behavioral of print_data is + + file output : text open write_mode is "STD_OUTPUT"; + +begin + + U_WRITE_OUT: process(sel,clk) + variable msg : line; + begin + if falling_edge(clk) and sel = '0' then + write ( msg, string'(SLV32HEX(data)) ); + writeline( output, msg ); + end if; + end process U_WRITE_OUT; + +end behavioral; +-- ++ print_data +++++++++++++++++++++++++++++++++++++++++++++++++++++++++ @@ -156,9 +206,9 @@ end behavioral; -- write_file_data --++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++ -- peripheral: read_data_from_file -- read one 32bit integer from file "input.data" --- if not EOF then write data to file --- else status <= 1 --- on a read, return last status (EOF=1 or otherwise=0) +-- if not EOF then read data from file +-- else status = 1 +-- on a read, return last status (EOF=1, otherwise=0) --++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++ library IEEE; use IEEE.std_logic_1164.all; diff --git a/cMIPS/vhdl/tb_cMIPS.vhd b/cMIPS/vhdl/tb_cMIPS.vhd index 3f4f552aa14094209157a704134ebcc90bda0cc8..e6fff99dee1a6eefa59667117ddae99ab6f45c72 100644 --- a/cMIPS/vhdl/tb_cMIPS.vhd +++ b/cMIPS/vhdl/tb_cMIPS.vhd @@ -71,22 +71,30 @@ architecture TB of tb_cMIPS is sw : in std_logic_vector (3 downto 0)); end component read_keys; - component print_data is + component to_stdout is port (rst : in std_logic; clk : in std_logic; sel : in std_logic; wr : in std_logic; data : in std_logic_vector); - end component print_data; + end component to_stdout; - component to_stdout is + component from_stdin is port (rst : in std_logic; clk : in std_logic; sel : in std_logic; wr : in std_logic; - data : in std_logic_vector); - end component to_stdout; + data : out std_logic_vector); + end component from_stdin; + component print_data is + port (rst : in std_logic; + clk : in std_logic; + sel : in std_logic; + wr : in std_logic; + data : in std_logic_vector); + end component print_data; + component write_data_file is generic (OUTPUT_FILE_NAME : string); port (rst : in std_logic; @@ -553,8 +561,7 @@ begin -- TB dev_select <= dev_select_io or dev_select_ram; with dev_select select - cpu_data_inp <= (others => 'X') when b"0000", - d_cache_d_out when b"0001", + cpu_data_inp <= d_cache_d_out when b"0001", stdin_d_out when b"0100", read_d_out when b"0101", counter_d_out when b"0111", @@ -578,7 +585,15 @@ begin -- TB -- U_RAM: fpga_RAM generic map ("data.bin", "dump.data") port map (rst, clk, mem_d_sel, ram_rdy, mem_wr, phi2, mem_addr, datram_out, datram_inp, mem_xfer, dump_ram); + + + U_to_stdout: to_stdout + port map (rst,clk, io_stdout_sel, wr, cpu_data); + + U_from_stdin: from_stdin + port map (rst,clk, io_stdin_sel, wr, stdin_d_out); + U_read_inp: read_data_file generic map ("input.data") port map (rst,clk, io_read_sel, wr, d_addr,read_d_out, cpu_xfer); @@ -588,13 +603,14 @@ begin -- TB U_print_data: print_data port map (rst,clk, io_print_sel, wr, cpu_data); - U_to_stdout: to_stdout - port map (rst,clk, io_stdout_sel, wr, cpu_data); + U_interrupt_counter: do_interrupt -- external counter+interrupt port map (rst,clk, io_counter_sel, wr, cpu_data, counter_d_out, counter_irq); + + U_to_7seg: to_7seg port map (rst,clk,io_7seg_sel, wr, cpu_data, disp0, disp1); @@ -636,6 +652,8 @@ begin -- TB -- port map (cpu_reset,clk, io_sstats_sel, wr, d_addr, sstats_d_out, -- cnt_d_ref,cnt_d_rd_hit,cnt_d_wr_hit,cnt_d_flush, -- cnt_i_ref,cnt_i_hit); + + U_clock: process -- simulate external clock begin