OpenCores
URL https://opencores.org/ocsvn/xucpu/xucpu/trunk

Subversion Repositories xucpu

Compare Revisions

  • This comparison shows the changes necessary to convert path
    /xucpu
    from Rev 15 to Rev 16
    Reverse comparison

Rev 15 → Rev 16

/trunk/src/system/system_2k.vhdl
0,0 → 1,349
 
--
-- This file is part of the Experimental Unstable CPU System.
--
-- The Experimental Unstable CPU System Is free software: you can redistribute
-- it and/or modify it under the terms of the GNU Lesser General Public License
-- as published by the Free Software Foundation, either version 3 of the
-- License, or (at your option) any later version.
--
-- The Experimental Unstable CPU System is distributed in the hope that it will
-- be useful, but WITHOUT ANY WARRANTY; without even the implied warranty of
-- MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU Lesser
-- General Public License for more details.
--
-- You should have received a copy of the GNU Lesser General Public License
-- along with Experimental Unstable CPU System. If not, see
-- http://www.gnu.org/licenses/lgpl.txt.
 
 
LIBRARY IEEE;
USE IEEE.STD_LOGIC_1164.ALL;
USE IEEE.numeric_std.ALL;
USE work.components.ALL;
USE work.ram_parts.ALL;
USE work.mux_parts.ALL;
USE work.controllers.ALL;
 
-- LIBRARY unisim;
-- USE unisim.vcomponents.ALL;
 
ENTITY system IS
PORT (
clock : IN STD_LOGIC;
reset : IN STD_LOGIC;
led_out : OUT STD_LOGIC_VECTOR(7 DOWNTO 0);
switch_in : IN STD_LOGIC_VECTOR(7 DOWNTO 0);
pushb_in : IN STD_LOGIC_VECTOR(4 DOWNTO 0));
END system;
 
ARCHITECTURE Structural OF system IS
 
CONSTANT w_data : POSITIVE := 16;
 
SIGNAL CLK : STD_LOGIC; -- System clock
SIGNAL CLK_VAL : STD_LOGIC; -- System clock valid
SIGNAL RST : STD_LOGIC; -- System synchronous reset
 
-- All signals for the instruction and data processing
-- Ordered in proper bundles per pipeline stage
 
-- FiRST stage in the instruction pipeline is the program counter circuitry
SIGNAL PC_SRC : STD_LOGIC_VECTOR(2 DOWNTO 0) := "000";
SIGNAL LD_PC : STD_LOGIC := '0';
SIGNAL PC_INC : STD_LOGIC_VECTOR(14 DOWNTO 0) := "000000000000000";
SIGNAL PC_NEXT : STD_LOGIC_VECTOR(14 DOWNTO 0) := "000000000000000";
 
-- The second stage in the instruction pipeline is the memory, followed by
-- the instruction queue.
SIGNAL LD_IR : STD_LOGIC := '0';
SIGNAL LD_DP : STD_LOGIC := '0';
SIGNAL LD_REG : STD_LOGIC := '0';
 
SIGNAL RFA_A : STD_LOGIC_VECTOR(3 DOWNTO 0) := "0000";
SIGNAL RFA_B : STD_LOGIC_VECTOR(3 DOWNTO 0) := "0000";
SIGNAL ALU_OP : STD_LOGIC_VECTOR(3 DOWNTO 0) := "0000";
 
SIGNAL REG_SRC : STD_LOGIC_VECTOR(2 DOWNTO 0) := "111";
SIGNAL DATABUS_OUT : STD_LOGIC_VECTOR(15 DOWNTO 0);
SIGNAL DATABUS_READ : STD_LOGIC_VECTOR(15 DOWNTO 0) := X"0000";
SIGNAL INSTR_OUT : STD_LOGIC_VECTOR(15 DOWNTO 0) := X"0000";
 
SIGNAL REG_WR : STD_LOGIC := '1';
SIGNAL REG_BUS : STD_LOGIC_VECTOR(15 DOWNTO 0) := X"0000";
SIGNAL A_OUT : STD_LOGIC_VECTOR(15 DOWNTO 0) := X"0000";
SIGNAL B_OUT : STD_LOGIC_VECTOR(15 DOWNTO 0) := X"0000";
 
SIGNAL LD_MAR : STD_LOGIC;
SIGNAL LD_MDR : STD_LOGIC;
 
SIGNAL QA : STD_LOGIC_VECTOR(15 DOWNTO 0) := X"0000";
SIGNAL QB : STD_LOGIC_VECTOR(15 DOWNTO 0) := X"0000";
SIGNAL ALU_OUT : STD_LOGIC_VECTOR(15 DOWNTO 0) := X"0000";
 
SIGNAL DATA_ADDRESS : STD_LOGIC_VECTOR(14 DOWNTO 0) := "000000000000000";
SIGNAL DATABUS_WRITE : STD_LOGIC_VECTOR(15 DOWNTO 0) := X"0000";
 
SIGNAL DOSEL : STD_LOGIC_VECTOR(2 DOWNTO 0) := "000";
SIGNAL EOUT1 : STD_LOGIC;
SIGNAL EIN1 : STD_LOGIC;
SIGNAL EIN2 : STD_LOGIC;
 
SIGNAL MEM_WR : STD_LOGIC := '1';
SIGNAL PC_OUT : STD_LOGIC_VECTOR(14 DOWNTO 0) := "000000000000000";
SIGNAL PC_TO_REG : STD_LOGIC_VECTOR(15 DOWNTO 0) := X"0000";
 
SIGNAL DO1 : STD_LOGIC_VECTOR(15 DOWNTO 0) := X"0000";
SIGNAL DO2 : STD_LOGIC_VECTOR(15 DOWNTO 0) := X"0000";
SIGNAL DO3 : STD_LOGIC_VECTOR(15 DOWNTO 0) := X"0000";
SIGNAL MEMO4 : STD_LOGIC_VECTOR(15 DOWNTO 0) := X"0000";
SIGNAL INSO4 : STD_LOGIC_VECTOR(15 DOWNTO 0) := X"0000";
SIGNAL INSTR : STD_LOGIC_VECTOR(15 DOWNTO 0) := X"0000";
SIGNAL IMMED : STD_LOGIC_VECTOR(15 DOWNTO 0) := X"0000";
 
SIGNAL I_ZERO : STD_LOGIC;
SIGNAL ZERO : STD_LOGIC;
SIGNAL INT : STD_LOGIC;
 
BEGIN
 
-- Clock generator with selectable speed and reset
--CLOCK1 : clock_gen
-- PORT MAP (
-- CLK_IN => CLOCK,
-- RESET => RESET,
-- CLK_VALID => CLK_VAL,
-- CLK_OUT => CLK);
 
-- Synchronous reset
--RST1 : sync_reset
-- PORT MAP (
-- ASYNC_RST => RESET,
-- CLK => CLK,
-- CLK_VALID => CLK_VAL,
-- RST => RST);
 
CLK <= CLOCK;
RST <= RESET;
 
PC_TO_REG <= '0' & PC_OUT;
 
-- Input multiplexer to register file
REG_MUX : mux8to1
PORT MAP (
SEL => REG_SRC,
S0 => ALU_OUT, -- "000"
S1 => DATABUS_READ, -- "001"
S2 => IMMED, -- "010"
S3 => PC_TO_REG, -- "011"
S4 => A_OUT, -- "100"
S5 => STD_LOGIC_VECTOR(TO_UNSIGNED(0, w_data)),
S6 => STD_LOGIC_VECTOR(TO_UNSIGNED(0, w_data)),
S7 => STD_LOGIC_VECTOR(TO_UNSIGNED(0, w_data)),
Y => REG_BUS);
 
-- True if A output of register file is zero
Z1 : zerof
PORT MAP (
A => A_OUT,
zero => I_ZERO);
 
PROCESS(CLK)
BEGIN
IF rising_edge(CLK) THEN
ZERO <= I_ZERO;
END IF;
END PROCESS;
 
-- 16-register register file
RF1 : regf
PORT MAP (
CLK => CLK,
we => REG_WR,
a1 => RFA_A,
a2 => RFA_B,
d => REG_BUS,
q1 => A_OUT,
q2 => B_OUT);
 
-- Memory address register from B output
MAR : data_reg
GENERIC MAP (
w_data => 15)
PORT MAP (
RST => RST,
CLK => CLK,
ENA => LD_MAR,
D => B_OUT(14 DOWNTO 0),
Q => DATA_ADDRESS);
 
-- Memory data register from A output
MDR : data_reg
PORT MAP (
RST => RST,
CLK => CLK,
ENA => LD_MDR,
D => A_OUT,
Q => DATABUS_WRITE);
 
-- 16 function A output
ALU1 : alu
PORT MAP (
clk => CLK,
op => ALU_OP,
A => A_OUT,
B => B_OUT,
Y => ALU_OUT);
 
-- Multiplexer for program counter input
PC_MUX : mux8to1
GENERIC MAP (
w_data => 15)
PORT MAP (
SEL => PC_SRC,
S0 => A_OUT(14 DOWNTO 0), -- "000"
S1 => PC_INC, -- "001"
S2 => IMMED(14 DOWNTO 0), -- "010"
S3 => PC_OUT, -- "011"
S4 => STD_LOGIC_VECTOR(TO_UNSIGNED(16#7FF0#, 15)), -- "100"
S5 => STD_LOGIC_VECTOR(TO_UNSIGNED(16#0000#, 15)), -- "101"
S6 => STD_LOGIC_VECTOR(TO_UNSIGNED(16#0000#, 15)), -- "110"
S7 => INSO4(14 DOWNTO 0), -- "111"
Y => PC_NEXT);
 
-- Program counter
PC : data_reg
GENERIC MAP (
w_data => 15)
PORT MAP (
RST => RST,
CLK => CLK,
ENA => LD_PC,
D => PC_NEXT,
Q => PC_OUT);
 
-- Incrementer for program counter
PC_INC1 : incr
GENERIC MAP (
w_data => 15)
PORT MAP (
A => PC_OUT,
Y => PC_INC);
 
CTRL1 : uctrl
PORT MAP (
CLK => CLK,
RST => RST,
PC_SRC => PC_SRC,
LD_PC => LD_PC,
LD_IR => LD_IR,
LD_DP => LD_DP,
REG_SRC => REG_SRC,
RFA_A => RFA_A,
RFA_B => RFA_B,
REG_WR => REG_WR,
LD_MAR => LD_MAR,
LD_MDR => LD_MDR,
MEM_WR => MEM_WR,
ALU_OP => ALU_OP,
INT => INT,
ZERO => ZERO,
IR_IN => INSTR);
 
-- Decoder for IO
IO_DEC : decoder
PORT MAP (
clk => CLK,
ena => LD_MAR,
a1 => B_OUT(14 DOWNTO 0),
gpio_1 => EOUT1,
gpio_2 => EIN1,
gpio_3 => EIN2,
bus_sel => DOSEL);
 
-- Simple output register for LED output port
OUT1 : gpio_out
GENERIC MAP (
w_port => 8)
PORT MAP (
RST => RST,
CLK => CLK,
ena => EOUT1,
we => MEM_WR,
D => DATABUS_WRITE,
Q => DO1,
port_out => led_out);
 
-- Simple input register for switches
IN1 : gpio_in
GENERIC MAP (
w_port => 8)
PORT MAP (
RST => RST,
CLK => CLK,
ena => EIN1,
Q => DO2,
port_in => switch_in);
 
-- Simple input register for push buttons
IN2 : gpio_in
GENERIC MAP (
w_port => 5)
PORT MAP (
RST => RST,
CLK => CLK,
ena => EIN2,
Q => DO3,
port_in => pushb_in);
 
-- 1kx16 two port RAM
MEM1 : generic_ram
GENERIC MAP (
filename => "input_data.txt",
w_addr => 11)
PORT MAP (
CLK => CLK,
we => MEM_WR,
a1 => B_OUT(10 DOWNTO 0),
a2 => PC_NEXT(10 DOWNTO 0),
d1 => A_OUT,
q1 => MEMO4, -- Data memory output
q2 => INSO4); -- Instruction memory output
 
IR : data_reg
PORT MAP (
RST => RST,
CLK => CLK,
ENA => LD_IR,
D => INSO4,
Q => INSTR);
 
DR : data_reg
PORT MAP (
RST => RST,
CLK => CLK,
ENA => LD_DP,
D => INSO4,
Q => IMMED);
 
-- RAM/input device READ multiplexer
BUS_MUX : mux8to1
PORT MAP (
SEL => DOSEL,
S0 => DO1,
S1 => DO2,
S2 => DO3,
S3 => STD_LOGIC_VECTOR(TO_UNSIGNED(0, w_data)),
S4 => STD_LOGIC_VECTOR(TO_UNSIGNED(0, w_data)),
S5 => STD_LOGIC_VECTOR(TO_UNSIGNED(0, w_data)),
S6 => STD_LOGIC_VECTOR(TO_UNSIGNED(0, w_data)),
S7 => MEMO4,
Y => DATABUS_OUT);
 
BUSR : data_reg_2 PORT MAP (
CLK => CLK,
D => DATABUS_OUT,
Q => DATABUS_READ);
 
END Structural;
/trunk/src/components/BRAM/ram_parts.vhdl
55,6 → 55,20
 
END COMPONENT RAM32K;
 
COMPONENT RAM8K IS
GENERIC (
initial : cstr_array_type(0 TO 8191);
w_data : NATURAL RANGE 1 TO 32 := 16);
PORT (
clk : IN STD_LOGIC;
we : IN STD_LOGIC;
a1 : IN STD_LOGIC_VECTOR(12 DOWNTO 0);
a2 : IN STD_LOGIC_VECTOR(12 DOWNTO 0);
d1 : IN STD_LOGIC_VECTOR(w_data - 1 DOWNTO 0);
q1 : OUT STD_LOGIC_VECTOR(w_data - 1 DOWNTO 0);
q2 : OUT STD_LOGIC_VECTOR(w_data - 1 DOWNTO 0));
END COMPONENT RAM8K;
 
END PACKAGE ram_parts;
 
LIBRARY ieee;
62,7 → 76,7
USE ieee.numeric_std.ALL;
USE std.textio.ALL;
USE ieee.std_logic_textio.ALL;
USE work.arrayio.ALL;
USE work.hexio.ALL;
 
ENTITY RAM_GENERIC IS
 
126,8 → 140,13
LIBRARY ieee;
USE ieee.std_logic_1164.ALL;
USE ieee.numeric_std.ALL;
USE work.hexio.ALL;
 
LIBRARY ieee;
USE ieee.std_logic_1164.ALL;
USE ieee.numeric_std.ALL;
USE work.mux_parts.ALL;
USE work.ram_parts.ALL;
USE work.hexio.ALL;
 
ENTITY RAM32K IS
 
201,11 → 220,10
 
RAM : FOR i IN 0 TO 3 GENERATE
 
R0 : memory
R0 : RAM8K
GENERIC MAP (
filename => i_file(i),
w_data => w_data,
w_addr => 13)
w_data => w_data)
PORT MAP (
clk => clk,
we => wr_sel(i),
/trunk/src/components/BRAM/generic_ram.vhdl
0,0 → 1,68
LIBRARY ieee;
USE ieee.std_logic_1164.ALL;
USE ieee.numeric_std.ALL;
USE work.hexio.ALL;
 
ENTITY RAM_GENERIC IS
 
-- Memory component based upon Xilinx Spartan-6 block RAM
-- Maximum capacity is 16k words
-- This component can be initialised by passing a file name as a generic
-- parameter.
 
GENERIC (
filename : STRING := "";
w_data : NATURAL RANGE 1 TO 32 := 16;
w_addr : NATURAL RANGE 8 TO 14 := 10);
PORT (
clk : IN STD_LOGIC;
we : IN STD_LOGIC;
a1 : IN STD_LOGIC_VECTOR(w_addr - 1 DOWNTO 0); -- Data port address
a2 : IN STD_LOGIC_VECTOR(w_addr - 1 DOWNTO 0); -- Instruction port address
d1 : IN STD_LOGIC_VECTOR(w_data - 1 DOWNTO 0); -- Data port input
q1 : OUT STD_LOGIC_VECTOR(w_data - 1 DOWNTO 0); -- Data port output
q2 : OUT STD_LOGIC_VECTOR(w_data - 1 DOWNTO 0)); -- Instruction port output
 
END RAM_GENERIC;
 
ARCHITECTURE Behavioral OF RAM_GENERIC IS
 
COMPONENT generic_memory_block IS
 
-- Memory component based upon Xilinx Spartan-6 block RAM
-- Maximum capacity is 16k words
-- This component can be initialised by passing a file name as a generic
-- parameter.
 
GENERIC (
init_data : cstr_array_type;
w_data : NATURAL RANGE 1 TO 32 := 16;
w_addr : NATURAL RANGE 8 TO 14 := 10);
PORT (
clk : IN STD_LOGIC;
we : IN STD_LOGIC;
a1 : IN STD_LOGIC_VECTOR(w_addr - 1 DOWNTO 0); -- Data port address
a2 : IN STD_LOGIC_VECTOR(w_addr - 1 DOWNTO 0); -- Instruction port address
d1 : IN STD_LOGIC_VECTOR(w_data - 1 DOWNTO 0); -- Data port input
q1 : OUT STD_LOGIC_VECTOR(w_data - 1 DOWNTO 0); -- Data port output
q2 : OUT STD_LOGIC_VECTOR(w_data - 1 DOWNTO 0)); -- Instruction port output
 
END COMPONENT generic_memory_block;
 
BEGIN -- Behavioral
 
MEM1 : generic_memory_block
GENERIC MAP (
init_data => init_cstr(2**w_addr, filename),
w_data => w_data,
w_addr => w_addr)
PORT MAP (
clk => clk,
we => we,
a1 => a1,
a2 => a2,
d1 => d1,
q1 => q1,
q2 => q2);
 
END Behavioral;
/trunk/src/components/BRAM/generic_memory_block.vhdl
0,0 → 1,62
LIBRARY ieee;
USE ieee.std_logic_1164.ALL;
USE ieee.numeric_std.ALL;
USE work.hexio.ALL;
 
ENTITY generic_memory_block IS
 
-- Memory component based upon Xilinx Spartan-6 block RAM
-- Maximum capacity is 16k words
-- This component can be initialised by passing a file name as a generic
-- parameter.
 
GENERIC (
init_data : cstr_array_type;
w_data : NATURAL RANGE 1 TO 32 := 16;
w_addr : NATURAL RANGE 8 TO 14 := 10);
PORT (
clk : IN STD_LOGIC;
we : IN STD_LOGIC;
a1 : IN STD_LOGIC_VECTOR(w_addr - 1 DOWNTO 0); -- Data port address
a2 : IN STD_LOGIC_VECTOR(w_addr - 1 DOWNTO 0); -- Instruction port address
d1 : IN STD_LOGIC_VECTOR(w_data - 1 DOWNTO 0); -- Data port input
q1 : OUT STD_LOGIC_VECTOR(w_data - 1 DOWNTO 0); -- Data port output
q2 : OUT STD_LOGIC_VECTOR(w_data - 1 DOWNTO 0)); -- Instruction port output
 
END generic_memory_block;
 
ARCHITECTURE Behavioral OF generic_memory_block IS
 
SIGNAL mem : cstr_array_type(0 TO (2**w_addr) - 1) := init_data;
 
SIGNAL address_reg_1 : STD_LOGIC_VECTOR(w_addr - 1 DOWNTO 0);
SIGNAL address_reg_2 : STD_LOGIC_VECTOR(w_addr - 1 DOWNTO 0);
 
BEGIN -- Behavioral
 
-- purpose: Try to describe a proper block ram without needing to instantiate a BRAM
-- type : sequential
-- inputs : clk, we, a1, a2, d1
-- outputs: q1, q2
MP1 : PROCESS (clk, address_reg_1, address_reg_2, mem)
BEGIN -- PROCESS MP1
 
-- Reading
q1 <= STD_LOGIC_VECTOR(to_unsigned(mem(to_integer(UNSIGNED(address_reg_1))), w_data));
q2 <= STD_LOGIC_VECTOR(to_unsigned(mem(to_integer(UNSIGNED(address_reg_2))), w_data));
IF rising_edge(clk) THEN -- rising clock edge
 
-- These work like the block RAM registers
address_reg_1 <= a1;
address_reg_2 <= a2;
 
-- Writing
IF we = '1' THEN
mem(to_integer(UNSIGNED(a1))) <= to_integer(UNSIGNED(d1));
END IF;
 
END IF;
 
END PROCESS MP1;
 
END Behavioral;
/trunk/src/util/file/proc_reader.vhdl
19,7 → 19,7
 
LIBRARY std;
USE std.textio.ALL;
USE work.arrayio.ALL;
USE work.hexio.ALL;
 
ENTITY proc_reader IS
 
/trunk/src/util/file/hexio.vhdl
0,0 → 1,319
 
--
-- This file is part of the Experimental Unstable CPU System.
--
-- The Experimental Unstable CPU System Is free software: you can redistribute
-- it and/or modify it under the terms of the GNU Lesser General Public License
-- as published by the Free Software Foundation, either version 3 of the
-- License, or (at your option) any later version.
--
-- The Experimental Unstable CPU System is distributed in the hope that it will
-- be useful, but WITHOUT ANY WARRANTY; without even the implied warranty of
-- MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU Lesser
-- General Public License for more details.
--
-- You should have received a copy of the GNU Lesser General Public License
-- along with Experimental Unstable CPU System. If not, see
-- http://www.gnu.org/licenses/lgpl.txt.
 
 
LIBRARY std;
USE std.textio.ALL;
 
PACKAGE hexio IS
 
-- This type must be used for base memory arrays
TYPE cstr_array_type IS ARRAY(INTEGER RANGE <>) OF INTEGER RANGE 0 TO 65535;
 
FUNCTION init_cstr (
CONSTANT array_size : IN INTEGER;
CONSTANT input_file : IN STRING)
RETURN cstr_array_type;
PROCEDURE init_var_array (
VARIABLE array_in : INOUT cstr_array_type;
CONSTANT filename : IN STRING);
 
PROCEDURE init_sig_array (
SIGNAL array_in : INOUT cstr_array_type;
CONSTANT filename : IN STRING);
 
PROCEDURE dump_array (
CONSTANT array_in : IN cstr_array_type);
 
END PACKAGE hexio;
 
PACKAGE BODY hexio IS
 
-- Private declarations
PROCEDURE read_hex (
VARIABLE input_line : IN STRING;
VARIABLE hex_value : OUT INTEGER);
 
FUNCTION hex_char_to_value (
CONSTANT chr : IN CHARACTER)
RETURN INTEGER;
 
PROCEDURE fill_var_array (
CONSTANT value : IN INTEGER;
VARIABLE in_array : INOUT cstr_array_type);
 
PROCEDURE fill_sig_array (
CONSTANT value : IN INTEGER;
SIGNAL in_array : INOUT cstr_array_type);
 
PROCEDURE read_file_into_var_array (
VARIABLE array_in : INOUT cstr_array_type;
CONSTANT filename : IN STRING);
 
PROCEDURE read_file_into_sig_array (
SIGNAL array_in : INOUT cstr_array_type;
CONSTANT filename : IN STRING);
 
-- Procedure and function body definitions
FUNCTION init_cstr (
CONSTANT array_size : IN INTEGER;
CONSTANT input_file : IN STRING)
RETURN cstr_array_type IS
 
VARIABLE rv : cstr_array_type(0 TO array_size - 1) := (OTHERS => 0);
BEGIN -- FUNCTION init_cstr
 
init_var_array(rv, input_file);
RETURN rv;
END FUNCTION init_cstr;
 
-- Fill a signal array with the contents of a file
PROCEDURE init_sig_array (
SIGNAL array_in : INOUT cstr_array_type;
CONSTANT filename : IN STRING) IS
 
BEGIN
 
fill_sig_array(0, array_in);
read_file_into_sig_array(array_in, filename);
 
END PROCEDURE init_sig_array;
 
-- General procedure to fill an array of integers. This is to make sure that
-- the array does not contain any meta-data any more.
PROCEDURE fill_sig_array (
CONSTANT value : IN INTEGER;
SIGNAL in_array : INOUT cstr_array_type) IS
 
BEGIN -- PROCEDURE fill_array
 
FOR i IN in_array'RANGE LOOP
in_array(i) <= value;
END LOOP; -- i
END PROCEDURE fill_sig_array;
 
-- Read the file into the signal array
PROCEDURE read_file_into_sig_array (
SIGNAL array_in : INOUT cstr_array_type;
CONSTANT filename : IN STRING) IS
 
FILE input_file : TEXT;
 
VARIABLE input_line : LINE;
VARIABLE fstatus : FILE_OPEN_STATUS;
 
VARIABLE a_index : INTEGER := 0;
VARIABLE i_value : INTEGER := 0;
 
VARIABLE output_line : LINE;
VARIABLE line_value : STRING(1 TO 4);
 
BEGIN -- PROCEDURE read_file_into_sig_array
 
file_open(fstatus, input_file, filename, READ_MODE);
 
IF fstatus = OPEN_OK THEN
WHILE NOT endfile(input_file) LOOP
-- Read the next line and put its contents in a string
readline(input_file, input_line);
read(input_line, line_value);
 
-- Current debugging feedback
write(output_line, line_value);
writeline(OUTPUT, output_line);
 
-- Turn a hex value into an integer value
read_hex(line_value, i_value);
 
array_in(a_index) <= i_value;
a_index := a_index + 1;
 
write(output_line, STRING'("Index :"));
write(output_line, a_index);
write(output_line, STRING'(" Value: "));
write(output_line, i_value);
writeline(OUTPUT, output_line);
END LOOP;
 
file_close(input_file);
 
END IF;
 
END PROCEDURE read_file_into_sig_array;
 
--
--
 
-- Initialise a variable array
PROCEDURE init_var_array (
VARIABLE array_in : INOUT cstr_array_type;
CONSTANT filename : IN STRING) IS
 
BEGIN
 
fill_var_array(0, array_in);
read_file_into_var_array(array_in, filename);
 
END PROCEDURE init_var_array;
 
-- General procedure to fill an array of integers. This is to make sure that
-- the array does not contain any meta-data any more.
PROCEDURE fill_var_array (
CONSTANT value : IN INTEGER;
VARIABLE in_array : INOUT cstr_array_type) IS
 
BEGIN -- PROCEDURE fill_array
 
FOR i IN in_array'RANGE LOOP
in_array(i) := value;
END LOOP; -- i
END PROCEDURE fill_var_array;
 
PROCEDURE read_file_into_var_array (
VARIABLE array_in : INOUT cstr_array_type;
CONSTANT filename : IN STRING) IS
 
FILE input_file : TEXT;
 
VARIABLE input_line : LINE;
VARIABLE fstatus : FILE_OPEN_STATUS;
 
VARIABLE a_index : INTEGER := 0;
VARIABLE i_value : INTEGER := 0;
 
VARIABLE output_line : LINE;
VARIABLE line_value : STRING(1 TO 4);
 
BEGIN -- PROCEDURE read_file
 
file_open(fstatus, input_file, filename, READ_MODE);
 
IF fstatus = OPEN_OK THEN
WHILE NOT endfile(input_file) LOOP
-- Read the next line and put its contents in a string
readline(input_file, input_line);
read(input_line, line_value);
 
-- Current debugging feedback
write(output_line, line_value);
writeline(OUTPUT, output_line);
 
-- Turn a hex value into an integer value
read_hex(line_value, i_value);
 
array_in(a_index) := i_value;
a_index := a_index + 1;
 
write(output_line, STRING'("Index :"));
write(output_line, a_index);
write(output_line, STRING'(" Value: "));
write(output_line, i_value);
writeline(OUTPUT, output_line);
END LOOP;
 
file_close(input_file);
 
END IF;
 
END PROCEDURE read_file_into_var_array;
 
-- Shared and generic procedures
 
-- Read a hexadecimal value from the input string and turn it into an integer.
PROCEDURE read_hex (
VARIABLE input_line : IN STRING;
VARIABLE hex_value : OUT INTEGER) IS
 
VARIABLE input_length : INTEGER := input_line'LENGTH;
VARIABLE chr : CHARACTER;
VARIABLE output_line : LINE;
 
VARIABLE chr_value : INTEGER := 0;
VARIABLE radix : INTEGER := 1;
VARIABLE result : INTEGER := 0;
 
BEGIN -- PROCEDURE read_hex
 
FOR i IN input_line'REVERSE_RANGE LOOP
chr := input_line(i);
chr_value := hex_char_to_value(chr);
result := chr_value * radix + result;
radix := radix * 16;
END LOOP;
 
hex_value := result;
 
END PROCEDURE read_hex;
 
-- Return the integer value matching with the hexadecimal character
FUNCTION hex_char_to_value (
CONSTANT chr : IN CHARACTER)
RETURN INTEGER IS
 
VARIABLE digit : INTEGER := 0;
BEGIN -- PROCEDURE hex_char_to_value
 
CASE chr IS
WHEN '0' => digit := 0;
WHEN '1' => digit := 1;
WHEN '2' => digit := 2;
WHEN '3' => digit := 3;
WHEN '4' => digit := 4;
WHEN '5' => digit := 5;
WHEN '6' => digit := 6;
WHEN '7' => digit := 7;
WHEN '8' => digit := 8;
WHEN '9' => digit := 9;
WHEN 'A' => digit := 10;
WHEN 'B' => digit := 11;
WHEN 'C' => digit := 12;
WHEN 'D' => digit := 13;
WHEN 'E' => digit := 14;
WHEN 'F' => digit := 15;
WHEN OTHERS => digit := 0;
END CASE;
 
RETURN digit;
 
END FUNCTION hex_char_to_value;
 
PROCEDURE dump_array (
CONSTANT array_in : IN cstr_array_type) IS
 
VARIABLE output_line : LINE;
BEGIN -- PROCEDURE dump_array
 
FOR i IN array_in'RANGE LOOP
 
write(output_line, string'("Index: "));
write(output_line, i);
 
write(output_line, string'(" Value: "));
write(output_line, array_in(i));
 
writeline(OUTPUT, output_line);
END LOOP; -- i
END PROCEDURE dump_array;
 
END PACKAGE BODY hexio;
/trunk/src/util/file/sign_reader.vhdl
19,8 → 19,11
 
LIBRARY std;
USE std.textio.ALL;
USE work.arrayio.ALL;
USE work.hexio.ALL;
 
-- This is a test entity to check that reading the test input hex file
-- into a signal array via the initialisation function works and can be
-- dumped.
ENTITY sign_reader IS
 
END ENTITY sign_reader;
/trunk/ghdl/2k.mk
0,0 → 1,76
 
#
# This file is part of the Experimental Unstable CPU System.
#
# The Experimental Unstable CPU System Is free software: you can redistribute
# it and/or modify it under the terms of the GNU Lesser General Public License
# as published by the Free Software Foundation, either version 3 of the
# License, or (at your option) any later version.
#
# The Experimental Unstable CPU System is distributed in the hope that it will
# be useful, but WITHOUT ANY WARRANTY; without even the implied warranty of
# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU Lesser
# General Public License for more details.
#
# You should have received a copy of the GNU Lesser General Public License
# along with Experimental Unstable CPU System. If not, see
# http://www.gnu.org/licenses/lgpl.txt.
 
FIND=gfind
XARGS=gxargs
UNISIM=/usr/local/share
SOURCE= ../src/util/file/arrayio.vhdl \
../src/components/components.vhdl \
../src/components/multiplexer/MUX.vhdl \
../src/components/BRAM/RAM.vhdl \
../src/components/ALU/alu2.vhdl \
../src/components/ALU/logic.vhdl \
../src/components/ALU/shift.vhdl \
../src/components/ALU/summation.vhdl \
../src/components/data_reg.vhdl \
../src/components/incr.vhdl \
../src/components/regf.vhdl \
../src/components/zerof.vhdl \
../src/system/controllers.vhdl \
../src/system/uctrl.vhdl \
../src/system/system_2k.vhdl \
../src/system/decoder.vhdl \
../src/io/gpio_in.vhdl \
../src/io/gpio_out.vhdl \
../tb/startup_sim.vhdl
 
unisim: unisim-obj93.cf
ghdl -a --ieee=synopsys --work=unisim --workdir=tmp $(UNISIM)/unisims/*.vhd
$(FIND) $(UNISIM)/unisims/primitive/*.vhd -print0 | $(XARGS) -0 -n 1 -t ghdl -a --ieee=synopsys --work=unisim --workdir=tmp -fexplicit
 
unisim-obj93.cf:
 
analyse:
ghdl -a -P./. -P./tmp --ieee=synopsys --workdir=tmp $(SOURCE)
 
build: unisim-obj93.cf analyse
ghdl -e -g -P./. -P./tmp --warn-unused --ieee=synopsys --workdir=tmp startup_sim
 
run: build
ghdl -r -P. -P./tmp --ieee=synopsys --workdir=tmp startup_sim --wave=startup_sim.ghw --stop-time=300ns
 
clean:
-rm *.o
-rm unisim*
 
init: cp_init
 
cp_init:
cp uctrl-init.vhdl uctrl.vhdl
 
main: cp_main
 
cp_main:
cp uctrl-main.vhdl uctrl.vhdl
 
test: cp_test
 
cp_test:
cp test/$(INST).txt input_data.txt
 
# vim:set noet tw=0 ts=8 nowrap:

powered by: WebSVN 2.1.0

© copyright 1999-2024 OpenCores.org, equivalent to Oliscience, all rights reserved. OpenCores®, registered trademark.