Compare commits
| Author | SHA1 | Date | |
|---|---|---|---|
|
|
f91e762e94 |
@@ -12,8 +12,8 @@ vcom -explicit -93 "../src/core/dpath_ctrl.vhd"
|
|||||||
vcom -explicit -93 "../src/core/int_ctrl.vhd"
|
vcom -explicit -93 "../src/core/int_ctrl.vhd"
|
||||||
vcom -explicit -93 "../src/core/alu.vhd"
|
vcom -explicit -93 "../src/core/alu.vhd"
|
||||||
vcom -explicit -93 "../src/core/cpu.vhd"
|
vcom -explicit -93 "../src/core/cpu.vhd"
|
||||||
vcom -explicit -93 "../src/itest_irom.vhdl"
|
vcom -explicit -93 "../src/test_irom.vhdl"
|
||||||
vcom -explicit -93 "../src/tb_cpu_itest.vhd"
|
vcom -explicit -93 "../src/core/tb_cpu.vhd"
|
||||||
vsim -t 1ps -lib work tb_cpu
|
vsim -t 1ps -lib work tb_cpu
|
||||||
do {tb_cpu.wdo}
|
do {tb_cpu.wdo}
|
||||||
view wave
|
view wave
|
||||||
|
|||||||
@@ -12,7 +12,7 @@ vcom -explicit -93 "../src/core/alu.vhd"
|
|||||||
vcom -explicit -93 "../src/core/cpu.vhd"
|
vcom -explicit -93 "../src/core/cpu.vhd"
|
||||||
vcom -explicit -93 "../src/cpu_embedded.vhd"
|
vcom -explicit -93 "../src/cpu_embedded.vhd"
|
||||||
vcom -explicit -93 "../src/tb_cpu_embedded.vhd"
|
vcom -explicit -93 "../src/tb_cpu_embedded.vhd"
|
||||||
vcom -explicit -93 "../src/itest_irom.vhdl"
|
vcom -explicit -93 "../src/test_irom.vhdl"
|
||||||
vsim -t 1ps -lib work tb_cpu_embedded
|
vsim -t 1ps -lib work tb_cpu_embedded
|
||||||
do {tb_cpu_embedded.wdo}
|
do {tb_cpu_embedded.wdo}
|
||||||
view wave
|
view wave
|
||||||
|
|||||||
@@ -42,7 +42,7 @@ end chipreg;
|
|||||||
|
|
||||||
architecture Behavioral of chipreg is
|
architecture Behavioral of chipreg is
|
||||||
|
|
||||||
signal reg_bank_sel : bank_sel_t;
|
signal reg_page_sel : page_sel_t;
|
||||||
signal reg_int_ctrl : int_ctrl_in_t;
|
signal reg_int_ctrl : int_ctrl_in_t;
|
||||||
signal reg_stk_high : unsigned(IMEM_ADDR_WIDTH-DMEM_ADDR_WIDTH-1 downto 0);
|
signal reg_stk_high : unsigned(IMEM_ADDR_WIDTH-DMEM_ADDR_WIDTH-1 downto 0);
|
||||||
signal reg_cmem_high : unsigned(IMEM_ADDR_WIDTH-DMEM_ADDR_WIDTH-1 downto 0);
|
signal reg_cmem_high : unsigned(IMEM_ADDR_WIDTH-DMEM_ADDR_WIDTH-1 downto 0);
|
||||||
@@ -53,7 +53,7 @@ proc_assign_ctrl_lines:
|
|||||||
process (clk)
|
process (clk)
|
||||||
begin
|
begin
|
||||||
if rising_edge(clk) then
|
if rising_edge(clk) then
|
||||||
ctrl_out.bank_sel <= reg_bank_sel;
|
ctrl_out.page_sel <= reg_page_sel;
|
||||||
ctrl_out.int_ctrl <= reg_int_ctrl;
|
ctrl_out.int_ctrl <= reg_int_ctrl;
|
||||||
ctrl_out.stk_high <= reg_stk_high;
|
ctrl_out.stk_high <= reg_stk_high;
|
||||||
ctrl_out.cmem_high <= reg_cmem_high;
|
ctrl_out.cmem_high <= reg_cmem_high;
|
||||||
@@ -66,15 +66,21 @@ proc_reg_write:
|
|||||||
if rst = '1' then
|
if rst = '1' then
|
||||||
reg_stk_high <= (others => '0');
|
reg_stk_high <= (others => '0');
|
||||||
reg_cmem_high <= (others => '0');
|
reg_cmem_high <= (others => '0');
|
||||||
reg_bank_sel <= (others => '0');
|
reg_page_sel <= (others => '0');
|
||||||
reg_int_ctrl.enable <= '0';
|
reg_int_ctrl.enable <= '0';
|
||||||
|
reg_int_ctrl.polarity <= '1';
|
||||||
|
reg_int_ctrl.edge_sens <= '1';
|
||||||
elsif rising_edge(clk) then
|
elsif rising_edge(clk) then
|
||||||
|
reg_int_ctrl.request <= '0';
|
||||||
if we = '1' then
|
if we = '1' then
|
||||||
case addr is
|
case addr is
|
||||||
when X"01" =>
|
when X"01" =>
|
||||||
reg_bank_sel(bank_sel_t'range) <= din(bank_sel_t'range);
|
reg_page_sel(page_sel_t'range) <= din(page_sel_t'range);
|
||||||
when X"03" =>
|
when X"03" =>
|
||||||
reg_int_ctrl.enable <= din(0);
|
reg_int_ctrl.enable <= din(0);
|
||||||
|
reg_int_ctrl.polarity <= din(1);
|
||||||
|
reg_int_ctrl.edge_sens <= din(2);
|
||||||
|
reg_int_ctrl.request <= din(7);
|
||||||
when X"04" =>
|
when X"04" =>
|
||||||
reg_cmem_high <= din(IMEM_ADDR_WIDTH-DMEM_ADDR_WIDTH-1 downto 0);
|
reg_cmem_high <= din(IMEM_ADDR_WIDTH-DMEM_ADDR_WIDTH-1 downto 0);
|
||||||
when X"05" =>
|
when X"05" =>
|
||||||
@@ -93,11 +99,11 @@ proc_reg_read:
|
|||||||
when X"00" => -- Revison
|
when X"00" => -- Revison
|
||||||
dout <= to_unsigned(REVISION, dmem_data_t'length);
|
dout <= to_unsigned(REVISION, dmem_data_t'length);
|
||||||
when X"01" => -- Control 0
|
when X"01" => -- Control 0
|
||||||
dout <= (7 downto bank_sel_t'length => '0') & reg_bank_sel;
|
dout <= (7 downto page_sel_t'length => '0') & reg_page_sel;
|
||||||
when X"02" => -- CPU status
|
when X"02" => -- CPU status
|
||||||
dout <= "000000" & ctrl_in.alu.carry & ctrl_in.alu.zero;
|
dout <= "000000" & ctrl_in.alu.carry & ctrl_in.alu.zero;
|
||||||
when X"03" => -- Interrupt control
|
when X"03" => -- Interrupt control
|
||||||
dout <= "0000000" & reg_int_ctrl.enable;
|
dout <= "00000" & reg_int_ctrl.edge_sens & reg_int_ctrl.polarity & reg_int_ctrl.enable;
|
||||||
when X"04" => -- Upper stack bits out
|
when X"04" => -- Upper stack bits out
|
||||||
dout <= "0000" & reg_cmem_high;
|
dout <= "0000" & reg_cmem_high;
|
||||||
when X"05" => -- Upper cmem bits out
|
when X"05" => -- Upper cmem bits out
|
||||||
|
|||||||
@@ -39,6 +39,7 @@ entity cpu is
|
|||||||
ce : in STD_LOGIC;
|
ce : in STD_LOGIC;
|
||||||
int_in : in STD_LOGIC;
|
int_in : in STD_LOGIC;
|
||||||
int_ack : out STD_LOGIC;
|
int_ack : out STD_LOGIC;
|
||||||
|
xmem_wait : in STD_LOGIC;
|
||||||
xmem_we : out STD_LOGIC;
|
xmem_we : out STD_LOGIC;
|
||||||
xmem_re : out STD_LOGIC;
|
xmem_re : out STD_LOGIC;
|
||||||
instr_din : in unsigned (IMEM_DATA_WIDTH-1 downto 0);
|
instr_din : in unsigned (IMEM_DATA_WIDTH-1 downto 0);
|
||||||
@@ -214,12 +215,13 @@ begin
|
|||||||
pc_inc <= cpu_active and ctrl.lines.pc_inc;
|
pc_inc <= cpu_active and ctrl.lines.pc_inc;
|
||||||
stk_addr <= '0' & stk_ptr;
|
stk_addr <= '0' & stk_ptr;
|
||||||
cpu_status.alu <= alu_status;
|
cpu_status.alu <= alu_status;
|
||||||
|
cpu_status.xmem_wait <= xmem_wait;
|
||||||
creg_ctrl_in.alu <= alu_status;
|
creg_ctrl_in.alu <= alu_status;
|
||||||
|
|
||||||
xmem_dout <= mem_data;
|
xmem_dout <= mem_data;
|
||||||
xmem_addr <= mem_addr;
|
xmem_addr <= mem_addr;
|
||||||
cmem_din <= creg_ctrl_out.cmem_high & mem_data;
|
cmem_din <= creg_ctrl_out.cmem_high & mem_data;
|
||||||
cmem_addr <= '1' & creg_ctrl_out.bank_sel & mem_addr(MIN(cmem_addr'length-creg_ctrl_out.bank_sel'length-1, mem_addr'length)-1 downto 0);
|
cmem_addr <= '1' & creg_ctrl_out.page_sel & mem_addr(MIN(cmem_addr'length-creg_ctrl_out.page_sel'length-1, mem_addr'length)-1 downto 0);
|
||||||
|
|
||||||
--------------------------------------------------------------------
|
--------------------------------------------------------------------
|
||||||
mem_ctrl_lines:
|
mem_ctrl_lines:
|
||||||
@@ -366,7 +368,7 @@ mem_data_mux:
|
|||||||
end process;
|
end process;
|
||||||
|
|
||||||
mem_addr_mux:
|
mem_addr_mux:
|
||||||
process(ctrl.lines.daddr_src_sel, reg_a_dout, reg_b_dout, const_data, creg_ctrl_out.bank_sel)
|
process(ctrl.lines.daddr_src_sel, reg_a_dout, reg_b_dout, const_data, creg_ctrl_out.page_sel)
|
||||||
begin
|
begin
|
||||||
case ctrl.lines.daddr_src_sel is
|
case ctrl.lines.daddr_src_sel is
|
||||||
when reg_a =>
|
when reg_a =>
|
||||||
|
|||||||
@@ -34,6 +34,9 @@ package cpu_pkg is
|
|||||||
-- Chipram depth (valid values 9..floor(log2(BlockRamBytes)))
|
-- Chipram depth (valid values 9..floor(log2(BlockRamBytes)))
|
||||||
constant CHIPRAM_SIZE_BITS : integer := 10;
|
constant CHIPRAM_SIZE_BITS : integer := 10;
|
||||||
|
|
||||||
|
-- Chipregister file depth
|
||||||
|
constant CHIPREG_SIZE_BITS : integer := 8;
|
||||||
|
|
||||||
-- Number of registers (16 registers fixed)
|
-- Number of registers (16 registers fixed)
|
||||||
constant REG_SIZE_BITS : integer := 4;
|
constant REG_SIZE_BITS : integer := 4;
|
||||||
|
|
||||||
@@ -49,7 +52,7 @@ package cpu_pkg is
|
|||||||
constant IMEM_DATA_WIDTH : integer := INST_OPCODE_WIDTH + DMEM_DATA_WIDTH + REG_SIZE_BITS;
|
constant IMEM_DATA_WIDTH : integer := INST_OPCODE_WIDTH + DMEM_DATA_WIDTH + REG_SIZE_BITS;
|
||||||
|
|
||||||
-- Microcode ROM
|
-- Microcode ROM
|
||||||
constant MUCODE_ADDR_WIDTH : integer := 9;
|
constant MUCODE_ADDR_WIDTH : integer := 10;
|
||||||
|
|
||||||
-- Stack depth (uses lower half of CHIPRAM)
|
-- Stack depth (uses lower half of CHIPRAM)
|
||||||
constant STACK_SIZE_BITS : integer := CHIPRAM_SIZE_BITS-1;
|
constant STACK_SIZE_BITS : integer := CHIPRAM_SIZE_BITS-1;
|
||||||
@@ -72,7 +75,7 @@ package cpu_pkg is
|
|||||||
subtype reg_ptr_t is unsigned (3 downto 0);
|
subtype reg_ptr_t is unsigned (3 downto 0);
|
||||||
type dmem_array_t is array (natural range <>) of dmem_data_t;
|
type dmem_array_t is array (natural range <>) of dmem_data_t;
|
||||||
type instr_addr_array is array (integer range <>) of inst_addr_t;
|
type instr_addr_array is array (integer range <>) of inst_addr_t;
|
||||||
subtype bank_sel_t is unsigned (CHIPRAM_SIZE_BITS-DMEM_DATA_WIDTH-2 downto 0);
|
subtype page_sel_t is unsigned (CHIPRAM_SIZE_BITS-DMEM_DATA_WIDTH-2 downto 0);
|
||||||
|
|
||||||
type alu_op_t is
|
type alu_op_t is
|
||||||
(
|
(
|
||||||
@@ -100,6 +103,7 @@ package cpu_pkg is
|
|||||||
|
|
||||||
type cpu_status_t is record
|
type cpu_status_t is record
|
||||||
alu : alu_status_t;
|
alu : alu_status_t;
|
||||||
|
xmem_wait : STD_LOGIC;
|
||||||
end record;
|
end record;
|
||||||
|
|
||||||
type ctrl_lines_t is record
|
type ctrl_lines_t is record
|
||||||
@@ -132,10 +136,13 @@ package cpu_pkg is
|
|||||||
|
|
||||||
type int_ctrl_in_t is record
|
type int_ctrl_in_t is record
|
||||||
enable : std_logic;
|
enable : std_logic;
|
||||||
|
polarity : std_logic;
|
||||||
|
edge_sens : std_logic;
|
||||||
|
request : std_logic;
|
||||||
end record;
|
end record;
|
||||||
|
|
||||||
type creg_ctrl_out_t is record
|
type creg_ctrl_out_t is record
|
||||||
bank_sel : bank_sel_t;
|
page_sel : page_sel_t;
|
||||||
int_ctrl : int_ctrl_in_t;
|
int_ctrl : int_ctrl_in_t;
|
||||||
stk_high : unsigned(IMEM_ADDR_WIDTH-DMEM_ADDR_WIDTH-1 downto 0);
|
stk_high : unsigned(IMEM_ADDR_WIDTH-DMEM_ADDR_WIDTH-1 downto 0);
|
||||||
cmem_high : unsigned(IMEM_ADDR_WIDTH-DMEM_ADDR_WIDTH-1 downto 0);
|
cmem_high : unsigned(IMEM_ADDR_WIDTH-DMEM_ADDR_WIDTH-1 downto 0);
|
||||||
@@ -330,11 +337,12 @@ package body cpu_pkg is
|
|||||||
|
|
||||||
function idecoder(instr_name : instr_name_t; iphase : iphase_t; status : cpu_status_t) return ctrl_lines_t is
|
function idecoder(instr_name : instr_name_t; iphase : iphase_t; status : cpu_status_t) return ctrl_lines_t is
|
||||||
variable result : ctrl_lines_t;
|
variable result : ctrl_lines_t;
|
||||||
variable ze, cy : STD_LOGIC;
|
variable ze, cy, xmem_wait : STD_LOGIC;
|
||||||
|
|
||||||
begin
|
begin
|
||||||
ze := status.alu.zero;
|
ze := status.alu.zero;
|
||||||
cy := status.alu.carry;
|
cy := status.alu.carry;
|
||||||
|
xmem_wait := status.xmem_wait;
|
||||||
|
|
||||||
result := ctrl_lines_default;
|
result := ctrl_lines_default;
|
||||||
if iphase = 0 then
|
if iphase = 0 then
|
||||||
@@ -430,6 +438,10 @@ package body cpu_pkg is
|
|||||||
if iphase = 0 then
|
if iphase = 0 then
|
||||||
result.mem_write := '1';
|
result.mem_write := '1';
|
||||||
end if;
|
end if;
|
||||||
|
if xmem_wait = '1' then
|
||||||
|
result.mem_write := '1';
|
||||||
|
result.pc_inc := '0';
|
||||||
|
end if;
|
||||||
when "MOVX|Ri|K " => -- [R(a)] <= kk
|
when "MOVX|Ri|K " => -- [R(a)] <= kk
|
||||||
result.mem_access := xmem_access;
|
result.mem_access := xmem_access;
|
||||||
result.daddr_src_sel := reg_a;
|
result.daddr_src_sel := reg_a;
|
||||||
@@ -437,6 +449,10 @@ package body cpu_pkg is
|
|||||||
if iphase = 0 then
|
if iphase = 0 then
|
||||||
result.mem_write := '1';
|
result.mem_write := '1';
|
||||||
end if;
|
end if;
|
||||||
|
if xmem_wait = '1' then
|
||||||
|
result.mem_write := '1';
|
||||||
|
result.pc_inc := '0';
|
||||||
|
end if;
|
||||||
when "XOUT|Ri|K " => -- [R(a)] <= kk
|
when "XOUT|Ri|K " => -- [R(a)] <= kk
|
||||||
result.mem_access := xio_access;
|
result.mem_access := xio_access;
|
||||||
result.daddr_src_sel := reg_a;
|
result.daddr_src_sel := reg_a;
|
||||||
@@ -444,33 +460,55 @@ package body cpu_pkg is
|
|||||||
if iphase = 0 then
|
if iphase = 0 then
|
||||||
result.mem_write := '1';
|
result.mem_write := '1';
|
||||||
end if;
|
end if;
|
||||||
|
if xmem_wait = '1' then
|
||||||
|
result.pc_inc := '0';
|
||||||
|
result.mem_write := '1';
|
||||||
|
end if;
|
||||||
when "MOVX|R|Ri " => -- R(a) <= [R(b)]
|
when "MOVX|R|Ri " => -- R(a) <= [R(b)]
|
||||||
result.mem_access := xmem_access;
|
result.mem_access := xmem_access;
|
||||||
result.reg_src_sel := xmem_src;
|
result.reg_src_sel := xmem_src;
|
||||||
result.daddr_src_sel := reg_b;
|
result.daddr_src_sel := reg_b;
|
||||||
if iphase = 0 then
|
if iphase = 0 then
|
||||||
result.mem_read := '1';
|
result.mem_read := '1';
|
||||||
elsif iphase = 1 then
|
end if;
|
||||||
|
if xmem_wait = '0' then
|
||||||
|
if iphase = 1 then
|
||||||
result.reg_we := '1';
|
result.reg_we := '1';
|
||||||
end if;
|
end if;
|
||||||
|
else
|
||||||
|
result.pc_inc := '0';
|
||||||
|
result.mem_read := '1';
|
||||||
|
end if;
|
||||||
when "MOVX|R|Ki " => -- R(a) <= [#addr]
|
when "MOVX|R|Ki " => -- R(a) <= [#addr]
|
||||||
result.mem_access := xmem_access;
|
result.mem_access := xmem_access;
|
||||||
result.reg_src_sel := xmem_src;
|
result.reg_src_sel := xmem_src;
|
||||||
result.daddr_src_sel := const;
|
result.daddr_src_sel := const;
|
||||||
if iphase = 0 then
|
if iphase = 0 then
|
||||||
result.mem_read := '1';
|
result.mem_read := '1';
|
||||||
elsif iphase = 1 then
|
end if;
|
||||||
|
if xmem_wait = '0' then
|
||||||
|
if iphase = 1 then
|
||||||
result.reg_we := '1';
|
result.reg_we := '1';
|
||||||
end if;
|
end if;
|
||||||
|
else
|
||||||
|
result.pc_inc := '0';
|
||||||
|
result.mem_read := '1';
|
||||||
|
end if;
|
||||||
when "XIN|R|Ki " => -- R(a) <= [#addr]
|
when "XIN|R|Ki " => -- R(a) <= [#addr]
|
||||||
result.mem_access := xio_access;
|
result.mem_access := xio_access;
|
||||||
result.reg_src_sel := xmem_src;
|
result.reg_src_sel := xmem_src;
|
||||||
result.daddr_src_sel := const;
|
result.daddr_src_sel := const;
|
||||||
if iphase = 0 then
|
if iphase = 0 then
|
||||||
result.mem_read := '1';
|
result.mem_read := '1';
|
||||||
elsif iphase = 1 then
|
end if;
|
||||||
|
if xmem_wait = '0' then
|
||||||
|
if iphase = 1 then
|
||||||
result.reg_we := '1';
|
result.reg_we := '1';
|
||||||
end if;
|
end if;
|
||||||
|
else
|
||||||
|
result.pc_inc := '0';
|
||||||
|
result.mem_read := '1';
|
||||||
|
end if;
|
||||||
when "MOVX|Ki|R " => -- [#addr] <= R(a)
|
when "MOVX|Ki|R " => -- [#addr] <= R(a)
|
||||||
result.mem_access := xmem_access;
|
result.mem_access := xmem_access;
|
||||||
result.daddr_src_sel := const;
|
result.daddr_src_sel := const;
|
||||||
@@ -478,6 +516,10 @@ package body cpu_pkg is
|
|||||||
if iphase = 0 then
|
if iphase = 0 then
|
||||||
result.mem_write := '1';
|
result.mem_write := '1';
|
||||||
end if;
|
end if;
|
||||||
|
if xmem_wait = '1' then
|
||||||
|
result.pc_inc := '0';
|
||||||
|
result.mem_write := '1';
|
||||||
|
end if;
|
||||||
when "XOUT|Ki|R " => -- [#addr] <= R(a)
|
when "XOUT|Ki|R " => -- [#addr] <= R(a)
|
||||||
result.mem_access := xio_access;
|
result.mem_access := xio_access;
|
||||||
result.daddr_src_sel := const;
|
result.daddr_src_sel := const;
|
||||||
@@ -485,6 +527,10 @@ package body cpu_pkg is
|
|||||||
if iphase = 0 then
|
if iphase = 0 then
|
||||||
result.mem_write := '1';
|
result.mem_write := '1';
|
||||||
end if;
|
end if;
|
||||||
|
if xmem_wait = '1' then
|
||||||
|
result.pc_inc := '0';
|
||||||
|
result.mem_write := '1';
|
||||||
|
end if;
|
||||||
when "ADD|R|R " => -- R(a) <= R(a) + R(b)
|
when "ADD|R|R " => -- R(a) <= R(a) + R(b)
|
||||||
result.alu_opsel := op1_add_op2;
|
result.alu_opsel := op1_add_op2;
|
||||||
result.alu_op1_src_sel := reg_a;
|
result.alu_op1_src_sel := reg_a;
|
||||||
@@ -812,6 +858,8 @@ package body cpu_pkg is
|
|||||||
status.alu.zero := addr(pos);
|
status.alu.zero := addr(pos);
|
||||||
pos := pos + 1;
|
pos := pos + 1;
|
||||||
status.alu.carry := addr(pos);
|
status.alu.carry := addr(pos);
|
||||||
|
pos := pos + 1;
|
||||||
|
status.xmem_wait := addr(pos);
|
||||||
|
|
||||||
result(i) := idecoder(opcode, iphase, status);
|
result(i) := idecoder(opcode, iphase, status);
|
||||||
end loop;
|
end loop;
|
||||||
@@ -822,7 +870,7 @@ package body cpu_pkg is
|
|||||||
function get_muromaddr (opcode : opcode_t; iphase : iphase_t; status : cpu_status_t) return unsigned is
|
function get_muromaddr (opcode : opcode_t; iphase : iphase_t; status : cpu_status_t) return unsigned is
|
||||||
variable addr : unsigned(MUCODE_ADDR_WIDTH-1 downto 0);
|
variable addr : unsigned(MUCODE_ADDR_WIDTH-1 downto 0);
|
||||||
begin
|
begin
|
||||||
addr := status.alu.carry & status.alu.zero & to_unsigned(iphase, 1) & opcode;
|
addr := status.xmem_wait & status.alu.carry & status.alu.zero & to_unsigned(iphase, 1) & opcode;
|
||||||
return addr;
|
return addr;
|
||||||
|
|
||||||
end get_muromaddr;
|
end get_muromaddr;
|
||||||
|
|||||||
@@ -48,11 +48,13 @@ end int_ctrl;
|
|||||||
architecture Behavioral of int_ctrl is
|
architecture Behavioral of int_ctrl is
|
||||||
|
|
||||||
type int_state_t is (int_idle, int_inject, int_active, int_release);
|
type int_state_t is (int_idle, int_inject, int_active, int_release);
|
||||||
|
type pin_state_t is (pin_s0, pin_s1, pin_s2);
|
||||||
|
|
||||||
signal int_state, int_state_next : int_state_t;
|
signal int_state, int_state_next : int_state_t;
|
||||||
|
signal pin_state, pin_state_next : pin_state_t;
|
||||||
signal pc_load, int_ack, stk_push, stk_pop : STD_LOGIC;
|
signal pc_load, int_ack, stk_push, stk_pop : STD_LOGIC;
|
||||||
signal int_request : std_logic;
|
signal int_request : std_logic;
|
||||||
|
signal int_sampled : std_logic;
|
||||||
|
|
||||||
begin
|
begin
|
||||||
|
|
||||||
@@ -72,6 +74,7 @@ irg_ctrl_fsm:
|
|||||||
pc_load <= '0';
|
pc_load <= '0';
|
||||||
stk_push <= '0';
|
stk_push <= '0';
|
||||||
stk_pop <= '0';
|
stk_pop <= '0';
|
||||||
|
|
||||||
case int_state is
|
case int_state is
|
||||||
|
|
||||||
when int_idle =>
|
when int_idle =>
|
||||||
@@ -118,10 +121,46 @@ pin_sample:
|
|||||||
process (clk)
|
process (clk)
|
||||||
begin
|
begin
|
||||||
if rising_edge(clk) then
|
if rising_edge(clk) then
|
||||||
int_request <= '0';
|
int_sampled <= int_in xor (not ctrl_in.polarity);
|
||||||
if ctrl_in.enable = '1' then
|
|
||||||
int_request <= int_in;
|
|
||||||
end if;
|
end if;
|
||||||
|
end process;
|
||||||
|
|
||||||
|
-----------------------------------------------------------------------
|
||||||
|
pin_fsm:
|
||||||
|
process (pin_state, int_sampled, int_ack, ctrl_in)
|
||||||
|
begin
|
||||||
|
int_request <= '0';
|
||||||
|
pin_state_next <= pin_state;
|
||||||
|
case pin_state is
|
||||||
|
when pin_s0 =>
|
||||||
|
if int_sampled = '1' or ctrl_in.request = '1' then
|
||||||
|
if ctrl_in.enable = '1' then
|
||||||
|
pin_state_next <= pin_s1;
|
||||||
|
end if;
|
||||||
|
end if;
|
||||||
|
when pin_s1 =>
|
||||||
|
int_request <= '1';
|
||||||
|
if int_ack = '1' then
|
||||||
|
pin_state_next <= pin_s2;
|
||||||
|
end if;
|
||||||
|
when pin_s2 =>
|
||||||
|
if ctrl_in.edge_sens = '0' then
|
||||||
|
pin_state_next <= pin_s0;
|
||||||
|
elsif int_sampled = '0' then
|
||||||
|
pin_state_next <= pin_s0;
|
||||||
|
end if;
|
||||||
|
when others =>
|
||||||
|
pin_state_next <= pin_s0;
|
||||||
|
end case;
|
||||||
|
end process;
|
||||||
|
|
||||||
|
pin_states:
|
||||||
|
process (rst, clk, pin_state_next)
|
||||||
|
begin
|
||||||
|
if rst = '1' then
|
||||||
|
pin_state <= pin_s0;
|
||||||
|
elsif rising_edge(clk) then
|
||||||
|
pin_state <= pin_state_next;
|
||||||
end if;
|
end if;
|
||||||
end process;
|
end process;
|
||||||
|
|
||||||
|
|||||||
@@ -34,6 +34,7 @@ entity cpu_embedded is
|
|||||||
ce : in STD_LOGIC;
|
ce : in STD_LOGIC;
|
||||||
int_in : in STD_LOGIC;
|
int_in : in STD_LOGIC;
|
||||||
int_ack : out STD_LOGIC;
|
int_ack : out STD_LOGIC;
|
||||||
|
xmem_wait : in STD_LOGIC;
|
||||||
xmem_we : out STD_LOGIC;
|
xmem_we : out STD_LOGIC;
|
||||||
xmem_re : out STD_LOGIC;
|
xmem_re : out STD_LOGIC;
|
||||||
xmem_din : in unsigned (DMEM_DATA_WIDTH-1 downto 0);
|
xmem_din : in unsigned (DMEM_DATA_WIDTH-1 downto 0);
|
||||||
@@ -55,6 +56,7 @@ architecture rtl of cpu_embedded is
|
|||||||
ce : in STD_LOGIC;
|
ce : in STD_LOGIC;
|
||||||
int_in : in STD_LOGIC;
|
int_in : in STD_LOGIC;
|
||||||
int_ack : out STD_LOGIC;
|
int_ack : out STD_LOGIC;
|
||||||
|
xmem_wait : in STD_LOGIC;
|
||||||
xmem_we : out STD_LOGIC;
|
xmem_we : out STD_LOGIC;
|
||||||
xmem_re : out STD_LOGIC;
|
xmem_re : out STD_LOGIC;
|
||||||
instr_din : in unsigned (IMEM_DATA_WIDTH-1 downto 0);
|
instr_din : in unsigned (IMEM_DATA_WIDTH-1 downto 0);
|
||||||
@@ -85,6 +87,7 @@ inst_cpu: cpu
|
|||||||
ce => ce,
|
ce => ce,
|
||||||
int_in => int_in,
|
int_in => int_in,
|
||||||
int_ack => int_ack,
|
int_ack => int_ack,
|
||||||
|
xmem_wait => xmem_wait,
|
||||||
xmem_we => xmem_we,
|
xmem_we => xmem_we,
|
||||||
xmem_re => xmem_re,
|
xmem_re => xmem_re,
|
||||||
instr_din => irom_data,
|
instr_din => irom_data,
|
||||||
|
|||||||
@@ -26,22 +26,25 @@ use IEEE.STD_LOGIC_1164.ALL;
|
|||||||
USE ieee.numeric_std.ALL;
|
USE ieee.numeric_std.ALL;
|
||||||
|
|
||||||
library work;
|
library work;
|
||||||
use work.cpu_pkg.all;
|
use work.types_pkg.all;
|
||||||
|
|
||||||
-- JASM_ROM_INSERT_HERE
|
-- JASM_ROM_INSERT_HERE
|
||||||
ENTITY irom IS
|
ENTITY irom IS
|
||||||
Port
|
Generic
|
||||||
(
|
(
|
||||||
|
depth : integer := 4
|
||||||
|
);
|
||||||
|
Port (
|
||||||
clk : in STD_LOGIC;
|
clk : in STD_LOGIC;
|
||||||
ce : in STD_LOGIC;
|
ce : in STD_LOGIC;
|
||||||
addr : in inst_addr_t;
|
addr : in addr_t;
|
||||||
dout : out inst_t
|
dout : out word_t
|
||||||
);
|
);
|
||||||
END irom;
|
END irom;
|
||||||
|
|
||||||
ARCHITECTURE itest OF irom IS
|
ARCHITECTURE itest OF irom IS
|
||||||
|
|
||||||
type imem_rom_t is array (0 to 1023) of inst_t;
|
type imem_rom_t is array (0 to depth-1) of word_t;
|
||||||
|
|
||||||
-- Assembled from itest.jsm
|
-- Assembled from itest.jsm
|
||||||
constant imem_rom : imem_rom_t :=
|
constant imem_rom : imem_rom_t :=
|
||||||
|
|||||||
@@ -41,6 +41,7 @@ ARCHITECTURE behavior OF tb_cpu_embedded IS
|
|||||||
ce : in STD_LOGIC;
|
ce : in STD_LOGIC;
|
||||||
int_in : in STD_LOGIC;
|
int_in : in STD_LOGIC;
|
||||||
int_ack : out STD_LOGIC;
|
int_ack : out STD_LOGIC;
|
||||||
|
xmem_wait : in STD_LOGIC;
|
||||||
xmem_we : out STD_LOGIC;
|
xmem_we : out STD_LOGIC;
|
||||||
xmem_re : out STD_LOGIC;
|
xmem_re : out STD_LOGIC;
|
||||||
xmem_din : in unsigned (DMEM_DATA_WIDTH-1 downto 0);
|
xmem_din : in unsigned (DMEM_DATA_WIDTH-1 downto 0);
|
||||||
@@ -57,6 +58,7 @@ ARCHITECTURE behavior OF tb_cpu_embedded IS
|
|||||||
signal ce : std_logic := '0';
|
signal ce : std_logic := '0';
|
||||||
signal int_in : std_logic := '0';
|
signal int_in : std_logic := '0';
|
||||||
signal int_ack : std_logic;
|
signal int_ack : std_logic;
|
||||||
|
signal xmem_wait : std_logic := '0';
|
||||||
signal xmem_din : dmem_data_t := (others => '-');
|
signal xmem_din : dmem_data_t := (others => '-');
|
||||||
signal xmem_dout : dmem_data_t;
|
signal xmem_dout : dmem_data_t;
|
||||||
signal xmem_addr : dmem_addr_t;
|
signal xmem_addr : dmem_addr_t;
|
||||||
@@ -75,6 +77,7 @@ uut: cpu_embedded
|
|||||||
ce => ce,
|
ce => ce,
|
||||||
int_in => int_in,
|
int_in => int_in,
|
||||||
int_ack => int_ack,
|
int_ack => int_ack,
|
||||||
|
xmem_wait => xmem_wait,
|
||||||
xmem_we => xmem_we,
|
xmem_we => xmem_we,
|
||||||
xmem_re => xmem_re,
|
xmem_re => xmem_re,
|
||||||
xmem_din => xmem_din,
|
xmem_din => xmem_din,
|
||||||
|
|||||||
@@ -47,6 +47,7 @@ ARCHITECTURE behavior OF tb_cpu IS
|
|||||||
ce : in STD_LOGIC;
|
ce : in STD_LOGIC;
|
||||||
int_in : in STD_LOGIC;
|
int_in : in STD_LOGIC;
|
||||||
int_ack : out STD_LOGIC;
|
int_ack : out STD_LOGIC;
|
||||||
|
xmem_wait : in STD_LOGIC;
|
||||||
xmem_we : out STD_LOGIC;
|
xmem_we : out STD_LOGIC;
|
||||||
xmem_re : out STD_LOGIC;
|
xmem_re : out STD_LOGIC;
|
||||||
instr_din : in unsigned (IMEM_DATA_WIDTH-1 downto 0);
|
instr_din : in unsigned (IMEM_DATA_WIDTH-1 downto 0);
|
||||||
@@ -76,6 +77,7 @@ ARCHITECTURE behavior OF tb_cpu IS
|
|||||||
signal ce : std_logic := '0';
|
signal ce : std_logic := '0';
|
||||||
signal int_in : std_logic := '0';
|
signal int_in : std_logic := '0';
|
||||||
signal int_ack : std_logic;
|
signal int_ack : std_logic;
|
||||||
|
signal xmem_wait : std_logic := '1';
|
||||||
signal irom_data : unsigned (IMEM_DATA_WIDTH-1 downto 0) := (others => '-');
|
signal irom_data : unsigned (IMEM_DATA_WIDTH-1 downto 0) := (others => '-');
|
||||||
signal irom_addr : unsigned (IMEM_ADDR_WIDTH-1 downto 0);
|
signal irom_addr : unsigned (IMEM_ADDR_WIDTH-1 downto 0);
|
||||||
signal xmem_din : dmem_data_t := (others => '-');
|
signal xmem_din : dmem_data_t := (others => '-');
|
||||||
@@ -110,6 +112,7 @@ uut: cpu
|
|||||||
ce => ce,
|
ce => ce,
|
||||||
int_in => int_in,
|
int_in => int_in,
|
||||||
int_ack => int_ack,
|
int_ack => int_ack,
|
||||||
|
xmem_wait => xmem_wait,
|
||||||
xmem_we => xmem_we,
|
xmem_we => xmem_we,
|
||||||
xmem_re => xmem_re,
|
xmem_re => xmem_re,
|
||||||
instr_din => irom_data,
|
instr_din => irom_data,
|
||||||
@@ -134,6 +137,21 @@ CLK_GEN: process
|
|||||||
clk <= not clk;
|
clk <= not clk;
|
||||||
end process;
|
end process;
|
||||||
|
|
||||||
|
XWAIT_GEN:process(rst, clk)
|
||||||
|
variable cnt : unsigned(3 downto 0);
|
||||||
|
begin
|
||||||
|
if (rst = '1') then
|
||||||
|
cnt := (others => '1');
|
||||||
|
elsif rising_edge(clk) then
|
||||||
|
if cnt /= "0000" then
|
||||||
|
cnt := cnt - 1;
|
||||||
|
else
|
||||||
|
cnt := (others => '1');
|
||||||
|
xmem_wait <= not xmem_wait;
|
||||||
|
end if;
|
||||||
|
end if;
|
||||||
|
end process;
|
||||||
|
|
||||||
STIMULUS: process
|
STIMULUS: process
|
||||||
file RESULT: text open write_mode is "../tools/opc.list";
|
file RESULT: text open write_mode is "../tools/opc.list";
|
||||||
variable L: line;
|
variable L: line;
|
||||||
|
|||||||
Binary file not shown.
@@ -0,0 +1,15 @@
|
|||||||
|
## NOTE: Do not edit this file.
|
||||||
|
##
|
||||||
|
vlib work
|
||||||
|
vcom -explicit -93 "../../../PCK_FIO-1.16/PCK_FIO.vhd"
|
||||||
|
vcom -explicit -93 "../src/core/mips_types.vhd"
|
||||||
|
vcom -explicit -93 "../src/core/mips_instr.vhd"
|
||||||
|
vcom -explicit -93 "../src/core/mips_muldiv.vhd"
|
||||||
|
vcom -explicit -93 "../src/tb_mips_muldiv.vhd"
|
||||||
|
vsim -t 1ps -lib work tb_mips_muldiv
|
||||||
|
do {tb_mips_muldiv.wdo}
|
||||||
|
view wave
|
||||||
|
|
||||||
|
view structure
|
||||||
|
view signals
|
||||||
|
run 8ms
|
||||||
@@ -0,0 +1,78 @@
|
|||||||
|
onerror {resume}
|
||||||
|
quietly WaveActivateNextPane {} 0
|
||||||
|
add wave -noupdate -format Logic /tb_mips_muldiv/rst
|
||||||
|
add wave -noupdate -format Logic /tb_mips_muldiv/clk
|
||||||
|
add wave -noupdate -format Logic /tb_mips_muldiv/mul_divn
|
||||||
|
add wave -noupdate -format Logic /tb_mips_muldiv/start
|
||||||
|
add wave -noupdate -format Logic /tb_mips_muldiv/busy
|
||||||
|
add wave -noupdate -format Logic /tb_mips_muldiv/s_un
|
||||||
|
add wave -noupdate -format Literal -radix hexadecimal /tb_mips_muldiv/ref_hi
|
||||||
|
add wave -noupdate -format Literal -radix hexadecimal /tb_mips_muldiv/uut/din_hi
|
||||||
|
add wave -noupdate -format Literal -radix hexadecimal /tb_mips_muldiv/uut/din_lo
|
||||||
|
add wave -noupdate -format Logic /tb_mips_muldiv/hilo_sel
|
||||||
|
add wave -noupdate -format Logic /tb_mips_muldiv/hilo_we
|
||||||
|
add wave -noupdate -format Literal -radix hexadecimal /tb_mips_muldiv/dout
|
||||||
|
add wave -noupdate -format Literal -radix hexadecimal /tb_mips_muldiv/ref_result
|
||||||
|
add wave -noupdate -format Literal -radix hexadecimal /tb_mips_muldiv/md_result
|
||||||
|
add wave -noupdate -format Logic /tb_mips_muldiv/check
|
||||||
|
add wave -noupdate -format Logic /tb_mips_muldiv/uut/pre_sum_vld
|
||||||
|
add wave -noupdate -format Logic /tb_mips_muldiv/uut/mul_en
|
||||||
|
add wave -noupdate -format Logic /tb_mips_muldiv/uut/sum_en
|
||||||
|
add wave -noupdate -divider FSM
|
||||||
|
add wave -noupdate -format Literal /tb_mips_muldiv/uut/cycle_cnt
|
||||||
|
add wave -noupdate -format Logic /tb_mips_muldiv/uut/cycle_cnt_load
|
||||||
|
add wave -noupdate -format Literal /tb_mips_muldiv/uut/cycle_cnt_preset
|
||||||
|
add wave -noupdate -format Literal /tb_mips_muldiv/uut/s
|
||||||
|
add wave -noupdate -format Literal /tb_mips_muldiv/uut/sn
|
||||||
|
add wave -noupdate -divider {Multiplier internals}
|
||||||
|
add wave -noupdate -format Literal -radix hexadecimal -expand /tb_mips_muldiv/uut/pprod
|
||||||
|
add wave -noupdate -format Literal /tb_mips_muldiv/uut/ppadd_cyi
|
||||||
|
add wave -noupdate -format Literal /tb_mips_muldiv/uut/ppadd_cyo
|
||||||
|
add wave -noupdate -format Literal -radix hexadecimal /tb_mips_muldiv/uut/ppadd_op1
|
||||||
|
add wave -noupdate -format Literal -radix hexadecimal /tb_mips_muldiv/uut/ppadd_op2
|
||||||
|
add wave -noupdate -format Literal -radix hexadecimal /tb_mips_muldiv/uut/ppadd_res
|
||||||
|
add wave -noupdate -format Literal -radix hexadecimal /tb_mips_muldiv/uut/pp_op2
|
||||||
|
add wave -noupdate -format Literal -radix hexadecimal /tb_mips_muldiv/uut/pp_op2_r
|
||||||
|
add wave -noupdate -format Literal -radix hexadecimal /tb_mips_muldiv/uut/add_op1
|
||||||
|
add wave -noupdate -format Literal -radix hexadecimal /tb_mips_muldiv/uut/add_op2
|
||||||
|
add wave -noupdate -format Literal -radix hexadecimal /tb_mips_muldiv/uut/add_res
|
||||||
|
add wave -noupdate -format Literal -radix hexadecimal /tb_mips_muldiv/uut/pp_reg
|
||||||
|
add wave -noupdate -divider {Divider internals}
|
||||||
|
add wave -noupdate -format Logic /tb_mips_muldiv/busy
|
||||||
|
add wave -noupdate -format Logic /tb_mips_muldiv/s_un
|
||||||
|
add wave -noupdate -format Logic /tb_mips_muldiv/uut/div_start
|
||||||
|
add wave -noupdate -format Literal -radix hexadecimal /tb_mips_muldiv/uut/din_hi
|
||||||
|
add wave -noupdate -format Literal -radix hexadecimal /tb_mips_muldiv/uut/din_lo
|
||||||
|
add wave -noupdate -format Literal -radix hexadecimal /tb_mips_muldiv/uut/result
|
||||||
|
add wave -noupdate -format Logic /tb_mips_muldiv/uut/div_add_cyi
|
||||||
|
add wave -noupdate -format Literal -radix hexadecimal /tb_mips_muldiv/uut/div_add_op1
|
||||||
|
add wave -noupdate -format Literal -radix hexadecimal /tb_mips_muldiv/uut/div_add_op2
|
||||||
|
add wave -noupdate -format Literal -radix hexadecimal /tb_mips_muldiv/uut/div_add_res
|
||||||
|
add wave -noupdate -format Literal -radix hexadecimal /tb_mips_muldiv/uut/div_m
|
||||||
|
add wave -noupdate -format Literal -radix hexadecimal /tb_mips_muldiv/uut/div_m_n
|
||||||
|
add wave -noupdate -format Literal -radix hexadecimal /tb_mips_muldiv/uut/div_a
|
||||||
|
add wave -noupdate -format Literal -radix hexadecimal /tb_mips_muldiv/uut/div_q
|
||||||
|
add wave -noupdate -format Logic /tb_mips_muldiv/uut/div_qbit
|
||||||
|
add wave -noupdate -format Logic /tb_mips_muldiv/uut/div_en
|
||||||
|
add wave -noupdate -divider FSM
|
||||||
|
add wave -noupdate -format Literal /tb_mips_muldiv/uut/cycle_cnt
|
||||||
|
add wave -noupdate -format Logic /tb_mips_muldiv/uut/cycle_cnt_load
|
||||||
|
add wave -noupdate -format Literal /tb_mips_muldiv/uut/cycle_cnt_preset
|
||||||
|
add wave -noupdate -format Literal /tb_mips_muldiv/uut/s
|
||||||
|
add wave -noupdate -format Literal /tb_mips_muldiv/uut/sn
|
||||||
|
TreeUpdate [SetDefaultTree]
|
||||||
|
WaveRestoreCursors {{Cursor 1} {7735999838 ps} 0} {{Cursor 2} {512321 ps} 0}
|
||||||
|
configure wave -namecolwidth 149
|
||||||
|
configure wave -valuecolwidth 171
|
||||||
|
configure wave -justifyvalue left
|
||||||
|
configure wave -signalnamewidth 1
|
||||||
|
configure wave -snapdistance 10
|
||||||
|
configure wave -datasetprefix 0
|
||||||
|
configure wave -rowmargin 4
|
||||||
|
configure wave -childrowmargin 2
|
||||||
|
configure wave -gridoffset 0
|
||||||
|
configure wave -gridperiod 100
|
||||||
|
configure wave -griddelta 40
|
||||||
|
configure wave -timeline 1
|
||||||
|
update
|
||||||
|
WaveRestoreZoom {0 ps} {8400 us}
|
||||||
@@ -0,0 +1,39 @@
|
|||||||
|
## NOTE: Do not edit this file.
|
||||||
|
##
|
||||||
|
vlib work
|
||||||
|
|
||||||
|
# Misc
|
||||||
|
vcom -explicit -93 "../../../PCK_FIO-1.16/PCK_FIO.vhd"
|
||||||
|
|
||||||
|
# RAMS
|
||||||
|
vcom -explicit -93 "../../../misc/dpram_2w2r.vhd"
|
||||||
|
vcom -explicit -93 "../../../misc/dpram_1w1r.vhd"
|
||||||
|
vcom -explicit -93 "../../../misc/dpram_1w1r_dist.vhd"
|
||||||
|
|
||||||
|
# FIFOS
|
||||||
|
vcom -explicit -93 "../../../FIFO/src/fifo_ctrl_pkg.vhd"
|
||||||
|
vcom -explicit -93 "../../../FIFO/src/sync_fifo_ctrl.vhd"
|
||||||
|
vcom -explicit -93 "../../../FIFO/src/fifo_sync_dist.vhd"
|
||||||
|
|
||||||
|
# MIPS
|
||||||
|
vcom -explicit -93 "../src/core/mips_types.vhd"
|
||||||
|
vcom -explicit -93 "../src/core/mips_instr.vhd"
|
||||||
|
vcom -explicit -93 "../src/core/mips_idecode_rom.vhd"
|
||||||
|
vcom -explicit -93 "../src/core/mips_reg.vhd"
|
||||||
|
vcom -explicit -93 "../src/core/mips_shifter.vhd"
|
||||||
|
vcom -explicit -93 "../src/core/mips_alu.vhd"
|
||||||
|
vcom -explicit -93 "../src/core/mips_muldiv.vhd"
|
||||||
|
vcom -explicit -93 "../src/core/mips_cop.vhd"
|
||||||
|
vcom -explicit -93 "../src/core/mips_icache.vhd"
|
||||||
|
vcom -explicit -93 "../src/core/mips_dcache.vhd"
|
||||||
|
vcom -explicit -93 "../src/core/mips_biu.vhd"
|
||||||
|
vcom -explicit -93 "../src/core/mips_bcu.vhd"
|
||||||
|
vcom -explicit -93 "../src/core/mips_pipeline.vhd"
|
||||||
|
vcom -explicit -93 "../src/core/mips_top.vhd"
|
||||||
|
vcom -explicit -93 "../src/tb_mips_top.vhd"
|
||||||
|
vsim -t 1ps -lib work tb_mips_top
|
||||||
|
do {tb_mips_top.wdo}
|
||||||
|
view wave
|
||||||
|
view structure
|
||||||
|
view signals
|
||||||
|
run 40000ns
|
||||||
@@ -0,0 +1,42 @@
|
|||||||
|
onerror {resume}
|
||||||
|
quietly WaveActivateNextPane {} 0
|
||||||
|
add wave -noupdate -divider {TOP interface}
|
||||||
|
add wave -noupdate -format Literal /tb_mips_top/debug
|
||||||
|
add wave -noupdate -format Logic /tb_mips_top/rst_i
|
||||||
|
add wave -noupdate -format Logic /tb_mips_top/clk_i
|
||||||
|
add wave -noupdate -format Logic /tb_mips_top/ack_i
|
||||||
|
add wave -noupdate -format Logic /tb_mips_top/srdy_i
|
||||||
|
add wave -noupdate -format Literal -radix hexadecimal /tb_mips_top/addr_o
|
||||||
|
add wave -noupdate -format Literal -radix hexadecimal /tb_mips_top/dat_i
|
||||||
|
add wave -noupdate -format Literal -radix hexadecimal /tb_mips_top/dat_o
|
||||||
|
add wave -noupdate -format Logic /tb_mips_top/we_o
|
||||||
|
add wave -noupdate -format Literal /tb_mips_top/sel_o
|
||||||
|
add wave -noupdate -format Logic /tb_mips_top/cyc_o
|
||||||
|
add wave -noupdate -format Logic /tb_mips_top/stb_o
|
||||||
|
add wave -noupdate -format Logic /tb_mips_top/mrdy_o
|
||||||
|
add wave -noupdate -format Literal /tb_mips_top/int
|
||||||
|
add wave -noupdate -divider ALU
|
||||||
|
add wave -noupdate -format Literal /tb_mips_top/uut/inst_pipeline/hdu
|
||||||
|
add wave -noupdate -divider PC
|
||||||
|
add wave -noupdate -format Literal -radix hexadecimal /tb_mips_top/uut/inst_pipeline/pc
|
||||||
|
add wave -noupdate -divider PC
|
||||||
|
add wave -noupdate -format Literal -radix hexadecimal -expand /tb_mips_top/uut/inst_pipeline/id_stage
|
||||||
|
add wave -noupdate -format Literal -radix hexadecimal -expand /tb_mips_top/uut/inst_pipeline/ex_stage
|
||||||
|
add wave -noupdate -format Literal -radix hexadecimal -expand /tb_mips_top/uut/inst_pipeline/mem_stage
|
||||||
|
add wave -noupdate -format Literal -radix hexadecimal -expand /tb_mips_top/uut/inst_pipeline/wb_stage
|
||||||
|
TreeUpdate [SetDefaultTree]
|
||||||
|
WaveRestoreCursors {{Cursor 1} {21313433 ps} 0}
|
||||||
|
configure wave -namecolwidth 188
|
||||||
|
configure wave -valuecolwidth 100
|
||||||
|
configure wave -justifyvalue left
|
||||||
|
configure wave -signalnamewidth 1
|
||||||
|
configure wave -snapdistance 10
|
||||||
|
configure wave -datasetprefix 0
|
||||||
|
configure wave -rowmargin 4
|
||||||
|
configure wave -childrowmargin 2
|
||||||
|
configure wave -gridoffset 0
|
||||||
|
configure wave -gridperiod 100
|
||||||
|
configure wave -griddelta 40
|
||||||
|
configure wave -timeline 1
|
||||||
|
update
|
||||||
|
WaveRestoreZoom {0 ps} {42 us}
|
||||||
@@ -0,0 +1,17 @@
|
|||||||
|
## NOTE: Do not edit this file.
|
||||||
|
##
|
||||||
|
vlib work
|
||||||
|
## Compile Post-Map Model
|
||||||
|
vcom -explicit -93 "../syn/ise9/netgen/par/mips_top_syn_timesim.vhd"
|
||||||
|
vsim -t 1ps -sdfmax "/mips_top_syn=../syn/ise9/netgen/par/mips_top_syn_timesim.sdf" -lib work mips_top_syn
|
||||||
|
vcom -explicit -93 "../src/core/mips_types.vhd"
|
||||||
|
vcom -explicit -93 "../src/core/mips_instr.vhd"
|
||||||
|
vcom -explicit -93 "../src/irom_hello.vhd"
|
||||||
|
vcom -explicit -93 "../src/tb_mips_top_syn.vhd"
|
||||||
|
vsim -t 1ps -lib work tb_mips_top_syn
|
||||||
|
do {tb_mips_top_syn.wdo}
|
||||||
|
view wave
|
||||||
|
#add wave *
|
||||||
|
view structure
|
||||||
|
view signals
|
||||||
|
run 2400ns
|
||||||
@@ -0,0 +1,31 @@
|
|||||||
|
onerror {resume}
|
||||||
|
quietly WaveActivateNextPane {} 0
|
||||||
|
add wave -noupdate -format Logic /tb_mips_top_syn/rst
|
||||||
|
add wave -noupdate -format Logic /tb_mips_top_syn/clk
|
||||||
|
add wave -noupdate -format Logic /tb_mips_top_syn/ce
|
||||||
|
add wave -noupdate -format Literal -radix hexadecimal /tb_mips_top_syn/irom_data
|
||||||
|
add wave -noupdate -format Literal -radix hexadecimal /tb_mips_top_syn/irom_addr
|
||||||
|
add wave -noupdate -format Literal -radix hexadecimal /tb_mips_top_syn/dmem_din
|
||||||
|
add wave -noupdate -format Literal -radix hexadecimal /tb_mips_top_syn/dmem_dout
|
||||||
|
add wave -noupdate -format Literal -radix hexadecimal /tb_mips_top_syn/dmem_addr
|
||||||
|
add wave -noupdate -format Logic /tb_mips_top_syn/dmem_we
|
||||||
|
add wave -noupdate -format Logic /tb_mips_top_syn/dmem_re
|
||||||
|
add wave -noupdate -format Literal -radix hexadecimal /tb_mips_top_syn/uut/inst_mips_top_inst_pipeline_id_stage_boff
|
||||||
|
add wave -noupdate -format Literal -radix hexadecimal /tb_mips_top_syn/uut/inst_mips_top_inst_pipeline_stage_ex_inst_alu_sum_res
|
||||||
|
add wave -noupdate -format Literal -radix hexadecimal -expand /tb_mips_top_syn/sram
|
||||||
|
TreeUpdate [SetDefaultTree]
|
||||||
|
WaveRestoreCursors {{Cursor 1} {118199 ps} 0}
|
||||||
|
configure wave -namecolwidth 188
|
||||||
|
configure wave -valuecolwidth 100
|
||||||
|
configure wave -justifyvalue left
|
||||||
|
configure wave -signalnamewidth 1
|
||||||
|
configure wave -snapdistance 10
|
||||||
|
configure wave -datasetprefix 0
|
||||||
|
configure wave -rowmargin 4
|
||||||
|
configure wave -childrowmargin 2
|
||||||
|
configure wave -gridoffset 0
|
||||||
|
configure wave -gridperiod 100
|
||||||
|
configure wave -griddelta 40
|
||||||
|
configure wave -timeline 1
|
||||||
|
update
|
||||||
|
WaveRestoreZoom {0 ps} {2520 ns}
|
||||||
@@ -0,0 +1,431 @@
|
|||||||
|
LIBRARY IEEE;
|
||||||
|
USE IEEE.STD_LOGIC_1164.ALL;
|
||||||
|
USE IEEE.NUMERIC_STD.ALL;
|
||||||
|
use IEEE.MATH_REAL.ALL;
|
||||||
|
|
||||||
|
library work;
|
||||||
|
use work.mips_types.all;
|
||||||
|
|
||||||
|
ENTITY dcache IS
|
||||||
|
Generic
|
||||||
|
(
|
||||||
|
cache_size : natural := 2048; -- words
|
||||||
|
line_size : natural := 8 -- words
|
||||||
|
);
|
||||||
|
Port
|
||||||
|
(
|
||||||
|
RST_I : in STD_LOGIC;
|
||||||
|
CLK_I : in STD_LOGIC;
|
||||||
|
ACK_I : in STD_LOGIC;
|
||||||
|
SRDY_I : in STD_LOGIC;
|
||||||
|
ADDR_O : out word_t;
|
||||||
|
DAT_I : in word_t;
|
||||||
|
STB_O : out STD_LOGIC;
|
||||||
|
CYC_O : out STD_LOGIC;
|
||||||
|
en : in STD_LOGIC;
|
||||||
|
cpu_en : in STD_LOGIC;
|
||||||
|
cpu_we : in STD_LOGIC;
|
||||||
|
cpu_be : in unsigned(3 downto 0);
|
||||||
|
cpu_addr : in word_t;
|
||||||
|
cpu_din : in word_t;
|
||||||
|
cpu_dout : out word_t;
|
||||||
|
cpu_busy : out STD_LOGIC
|
||||||
|
);
|
||||||
|
END dcache;
|
||||||
|
|
||||||
|
ARCHITECTURE behavior OF dcache IS
|
||||||
|
|
||||||
|
COMPONENT dpram_1w1r
|
||||||
|
GENERIC
|
||||||
|
(
|
||||||
|
addr_width : integer := 3;
|
||||||
|
data_width : integer := 8
|
||||||
|
);
|
||||||
|
PORT (
|
||||||
|
clka : in STD_LOGIC;
|
||||||
|
clkb : in STD_LOGIC;
|
||||||
|
en_a : in STD_LOGIC;
|
||||||
|
en_b : in STD_LOGIC;
|
||||||
|
we_a : in STD_LOGIC;
|
||||||
|
addr_a : in unsigned (addr_width-1 downto 0);
|
||||||
|
addr_b : in unsigned (addr_width-1 downto 0);
|
||||||
|
din_a : in unsigned (data_width-1 downto 0);
|
||||||
|
dout_b : out unsigned (data_width-1 downto 0)
|
||||||
|
);
|
||||||
|
END COMPONENT;
|
||||||
|
|
||||||
|
COMPONENT dpram_2w2r is
|
||||||
|
GENERIC
|
||||||
|
(
|
||||||
|
addr_width : integer := 3;
|
||||||
|
data_width : integer := 8
|
||||||
|
);
|
||||||
|
PORT
|
||||||
|
(
|
||||||
|
clk_a : in STD_LOGIC;
|
||||||
|
clk_b : in STD_LOGIC;
|
||||||
|
en_a : in STD_LOGIC;
|
||||||
|
en_b : in STD_LOGIC;
|
||||||
|
we_a : in STD_LOGIC;
|
||||||
|
we_b : in STD_LOGIC;
|
||||||
|
addr_a : in unsigned (addr_width-1 downto 0);
|
||||||
|
addr_b : in unsigned (addr_width-1 downto 0);
|
||||||
|
din_a : in unsigned (data_width-1 downto 0);
|
||||||
|
din_b : in unsigned (data_width-1 downto 0);
|
||||||
|
dout_a : out unsigned (data_width-1 downto 0);
|
||||||
|
dout_b : out unsigned (data_width-1 downto 0)
|
||||||
|
);
|
||||||
|
END COMPONENT;
|
||||||
|
|
||||||
|
function lg2(x : natural) return natural is
|
||||||
|
begin
|
||||||
|
return natural(ceil(log2(real(x))));
|
||||||
|
end lg2;
|
||||||
|
|
||||||
|
function po2(x : natural) return natural is
|
||||||
|
begin
|
||||||
|
|
||||||
|
return 2**lg2(x);
|
||||||
|
end po2;
|
||||||
|
|
||||||
|
constant word_index_width : natural := lg2(line_size);
|
||||||
|
constant cache_index_width : natural := lg2(cache_size) - word_index_width;
|
||||||
|
constant tag_width : natural := 32 - word_index_width - cache_index_width - 2;
|
||||||
|
constant tag_parity_width : natural := 3;
|
||||||
|
constant tram_data_width : natural := 1 + tag_parity_width + tag_width;
|
||||||
|
constant tram_addr_width : natural := cache_index_width;
|
||||||
|
|
||||||
|
subtype tram_data_t is unsigned (tram_data_width-1 downto 0);
|
||||||
|
|
||||||
|
type dcache_entry_t is record
|
||||||
|
valid : std_logic;
|
||||||
|
tv_p : unsigned(tag_parity_width-1 downto 0);
|
||||||
|
tag : unsigned(tag_width-1 downto 0);
|
||||||
|
end record;
|
||||||
|
|
||||||
|
alias cpu_word_index is cpu_addr(word_index_width+1 downto 2);
|
||||||
|
alias cpu_cache_index is cpu_addr(cache_index_width+word_index_width+1 downto word_index_width+2);
|
||||||
|
alias cpu_tag is cpu_addr(tag_width+cache_index_width+word_index_width+1 downto cache_index_width+word_index_width+2);
|
||||||
|
|
||||||
|
function to_dcache_entry(x : tram_data_t) return dcache_entry_t is
|
||||||
|
variable result : dcache_entry_t;
|
||||||
|
begin
|
||||||
|
result.valid := x(0);
|
||||||
|
result.tv_p := x(3 downto 1);
|
||||||
|
result.tag := x(tag_width+3 downto 4);
|
||||||
|
|
||||||
|
return result;
|
||||||
|
end to_dcache_entry;
|
||||||
|
|
||||||
|
function to_tram_data(x : dcache_entry_t) return tram_data_t is
|
||||||
|
variable result : tram_data_t;
|
||||||
|
begin
|
||||||
|
result(0) := x.valid;
|
||||||
|
result(3 downto 1) := x.tv_p;
|
||||||
|
result(tag_width+3 downto 4) := x.tag;
|
||||||
|
|
||||||
|
return result;
|
||||||
|
end to_tram_data;
|
||||||
|
|
||||||
|
type cache_state_t is (init, ready, flush, mem_request, mem_access, mem_wait, mem_data, upd_cache, rd_cache);
|
||||||
|
signal s, sn : cache_state_t;
|
||||||
|
|
||||||
|
signal cache_busy : std_logic;
|
||||||
|
signal cache_hit : std_logic;
|
||||||
|
signal tag_match : std_logic;
|
||||||
|
signal word_index_reg : unsigned(word_index_width-1 downto 0);
|
||||||
|
signal cache_index_reg : unsigned(cache_index_width-1 downto 0);
|
||||||
|
signal tag_index_reg : unsigned(tag_width-1 downto 0);
|
||||||
|
|
||||||
|
signal cache_entry_in : dcache_entry_t;
|
||||||
|
signal cache_entry_out : dcache_entry_t;
|
||||||
|
signal cpu_dram_addr : unsigned(lg2(cache_size)-1 downto 0);
|
||||||
|
signal cpu_dram_dout : word_t;
|
||||||
|
signal cpu_dram_din : word_t;
|
||||||
|
signal cpu_data_reg : word_t;
|
||||||
|
signal cpu_be_reg : unsigned(3 downto 0);
|
||||||
|
signal cpu_we_reg : std_logic;
|
||||||
|
signal ctrl_dram_en : std_logic;
|
||||||
|
signal ctrl_dram_addr : unsigned(lg2(cache_size)-1 downto 0);
|
||||||
|
signal ctrl_dram_din : word_t;
|
||||||
|
signal ctrl_dram_we : unsigned(3 downto 0);
|
||||||
|
signal cpu_dram_we : unsigned(3 downto 0);
|
||||||
|
signal cpu_dram_en : std_logic;
|
||||||
|
signal cpu_en2 : std_logic;
|
||||||
|
signal cpu_we2 : std_logic;
|
||||||
|
|
||||||
|
signal tram_addr_rd : unsigned(cache_index_width-1 downto 0);
|
||||||
|
signal tram_dout : tram_data_t;
|
||||||
|
signal tram_addr_wr : unsigned(cache_index_width-1 downto 0);
|
||||||
|
signal tram_din : tram_data_t;
|
||||||
|
signal tram_re : std_logic;
|
||||||
|
signal tram_we : std_logic;
|
||||||
|
|
||||||
|
signal ram_index_count : natural range 0 to 2**word_index_width-1;
|
||||||
|
signal ram_index_count_rst : std_logic;
|
||||||
|
signal cache_index_count : natural range 0 to 2**cache_index_width-1;
|
||||||
|
signal cache_index_count_en : std_logic;
|
||||||
|
signal mem_index_count : natural range 0 to 2**word_index_width-1;
|
||||||
|
signal mem_index_count_en : std_logic;
|
||||||
|
signal mem_index_count_rst : std_logic;
|
||||||
|
signal cpu_reg_en : std_logic;
|
||||||
|
signal was_miss : std_logic;
|
||||||
|
signal data_write : std_logic;
|
||||||
|
signal cpu_hit_we : std_logic;
|
||||||
|
signal instant_raw : std_logic;
|
||||||
|
|
||||||
|
begin
|
||||||
|
|
||||||
|
cpu_hit_we <= cpu_we2 and cache_hit;
|
||||||
|
|
||||||
|
cpu_index_register:
|
||||||
|
process(CLK_I)
|
||||||
|
begin
|
||||||
|
if rising_edge(CLK_I) then
|
||||||
|
if RST_I = '1' then
|
||||||
|
cache_index_reg <= (others => '0');
|
||||||
|
tag_index_reg <= (others => '0');
|
||||||
|
elsif cpu_reg_en = '1' and en = '1' and instant_raw = '0' then
|
||||||
|
word_index_reg <= cpu_word_index;
|
||||||
|
cache_index_reg <= cpu_cache_index;
|
||||||
|
tag_index_reg <= cpu_tag;
|
||||||
|
end if;
|
||||||
|
end if;
|
||||||
|
end process;
|
||||||
|
|
||||||
|
cpu_data_register:
|
||||||
|
process(CLK_I)
|
||||||
|
begin
|
||||||
|
if rising_edge(CLK_I) then
|
||||||
|
if RST_I = '1' then
|
||||||
|
cpu_we_reg <= '0';
|
||||||
|
elsif cpu_reg_en = '1' and en = '1' then
|
||||||
|
cpu_data_reg <= cpu_din;
|
||||||
|
cpu_be_reg <= cpu_be;
|
||||||
|
cpu_we_reg <= cpu_we;
|
||||||
|
end if;
|
||||||
|
end if;
|
||||||
|
end process;
|
||||||
|
|
||||||
|
cpu_was_wr_register:
|
||||||
|
process(CLK_I)
|
||||||
|
begin
|
||||||
|
if rising_edge(CLK_I) then
|
||||||
|
cpu_en2 <= '0';
|
||||||
|
cpu_we2 <= '0';
|
||||||
|
if cpu_en = '1' and en = '1' then
|
||||||
|
cpu_we2 <= cpu_we;
|
||||||
|
cpu_en2 <= '1';
|
||||||
|
cpu_dram_din <= cpu_din;
|
||||||
|
end if;
|
||||||
|
end if;
|
||||||
|
end process;
|
||||||
|
|
||||||
|
instant_raw_logic:
|
||||||
|
process(CLK_I)
|
||||||
|
begin
|
||||||
|
if rising_edge(CLK_I) then
|
||||||
|
instant_raw <= cpu_hit_we and cpu_en and en and not cpu_we;
|
||||||
|
end if;
|
||||||
|
end process;
|
||||||
|
|
||||||
|
inst_tag_ram : dpram_1w1r
|
||||||
|
GENERIC MAP (
|
||||||
|
addr_width => tram_addr_width,
|
||||||
|
data_width => tram_data_width
|
||||||
|
)
|
||||||
|
PORT MAP (
|
||||||
|
clka => CLK_I,
|
||||||
|
clkb => CLK_I,
|
||||||
|
en_a => '1',
|
||||||
|
en_b => tram_re,
|
||||||
|
we_a => tram_we,
|
||||||
|
addr_a => tram_addr_wr,
|
||||||
|
addr_b => tram_addr_rd,
|
||||||
|
din_a => tram_din,
|
||||||
|
dout_b => tram_dout
|
||||||
|
);
|
||||||
|
|
||||||
|
gen_data_ram:
|
||||||
|
for i in 0 to 3 generate
|
||||||
|
begin
|
||||||
|
|
||||||
|
inst_data_ram : dpram_2w2r
|
||||||
|
GENERIC MAP (
|
||||||
|
addr_width => lg2(cache_size),
|
||||||
|
data_width => word_t'length/4
|
||||||
|
)
|
||||||
|
PORT MAP (
|
||||||
|
clk_a => CLK_I,
|
||||||
|
clk_b => CLK_I,
|
||||||
|
en_a => ctrl_dram_en,
|
||||||
|
en_b => '1',
|
||||||
|
we_a => ctrl_dram_we(i),
|
||||||
|
we_b => cpu_dram_we(i),
|
||||||
|
addr_a => ctrl_dram_addr,
|
||||||
|
addr_b => cpu_dram_addr,
|
||||||
|
din_a => ctrl_dram_din(8*(i+1)-1 downto 8*i),
|
||||||
|
din_b => cpu_dram_din(8*(i+1)-1 downto 8*i),
|
||||||
|
dout_a => open,
|
||||||
|
dout_b => cpu_dram_dout(8*(i+1)-1 downto 8*i)
|
||||||
|
);
|
||||||
|
end generate;
|
||||||
|
|
||||||
|
cache_state_next:
|
||||||
|
process(CLK_I)
|
||||||
|
begin
|
||||||
|
if rising_edge(CLK_I) then
|
||||||
|
if RST_I = '1' then
|
||||||
|
s <= init;
|
||||||
|
else
|
||||||
|
s <= sn;
|
||||||
|
end if;
|
||||||
|
end if;
|
||||||
|
end process;
|
||||||
|
|
||||||
|
cpu_busy <= cache_busy or instant_raw;
|
||||||
|
cpu_dout <= cpu_dram_dout;
|
||||||
|
|
||||||
|
tag_match <= '1' when tag_index_reg = cache_entry_out.tag else '0';
|
||||||
|
cache_hit <= tag_match and cache_entry_out.valid;
|
||||||
|
tram_din <= to_tram_data(cache_entry_in);
|
||||||
|
tram_addr_rd <= cpu_cache_index when was_miss = '0' else cache_index_reg;
|
||||||
|
cache_entry_out <= to_dcache_entry(tram_dout);
|
||||||
|
cpu_dram_addr <= (cpu_cache_index & cpu_word_index) when (was_miss = '0' and cpu_hit_we = '0' and instant_raw = '0') else (cache_index_reg & word_index_reg);
|
||||||
|
ADDR_O <= tag_index_reg & cache_index_reg & to_unsigned(mem_index_count, word_index_width) & "00";
|
||||||
|
ctrl_dram_addr <= cache_index_reg & to_unsigned(ram_index_count, word_index_width);
|
||||||
|
ctrl_dram_din <= DAT_I;
|
||||||
|
ctrl_dram_we <= (others => '1');
|
||||||
|
ctrl_dram_en <= data_write and ACK_I;
|
||||||
|
cpu_dram_we <= cpu_be_reg when (cpu_hit_we = '1') else (others => '0');
|
||||||
|
|
||||||
|
cache_state:
|
||||||
|
process(s, instant_raw, cache_hit, cache_index_count, ram_index_count, mem_index_count, cache_index_reg, ACK_I, tag_index_reg, cpu_en, SRDY_I, cpu_en2, cpu_we_reg)
|
||||||
|
begin
|
||||||
|
cpu_reg_en <= '0';
|
||||||
|
cache_busy <= '1';
|
||||||
|
tram_we <= '0';
|
||||||
|
cache_index_count_en <= '0';
|
||||||
|
ram_index_count_rst <= '0';
|
||||||
|
mem_index_count_en <= '0';
|
||||||
|
mem_index_count_rst <= '0';
|
||||||
|
CYC_O <= '0';
|
||||||
|
STB_O <= '0';
|
||||||
|
tram_re <= '0';
|
||||||
|
was_miss <= '0';
|
||||||
|
data_write <= '0';
|
||||||
|
tram_addr_wr <= to_unsigned(cache_index_count, cache_index_width);
|
||||||
|
cache_entry_in.tv_p <= (others => '0');
|
||||||
|
cache_entry_in.tag <= tag_index_reg;
|
||||||
|
cache_entry_in.valid <= '0';
|
||||||
|
sn <= s;
|
||||||
|
|
||||||
|
case s is
|
||||||
|
when init =>
|
||||||
|
sn <= flush;
|
||||||
|
when ready =>
|
||||||
|
cache_busy <= '0';
|
||||||
|
cpu_reg_en <= '1';
|
||||||
|
tram_re <= cpu_en;
|
||||||
|
if cpu_en2 = '1' then
|
||||||
|
if cache_hit = '0' and cpu_we_reg = '0' then
|
||||||
|
sn <= mem_request;
|
||||||
|
cpu_reg_en <= '0';
|
||||||
|
cache_busy <= '1';
|
||||||
|
CYC_O <= '1';
|
||||||
|
end if;
|
||||||
|
end if;
|
||||||
|
when flush =>
|
||||||
|
cache_index_count_en <= '1';
|
||||||
|
tram_addr_wr <= to_unsigned(cache_index_count, cache_index_width);
|
||||||
|
tram_we <= '1';
|
||||||
|
cache_entry_in.valid <= '0';
|
||||||
|
cache_entry_in.tag <= (others => '0');
|
||||||
|
if cache_index_count = 0 then
|
||||||
|
sn <= ready;
|
||||||
|
if cpu_en = '1' then
|
||||||
|
cpu_reg_en <= '1';
|
||||||
|
tram_re <= '1';
|
||||||
|
end if;
|
||||||
|
end if;
|
||||||
|
when mem_request =>
|
||||||
|
ram_index_count_rst <= '1';
|
||||||
|
mem_index_count_rst <= '1';
|
||||||
|
CYC_O <= '1';
|
||||||
|
if SRDY_I = '1' then
|
||||||
|
sn <= mem_access;
|
||||||
|
end if;
|
||||||
|
when mem_access =>
|
||||||
|
data_write <= '1';
|
||||||
|
mem_index_count_en <= '1';
|
||||||
|
CYC_O <= '1';
|
||||||
|
STB_O <= '1';
|
||||||
|
if mem_index_count = 2**word_index_width-1 then
|
||||||
|
if SRDY_I = '1' then
|
||||||
|
sn <= mem_data;
|
||||||
|
end if;
|
||||||
|
end if;
|
||||||
|
when mem_data =>
|
||||||
|
CYC_O <= '1';
|
||||||
|
data_write <= '1';
|
||||||
|
if ram_index_count = 2**word_index_width-1 then
|
||||||
|
if ACK_I = '1' then
|
||||||
|
sn <= upd_cache;
|
||||||
|
end if;
|
||||||
|
end if;
|
||||||
|
when upd_cache =>
|
||||||
|
tram_addr_wr <= cache_index_reg;
|
||||||
|
tram_we <= '1';
|
||||||
|
cache_entry_in.valid <= '1';
|
||||||
|
sn <= rd_cache;
|
||||||
|
when rd_cache =>
|
||||||
|
tram_re <= '1';
|
||||||
|
was_miss <= '1';
|
||||||
|
sn <= ready;
|
||||||
|
|
||||||
|
when others =>
|
||||||
|
sn <= ready;
|
||||||
|
end case;
|
||||||
|
end process;
|
||||||
|
|
||||||
|
cache_index_counter:
|
||||||
|
process(CLK_I)
|
||||||
|
begin
|
||||||
|
if rising_edge(CLK_I) then
|
||||||
|
if cache_index_count_en = '0' then
|
||||||
|
cache_index_count <= 2**cache_index_width-1;
|
||||||
|
elsif cache_index_count /= 0 then
|
||||||
|
cache_index_count <= cache_index_count - 1;
|
||||||
|
end if;
|
||||||
|
end if;
|
||||||
|
end process;
|
||||||
|
|
||||||
|
ram_index_counter:
|
||||||
|
process(CLK_I)
|
||||||
|
begin
|
||||||
|
if rising_edge(CLK_I) then
|
||||||
|
if ram_index_count_rst = '1' then
|
||||||
|
ram_index_count <= 0;
|
||||||
|
elsif data_write = '1' and ACK_I = '1' then
|
||||||
|
if ram_index_count /= 2**word_index_width-1 then
|
||||||
|
ram_index_count <= ram_index_count + 1;
|
||||||
|
end if;
|
||||||
|
end if;
|
||||||
|
end if;
|
||||||
|
end process;
|
||||||
|
|
||||||
|
mem_index_counter:
|
||||||
|
process(CLK_I)
|
||||||
|
begin
|
||||||
|
if rising_edge(CLK_I) then
|
||||||
|
if mem_index_count_rst = '1' then
|
||||||
|
mem_index_count <= 0;
|
||||||
|
elsif mem_index_count_en = '1' and SRDY_I = '1' then
|
||||||
|
if mem_index_count /= 2**word_index_width-1 then
|
||||||
|
mem_index_count <= mem_index_count + 1;
|
||||||
|
end if;
|
||||||
|
end if;
|
||||||
|
end if;
|
||||||
|
end process;
|
||||||
|
|
||||||
|
end behavior;
|
||||||
@@ -0,0 +1,354 @@
|
|||||||
|
LIBRARY IEEE;
|
||||||
|
USE IEEE.STD_LOGIC_1164.ALL;
|
||||||
|
USE IEEE.NUMERIC_STD.ALL;
|
||||||
|
use IEEE.MATH_REAL.ALL;
|
||||||
|
|
||||||
|
library work;
|
||||||
|
use work.mips_types.all;
|
||||||
|
|
||||||
|
ENTITY icache IS
|
||||||
|
Generic
|
||||||
|
(
|
||||||
|
cache_size : natural := 2048; -- words
|
||||||
|
line_size : natural := 8 -- words
|
||||||
|
);
|
||||||
|
Port
|
||||||
|
(
|
||||||
|
RST_I : in STD_LOGIC;
|
||||||
|
CLK_I : in STD_LOGIC;
|
||||||
|
ACK_I : in STD_LOGIC;
|
||||||
|
SRDY_I : in STD_LOGIC;
|
||||||
|
ADDR_O : out word_t;
|
||||||
|
DAT_I : in word_t;
|
||||||
|
STB_O : out STD_LOGIC;
|
||||||
|
CYC_O : out STD_LOGIC;
|
||||||
|
en : in STD_LOGIC;
|
||||||
|
cpu_en : in STD_LOGIC;
|
||||||
|
cpu_addr : in word_t;
|
||||||
|
cpu_dout : out word_t;
|
||||||
|
cpu_busy : out STD_LOGIC
|
||||||
|
);
|
||||||
|
END icache;
|
||||||
|
|
||||||
|
ARCHITECTURE behavior OF icache IS
|
||||||
|
|
||||||
|
COMPONENT dpram_1w1r
|
||||||
|
GENERIC
|
||||||
|
(
|
||||||
|
addr_width : integer := 3;
|
||||||
|
data_width : integer := 8
|
||||||
|
);
|
||||||
|
PORT (
|
||||||
|
clka : in STD_LOGIC;
|
||||||
|
clkb : in STD_LOGIC;
|
||||||
|
en_a : in STD_LOGIC;
|
||||||
|
en_b : in STD_LOGIC;
|
||||||
|
we_a : in STD_LOGIC;
|
||||||
|
addr_a : in unsigned (addr_width-1 downto 0);
|
||||||
|
addr_b : in unsigned (addr_width-1 downto 0);
|
||||||
|
din_a : in unsigned (data_width-1 downto 0);
|
||||||
|
dout_b : out unsigned (data_width-1 downto 0)
|
||||||
|
);
|
||||||
|
END COMPONENT;
|
||||||
|
|
||||||
|
function lg2(x : natural) return natural is
|
||||||
|
begin
|
||||||
|
return natural(ceil(log2(real(x))));
|
||||||
|
end lg2;
|
||||||
|
|
||||||
|
function po2(x : natural) return natural is
|
||||||
|
begin
|
||||||
|
|
||||||
|
return 2**lg2(x);
|
||||||
|
end po2;
|
||||||
|
|
||||||
|
constant word_index_width : natural := lg2(line_size);
|
||||||
|
constant cache_index_width : natural := lg2(cache_size) - word_index_width;
|
||||||
|
constant tag_width : natural := 32 - word_index_width - cache_index_width - 2;
|
||||||
|
constant tag_parity_width : natural := 3;
|
||||||
|
constant tag_ram_data_width : natural := 1 + tag_parity_width + tag_width;
|
||||||
|
constant tag_ram_addr_width : natural := cache_index_width;
|
||||||
|
|
||||||
|
subtype tag_ram_data_t is unsigned (tag_ram_data_width-1 downto 0);
|
||||||
|
|
||||||
|
type icache_entry_t is record
|
||||||
|
valid : std_logic;
|
||||||
|
tv_p : unsigned(tag_parity_width-1 downto 0);
|
||||||
|
tag : unsigned(tag_width-1 downto 0);
|
||||||
|
end record;
|
||||||
|
|
||||||
|
alias cpu_word_index is cpu_addr(word_index_width+1 downto 2);
|
||||||
|
alias cpu_cache_index is cpu_addr(cache_index_width+word_index_width+1 downto word_index_width+2);
|
||||||
|
alias cpu_tag is cpu_addr(tag_width+cache_index_width+word_index_width+1 downto cache_index_width+word_index_width+2);
|
||||||
|
|
||||||
|
function to_icache_entry(x : tag_ram_data_t) return icache_entry_t is
|
||||||
|
variable result : icache_entry_t;
|
||||||
|
begin
|
||||||
|
result.valid := x(0);
|
||||||
|
result.tv_p := x(3 downto 1);
|
||||||
|
result.tag := x(tag_width+3 downto 4);
|
||||||
|
|
||||||
|
return result;
|
||||||
|
end to_icache_entry;
|
||||||
|
|
||||||
|
function to_tag_ram_data(x : icache_entry_t) return tag_ram_data_t is
|
||||||
|
variable result : tag_ram_data_t;
|
||||||
|
begin
|
||||||
|
result(0) := x.valid;
|
||||||
|
result(3 downto 1) := x.tv_p;
|
||||||
|
result(tag_width+3 downto 4) := x.tag;
|
||||||
|
|
||||||
|
return result;
|
||||||
|
end to_tag_ram_data;
|
||||||
|
|
||||||
|
type cache_state_t is (init, ready, flush, mem_request, mem_access, mem_wait, mem_data, upd_cache, rd_cache);
|
||||||
|
signal s, sn : cache_state_t;
|
||||||
|
|
||||||
|
signal cache_busy : std_logic;
|
||||||
|
signal cache_miss : std_logic;
|
||||||
|
signal tag_match : std_logic;
|
||||||
|
signal word_index_reg : unsigned(word_index_width-1 downto 0);
|
||||||
|
signal cache_index_reg : unsigned(cache_index_width-1 downto 0);
|
||||||
|
signal tag_index_reg : unsigned(tag_width-1 downto 0);
|
||||||
|
|
||||||
|
signal cache_entry_in : icache_entry_t;
|
||||||
|
signal cache_entry_out : icache_entry_t;
|
||||||
|
signal data_ram_addr_rd : unsigned(lg2(cache_size)-1 downto 0);
|
||||||
|
signal data_ram_data_rd : word_t;
|
||||||
|
signal data_ram_addr_wr : unsigned(lg2(cache_size)-1 downto 0);
|
||||||
|
signal data_ram_data_wr : word_t;
|
||||||
|
signal data_ram_we : std_logic;
|
||||||
|
signal data_ram_re : std_logic;
|
||||||
|
|
||||||
|
signal tag_ram_addr_rd : unsigned(cache_index_width-1 downto 0);
|
||||||
|
signal tag_ram_data_rd : tag_ram_data_t;
|
||||||
|
signal tag_ram_addr_wr : unsigned(cache_index_width-1 downto 0);
|
||||||
|
signal tag_ram_data_wr : tag_ram_data_t;
|
||||||
|
signal tag_ram_re : std_logic;
|
||||||
|
signal tag_ram_we : std_logic;
|
||||||
|
|
||||||
|
signal ram_index_count : natural range 0 to 2**word_index_width-1;
|
||||||
|
signal ram_index_count_rst : std_logic;
|
||||||
|
signal cache_index_count : natural range 0 to 2**cache_index_width-1;
|
||||||
|
signal cache_index_count_en : std_logic;
|
||||||
|
signal mem_index_count : natural range 0 to 2**word_index_width-1;
|
||||||
|
signal mem_index_count_en : std_logic;
|
||||||
|
signal mem_index_count_rst : std_logic;
|
||||||
|
signal cpu_reg_en : std_logic;
|
||||||
|
signal was_miss : std_logic;
|
||||||
|
signal data_write : std_logic;
|
||||||
|
|
||||||
|
begin
|
||||||
|
|
||||||
|
|
||||||
|
cpu_index_reg:
|
||||||
|
process(CLK_I)
|
||||||
|
begin
|
||||||
|
if rising_edge(CLK_I) then
|
||||||
|
if RST_I = '1' then
|
||||||
|
cache_index_reg <= (others => '0');
|
||||||
|
tag_index_reg <= (others => '0');
|
||||||
|
elsif cpu_reg_en = '1' then
|
||||||
|
word_index_reg <= cpu_word_index;
|
||||||
|
cache_index_reg <= cpu_cache_index;
|
||||||
|
tag_index_reg <= cpu_tag;
|
||||||
|
end if;
|
||||||
|
end if;
|
||||||
|
end process;
|
||||||
|
|
||||||
|
inst_tag_ram : dpram_1w1r
|
||||||
|
GENERIC MAP (
|
||||||
|
addr_width => tag_ram_addr_width,
|
||||||
|
data_width => tag_ram_data_width
|
||||||
|
)
|
||||||
|
PORT MAP (
|
||||||
|
clka => CLK_I,
|
||||||
|
clkb => CLK_I,
|
||||||
|
en_a => '1',
|
||||||
|
en_b => tag_ram_re,
|
||||||
|
we_a => tag_ram_we,
|
||||||
|
addr_a => tag_ram_addr_wr,
|
||||||
|
addr_b => tag_ram_addr_rd,
|
||||||
|
din_a => tag_ram_data_wr,
|
||||||
|
dout_b => tag_ram_data_rd
|
||||||
|
);
|
||||||
|
|
||||||
|
inst_data_ram : dpram_1w1r
|
||||||
|
GENERIC MAP (
|
||||||
|
addr_width => lg2(cache_size),
|
||||||
|
data_width => word_t'length
|
||||||
|
)
|
||||||
|
PORT MAP (
|
||||||
|
clka => CLK_I,
|
||||||
|
clkb => CLK_I,
|
||||||
|
en_a => '1',
|
||||||
|
en_b => data_ram_re,
|
||||||
|
we_a => data_ram_we,
|
||||||
|
addr_a => data_ram_addr_wr,
|
||||||
|
addr_b => data_ram_addr_rd,
|
||||||
|
din_a => data_ram_data_wr,
|
||||||
|
dout_b => data_ram_data_rd
|
||||||
|
);
|
||||||
|
|
||||||
|
|
||||||
|
cache_state_next:
|
||||||
|
process(CLK_I)
|
||||||
|
begin
|
||||||
|
if rising_edge(CLK_I) then
|
||||||
|
if RST_I = '1' then
|
||||||
|
s <= init;
|
||||||
|
else
|
||||||
|
s <= sn;
|
||||||
|
end if;
|
||||||
|
end if;
|
||||||
|
end process;
|
||||||
|
|
||||||
|
cpu_busy <= cache_busy;
|
||||||
|
cpu_dout <= data_ram_data_rd;
|
||||||
|
|
||||||
|
tag_match <= '1' when tag_index_reg = cache_entry_out.tag else '0';
|
||||||
|
cache_miss <= not (tag_match and cache_entry_out.valid);
|
||||||
|
tag_ram_data_wr <= to_tag_ram_data(cache_entry_in);
|
||||||
|
tag_ram_addr_rd <= cpu_cache_index when was_miss = '0' else cache_index_reg;
|
||||||
|
cache_entry_out <= to_icache_entry(tag_ram_data_rd);
|
||||||
|
data_ram_addr_rd <= (cpu_cache_index & cpu_word_index) when was_miss = '0' else (cache_index_reg & word_index_reg);
|
||||||
|
ADDR_O <= tag_index_reg & cache_index_reg & to_unsigned(mem_index_count, word_index_width) & "00";
|
||||||
|
data_ram_addr_wr <= cache_index_reg & to_unsigned(ram_index_count, word_index_width);
|
||||||
|
data_ram_data_wr <= DAT_I;
|
||||||
|
data_ram_we <= data_write and ACK_I;
|
||||||
|
|
||||||
|
cache_state:
|
||||||
|
process(s, cache_miss, cache_index_count, ram_index_count, mem_index_count, cache_index_reg, ACK_I, tag_index_reg, cpu_en, SRDY_I, en)
|
||||||
|
begin
|
||||||
|
cpu_reg_en <= '0';
|
||||||
|
cache_busy <= '1';
|
||||||
|
tag_ram_we <= '0';
|
||||||
|
cache_index_count_en <= '0';
|
||||||
|
ram_index_count_rst <= '0';
|
||||||
|
mem_index_count_en <= '0';
|
||||||
|
mem_index_count_rst <= '0';
|
||||||
|
CYC_O <= '0';
|
||||||
|
STB_O <= '0';
|
||||||
|
data_ram_re <= '0';
|
||||||
|
tag_ram_re <= '0';
|
||||||
|
was_miss <= '0';
|
||||||
|
data_write <= '0';
|
||||||
|
tag_ram_addr_wr <= to_unsigned(cache_index_count, cache_index_width);
|
||||||
|
cache_entry_in.tv_p <= (others => '0');
|
||||||
|
cache_entry_in.tag <= tag_index_reg;
|
||||||
|
cache_entry_in.valid <= '0';
|
||||||
|
sn <= s;
|
||||||
|
|
||||||
|
case s is
|
||||||
|
when init =>
|
||||||
|
sn <= flush;
|
||||||
|
when ready =>
|
||||||
|
if en = '1' then
|
||||||
|
cache_busy <= '0';
|
||||||
|
if cache_miss = '1' then
|
||||||
|
sn <= mem_request;
|
||||||
|
cpu_reg_en <= '0';
|
||||||
|
cache_busy <= '1';
|
||||||
|
CYC_O <= '1';
|
||||||
|
elsif cpu_en = '1' then
|
||||||
|
cpu_reg_en <= '1';
|
||||||
|
data_ram_re <= '1';
|
||||||
|
tag_ram_re <= '1';
|
||||||
|
end if;
|
||||||
|
end if;
|
||||||
|
when flush =>
|
||||||
|
cache_index_count_en <= '1';
|
||||||
|
tag_ram_addr_wr <= to_unsigned(cache_index_count, cache_index_width);
|
||||||
|
tag_ram_we <= '1';
|
||||||
|
cache_entry_in.valid <= '0';
|
||||||
|
cache_entry_in.tag <= (others => '0');
|
||||||
|
if cache_index_count = 0 then
|
||||||
|
sn <= ready;
|
||||||
|
if cpu_en = '1' then
|
||||||
|
cpu_reg_en <= '1';
|
||||||
|
data_ram_re <= '1';
|
||||||
|
tag_ram_re <= '1';
|
||||||
|
end if;
|
||||||
|
end if;
|
||||||
|
when mem_request =>
|
||||||
|
ram_index_count_rst <= '1';
|
||||||
|
mem_index_count_rst <= '1';
|
||||||
|
CYC_O <= '1';
|
||||||
|
if SRDY_I = '1' then
|
||||||
|
sn <= mem_access;
|
||||||
|
end if;
|
||||||
|
when mem_access =>
|
||||||
|
mem_index_count_en <= '1';
|
||||||
|
data_write <= '1';
|
||||||
|
CYC_O <= '1';
|
||||||
|
STB_O <= '1';
|
||||||
|
if mem_index_count = 2**word_index_width-1 then
|
||||||
|
if SRDY_I = '1' then
|
||||||
|
sn <= mem_data;
|
||||||
|
end if;
|
||||||
|
end if;
|
||||||
|
when mem_data =>
|
||||||
|
CYC_O <= '1';
|
||||||
|
data_write <= '1';
|
||||||
|
if ram_index_count = 2**word_index_width-1 then
|
||||||
|
if ACK_I = '1' then
|
||||||
|
sn <= upd_cache;
|
||||||
|
end if;
|
||||||
|
end if;
|
||||||
|
when upd_cache =>
|
||||||
|
tag_ram_addr_wr <= cache_index_reg;
|
||||||
|
tag_ram_we <= '1';
|
||||||
|
cache_entry_in.valid <= '1';
|
||||||
|
sn <= rd_cache;
|
||||||
|
|
||||||
|
when rd_cache =>
|
||||||
|
tag_ram_re <= '1';
|
||||||
|
data_ram_re <= '1';
|
||||||
|
was_miss <= '1';
|
||||||
|
sn <= ready;
|
||||||
|
when others =>
|
||||||
|
sn <= ready;
|
||||||
|
end case;
|
||||||
|
end process;
|
||||||
|
|
||||||
|
cache_index_counter:
|
||||||
|
process(CLK_I)
|
||||||
|
begin
|
||||||
|
if rising_edge(CLK_I) then
|
||||||
|
if cache_index_count_en = '0' then
|
||||||
|
cache_index_count <= 2**cache_index_width-1;
|
||||||
|
elsif cache_index_count /= 0 then
|
||||||
|
cache_index_count <= cache_index_count - 1;
|
||||||
|
end if;
|
||||||
|
end if;
|
||||||
|
end process;
|
||||||
|
|
||||||
|
ram_index_counter:
|
||||||
|
process(CLK_I)
|
||||||
|
begin
|
||||||
|
if rising_edge(CLK_I) then
|
||||||
|
if ram_index_count_rst = '1' then
|
||||||
|
ram_index_count <= 0;
|
||||||
|
elsif data_write = '1' and ACK_I = '1' then
|
||||||
|
if ram_index_count /= 2**word_index_width-1 then
|
||||||
|
ram_index_count <= ram_index_count + 1;
|
||||||
|
end if;
|
||||||
|
end if;
|
||||||
|
end if;
|
||||||
|
end process;
|
||||||
|
|
||||||
|
mem_index_counter:
|
||||||
|
process(CLK_I)
|
||||||
|
begin
|
||||||
|
if rising_edge(CLK_I) then
|
||||||
|
if mem_index_count_rst = '1' then
|
||||||
|
mem_index_count <= 0;
|
||||||
|
elsif mem_index_count_en = '1' and SRDY_I = '1' then
|
||||||
|
if mem_index_count /= 2**word_index_width-1 then
|
||||||
|
mem_index_count <= mem_index_count + 1;
|
||||||
|
end if;
|
||||||
|
end if;
|
||||||
|
end if;
|
||||||
|
end process;
|
||||||
|
|
||||||
|
end behavior;
|
||||||
@@ -0,0 +1,184 @@
|
|||||||
|
--------------------------------------------------------------------------
|
||||||
|
-- Project: JIPS, a portable 32-bit RISC CPU written in VHDL
|
||||||
|
-- This file: The arithmetic logic unit
|
||||||
|
--
|
||||||
|
-- Copyright (C) 2008 J. Ahrensfeld
|
||||||
|
--
|
||||||
|
-- This program is free software: you can redistribute it and/or modify
|
||||||
|
-- it under the terms of the GNU General Public License as published by
|
||||||
|
-- the Free Software Foundation, either version 3 of the License, or
|
||||||
|
-- (at your option) any later version.
|
||||||
|
--
|
||||||
|
-- This program 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 General Public License for more details.
|
||||||
|
--
|
||||||
|
-- You should have received a copy of the GNU General Public License
|
||||||
|
-- along with this program. If not, see <http://www.gnu.org/licenses/>.
|
||||||
|
--
|
||||||
|
-- For questions and ideas, please contact the author at jens@jayfield.org
|
||||||
|
--
|
||||||
|
--------------------------------------------------------------------------
|
||||||
|
|
||||||
|
library IEEE;
|
||||||
|
use IEEE.STD_LOGIC_1164.ALL;
|
||||||
|
use IEEE.numeric_std.ALL;
|
||||||
|
|
||||||
|
use work.mips_types.all;
|
||||||
|
|
||||||
|
entity alu is
|
||||||
|
Generic
|
||||||
|
(
|
||||||
|
data_width : integer := 8
|
||||||
|
);
|
||||||
|
Port
|
||||||
|
(
|
||||||
|
op1_in : in unsigned (data_width-1 downto 0);
|
||||||
|
op2_in : in unsigned (data_width-1 downto 0);
|
||||||
|
op2_shifted : in unsigned (data_width-1 downto 0);
|
||||||
|
ctrl : in alu_ctrl_t;
|
||||||
|
result : out unsigned (data_width-1 downto 0);
|
||||||
|
flags : out alu_flags_t
|
||||||
|
);
|
||||||
|
end alu;
|
||||||
|
|
||||||
|
architecture Behavioral of alu is
|
||||||
|
|
||||||
|
signal sum_res : unsigned (data_width-1 downto 0);
|
||||||
|
signal and_res : unsigned (data_width-1 downto 0);
|
||||||
|
signal xor_res : unsigned (data_width-1 downto 0);
|
||||||
|
signal nor_res : unsigned (data_width-1 downto 0);
|
||||||
|
signal or_res : unsigned (data_width-1 downto 0);
|
||||||
|
signal eq, sa, sb, sr, c, z : STD_LOGIC;
|
||||||
|
signal lts, ltu : STD_LOGIC;
|
||||||
|
|
||||||
|
--------------------------------------------------------------------------
|
||||||
|
begin
|
||||||
|
|
||||||
|
eq <= '1' when op1_in = op2_in else '0' after 3 ns;
|
||||||
|
sa <= op1_in(op1_in'left);
|
||||||
|
sb <= op2_in(op2_in'left);
|
||||||
|
sr <= sum_res(sum_res'left);
|
||||||
|
z <= '1' when op1_in = (data_width-1 downto 0 => '0') else '0' after 2 ns;
|
||||||
|
|
||||||
|
flags.uvf <= (not ctrl.add) and ((sa and (not sb) and (not sr)) or ((not sa) and sb and sr));
|
||||||
|
flags.ovf <= ctrl.add and ((sa and sb and (not sr)) or ((not sa) and (not sb) and sr));
|
||||||
|
-- lts <= (not eq) and (((not c) and sa and sb) or (((not sr) and sa) or (sa and (not sb)) or (sr and (not sb))));
|
||||||
|
lts <= not eq and ((not c and sa) or (not sb and sa) or (not sb and sr));
|
||||||
|
|
||||||
|
ltu <= (not eq) and (not c);
|
||||||
|
flags.lts <= lts;
|
||||||
|
flags.ltu <= ltu;
|
||||||
|
flags.c <= c;
|
||||||
|
|
||||||
|
--------------------------------------------------------------------------
|
||||||
|
proc_op_and:
|
||||||
|
process(op1_in, op2_in)
|
||||||
|
variable x1, x2 : unsigned (data_width-1 downto 0);
|
||||||
|
begin
|
||||||
|
x1 := op1_in;
|
||||||
|
x2 := op2_in;
|
||||||
|
|
||||||
|
and_res <= (x1 and x2) after 1 ns;
|
||||||
|
|
||||||
|
end process;
|
||||||
|
|
||||||
|
--------------------------------------------------------------------------
|
||||||
|
proc_proc_xor:
|
||||||
|
process(op1_in, op2_in)
|
||||||
|
variable x1, x2 : unsigned (data_width-1 downto 0);
|
||||||
|
begin
|
||||||
|
x1 := op1_in;
|
||||||
|
x2 := op2_in;
|
||||||
|
|
||||||
|
xor_res <= (x1 xor x2) after 2 ns;
|
||||||
|
|
||||||
|
end process;
|
||||||
|
|
||||||
|
--------------------------------------------------------------------------
|
||||||
|
proc_proc_nor:
|
||||||
|
process(op1_in, op2_in)
|
||||||
|
variable x1, x2 : unsigned (data_width-1 downto 0);
|
||||||
|
begin
|
||||||
|
x1 := op1_in;
|
||||||
|
x2 := op2_in;
|
||||||
|
|
||||||
|
nor_res <= (x1 nor x2) after 1 ns;
|
||||||
|
|
||||||
|
end process;
|
||||||
|
|
||||||
|
--------------------------------------------------------------------------
|
||||||
|
proc_proc_or:
|
||||||
|
process(op1_in, op2_in)
|
||||||
|
variable x1, x2 : unsigned (data_width-1 downto 0);
|
||||||
|
begin
|
||||||
|
x1 := op1_in;
|
||||||
|
x2 := op2_in;
|
||||||
|
|
||||||
|
or_res <= (x1 or x2) after 1 ns;
|
||||||
|
|
||||||
|
end process;
|
||||||
|
|
||||||
|
--------------------------------------------------------------------------
|
||||||
|
proc_alu_out:
|
||||||
|
process(ctrl, sum_res, and_res, xor_res, nor_res, or_res, op2_shifted, lts, ltu)
|
||||||
|
begin
|
||||||
|
|
||||||
|
result <= sum_res;
|
||||||
|
|
||||||
|
case ctrl.outsel is
|
||||||
|
|
||||||
|
when alu_adder =>
|
||||||
|
result <= sum_res;
|
||||||
|
|
||||||
|
when alu_and =>
|
||||||
|
result <= and_res;
|
||||||
|
|
||||||
|
when alu_xor =>
|
||||||
|
result <= xor_res;
|
||||||
|
|
||||||
|
when alu_nor =>
|
||||||
|
result <= nor_res;
|
||||||
|
|
||||||
|
when alu_or =>
|
||||||
|
result <= or_res;
|
||||||
|
|
||||||
|
when alu_shift2 =>
|
||||||
|
result <= op2_shifted;
|
||||||
|
|
||||||
|
when alu_ltu =>
|
||||||
|
result <= (data_width-1 downto 1 => '0') & ltu;
|
||||||
|
|
||||||
|
when alu_lts =>
|
||||||
|
result <= (data_width-1 downto 1 => '0') & lts;
|
||||||
|
|
||||||
|
when others => null;
|
||||||
|
|
||||||
|
end case;
|
||||||
|
|
||||||
|
end process;
|
||||||
|
|
||||||
|
--------------------------------------------------------------------------
|
||||||
|
alu_addsub:
|
||||||
|
process(op1_in, op2_in, ctrl)
|
||||||
|
variable sum : unsigned(data_width+1 downto 0);
|
||||||
|
variable op1, op2 : unsigned(data_width+1 downto 0);
|
||||||
|
begin
|
||||||
|
|
||||||
|
op1 := '0' & op1_in & not ctrl.add;
|
||||||
|
if (ctrl.add = '1') then
|
||||||
|
op2 := '0' & op2_in & '0';
|
||||||
|
else
|
||||||
|
op2 := '0' & not op2_in & '1';
|
||||||
|
end if;
|
||||||
|
sum := op1 + op2;
|
||||||
|
|
||||||
|
-- Form sum + carry
|
||||||
|
sum_res <= unsigned(sum(data_width downto 1)) after 4 ns;
|
||||||
|
c <= sum(sum'left) after 4 ns;
|
||||||
|
|
||||||
|
end process;
|
||||||
|
|
||||||
|
--------------------------------------------------------------------------
|
||||||
|
end Behavioral;
|
||||||
@@ -0,0 +1,52 @@
|
|||||||
|
--------------------------------------------------------------------------
|
||||||
|
-- Project: JIPS, a portable 32-bit RISC CPU written in VHDL
|
||||||
|
-- This file: The arithmetic logic unit
|
||||||
|
--
|
||||||
|
-- Copyright (C) 2008 J. Ahrensfeld
|
||||||
|
--
|
||||||
|
-- This program is free software: you can redistribute it and/or modify
|
||||||
|
-- it under the terms of the GNU General Public License as published by
|
||||||
|
-- the Free Software Foundation, either version 3 of the License, or
|
||||||
|
-- (at your option) any later version.
|
||||||
|
--
|
||||||
|
-- This program 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 General Public License for more details.
|
||||||
|
--
|
||||||
|
-- You should have received a copy of the GNU General Public License
|
||||||
|
-- along with this program. If not, see <http://www.gnu.org/licenses/>.
|
||||||
|
--
|
||||||
|
-- For questions and ideas, please contact the author at jens@jayfield.org
|
||||||
|
--
|
||||||
|
--------------------------------------------------------------------------
|
||||||
|
|
||||||
|
library IEEE;
|
||||||
|
use IEEE.STD_LOGIC_1164.ALL;
|
||||||
|
use IEEE.numeric_std.ALL;
|
||||||
|
|
||||||
|
use work.mips_types.all;
|
||||||
|
|
||||||
|
entity bcu is
|
||||||
|
Generic
|
||||||
|
(
|
||||||
|
data_width : integer := 8
|
||||||
|
);
|
||||||
|
Port
|
||||||
|
(
|
||||||
|
op1_in : in unsigned (data_width-1 downto 0);
|
||||||
|
op2_in : in unsigned (data_width-1 downto 0);
|
||||||
|
flags : out bcu_flags_t
|
||||||
|
);
|
||||||
|
end bcu;
|
||||||
|
|
||||||
|
architecture Behavioral of bcu is
|
||||||
|
|
||||||
|
--------------------------------------------------------------------------
|
||||||
|
begin
|
||||||
|
|
||||||
|
flags.eq <= '1' when op1_in = op2_in else '0' after 3 ns;
|
||||||
|
flags.ltz <= op1_in(op1_in'left) after 1 ns;
|
||||||
|
|
||||||
|
--------------------------------------------------------------------------
|
||||||
|
end Behavioral;
|
||||||
@@ -0,0 +1,496 @@
|
|||||||
|
--------------------------------------------------------------------------
|
||||||
|
-- Project: JIPS, a portable 32-bit RISC CPU written in VHDL
|
||||||
|
-- This file: JIPS top file
|
||||||
|
--
|
||||||
|
-- Copyright (C) 2008 J. Ahrensfeld
|
||||||
|
--
|
||||||
|
-- This program is free software: you can redistribute it and/or modify
|
||||||
|
-- it under the terms of the GNU General Public License as published by
|
||||||
|
-- the Free Software Foundation, either version 3 of the License, or
|
||||||
|
-- (at your option) any later version.
|
||||||
|
--
|
||||||
|
-- This program 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 General Public License for more details.
|
||||||
|
--
|
||||||
|
-- You should have received a copy of the GNU General Public License
|
||||||
|
-- along with this program. If not, see <http://www.gnu.org/licenses/>.
|
||||||
|
--
|
||||||
|
-- For questions and ideas, please contact the author at jens@jayfield.org
|
||||||
|
--
|
||||||
|
--------------------------------------------------------------------------
|
||||||
|
|
||||||
|
library IEEE;
|
||||||
|
use IEEE.STD_LOGIC_1164.ALL;
|
||||||
|
use IEEE.numeric_std.ALL;
|
||||||
|
|
||||||
|
library work;
|
||||||
|
use work.mips_types.all;
|
||||||
|
|
||||||
|
entity biu is
|
||||||
|
Generic
|
||||||
|
(
|
||||||
|
icache_size : natural := 2048; -- words
|
||||||
|
dcache_size : natural := 2048 -- words
|
||||||
|
);
|
||||||
|
Port
|
||||||
|
(
|
||||||
|
RST_I : in STD_LOGIC;
|
||||||
|
CLK_I : in STD_LOGIC;
|
||||||
|
ACK_I : in STD_LOGIC;
|
||||||
|
SRDY_I : in STD_LOGIC;
|
||||||
|
ADDR_O : out word_t;
|
||||||
|
DAT_I : in word_t;
|
||||||
|
DAT_O : out word_t;
|
||||||
|
WE_O : out STD_LOGIC;
|
||||||
|
SEL_O : out unsigned(3 downto 0);
|
||||||
|
CYC_O : out STD_LOGIC;
|
||||||
|
STB_O : out STD_LOGIC;
|
||||||
|
MRDY_O : out STD_LOGIC;
|
||||||
|
cpu_imem_err : out STD_LOGIC;
|
||||||
|
cpu_imem_rdy : out STD_LOGIC;
|
||||||
|
cpu_imem_en : in STD_LOGIC;
|
||||||
|
cpu_imem_addr : in word_t;
|
||||||
|
cpu_imem_din : out word_t;
|
||||||
|
cpu_dmem_err : out STD_LOGIC;
|
||||||
|
cpu_dmem_rdy : out STD_LOGIC;
|
||||||
|
cpu_dmem_en : in STD_LOGIC;
|
||||||
|
cpu_dmem_we : in STD_LOGIC;
|
||||||
|
cpu_dmem_be : in unsigned(3 downto 0);
|
||||||
|
cpu_dmem_dout : in word_t;
|
||||||
|
cpu_dmem_din : out word_t;
|
||||||
|
cpu_dmem_addr : in word_t
|
||||||
|
);
|
||||||
|
end biu;
|
||||||
|
|
||||||
|
architecture behavior of biu is
|
||||||
|
|
||||||
|
COMPONENT icache
|
||||||
|
GENERIC
|
||||||
|
(
|
||||||
|
cache_size : natural; -- words
|
||||||
|
line_size : natural -- words
|
||||||
|
);
|
||||||
|
PORT
|
||||||
|
(
|
||||||
|
RST_I : in STD_LOGIC;
|
||||||
|
CLK_I : in STD_LOGIC;
|
||||||
|
ACK_I : in STD_LOGIC;
|
||||||
|
SRDY_I : in STD_LOGIC;
|
||||||
|
ADDR_O : out word_t;
|
||||||
|
DAT_I : in word_t;
|
||||||
|
STB_O : out STD_LOGIC;
|
||||||
|
CYC_O : out STD_LOGIC;
|
||||||
|
en : in STD_LOGIC;
|
||||||
|
cpu_en : in STD_LOGIC;
|
||||||
|
cpu_addr : in word_t;
|
||||||
|
cpu_dout : out word_t;
|
||||||
|
cpu_busy : out STD_LOGIC
|
||||||
|
);
|
||||||
|
END COMPONENT;
|
||||||
|
|
||||||
|
COMPONENT dcache
|
||||||
|
GENERIC
|
||||||
|
(
|
||||||
|
cache_size : natural; -- words
|
||||||
|
line_size : natural -- words
|
||||||
|
);
|
||||||
|
PORT
|
||||||
|
(
|
||||||
|
RST_I : in STD_LOGIC;
|
||||||
|
CLK_I : in STD_LOGIC;
|
||||||
|
ACK_I : in STD_LOGIC;
|
||||||
|
SRDY_I : in STD_LOGIC;
|
||||||
|
ADDR_O : out word_t;
|
||||||
|
DAT_I : in word_t;
|
||||||
|
STB_O : out STD_LOGIC;
|
||||||
|
CYC_O : out STD_LOGIC;
|
||||||
|
en : in STD_LOGIC;
|
||||||
|
cpu_en : in STD_LOGIC;
|
||||||
|
cpu_we : in STD_LOGIC;
|
||||||
|
cpu_be : in unsigned(3 downto 0);
|
||||||
|
cpu_addr : in word_t;
|
||||||
|
cpu_din : in word_t;
|
||||||
|
cpu_dout : out word_t;
|
||||||
|
cpu_busy : out STD_LOGIC
|
||||||
|
);
|
||||||
|
END COMPONENT;
|
||||||
|
|
||||||
|
type bus_state_t is (init, ready, icache_bus_access, dcache_bus_access, write_bus, read_bus, read_finish);
|
||||||
|
|
||||||
|
signal s, sn : bus_state_t;
|
||||||
|
signal bus_idle : std_logic;
|
||||||
|
signal busy : std_logic;
|
||||||
|
signal dmem_be : unsigned(3 downto 0);
|
||||||
|
signal dcache_dout : word_t;
|
||||||
|
signal dcache_mem_gnt : std_logic;
|
||||||
|
signal icache_mem_gnt : std_logic;
|
||||||
|
signal dmem_mem_wr_gnt : std_logic;
|
||||||
|
signal dmem_mem_rd_gnt : std_logic;
|
||||||
|
signal dcache_busy : std_logic;
|
||||||
|
signal icache_busy : std_logic;
|
||||||
|
signal CYC_O_icache : std_logic;
|
||||||
|
signal CYC_O_dcache : std_logic;
|
||||||
|
signal CYC_O_dmem_rd : std_logic;
|
||||||
|
signal CYC_O_dmem_wr : std_logic;
|
||||||
|
signal SRDY_I_icache : std_logic;
|
||||||
|
signal SRDY_I_dcache : std_logic;
|
||||||
|
signal ADDR_O_icache : word_t;
|
||||||
|
signal ADDR_O_dcache : word_t;
|
||||||
|
signal ADDR_O_dmem_rd : word_t;
|
||||||
|
signal ADDR_O_dmem_wr : word_t;
|
||||||
|
signal STB_O_icache : std_logic;
|
||||||
|
signal STB_O_dcache : std_logic;
|
||||||
|
signal STB_O_dmem_rd : std_logic;
|
||||||
|
signal STB_O_dmem_wr : std_logic;
|
||||||
|
signal DAT_I_dmem_rd : word_t;
|
||||||
|
signal DAT_O_dmem_wr : word_t;
|
||||||
|
signal SEL_O_dmem_wr : unsigned(3 downto 0);
|
||||||
|
signal dcached : std_logic;
|
||||||
|
signal dcache_en : std_logic;
|
||||||
|
signal uncached_access : std_logic;
|
||||||
|
|
||||||
|
type timeout_cnt_t is range 0 to 1E5-1;
|
||||||
|
signal bus_timeout_cnt : timeout_cnt_t;
|
||||||
|
signal bus_timeout : std_logic;
|
||||||
|
|
||||||
|
signal bout_fifo_din : unsigned(68 downto 0);
|
||||||
|
signal bout_fifo_dout : unsigned(68 downto 0);
|
||||||
|
signal bout_fifo_re : std_logic;
|
||||||
|
signal bout_fifo_we : std_logic;
|
||||||
|
signal bout_fifo_full : std_logic;
|
||||||
|
signal bout_fifo_empty : std_logic;
|
||||||
|
signal bout_rdy : std_logic;
|
||||||
|
|
||||||
|
alias bout_fifo_addr_in is bout_fifo_din(31 downto 0);
|
||||||
|
alias bout_fifo_data_in is bout_fifo_din(63 downto 32);
|
||||||
|
alias bout_fifo_sel_in is bout_fifo_din(67 downto 64);
|
||||||
|
alias bout_fifo_we_in is bout_fifo_din(68);
|
||||||
|
alias bout_fifo_addr_out is bout_fifo_dout(31 downto 0);
|
||||||
|
alias bout_fifo_data_out is bout_fifo_dout(63 downto 32);
|
||||||
|
alias bout_fifo_sel_out is bout_fifo_dout(67 downto 64);
|
||||||
|
alias bout_fifo_we_out is bout_fifo_dout(68);
|
||||||
|
|
||||||
|
signal write_fifo_din : unsigned(67 downto 0);
|
||||||
|
signal write_fifo_dout : unsigned(67 downto 0);
|
||||||
|
signal write_fifo_re : std_logic;
|
||||||
|
signal write_fifo_we : std_logic;
|
||||||
|
signal write_fifo_full : std_logic;
|
||||||
|
signal write_fifo_empty : std_logic;
|
||||||
|
signal write_busy : std_logic;
|
||||||
|
|
||||||
|
alias write_fifo_addr_in is write_fifo_din(31 downto 0);
|
||||||
|
alias write_fifo_data_in is write_fifo_din(63 downto 32);
|
||||||
|
alias write_fifo_sel_in is write_fifo_din(67 downto 64);
|
||||||
|
alias write_fifo_addr_out is write_fifo_dout(31 downto 0);
|
||||||
|
alias write_fifo_data_out is write_fifo_dout(63 downto 32);
|
||||||
|
alias write_fifo_sel_out is write_fifo_dout(67 downto 64);
|
||||||
|
|
||||||
|
signal read_cycle : std_logic;
|
||||||
|
|
||||||
|
begin
|
||||||
|
|
||||||
|
|
||||||
|
MRDY_O <= '1';
|
||||||
|
|
||||||
|
read_cyc_register:
|
||||||
|
process(CLK_I)
|
||||||
|
begin
|
||||||
|
if rising_edge(CLK_I) then
|
||||||
|
if RST_I = '1' then
|
||||||
|
read_cycle <= '0';
|
||||||
|
else
|
||||||
|
read_cycle <= (dmem_mem_rd_gnt and CYC_O_dmem_rd)
|
||||||
|
or (dcache_mem_gnt and CYC_O_dcache)
|
||||||
|
or (icache_mem_gnt and CYC_O_icache);
|
||||||
|
end if;
|
||||||
|
end if;
|
||||||
|
end process;
|
||||||
|
|
||||||
|
CYC_O <= not bout_fifo_empty or read_cycle;
|
||||||
|
STB_O <= not bout_fifo_empty;
|
||||||
|
ADDR_O <= bout_fifo_addr_out;
|
||||||
|
DAT_O <= bout_fifo_data_out;
|
||||||
|
SEL_O <= bout_fifo_sel_out;
|
||||||
|
WE_O <= bout_fifo_we_out;
|
||||||
|
|
||||||
|
cpu_imem_rdy <= not icache_busy after 4.5 ns;
|
||||||
|
busy <= CYC_O_dmem_rd or dcache_busy or (write_busy);
|
||||||
|
cpu_dmem_rdy <= not busy after 4.5 ns;
|
||||||
|
|
||||||
|
inst_icache : icache
|
||||||
|
GENERIC MAP
|
||||||
|
(
|
||||||
|
cache_size => icache_size, -- words
|
||||||
|
line_size => 8
|
||||||
|
)
|
||||||
|
PORT MAP
|
||||||
|
(
|
||||||
|
CLK_I => CLK_I,
|
||||||
|
RST_I => RST_I,
|
||||||
|
STB_O => STB_O_icache,
|
||||||
|
CYC_O => CYC_O_icache,
|
||||||
|
ADDR_O => ADDR_O_icache,
|
||||||
|
DAT_I => DAT_I,
|
||||||
|
ACK_I => ACK_I,
|
||||||
|
SRDY_I => SRDY_I_icache,
|
||||||
|
en => '1',
|
||||||
|
cpu_en => cpu_imem_en,
|
||||||
|
cpu_addr => cpu_imem_addr,
|
||||||
|
cpu_dout => cpu_imem_din,
|
||||||
|
cpu_busy => icache_busy
|
||||||
|
);
|
||||||
|
|
||||||
|
SRDY_I_icache <= bout_rdy and icache_mem_gnt;
|
||||||
|
|
||||||
|
inst_dcache : dcache
|
||||||
|
GENERIC MAP
|
||||||
|
(
|
||||||
|
cache_size => dcache_size, -- words
|
||||||
|
line_size => 8
|
||||||
|
)
|
||||||
|
PORT MAP
|
||||||
|
(
|
||||||
|
CLK_I => CLK_I,
|
||||||
|
RST_I => RST_I,
|
||||||
|
CYC_O => CYC_O_dcache,
|
||||||
|
STB_O => STB_O_dcache,
|
||||||
|
ADDR_O => ADDR_O_dcache,
|
||||||
|
DAT_I => DAT_I,
|
||||||
|
ACK_I => ACK_I,
|
||||||
|
SRDY_I => SRDY_I_dcache,
|
||||||
|
en => dcached,
|
||||||
|
cpu_en => dcache_en,
|
||||||
|
cpu_we => cpu_dmem_we,
|
||||||
|
cpu_be => cpu_dmem_be,
|
||||||
|
cpu_addr => cpu_dmem_addr,
|
||||||
|
cpu_din => cpu_dmem_dout,
|
||||||
|
cpu_dout => dcache_dout,
|
||||||
|
cpu_busy => dcache_busy
|
||||||
|
);
|
||||||
|
|
||||||
|
SRDY_I_dcache <= bout_rdy and dcache_mem_gnt;
|
||||||
|
|
||||||
|
dcached <= '1' when cpu_dmem_addr(31 downto 28) /= X"A" else '0';
|
||||||
|
cpu_dmem_din <= dcache_dout when uncached_access = '0' else DAT_I_dmem_rd;
|
||||||
|
dcache_en <= cpu_dmem_en and not busy;
|
||||||
|
|
||||||
|
-- Instantiate synchronous FIFO
|
||||||
|
inst_bout_fifo: entity work.fifo_sync_dist
|
||||||
|
GENERIC MAP
|
||||||
|
(
|
||||||
|
addr_width => 4,
|
||||||
|
data_width => 69
|
||||||
|
)
|
||||||
|
PORT MAP
|
||||||
|
(
|
||||||
|
rst => RST_I,
|
||||||
|
clk => CLK_I,
|
||||||
|
we => bout_fifo_we,
|
||||||
|
re => bout_fifo_re,
|
||||||
|
fifo_full => bout_fifo_full,
|
||||||
|
fifo_empty => bout_fifo_empty,
|
||||||
|
fifo_afull => open,
|
||||||
|
fifo_aempty => open,
|
||||||
|
data_w => bout_fifo_din,
|
||||||
|
data_r => bout_fifo_dout
|
||||||
|
);
|
||||||
|
bout_rdy <= not bout_fifo_full;
|
||||||
|
bout_fifo_re <= not bout_fifo_empty and SRDY_I;
|
||||||
|
|
||||||
|
bout_fifo_we <= STB_O_dmem_wr or STB_O_dmem_rd or STB_O_dcache or STB_O_icache;
|
||||||
|
|
||||||
|
bout_fifo_data_in <= DAT_O_dmem_wr when dmem_mem_wr_gnt = '1' else (others => '-');
|
||||||
|
|
||||||
|
bout_fifo_addr_in <= ADDR_O_dmem_wr when dmem_mem_wr_gnt = '1' else
|
||||||
|
ADDR_O_dmem_rd when dmem_mem_rd_gnt = '1' else
|
||||||
|
ADDR_O_dcache when dcache_mem_gnt = '1' else
|
||||||
|
ADDR_O_icache when icache_mem_gnt = '1' else (others => '-');
|
||||||
|
|
||||||
|
bout_fifo_sel_in <= SEL_O_dmem_wr when dmem_mem_wr_gnt = '1' else (others => '0');
|
||||||
|
bout_fifo_we_in <= '1' when dmem_mem_wr_gnt = '1' else '0';
|
||||||
|
|
||||||
|
-- Instantiate synchronous FIFO
|
||||||
|
inst_write_fifo: entity work.fifo_sync_dist
|
||||||
|
GENERIC MAP
|
||||||
|
(
|
||||||
|
addr_width => 4,
|
||||||
|
data_width => 68
|
||||||
|
)
|
||||||
|
PORT MAP
|
||||||
|
(
|
||||||
|
rst => RST_I,
|
||||||
|
clk => CLK_I,
|
||||||
|
we => write_fifo_we,
|
||||||
|
re => write_fifo_re,
|
||||||
|
fifo_full => write_busy,
|
||||||
|
fifo_empty => write_fifo_empty,
|
||||||
|
fifo_afull => open,
|
||||||
|
fifo_aempty => open,
|
||||||
|
data_w => write_fifo_din,
|
||||||
|
data_r => write_fifo_dout
|
||||||
|
);
|
||||||
|
|
||||||
|
CYC_O_dmem_wr <= not write_fifo_empty;
|
||||||
|
DAT_O_dmem_wr <= write_fifo_data_out;
|
||||||
|
ADDR_O_dmem_wr <= write_fifo_addr_out;
|
||||||
|
SEL_O_dmem_wr <= write_fifo_sel_out;
|
||||||
|
|
||||||
|
write_fifo_data_in <= cpu_dmem_dout;
|
||||||
|
write_fifo_addr_in <= cpu_dmem_addr;
|
||||||
|
write_fifo_sel_in <= cpu_dmem_be;
|
||||||
|
write_fifo_re <= STB_O_dmem_wr;
|
||||||
|
write_fifo_we <= cpu_dmem_en and not busy and cpu_dmem_we;
|
||||||
|
|
||||||
|
dmem_rd_flags:
|
||||||
|
process(CLK_I)
|
||||||
|
begin
|
||||||
|
if rising_edge(CLK_I) then
|
||||||
|
uncached_access <= '0';
|
||||||
|
if RST_I = '1' then
|
||||||
|
CYC_O_dmem_rd <= '0';
|
||||||
|
else
|
||||||
|
if ACK_I = '1' and dmem_mem_rd_gnt = '1' then
|
||||||
|
uncached_access <= '1';
|
||||||
|
CYC_O_dmem_rd <= '0';
|
||||||
|
end if;
|
||||||
|
if cpu_dmem_en = '1' and busy = '0' and cpu_dmem_we = '0' then
|
||||||
|
if dcached = '0' then
|
||||||
|
CYC_O_dmem_rd <= '1';
|
||||||
|
end if;
|
||||||
|
end if;
|
||||||
|
end if;
|
||||||
|
end if;
|
||||||
|
end process;
|
||||||
|
|
||||||
|
dmem_rd_data:
|
||||||
|
process(CLK_I)
|
||||||
|
begin
|
||||||
|
if rising_edge(CLK_I) then
|
||||||
|
if RST_I = '1' then
|
||||||
|
DAT_I_dmem_rd <= (others => '0');
|
||||||
|
elsif ACK_I = '1' and CYC_O_dmem_rd = '1' then
|
||||||
|
DAT_I_dmem_rd <= DAT_I;
|
||||||
|
end if;
|
||||||
|
end if;
|
||||||
|
end process;
|
||||||
|
|
||||||
|
dmem_rd_regs:
|
||||||
|
process(CLK_I)
|
||||||
|
begin
|
||||||
|
if rising_edge(CLK_I) then
|
||||||
|
if cpu_dmem_en = '1' and busy = '0' then
|
||||||
|
ADDR_O_dmem_rd <= cpu_dmem_addr;
|
||||||
|
end if;
|
||||||
|
end if;
|
||||||
|
end process;
|
||||||
|
|
||||||
|
bus_state_next:
|
||||||
|
process(CLK_I)
|
||||||
|
begin
|
||||||
|
if rising_edge(CLK_I) then
|
||||||
|
if RST_I = '1' then
|
||||||
|
s <= init;
|
||||||
|
else
|
||||||
|
s <= sn;
|
||||||
|
end if;
|
||||||
|
end if;
|
||||||
|
end process;
|
||||||
|
|
||||||
|
bus_state:
|
||||||
|
process(s, CYC_O_icache, CYC_O_dcache, CYC_O_dmem_wr, CYC_O_dmem_rd, bout_rdy, ACK_I)
|
||||||
|
begin
|
||||||
|
|
||||||
|
icache_mem_gnt <= '0';
|
||||||
|
dcache_mem_gnt <= '0';
|
||||||
|
dmem_mem_rd_gnt <= '0';
|
||||||
|
dmem_mem_wr_gnt <= '0';
|
||||||
|
STB_O_dmem_rd <= '0';
|
||||||
|
STB_O_dmem_wr <= '0';
|
||||||
|
bus_idle <= '0';
|
||||||
|
sn <= s;
|
||||||
|
case s is
|
||||||
|
when init =>
|
||||||
|
sn <= ready;
|
||||||
|
when ready =>
|
||||||
|
bus_idle <= '1';
|
||||||
|
if CYC_O_dmem_wr = '1' then
|
||||||
|
sn <= write_bus;
|
||||||
|
elsif CYC_O_dmem_rd = '1' then
|
||||||
|
sn <= read_bus;
|
||||||
|
elsif CYC_O_icache = '1' then
|
||||||
|
sn <= icache_bus_access;
|
||||||
|
elsif CYC_O_dcache = '1' then
|
||||||
|
sn <= dcache_bus_access;
|
||||||
|
end if;
|
||||||
|
when icache_bus_access =>
|
||||||
|
icache_mem_gnt <= '1';
|
||||||
|
if CYC_O_icache = '0' then
|
||||||
|
sn <= ready;
|
||||||
|
end if;
|
||||||
|
when dcache_bus_access =>
|
||||||
|
dcache_mem_gnt <= '1';
|
||||||
|
if CYC_O_dcache = '0' then
|
||||||
|
sn <= ready;
|
||||||
|
end if;
|
||||||
|
when write_bus =>
|
||||||
|
dmem_mem_wr_gnt <= '1';
|
||||||
|
if CYC_O_dmem_wr = '1' then
|
||||||
|
if bout_rdy = '1' then
|
||||||
|
STB_O_dmem_wr <= '1';
|
||||||
|
end if;
|
||||||
|
else
|
||||||
|
sn <= ready;
|
||||||
|
end if;
|
||||||
|
when read_bus =>
|
||||||
|
dmem_mem_rd_gnt <= '1';
|
||||||
|
if bout_rdy = '1' then
|
||||||
|
STB_O_dmem_rd <= '1';
|
||||||
|
sn <= read_finish;
|
||||||
|
end if;
|
||||||
|
when read_finish =>
|
||||||
|
dmem_mem_rd_gnt <= '1';
|
||||||
|
if ACK_I = '1' then
|
||||||
|
sn <= ready;
|
||||||
|
end if;
|
||||||
|
when others =>
|
||||||
|
sn <= ready;
|
||||||
|
end case;
|
||||||
|
|
||||||
|
end process;
|
||||||
|
|
||||||
|
bus_timeout_counter:
|
||||||
|
process(CLK_I)
|
||||||
|
begin
|
||||||
|
if rising_edge(CLK_I) then
|
||||||
|
if bus_idle = '0' then
|
||||||
|
if bus_timeout_cnt /= 0 then
|
||||||
|
bus_timeout_cnt <= bus_timeout_cnt - 1;
|
||||||
|
else
|
||||||
|
bus_timeout <= '1';
|
||||||
|
end if;
|
||||||
|
else
|
||||||
|
bus_timeout_cnt <= timeout_cnt_t'high;
|
||||||
|
bus_timeout <= '0';
|
||||||
|
end if;
|
||||||
|
end if;
|
||||||
|
end process;
|
||||||
|
|
||||||
|
bus_err:
|
||||||
|
process(CLK_I)
|
||||||
|
begin
|
||||||
|
if rising_edge(CLK_I) then
|
||||||
|
if RST_I = '1' then
|
||||||
|
cpu_imem_err <= '0';
|
||||||
|
cpu_dmem_err <= '0';
|
||||||
|
elsif bus_timeout = '1' then
|
||||||
|
cpu_imem_err <= icache_mem_gnt;
|
||||||
|
cpu_dmem_err <= dcache_mem_gnt or dmem_mem_wr_gnt or dmem_mem_rd_gnt;
|
||||||
|
end if;
|
||||||
|
end if;
|
||||||
|
end process;
|
||||||
|
|
||||||
|
-------------------------------------------------------------------
|
||||||
|
|
||||||
|
end behavior;
|
||||||
@@ -0,0 +1,415 @@
|
|||||||
|
--------------------------------------------------------------------------
|
||||||
|
-- Project: JIPS, a portable 32-bit RISC CPU written in VHDL
|
||||||
|
-- This file: The arithmetic logic unit
|
||||||
|
--
|
||||||
|
-- Copyright (C) 2008 J. Ahrensfeld
|
||||||
|
--
|
||||||
|
-- This program is free software: you can redistribute it and/or modify
|
||||||
|
-- it under the terms of the GNU General Public License as published by
|
||||||
|
-- the Free Software Foundation, either version 3 of the License, or
|
||||||
|
-- (at your option) any later version.
|
||||||
|
--
|
||||||
|
-- This program 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 General Public License for more details.
|
||||||
|
--
|
||||||
|
-- You should have received a copy of the GNU General Public License
|
||||||
|
-- along with this program. If not, see <http://www.gnu.org/licenses/>.
|
||||||
|
--
|
||||||
|
-- For questions and ideas, please contact the author at jens@jayfield.org
|
||||||
|
--
|
||||||
|
--------------------------------------------------------------------------
|
||||||
|
|
||||||
|
library IEEE;
|
||||||
|
use IEEE.STD_LOGIC_1164.ALL;
|
||||||
|
use IEEE.numeric_std.ALL;
|
||||||
|
|
||||||
|
use work.mips_types.all;
|
||||||
|
use work.mips_instr.all;
|
||||||
|
|
||||||
|
entity cop is
|
||||||
|
Port
|
||||||
|
(
|
||||||
|
rst : in STD_LOGIC;
|
||||||
|
clk : in STD_LOGIC;
|
||||||
|
sdu : in sdu_t;
|
||||||
|
IR_valid : in STD_LOGIC;
|
||||||
|
IR : in word_t;
|
||||||
|
events : in event_t;
|
||||||
|
ctrl_in : in cop_ctrl_in_t;
|
||||||
|
ctrl_out : out cop_ctrl_out_t;
|
||||||
|
din : in word_t;
|
||||||
|
dout : out word_t
|
||||||
|
);
|
||||||
|
end cop;
|
||||||
|
|
||||||
|
architecture Behavioral of cop is
|
||||||
|
|
||||||
|
signal epc : word_t;
|
||||||
|
signal cause : word_t;
|
||||||
|
signal status : word_t;
|
||||||
|
signal BadVAddr : word_t;
|
||||||
|
signal exc_code : unsigned(4 downto 0);
|
||||||
|
signal test_reg : word_t;
|
||||||
|
signal test_reg_we : STD_LOGIC;
|
||||||
|
signal stat_reg_we : STD_LOGIC;
|
||||||
|
signal eflags_reg_we : STD_LOGIC;
|
||||||
|
signal epc_reg_we : STD_LOGIC;
|
||||||
|
signal code_reg_we : STD_LOGIC;
|
||||||
|
signal ip_reg_we : STD_LOGIC;
|
||||||
|
signal bd : STD_LOGIC;
|
||||||
|
signal ip : unsigned(7 downto 0);
|
||||||
|
signal im : unsigned(7 downto 0);
|
||||||
|
signal status_save : STD_LOGIC;
|
||||||
|
signal status_rest : STD_LOGIC;
|
||||||
|
signal exception : STD_LOGIC;
|
||||||
|
signal exception_end : STD_LOGIC;
|
||||||
|
signal eflags : exc_flags_t;
|
||||||
|
signal exc_enable : STD_LOGIC;
|
||||||
|
signal cop_EX_en : STD_LOGIC;
|
||||||
|
|
||||||
|
type cop_pipe_t is record
|
||||||
|
din : word_t;
|
||||||
|
rs : reg_ptr_t;
|
||||||
|
rd : reg_ptr_t;
|
||||||
|
func : func_t;
|
||||||
|
we : std_logic;
|
||||||
|
re : std_logic;
|
||||||
|
cs : std_logic;
|
||||||
|
end record;
|
||||||
|
|
||||||
|
signal cop_pipe_ID : cop_pipe_t;
|
||||||
|
signal cop_pipe_EX : cop_pipe_t;
|
||||||
|
|
||||||
|
function eval_int(ip : unsigned) return STD_LOGIC is
|
||||||
|
variable result : STD_LOGIC;
|
||||||
|
begin
|
||||||
|
result := '0';
|
||||||
|
for i in ip'range loop
|
||||||
|
result := result or ip(i);
|
||||||
|
end loop;
|
||||||
|
|
||||||
|
return result;
|
||||||
|
end eval_int;
|
||||||
|
|
||||||
|
type exc_state_t is (exc_init, exc_idle, exc_commit_ID, exc_commit_EX, exc_commit_MEM);
|
||||||
|
signal exc_state, exc_staten : exc_state_t;
|
||||||
|
|
||||||
|
--------------------------------------------------------------------------
|
||||||
|
begin
|
||||||
|
|
||||||
|
cop_pipe_ID.din <= din;
|
||||||
|
cop_pipe_ID.cs <= IR_valid;
|
||||||
|
cop_pipe_ID.rs <= extract_rs(IR);
|
||||||
|
cop_pipe_ID.rd <= extract_rd(IR);
|
||||||
|
cop_pipe_ID.func <= extract_func(IR);
|
||||||
|
cop_pipe_ID.re <= cop_pipe_ID.cs when cop_pipe_ID.rs = "00000" else '0';
|
||||||
|
cop_pipe_ID.we <= cop_pipe_ID.cs when cop_pipe_ID.rs = "00100" else '0';
|
||||||
|
cop_EX_en <= exc_enable and not status_save;
|
||||||
|
|
||||||
|
ctrl_out.ee <= exc_enable;
|
||||||
|
ctrl_out.ec <= status_save;
|
||||||
|
ctrl_out.RE <= status(25);
|
||||||
|
ctrl_out.user_mode <= status(1);
|
||||||
|
ctrl_out.int <= eflags.Int;
|
||||||
|
|
||||||
|
ctrl_out.cop_read <= cop_pipe_EX.cs and cop_pipe_EX.re after 1 ns;
|
||||||
|
ctrl_out.reg_write <= cop_pipe_ID.re after 1 ns;
|
||||||
|
|
||||||
|
im <= status(15 downto 8);
|
||||||
|
cause <= bd & (30 downto 16 => '0') & ip & '0' & exc_code & "00";
|
||||||
|
|
||||||
|
eflags.Ov <= events.alu_ovf or events.alu_uvf;
|
||||||
|
eflags.DAdEL <= events.data_load_err;
|
||||||
|
eflags.DAdES <= events.data_store_err;
|
||||||
|
eflags.IAdEL <= events.inst_load_err;
|
||||||
|
eflags.IAdEK <= events.inst_priv_addr and status(1);
|
||||||
|
eflags.Sys <= events.syscall;
|
||||||
|
eflags.Bp <= events.break;
|
||||||
|
eflags.RI <= events.illegal;
|
||||||
|
eflags.Int <= eval_int(ip) and status(0);
|
||||||
|
|
||||||
|
exception <= eflags.Ov or eflags.Sys or eflags.Bp or eflags.RI or eflags.IAdEL or eflags.IAdEK or eflags.DAdEL or eflags.DAdES or eflags.Int after 1 ns;
|
||||||
|
|
||||||
|
exception_state:
|
||||||
|
process(exc_state, ctrl_in, exception, sdu)
|
||||||
|
begin
|
||||||
|
|
||||||
|
exc_enable <= '0';
|
||||||
|
ctrl_out.exc_commit <= '0';
|
||||||
|
ctrl_out.exc_pending <= '0';
|
||||||
|
epc_reg_we <= '0';
|
||||||
|
code_reg_we <= '0';
|
||||||
|
status_save <= '0';
|
||||||
|
eflags_reg_we <= '0';
|
||||||
|
|
||||||
|
exc_staten <= exc_state;
|
||||||
|
|
||||||
|
case exc_state is
|
||||||
|
|
||||||
|
when exc_init =>
|
||||||
|
exc_staten <= exc_idle;
|
||||||
|
|
||||||
|
when exc_idle =>
|
||||||
|
exc_enable <= '1';
|
||||||
|
if exception = '1' then
|
||||||
|
status_save <= '1';
|
||||||
|
eflags_reg_we <= '1';
|
||||||
|
code_reg_we <= '1';
|
||||||
|
exc_staten <= exc_commit_ID;
|
||||||
|
end if;
|
||||||
|
|
||||||
|
when exc_commit_ID =>
|
||||||
|
ctrl_out.exc_pending <= '1';
|
||||||
|
ctrl_out.exc_commit <= '1';
|
||||||
|
if sdu.ID_stall = '0' then
|
||||||
|
exc_staten <= exc_commit_EX;
|
||||||
|
end if;
|
||||||
|
|
||||||
|
when exc_commit_EX =>
|
||||||
|
ctrl_out.exc_pending <= '1';
|
||||||
|
ctrl_out.exc_commit <= '1';
|
||||||
|
if sdu.EX_stall = '0' then
|
||||||
|
exc_staten <= exc_commit_MEM;
|
||||||
|
end if;
|
||||||
|
|
||||||
|
when exc_commit_MEM =>
|
||||||
|
ctrl_out.exc_pending <= '1';
|
||||||
|
if sdu.MEM_stall = '0' then
|
||||||
|
epc_reg_we <= '1';
|
||||||
|
exc_staten <= exc_idle;
|
||||||
|
end if;
|
||||||
|
|
||||||
|
when others =>
|
||||||
|
exc_staten <= exc_idle;
|
||||||
|
|
||||||
|
end case;
|
||||||
|
end process;
|
||||||
|
|
||||||
|
exception_state_next:
|
||||||
|
process(clk)
|
||||||
|
begin
|
||||||
|
if rising_edge(clk) then
|
||||||
|
if rst = '1' then
|
||||||
|
exc_state <= exc_init;
|
||||||
|
else
|
||||||
|
exc_state <= exc_staten;
|
||||||
|
end if;
|
||||||
|
end if;
|
||||||
|
end process;
|
||||||
|
|
||||||
|
cop_exception_epc_write:
|
||||||
|
process(clk)
|
||||||
|
begin
|
||||||
|
if rising_edge(clk) then
|
||||||
|
if rst = '1' then
|
||||||
|
bd <= '0';
|
||||||
|
epc <= (others => '0');
|
||||||
|
elsif epc_reg_we = '1' then
|
||||||
|
bd <= '0';
|
||||||
|
epc <= ctrl_in.epc_mem;
|
||||||
|
if ctrl_in.bd_wb = '1' then
|
||||||
|
bd <= '1';
|
||||||
|
epc <= ctrl_in.epc_wb;
|
||||||
|
end if;
|
||||||
|
end if;
|
||||||
|
end if;
|
||||||
|
end process;
|
||||||
|
|
||||||
|
cop_exception_map:
|
||||||
|
process(clk)
|
||||||
|
begin
|
||||||
|
if rising_edge(clk) then
|
||||||
|
if rst = '1' then
|
||||||
|
exc_code <= (others => '0');
|
||||||
|
BadVAddr <= (others => '0');
|
||||||
|
elsif code_reg_we = '1' then
|
||||||
|
if eflags.Ov = '1' then
|
||||||
|
exc_code <= "01100";
|
||||||
|
elsif eflags.Sys = '1' then
|
||||||
|
exc_code <= "01000";
|
||||||
|
elsif eflags.Bp = '1' then
|
||||||
|
exc_code <= "01001";
|
||||||
|
elsif eflags.RI = '1' then
|
||||||
|
exc_code <= "01010";
|
||||||
|
elsif eflags.IAdEL = '1' then
|
||||||
|
exc_code <= "00100";
|
||||||
|
BadVAddr <= ctrl_in.imem_addr;
|
||||||
|
elsif eflags.IAdEK = '1' then
|
||||||
|
exc_code <= "00100";
|
||||||
|
BadVAddr <= ctrl_in.imem_addr;
|
||||||
|
elsif eflags.DAdEL = '1' then
|
||||||
|
exc_code <= "00100";
|
||||||
|
BadVAddr <= ctrl_in.dmem_addr;
|
||||||
|
elsif eflags.DAdES = '1' then
|
||||||
|
exc_code <= "00101";
|
||||||
|
BadVAddr <= ctrl_in.dmem_addr;
|
||||||
|
elsif eflags.Int = '1' then
|
||||||
|
exc_code <= "00000";
|
||||||
|
end if;
|
||||||
|
end if;
|
||||||
|
end if;
|
||||||
|
end process;
|
||||||
|
|
||||||
|
status_rest <= exception_end and ctrl_in.exc_left;
|
||||||
|
|
||||||
|
cop_status_restore:
|
||||||
|
process(clk)
|
||||||
|
begin
|
||||||
|
if rising_edge(clk) then
|
||||||
|
if rst = '1' then
|
||||||
|
exception_end <= '0';
|
||||||
|
ctrl_out.exc_exit <= '0';
|
||||||
|
else
|
||||||
|
if cop_pipe_ID.func = "10000" and exception_end = '0' then -- RFE
|
||||||
|
exception_end <= cop_pipe_ID.cs;
|
||||||
|
ctrl_out.exc_exit <= cop_pipe_ID.cs;
|
||||||
|
elsif exception_end = '1' and ctrl_in.exc_left = '1' then
|
||||||
|
exception_end <= '0';
|
||||||
|
ctrl_out.exc_exit <= '0';
|
||||||
|
end if;
|
||||||
|
end if;
|
||||||
|
end if;
|
||||||
|
end process;
|
||||||
|
|
||||||
|
cop_ip_reg_write:
|
||||||
|
process(clk)
|
||||||
|
begin
|
||||||
|
if rising_edge(clk) then
|
||||||
|
if rst = '1' then
|
||||||
|
ip(1 downto 0) <= (others => '0');
|
||||||
|
elsif ip_reg_we = '1' then
|
||||||
|
ip(1 downto 0) <= cop_pipe_EX.din(9 downto 8) and im(1 downto 0);
|
||||||
|
end if;
|
||||||
|
ip(7 downto 2) <= events.Int and im(7 downto 2);
|
||||||
|
end if;
|
||||||
|
end process;
|
||||||
|
|
||||||
|
cop_exc_vector:
|
||||||
|
process(clk)
|
||||||
|
begin
|
||||||
|
if rising_edge(clk) then
|
||||||
|
ctrl_out.exc_vec <= X"80000180";
|
||||||
|
if status(22) = '1' then
|
||||||
|
ctrl_out.exc_vec <= X"BFC00180";
|
||||||
|
end if;
|
||||||
|
end if;
|
||||||
|
end process;
|
||||||
|
|
||||||
|
cop_pipe:
|
||||||
|
process(clk)
|
||||||
|
begin
|
||||||
|
if rising_edge(clk) then
|
||||||
|
if rst = '1' then
|
||||||
|
cop_pipe_EX.cs <= '0';
|
||||||
|
cop_pipe_EX.we <= '0';
|
||||||
|
cop_pipe_EX.re <= '0';
|
||||||
|
else
|
||||||
|
if sdu.EX_stall = '0' then
|
||||||
|
cop_pipe_EX <= cop_pipe_ID;
|
||||||
|
end if;
|
||||||
|
end if;
|
||||||
|
end if;
|
||||||
|
end process;
|
||||||
|
|
||||||
|
cop_register_read:
|
||||||
|
process(clk)
|
||||||
|
variable reg : word_t;
|
||||||
|
begin
|
||||||
|
if rising_edge(clk) and cop_pipe_ID.re = '1' and sdu.ID_stall = '0' then
|
||||||
|
case cop_pipe_ID.rd is
|
||||||
|
when "01000" => -- BadVAddr
|
||||||
|
reg := BadVAddr;
|
||||||
|
|
||||||
|
when "01100" => -- Status
|
||||||
|
reg := status;
|
||||||
|
|
||||||
|
when "01101" => -- Cause
|
||||||
|
reg := cause;
|
||||||
|
|
||||||
|
when "01110" => -- EPC (Exception Program Counter)
|
||||||
|
reg := epc;
|
||||||
|
|
||||||
|
when "01111" => -- PRId (Processor Revision Register)
|
||||||
|
reg := X"000002" & to_unsigned(REVISION ,8);
|
||||||
|
|
||||||
|
when "11111" => -- test_reg
|
||||||
|
reg := test_reg;
|
||||||
|
|
||||||
|
when others =>
|
||||||
|
reg := (others => '-');
|
||||||
|
|
||||||
|
end case;
|
||||||
|
dout <= reg after 1 ns;
|
||||||
|
end if;
|
||||||
|
end process;
|
||||||
|
|
||||||
|
cop_we_gen:
|
||||||
|
process(clk)
|
||||||
|
begin
|
||||||
|
if rising_edge(clk) then
|
||||||
|
if rst = '1' then
|
||||||
|
test_reg_we <= '0';
|
||||||
|
stat_reg_we <= '0';
|
||||||
|
ip_reg_we <= '0';
|
||||||
|
else
|
||||||
|
test_reg_we <= '0';
|
||||||
|
stat_reg_we <= '0';
|
||||||
|
ip_reg_we <= '0';
|
||||||
|
if (cop_EX_en and cop_pipe_EX.we) = '1' then
|
||||||
|
|
||||||
|
case cop_pipe_EX.rd is
|
||||||
|
|
||||||
|
when "01100" =>
|
||||||
|
stat_reg_we <= not status(1) or status(28);
|
||||||
|
when "01101" =>
|
||||||
|
ip_reg_we <= not status(1) or status(28);
|
||||||
|
when "11111" =>
|
||||||
|
test_reg_we <= not status(1) or status(28);
|
||||||
|
when others => null;
|
||||||
|
|
||||||
|
end case;
|
||||||
|
|
||||||
|
end if;
|
||||||
|
end if;
|
||||||
|
end if;
|
||||||
|
end process;
|
||||||
|
|
||||||
|
cop_test_reg_write:
|
||||||
|
process(clk)
|
||||||
|
begin
|
||||||
|
if rising_edge(clk) then
|
||||||
|
if rst = '1' then
|
||||||
|
test_reg <= (others => '0');
|
||||||
|
else --if ce = '1' then
|
||||||
|
if test_reg_we = '1' then
|
||||||
|
test_reg <= cop_pipe_EX.din;
|
||||||
|
end if;
|
||||||
|
end if;
|
||||||
|
end if;
|
||||||
|
end process;
|
||||||
|
|
||||||
|
cop_status_reg_write:
|
||||||
|
process(clk)
|
||||||
|
begin
|
||||||
|
if rising_edge(clk) then
|
||||||
|
if rst = '1' then
|
||||||
|
status <= X"00400000";
|
||||||
|
else
|
||||||
|
if status_save = '1' then
|
||||||
|
status(5 downto 4) <= status(3 downto 2);
|
||||||
|
status(3 downto 2) <= status(1 downto 0);
|
||||||
|
status(1 downto 0) <= "00";
|
||||||
|
elsif status_rest = '1' then
|
||||||
|
status(1 downto 0) <= status(3 downto 2);
|
||||||
|
status(3 downto 2) <= status(5 downto 4);
|
||||||
|
elsif stat_reg_we = '1' then
|
||||||
|
status <= cop_pipe_EX.din;
|
||||||
|
end if;
|
||||||
|
end if;
|
||||||
|
end if;
|
||||||
|
end process;
|
||||||
|
|
||||||
|
--------------------------------------------------------------------------
|
||||||
|
end Behavioral;
|
||||||
@@ -0,0 +1,101 @@
|
|||||||
|
--------------------------------------------------------------------------
|
||||||
|
-- Project: JIPS, a portable 32-bit RISC CPU written in VHDL
|
||||||
|
-- This file: The datapath controller
|
||||||
|
--
|
||||||
|
-- Copyright (C) 2008 J. Ahrensfeld
|
||||||
|
--
|
||||||
|
-- This program is free software: you can redistribute it and/or modify
|
||||||
|
-- it under the terms of the GNU General Public License as published by
|
||||||
|
-- the Free Software Foundation, either version 3 of the License, or
|
||||||
|
-- (at your option) any later version.
|
||||||
|
--
|
||||||
|
-- This program 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 General Public License for more details.
|
||||||
|
--
|
||||||
|
-- You should have received a copy of the GNU General Public License
|
||||||
|
-- along with this program. If not, see <http://www.gnu.org/licenses/>.
|
||||||
|
--
|
||||||
|
-- For questions and ideas, please contact the author at jens@jayfield.org
|
||||||
|
--
|
||||||
|
--------------------------------------------------------------------------
|
||||||
|
|
||||||
|
library IEEE;
|
||||||
|
use IEEE.STD_LOGIC_1164.ALL;
|
||||||
|
use IEEE.numeric_std.ALL;
|
||||||
|
|
||||||
|
library work;
|
||||||
|
use work.mips_types.all;
|
||||||
|
use work.mips_instr.all;
|
||||||
|
|
||||||
|
entity idecode_rom is
|
||||||
|
Port
|
||||||
|
(
|
||||||
|
nop : in std_logic;
|
||||||
|
inst_in : in word_t;
|
||||||
|
ctrl_out : out ctrl_lines_t
|
||||||
|
);
|
||||||
|
end idecode_rom;
|
||||||
|
|
||||||
|
architecture Behavioral of idecode_rom is
|
||||||
|
|
||||||
|
signal ctrl_special : ctrl_lines_t;
|
||||||
|
signal ctrl_regimm : ctrl_lines_t;
|
||||||
|
signal ctrl_opcode : ctrl_lines_t;
|
||||||
|
|
||||||
|
signal rom_special : rom_special_t := gen_rom_special;
|
||||||
|
signal rom_regimm : rom_regimm_t := gen_rom_regimm;
|
||||||
|
signal rom_opcode : rom_opcode_t := gen_rom_opcode;
|
||||||
|
|
||||||
|
attribute rom_style : string;
|
||||||
|
|
||||||
|
attribute rom_style of rom_special: signal is "distributed";
|
||||||
|
attribute rom_style of rom_regimm: signal is "distributed";
|
||||||
|
attribute rom_style of rom_opcode: signal is "distributed";
|
||||||
|
|
||||||
|
begin
|
||||||
|
|
||||||
|
i_dec_special:
|
||||||
|
process(inst_in, rom_special)
|
||||||
|
variable func : func_t;
|
||||||
|
begin
|
||||||
|
func := extract_func(inst_in);
|
||||||
|
ctrl_special <= rom_special(to_integer(func));
|
||||||
|
end process;
|
||||||
|
|
||||||
|
i_dec_regimm:
|
||||||
|
process(inst_in, rom_regimm)
|
||||||
|
variable rt : reg_ptr_t;
|
||||||
|
begin
|
||||||
|
rt := extract_rt(inst_in);
|
||||||
|
ctrl_regimm <= rom_regimm(to_integer(rt));
|
||||||
|
end process;
|
||||||
|
|
||||||
|
i_dec_opcode:
|
||||||
|
process(inst_in, rom_opcode)
|
||||||
|
variable opc : opcode_t;
|
||||||
|
begin
|
||||||
|
opc := extract_opc(inst_in);
|
||||||
|
ctrl_opcode <= rom_opcode(to_integer(opc));
|
||||||
|
end process;
|
||||||
|
|
||||||
|
proc_decode:
|
||||||
|
process(inst_in, ctrl_special, ctrl_regimm, ctrl_opcode, nop)
|
||||||
|
variable opclass : opcode_t;
|
||||||
|
begin
|
||||||
|
opclass := extract_opc(inst_in);
|
||||||
|
ctrl_out <= ctrl_lines_default after 2 ns;
|
||||||
|
if nop = '0' then
|
||||||
|
case opclass is
|
||||||
|
when "000000" =>
|
||||||
|
ctrl_out <= ctrl_special after 2 ns;
|
||||||
|
when "000001" =>
|
||||||
|
ctrl_out <= ctrl_regimm after 2 ns;
|
||||||
|
when others =>
|
||||||
|
ctrl_out <= ctrl_opcode after 2 ns;
|
||||||
|
end case;
|
||||||
|
end if;
|
||||||
|
end process;
|
||||||
|
|
||||||
|
end Behavioral;
|
||||||
@@ -0,0 +1,997 @@
|
|||||||
|
--------------------------------------------------------------------------
|
||||||
|
-- Project: JIPS, a portable 32-bit RISC CPU written in VHDL
|
||||||
|
-- This file: Types, constants and functions for JCPU
|
||||||
|
--
|
||||||
|
-- Copyright (C) 2008 J. Ahrensfeld
|
||||||
|
--
|
||||||
|
-- This program is free software: you can redistribute it and/or modify
|
||||||
|
-- it under the terms of the GNU General Public License as published by
|
||||||
|
-- the Free Software Foundation, either version 3 of the License, or
|
||||||
|
-- (at your option) any later version.
|
||||||
|
--
|
||||||
|
-- This program 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 General Public License for more details.
|
||||||
|
--
|
||||||
|
-- You should have received a copy of the GNU General Public License
|
||||||
|
-- along with this program. If not, see <http://www.gnu.org/licenses/>.
|
||||||
|
--
|
||||||
|
-- For questions and ideas, please contact the author at jens@jayfield.org
|
||||||
|
--
|
||||||
|
--------------------------------------------------------------------------
|
||||||
|
|
||||||
|
library IEEE;
|
||||||
|
use IEEE.STD_LOGIC_1164.ALL;
|
||||||
|
use IEEE.numeric_std.ALL;
|
||||||
|
|
||||||
|
library work;
|
||||||
|
use work.mips_types.all;
|
||||||
|
|
||||||
|
--------------------------------------------------------------------------
|
||||||
|
package mips_instr is
|
||||||
|
|
||||||
|
function extract_opc(instr : word_t) return opcode_t;
|
||||||
|
function extract_rs(instr : word_t) return reg_ptr_t;
|
||||||
|
function extract_rt(instr : word_t) return reg_ptr_t;
|
||||||
|
function extract_rd(instr : word_t) return reg_ptr_t;
|
||||||
|
function extract_shamt(instr : word_t) return shamt_t;
|
||||||
|
function extract_func(instr : word_t) return func_t;
|
||||||
|
function extract_simm32(instr : word_t) return word_t;
|
||||||
|
function extract_uimm16(instr : word_t) return word_t;
|
||||||
|
function extract_jimm32(instr, pc : word_t) return word_t;
|
||||||
|
function extract_bimm18(instr, pc : word_t) return word_t;
|
||||||
|
function decode_op(instr : word_t) return op_t;
|
||||||
|
function ctrl_lines_default return ctrl_lines_t;
|
||||||
|
function special_ctrl_lines(func : func_t) return ctrl_lines_t;
|
||||||
|
function regimm_ctrl_lines(rt : reg_ptr_t) return ctrl_lines_t;
|
||||||
|
function opcode_ctrl_lines(opc : opcode_t) return ctrl_lines_t;
|
||||||
|
function gen_rom_opcode return rom_opcode_t;
|
||||||
|
function gen_rom_regimm return rom_regimm_t;
|
||||||
|
function gen_rom_special return rom_special_t;
|
||||||
|
|
||||||
|
end mips_instr;
|
||||||
|
|
||||||
|
--------------------------------------------------------------------------
|
||||||
|
library work;
|
||||||
|
use work.mips_types.all;
|
||||||
|
|
||||||
|
package body mips_instr is
|
||||||
|
|
||||||
|
function extract_opc(instr : word_t) return opcode_t is
|
||||||
|
variable result : opcode_t;
|
||||||
|
begin
|
||||||
|
result := instr(31 downto 26);
|
||||||
|
|
||||||
|
return result;
|
||||||
|
|
||||||
|
end extract_opc;
|
||||||
|
|
||||||
|
function extract_rs(instr : word_t) return reg_ptr_t is
|
||||||
|
variable result : reg_ptr_t;
|
||||||
|
begin
|
||||||
|
result := instr(25 downto 21);
|
||||||
|
|
||||||
|
return result;
|
||||||
|
|
||||||
|
end extract_rs;
|
||||||
|
|
||||||
|
function extract_rt(instr : word_t) return reg_ptr_t is
|
||||||
|
variable result : reg_ptr_t;
|
||||||
|
begin
|
||||||
|
result := instr(20 downto 16);
|
||||||
|
|
||||||
|
return result;
|
||||||
|
|
||||||
|
end extract_rt;
|
||||||
|
|
||||||
|
function extract_rd(instr : word_t) return reg_ptr_t is
|
||||||
|
variable result : reg_ptr_t;
|
||||||
|
begin
|
||||||
|
result := instr(15 downto 11);
|
||||||
|
|
||||||
|
return result;
|
||||||
|
|
||||||
|
end extract_rd;
|
||||||
|
|
||||||
|
function extract_shamt(instr : word_t) return shamt_t is
|
||||||
|
variable result : shamt_t;
|
||||||
|
begin
|
||||||
|
result := instr(10 downto 6);
|
||||||
|
|
||||||
|
return result;
|
||||||
|
|
||||||
|
end extract_shamt;
|
||||||
|
|
||||||
|
function extract_func(instr : word_t) return func_t is
|
||||||
|
variable result : func_t;
|
||||||
|
begin
|
||||||
|
result := instr(5 downto 0);
|
||||||
|
|
||||||
|
return result;
|
||||||
|
|
||||||
|
end extract_func;
|
||||||
|
|
||||||
|
function extract_simm32(instr : word_t) return word_t is
|
||||||
|
variable result : word_t;
|
||||||
|
begin
|
||||||
|
result := (31 downto 16 => instr(15)) & instr(15 downto 0);
|
||||||
|
|
||||||
|
return result;
|
||||||
|
|
||||||
|
end extract_simm32;
|
||||||
|
|
||||||
|
function extract_uimm16(instr : word_t) return word_t is
|
||||||
|
variable result : word_t;
|
||||||
|
begin
|
||||||
|
result := (31 downto 16 => '0') & instr(15 downto 0);
|
||||||
|
|
||||||
|
return result;
|
||||||
|
|
||||||
|
end extract_uimm16;
|
||||||
|
|
||||||
|
function extract_jimm32(instr, pc : word_t) return word_t is
|
||||||
|
variable result : word_t;
|
||||||
|
begin
|
||||||
|
result := pc(31 downto 28) & instr(25 downto 0) & "00";
|
||||||
|
|
||||||
|
return result;
|
||||||
|
|
||||||
|
end extract_jimm32;
|
||||||
|
|
||||||
|
function extract_bimm18(instr, pc : word_t) return word_t is
|
||||||
|
variable result : word_t;
|
||||||
|
begin
|
||||||
|
result := (31 downto 18 => instr(15)) & instr(15 downto 0) & "00";
|
||||||
|
|
||||||
|
return result;
|
||||||
|
|
||||||
|
end extract_bimm18;
|
||||||
|
|
||||||
|
function decode_op(instr : word_t) return op_t is
|
||||||
|
variable result : op_t;
|
||||||
|
variable opc : natural range 0 to 63;
|
||||||
|
variable func : natural range 0 to 63;
|
||||||
|
variable rt : natural range 0 to 31;
|
||||||
|
|
||||||
|
begin
|
||||||
|
|
||||||
|
opc := to_integer(extract_opc(instr));
|
||||||
|
func := to_integer(extract_func(instr));
|
||||||
|
rt := to_integer(extract_rt(instr));
|
||||||
|
|
||||||
|
result := op_sll;
|
||||||
|
|
||||||
|
case opc is
|
||||||
|
|
||||||
|
when 0 =>
|
||||||
|
case func is
|
||||||
|
|
||||||
|
when 0 =>
|
||||||
|
result := op_sll;
|
||||||
|
|
||||||
|
when 2 =>
|
||||||
|
result := op_srl;
|
||||||
|
|
||||||
|
when 3 =>
|
||||||
|
result := op_sra;
|
||||||
|
|
||||||
|
when 4 =>
|
||||||
|
result := op_sllv;
|
||||||
|
|
||||||
|
when 6 =>
|
||||||
|
result := op_srlv;
|
||||||
|
|
||||||
|
when 7 =>
|
||||||
|
result := op_srav;
|
||||||
|
|
||||||
|
when 8 =>
|
||||||
|
result := op_jr;
|
||||||
|
|
||||||
|
when 9 =>
|
||||||
|
result := op_jalr;
|
||||||
|
|
||||||
|
when 12 =>
|
||||||
|
result := op_syscall;
|
||||||
|
|
||||||
|
when 13 =>
|
||||||
|
result := op_break;
|
||||||
|
|
||||||
|
when 16 =>
|
||||||
|
result := op_mfhi;
|
||||||
|
|
||||||
|
when 17 =>
|
||||||
|
result := op_mthi;
|
||||||
|
|
||||||
|
when 18 =>
|
||||||
|
result := op_mflo;
|
||||||
|
|
||||||
|
when 19 =>
|
||||||
|
result := op_mtlo;
|
||||||
|
|
||||||
|
when 24 =>
|
||||||
|
result := op_mult;
|
||||||
|
|
||||||
|
when 25 =>
|
||||||
|
result := op_multu;
|
||||||
|
|
||||||
|
when 26 =>
|
||||||
|
result := op_div;
|
||||||
|
|
||||||
|
when 27 =>
|
||||||
|
result := op_divu;
|
||||||
|
|
||||||
|
when 32 =>
|
||||||
|
result := op_add;
|
||||||
|
|
||||||
|
when 33 =>
|
||||||
|
result := op_addu;
|
||||||
|
|
||||||
|
when 34 =>
|
||||||
|
result := op_sub;
|
||||||
|
|
||||||
|
when 35 =>
|
||||||
|
result := op_subu;
|
||||||
|
|
||||||
|
when 36 =>
|
||||||
|
result := op_and;
|
||||||
|
|
||||||
|
when 37 =>
|
||||||
|
result := op_or;
|
||||||
|
|
||||||
|
when 38 =>
|
||||||
|
result := op_xor;
|
||||||
|
|
||||||
|
when 39 =>
|
||||||
|
result := op_nor;
|
||||||
|
|
||||||
|
when 42 =>
|
||||||
|
result := op_slt;
|
||||||
|
|
||||||
|
when 43 =>
|
||||||
|
result := op_sltu;
|
||||||
|
|
||||||
|
when others => null; -- undef
|
||||||
|
|
||||||
|
end case;
|
||||||
|
|
||||||
|
when 1 =>
|
||||||
|
case rt is
|
||||||
|
|
||||||
|
when 0 =>
|
||||||
|
result := op_bltz;
|
||||||
|
|
||||||
|
when 1 =>
|
||||||
|
result := op_bgez;
|
||||||
|
|
||||||
|
when 16 =>
|
||||||
|
result := op_bltzal;
|
||||||
|
|
||||||
|
when 17 =>
|
||||||
|
result := op_bgezal;
|
||||||
|
|
||||||
|
when others => null; -- undef
|
||||||
|
|
||||||
|
end case;
|
||||||
|
|
||||||
|
when 2 =>
|
||||||
|
result := op_j;
|
||||||
|
|
||||||
|
when 3 =>
|
||||||
|
result := op_jal;
|
||||||
|
|
||||||
|
when 4 =>
|
||||||
|
result := op_beq;
|
||||||
|
|
||||||
|
when 5 =>
|
||||||
|
result := op_bne;
|
||||||
|
|
||||||
|
when 6 =>
|
||||||
|
result := op_blez;
|
||||||
|
|
||||||
|
when 7 =>
|
||||||
|
result := op_bgtz;
|
||||||
|
|
||||||
|
when 8 =>
|
||||||
|
result := op_addi;
|
||||||
|
|
||||||
|
when 9 =>
|
||||||
|
result := op_addiu;
|
||||||
|
|
||||||
|
when 10 =>
|
||||||
|
result := op_slti;
|
||||||
|
|
||||||
|
when 11 =>
|
||||||
|
result := op_sltiu;
|
||||||
|
|
||||||
|
when 12 =>
|
||||||
|
result := op_andi;
|
||||||
|
|
||||||
|
when 13 =>
|
||||||
|
result := op_ori;
|
||||||
|
|
||||||
|
when 14 =>
|
||||||
|
result := op_xori;
|
||||||
|
|
||||||
|
when 15 =>
|
||||||
|
result := op_lui;
|
||||||
|
|
||||||
|
when 16 =>
|
||||||
|
result := op_cop0;
|
||||||
|
|
||||||
|
when 17 =>
|
||||||
|
result := op_cop1;
|
||||||
|
|
||||||
|
when 18 =>
|
||||||
|
result := op_cop2;
|
||||||
|
|
||||||
|
when 19 =>
|
||||||
|
result := op_cop3;
|
||||||
|
|
||||||
|
when 32 =>
|
||||||
|
result := op_lb;
|
||||||
|
|
||||||
|
when 33 =>
|
||||||
|
result := op_lh;
|
||||||
|
|
||||||
|
when 34 =>
|
||||||
|
result := op_lwl;
|
||||||
|
|
||||||
|
when 35 =>
|
||||||
|
result := op_lw;
|
||||||
|
|
||||||
|
when 36 =>
|
||||||
|
result := op_lbu;
|
||||||
|
|
||||||
|
when 37 =>
|
||||||
|
result := op_lhu;
|
||||||
|
|
||||||
|
when 38 =>
|
||||||
|
result := op_lwr;
|
||||||
|
|
||||||
|
when 40 =>
|
||||||
|
result := op_sb;
|
||||||
|
|
||||||
|
when 41 =>
|
||||||
|
result := op_sh;
|
||||||
|
|
||||||
|
when 42 =>
|
||||||
|
result := op_swl;
|
||||||
|
|
||||||
|
when 43 =>
|
||||||
|
result := op_sw;
|
||||||
|
|
||||||
|
when 46 =>
|
||||||
|
result := op_swr;
|
||||||
|
|
||||||
|
when 49 =>
|
||||||
|
result := op_lwc1;
|
||||||
|
|
||||||
|
when 50 =>
|
||||||
|
result := op_lwc2;
|
||||||
|
|
||||||
|
when 51 =>
|
||||||
|
result := op_lwc3;
|
||||||
|
|
||||||
|
when 57 =>
|
||||||
|
result := op_swc1;
|
||||||
|
|
||||||
|
when 58 =>
|
||||||
|
result := op_swc2;
|
||||||
|
|
||||||
|
when 59 =>
|
||||||
|
result := op_swc3;
|
||||||
|
|
||||||
|
when others => null; -- undef
|
||||||
|
|
||||||
|
end case;
|
||||||
|
|
||||||
|
return result;
|
||||||
|
|
||||||
|
end decode_op;
|
||||||
|
|
||||||
|
function ctrl_lines_default return ctrl_lines_t is
|
||||||
|
variable result : ctrl_lines_t;
|
||||||
|
begin
|
||||||
|
result.cop_instr_en := '0';
|
||||||
|
result.jump := '0';
|
||||||
|
result.jump_long := '0';
|
||||||
|
result.branch := '0';
|
||||||
|
result.bc_src := bc_eq_ne;
|
||||||
|
result.bc_not := '0';
|
||||||
|
result.alu.outsel := alu_adder;
|
||||||
|
result.alu.add := '1';
|
||||||
|
result.alu.shift_right := '0';
|
||||||
|
result.alu.shift_arith := '0';
|
||||||
|
result.shamt2_srcsel := sa_src_imm;
|
||||||
|
result.alu.op1_src := alu_src_reg;
|
||||||
|
result.alu.op2_src := alu_src_reg;
|
||||||
|
result.imm_src := src_imm16;
|
||||||
|
result.reg_write := '0';
|
||||||
|
result.dmem_we := '0';
|
||||||
|
result.dmem_en := '0';
|
||||||
|
result.wptr_srcsel := wptr_src_imm;
|
||||||
|
result.reg_link := '0';
|
||||||
|
result.shift_offset := "00";
|
||||||
|
result.shift_byp := '1';
|
||||||
|
result.byte_en_byp := '1';
|
||||||
|
result.sign_ext_byp := '1';
|
||||||
|
result.word4_en := '0';
|
||||||
|
result.word2_en := '0';
|
||||||
|
result.align_left := '0';
|
||||||
|
result.load_signed := '0';
|
||||||
|
result.mul_access := '0';
|
||||||
|
result.mul_hilo_we := '0';
|
||||||
|
result.mul_start := '0';
|
||||||
|
result.mul_s_un := '0';
|
||||||
|
result.mul_mul_divn := '0';
|
||||||
|
result.mul_hilo_sel := '1';
|
||||||
|
result.exc_break := '0';
|
||||||
|
result.exc_syscall := '0';
|
||||||
|
result.exc_illegal := '0';
|
||||||
|
result.except_en := '0';
|
||||||
|
result.alu_exc_en := '0';
|
||||||
|
|
||||||
|
return result;
|
||||||
|
|
||||||
|
end ctrl_lines_default;
|
||||||
|
|
||||||
|
|
||||||
|
function special_ctrl_lines(func : func_t) return ctrl_lines_t is
|
||||||
|
variable result : ctrl_lines_t;
|
||||||
|
variable op : integer range 0 to 2**func_t'length-1;
|
||||||
|
begin
|
||||||
|
|
||||||
|
result := ctrl_lines_default;
|
||||||
|
|
||||||
|
op := to_integer(func);
|
||||||
|
case op is
|
||||||
|
|
||||||
|
-- when op_add =>
|
||||||
|
when 32 =>
|
||||||
|
result.alu.outsel := alu_adder;
|
||||||
|
result.alu.add := '1';
|
||||||
|
result.alu.op1_src := alu_src_reg;
|
||||||
|
result.alu.op2_src := alu_src_reg;
|
||||||
|
result.reg_write := '1';
|
||||||
|
result.alu_exc_en := '1';
|
||||||
|
|
||||||
|
-- when op_addu =>
|
||||||
|
when 33 =>
|
||||||
|
result.alu.outsel := alu_adder;
|
||||||
|
result.alu.add := '1';
|
||||||
|
result.alu.op1_src := alu_src_reg;
|
||||||
|
result.alu.op2_src := alu_src_reg;
|
||||||
|
result.reg_write := '1';
|
||||||
|
|
||||||
|
-- when op_and =>
|
||||||
|
when 36 =>
|
||||||
|
result.alu.outsel := alu_and;
|
||||||
|
result.alu.op1_src := alu_src_reg;
|
||||||
|
result.alu.op2_src := alu_src_reg;
|
||||||
|
result.reg_write := '1';
|
||||||
|
|
||||||
|
-- when op_break =>
|
||||||
|
when 13 =>
|
||||||
|
result.exc_break := '1';
|
||||||
|
result.except_en := '1';
|
||||||
|
|
||||||
|
-- when op_div =>
|
||||||
|
when 26 =>
|
||||||
|
result.mul_access := '1';
|
||||||
|
result.mul_start := '1';
|
||||||
|
result.mul_s_un := '1';
|
||||||
|
result.mul_mul_divn := '0';
|
||||||
|
|
||||||
|
-- when op_divu =>
|
||||||
|
when 27 =>
|
||||||
|
result.mul_access := '1';
|
||||||
|
result.mul_start := '1';
|
||||||
|
result.mul_s_un := '0';
|
||||||
|
result.mul_mul_divn := '0';
|
||||||
|
|
||||||
|
-- when op_jalr =>
|
||||||
|
when 9 =>
|
||||||
|
result.jump_long := '1';
|
||||||
|
result.wptr_srcsel := wptr_src_imm;
|
||||||
|
result.reg_write := '1';
|
||||||
|
result.reg_link := '1';
|
||||||
|
|
||||||
|
-- when op_jr =>
|
||||||
|
when 8 =>
|
||||||
|
result.jump_long := '1';
|
||||||
|
|
||||||
|
-- when op_mfhi =>
|
||||||
|
when 16 =>
|
||||||
|
result.reg_write := '1';
|
||||||
|
result.mul_access := '1';
|
||||||
|
result.mul_hilo_sel := '1';
|
||||||
|
|
||||||
|
-- when op_mflo =>
|
||||||
|
when 18 =>
|
||||||
|
result.reg_write := '1';
|
||||||
|
result.mul_access := '1';
|
||||||
|
result.mul_hilo_sel := '0';
|
||||||
|
|
||||||
|
-- when op_mthi =>
|
||||||
|
when 17 =>
|
||||||
|
result.mul_hilo_we := '1';
|
||||||
|
result.mul_hilo_sel := '1';
|
||||||
|
|
||||||
|
-- when op_mtlo =>
|
||||||
|
when 19 =>
|
||||||
|
result.mul_hilo_we := '1';
|
||||||
|
result.mul_hilo_sel := '0';
|
||||||
|
|
||||||
|
-- when op_mult =>
|
||||||
|
when 24 =>
|
||||||
|
result.mul_access := '1';
|
||||||
|
result.mul_start := '1';
|
||||||
|
result.mul_s_un := '1';
|
||||||
|
result.mul_mul_divn := '1';
|
||||||
|
|
||||||
|
-- when op_multu =>
|
||||||
|
when 25 =>
|
||||||
|
result.mul_access := '1';
|
||||||
|
result.mul_start := '1';
|
||||||
|
result.mul_s_un := '0';
|
||||||
|
result.mul_mul_divn := '1';
|
||||||
|
|
||||||
|
-- when op_or =>
|
||||||
|
when 37 =>
|
||||||
|
result.alu.outsel := alu_or;
|
||||||
|
result.alu.op1_src := alu_src_reg;
|
||||||
|
result.alu.op2_src := alu_src_reg;
|
||||||
|
result.reg_write := '1';
|
||||||
|
|
||||||
|
-- when op_nor =>
|
||||||
|
when 39 =>
|
||||||
|
result.alu.outsel := alu_nor;
|
||||||
|
result.alu.op1_src := alu_src_reg;
|
||||||
|
result.alu.op2_src := alu_src_reg;
|
||||||
|
result.reg_write := '1';
|
||||||
|
|
||||||
|
-- when op_sll =>
|
||||||
|
when 0 =>
|
||||||
|
result.alu.op2_src := alu_src_reg;
|
||||||
|
result.alu.outsel := alu_shift2;
|
||||||
|
result.alu.shift_right := '0';
|
||||||
|
result.shamt2_srcsel := sa_src_imm;
|
||||||
|
result.reg_write := '1';
|
||||||
|
|
||||||
|
-- when op_sllv =>
|
||||||
|
when 4 =>
|
||||||
|
result.alu.op2_src := alu_src_reg;
|
||||||
|
result.alu.outsel := alu_shift2;
|
||||||
|
result.alu.shift_right := '0';
|
||||||
|
result.shamt2_srcsel := sa_src_reg;
|
||||||
|
result.reg_write := '1';
|
||||||
|
|
||||||
|
-- when op_slt =>
|
||||||
|
when 42 =>
|
||||||
|
result.alu.outsel := alu_lts;
|
||||||
|
result.alu.add := '0';
|
||||||
|
result.alu.op1_src := alu_src_reg;
|
||||||
|
result.alu.op2_src := alu_src_reg;
|
||||||
|
result.reg_write := '1';
|
||||||
|
|
||||||
|
-- when op_sltu =>
|
||||||
|
when 43 =>
|
||||||
|
result.alu.outsel := alu_ltu;
|
||||||
|
result.alu.add := '0';
|
||||||
|
result.alu.op1_src := alu_src_reg;
|
||||||
|
result.alu.op2_src := alu_src_reg;
|
||||||
|
result.reg_write := '1';
|
||||||
|
|
||||||
|
-- when op_sra =>
|
||||||
|
when 3 =>
|
||||||
|
result.alu.op2_src := alu_src_reg;
|
||||||
|
result.alu.outsel := alu_shift2;
|
||||||
|
result.alu.shift_right := '1';
|
||||||
|
result.alu.shift_arith := '1';
|
||||||
|
result.shamt2_srcsel := sa_src_imm;
|
||||||
|
result.reg_write := '1';
|
||||||
|
|
||||||
|
-- when op_srav =>
|
||||||
|
when 7 =>
|
||||||
|
result.alu.op2_src := alu_src_reg;
|
||||||
|
result.alu.outsel := alu_shift2;
|
||||||
|
result.alu.shift_right := '1';
|
||||||
|
result.alu.shift_arith := '1';
|
||||||
|
result.shamt2_srcsel := sa_src_reg;
|
||||||
|
result.reg_write := '1';
|
||||||
|
|
||||||
|
-- when op_srl =>
|
||||||
|
when 2 =>
|
||||||
|
result.alu.op2_src := alu_src_reg;
|
||||||
|
result.alu.outsel := alu_shift2;
|
||||||
|
result.alu.shift_right := '1';
|
||||||
|
result.alu.shift_arith := '0';
|
||||||
|
result.shamt2_srcsel := sa_src_imm;
|
||||||
|
result.reg_write := '1';
|
||||||
|
|
||||||
|
-- when op_srlv =>
|
||||||
|
when 6 =>
|
||||||
|
result.alu.op2_src := alu_src_reg;
|
||||||
|
result.alu.outsel := alu_shift2;
|
||||||
|
result.alu.shift_right := '1';
|
||||||
|
result.alu.shift_arith := '0';
|
||||||
|
result.shamt2_srcsel := sa_src_reg;
|
||||||
|
result.reg_write := '1';
|
||||||
|
|
||||||
|
-- when op_sub =>
|
||||||
|
when 34 =>
|
||||||
|
result.alu.outsel := alu_adder;
|
||||||
|
result.alu.add := '0';
|
||||||
|
result.alu.op1_src := alu_src_reg;
|
||||||
|
result.alu.op2_src := alu_src_reg;
|
||||||
|
result.reg_write := '1';
|
||||||
|
result.alu_exc_en := '1';
|
||||||
|
|
||||||
|
-- when op_subu =>
|
||||||
|
when 35 =>
|
||||||
|
result.alu.outsel := alu_adder;
|
||||||
|
result.alu.add := '0';
|
||||||
|
result.alu.op1_src := alu_src_reg;
|
||||||
|
result.alu.op2_src := alu_src_reg;
|
||||||
|
result.reg_write := '1';
|
||||||
|
|
||||||
|
-- when op_syscall =>
|
||||||
|
when 12 =>
|
||||||
|
result.exc_syscall := '1';
|
||||||
|
result.except_en := '1';
|
||||||
|
|
||||||
|
-- when op_xor =>
|
||||||
|
when 38 =>
|
||||||
|
result.alu.outsel := alu_xor;
|
||||||
|
result.alu.op1_src := alu_src_reg;
|
||||||
|
result.alu.op2_src := alu_src_reg;
|
||||||
|
result.reg_write := '1';
|
||||||
|
|
||||||
|
when others =>
|
||||||
|
result.exc_illegal := '1';
|
||||||
|
|
||||||
|
end case;
|
||||||
|
|
||||||
|
return result;
|
||||||
|
|
||||||
|
end special_ctrl_lines;
|
||||||
|
|
||||||
|
function gen_rom_special return rom_special_t is
|
||||||
|
variable result : rom_special_t;
|
||||||
|
variable func : func_t;
|
||||||
|
begin
|
||||||
|
|
||||||
|
for i in 0 to 2**func_t'length-1 loop
|
||||||
|
func := to_unsigned(i, func_t'length);
|
||||||
|
result(i) := special_ctrl_lines(func);
|
||||||
|
end loop;
|
||||||
|
|
||||||
|
return result;
|
||||||
|
end gen_rom_special;
|
||||||
|
|
||||||
|
function regimm_ctrl_lines(rt : reg_ptr_t) return ctrl_lines_t is
|
||||||
|
variable result : ctrl_lines_t;
|
||||||
|
variable op : integer range 0 to 2**reg_ptr_t'length-1;
|
||||||
|
begin
|
||||||
|
|
||||||
|
result := ctrl_lines_default;
|
||||||
|
|
||||||
|
op := to_integer(rt);
|
||||||
|
case op is
|
||||||
|
|
||||||
|
-- when op_bgez =>
|
||||||
|
when 1 =>
|
||||||
|
result.branch := '1';
|
||||||
|
result.bc_src := bc_ltz_gez;
|
||||||
|
result.bc_not := '1';
|
||||||
|
|
||||||
|
-- when op_bgezal =>
|
||||||
|
when 17 =>
|
||||||
|
result.branch := '1';
|
||||||
|
result.bc_src := bc_ltz_gez;
|
||||||
|
result.bc_not := '1';
|
||||||
|
result.wptr_srcsel := wptr_src_const;
|
||||||
|
result.reg_write := '1';
|
||||||
|
result.reg_link := '1';
|
||||||
|
|
||||||
|
-- when op_bltz =>
|
||||||
|
when 0 =>
|
||||||
|
result.branch := '1';
|
||||||
|
result.bc_src := bc_ltz_gez;
|
||||||
|
result.bc_not := '0';
|
||||||
|
|
||||||
|
-- when op_bltzal =>
|
||||||
|
when 16 =>
|
||||||
|
result.branch := '1';
|
||||||
|
result.bc_src := bc_ltz_gez;
|
||||||
|
result.bc_not := '0';
|
||||||
|
result.wptr_srcsel := wptr_src_const;
|
||||||
|
result.reg_write := '1';
|
||||||
|
result.reg_link := '1';
|
||||||
|
|
||||||
|
when others =>
|
||||||
|
result.exc_illegal := '1';
|
||||||
|
|
||||||
|
end case;
|
||||||
|
|
||||||
|
return result;
|
||||||
|
|
||||||
|
end regimm_ctrl_lines;
|
||||||
|
|
||||||
|
function gen_rom_regimm return rom_regimm_t is
|
||||||
|
variable result : rom_regimm_t;
|
||||||
|
variable rt : reg_ptr_t;
|
||||||
|
begin
|
||||||
|
|
||||||
|
for i in 0 to 2**reg_ptr_t'length-1 loop
|
||||||
|
rt := to_unsigned(i, reg_ptr_t'length);
|
||||||
|
result(i) := regimm_ctrl_lines(rt);
|
||||||
|
end loop;
|
||||||
|
|
||||||
|
return result;
|
||||||
|
end gen_rom_regimm;
|
||||||
|
|
||||||
|
function opcode_ctrl_lines(opc : opcode_t) return ctrl_lines_t is
|
||||||
|
variable result : ctrl_lines_t;
|
||||||
|
variable op : integer range 0 to 2**opcode_t'length-1;
|
||||||
|
begin
|
||||||
|
|
||||||
|
result := ctrl_lines_default;
|
||||||
|
|
||||||
|
op := to_integer(opc);
|
||||||
|
case op is
|
||||||
|
|
||||||
|
-- when op_addi =>
|
||||||
|
when 8 =>
|
||||||
|
result.imm_src := src_imm32;
|
||||||
|
result.alu.outsel := alu_adder;
|
||||||
|
result.alu.add := '1';
|
||||||
|
result.alu.op1_src := alu_src_reg;
|
||||||
|
result.alu.op2_src := alu_src_imm;
|
||||||
|
result.reg_write := '1';
|
||||||
|
result.alu_exc_en := '1';
|
||||||
|
|
||||||
|
-- when op_addiu =>
|
||||||
|
when 9 =>
|
||||||
|
result.imm_src := src_imm32;
|
||||||
|
result.alu.outsel := alu_adder;
|
||||||
|
result.alu.add := '1';
|
||||||
|
result.alu.op1_src := alu_src_reg;
|
||||||
|
result.alu.op2_src := alu_src_imm;
|
||||||
|
result.reg_write := '1';
|
||||||
|
|
||||||
|
-- when op_andi =>
|
||||||
|
when 12 =>
|
||||||
|
result.imm_src := src_imm16;
|
||||||
|
result.alu.outsel := alu_and;
|
||||||
|
result.alu.op1_src := alu_src_reg;
|
||||||
|
result.alu.op2_src := alu_src_imm;
|
||||||
|
result.reg_write := '1';
|
||||||
|
|
||||||
|
-- when op_beq =>
|
||||||
|
when 4 =>
|
||||||
|
result.branch := '1';
|
||||||
|
result.bc_src := bc_eq_ne;
|
||||||
|
result.bc_not := '0';
|
||||||
|
|
||||||
|
-- when op_bgtz =>
|
||||||
|
when 7 =>
|
||||||
|
result.branch := '1';
|
||||||
|
result.bc_src := bc_lez_gtz;
|
||||||
|
result.bc_not := '1';
|
||||||
|
|
||||||
|
-- when op_blez =>
|
||||||
|
when 6 =>
|
||||||
|
result.branch := '1';
|
||||||
|
result.bc_src := bc_lez_gtz;
|
||||||
|
result.bc_not := '0';
|
||||||
|
|
||||||
|
-- when op_bne =>
|
||||||
|
when 5 =>
|
||||||
|
result.branch := '1';
|
||||||
|
result.bc_src := bc_eq_ne;
|
||||||
|
result.bc_not := '1';
|
||||||
|
|
||||||
|
-- when op_cop =>
|
||||||
|
when 16 | 17 | 18 | 19 =>
|
||||||
|
result.cop_instr_en := '1';
|
||||||
|
|
||||||
|
-- when op_j =>
|
||||||
|
when 2 =>
|
||||||
|
result.jump := '1';
|
||||||
|
|
||||||
|
-- when op_jal =>
|
||||||
|
when 3 =>
|
||||||
|
result.jump := '1';
|
||||||
|
result.wptr_srcsel := wptr_src_const;
|
||||||
|
result.reg_write := '1';
|
||||||
|
result.reg_link := '1';
|
||||||
|
|
||||||
|
-- when op_lb =>
|
||||||
|
when 32 =>
|
||||||
|
result.imm_src := src_imm32;
|
||||||
|
result.dmem_en := '1';
|
||||||
|
result.reg_write := '1';
|
||||||
|
result.shift_byp := '0';
|
||||||
|
result.byte_en_byp := '1';
|
||||||
|
result.sign_ext_byp := '0';
|
||||||
|
result.load_signed := '1';
|
||||||
|
result.word4_en := '1';
|
||||||
|
|
||||||
|
-- when op_lbu =>
|
||||||
|
when 36 =>
|
||||||
|
result.imm_src := src_imm32;
|
||||||
|
result.dmem_en := '1';
|
||||||
|
result.reg_write := '1';
|
||||||
|
result.shift_byp := '0';
|
||||||
|
result.byte_en_byp := '1';
|
||||||
|
result.sign_ext_byp := '0';
|
||||||
|
result.load_signed := '0';
|
||||||
|
result.word4_en := '1';
|
||||||
|
|
||||||
|
-- when op_lh =>
|
||||||
|
when 33 =>
|
||||||
|
result.imm_src := src_imm32;
|
||||||
|
result.dmem_en := '1';
|
||||||
|
result.reg_write := '1';
|
||||||
|
result.shift_byp := '0';
|
||||||
|
result.sign_ext_byp := '0';
|
||||||
|
result.byte_en_byp := '1';
|
||||||
|
result.load_signed := '1';
|
||||||
|
result.word2_en := '1';
|
||||||
|
result.except_en := '1';
|
||||||
|
|
||||||
|
-- when op_lhu =>
|
||||||
|
when 37 =>
|
||||||
|
result.imm_src := src_imm32;
|
||||||
|
result.dmem_en := '1';
|
||||||
|
result.reg_write := '1';
|
||||||
|
result.shift_byp := '0';
|
||||||
|
result.sign_ext_byp := '0';
|
||||||
|
result.byte_en_byp := '1';
|
||||||
|
result.load_signed := '0';
|
||||||
|
result.word2_en := '1';
|
||||||
|
result.except_en := '1';
|
||||||
|
|
||||||
|
-- when op_lui =>
|
||||||
|
when 15 =>
|
||||||
|
result.imm_src := src_imm16_high;
|
||||||
|
result.alu.op1_src := alu_src_reg;
|
||||||
|
result.alu.op2_src := alu_src_imm;
|
||||||
|
result.alu.outsel := alu_adder;
|
||||||
|
result.reg_write := '1';
|
||||||
|
result.alu.add := '1';
|
||||||
|
|
||||||
|
-- when op_lw =>
|
||||||
|
when 35 =>
|
||||||
|
-- result.imm_src := src_imm32;
|
||||||
|
result.dmem_en := '1';
|
||||||
|
result.reg_write := '1';
|
||||||
|
result.except_en := '1';
|
||||||
|
|
||||||
|
-- when op_lwl =>
|
||||||
|
when 34 =>
|
||||||
|
-- result.imm_src := src_imm32;
|
||||||
|
result.dmem_en := '1';
|
||||||
|
result.reg_write := '1';
|
||||||
|
result.shift_byp := '0';
|
||||||
|
result.byte_en_byp := '0';
|
||||||
|
result.shift_offset := "01";
|
||||||
|
result.align_left := '1';
|
||||||
|
|
||||||
|
-- when op_lwr =>
|
||||||
|
when 38 =>
|
||||||
|
-- result.imm_src := src_imm32;
|
||||||
|
result.dmem_en := '1';
|
||||||
|
result.reg_write := '1';
|
||||||
|
result.shift_byp := '0';
|
||||||
|
result.byte_en_byp := '0';
|
||||||
|
result.shift_offset := "00";
|
||||||
|
result.align_left := '0';
|
||||||
|
|
||||||
|
-- when op_ori =>
|
||||||
|
when 13 =>
|
||||||
|
result.imm_src := src_imm16;
|
||||||
|
result.alu.outsel := alu_or;
|
||||||
|
result.alu.op1_src := alu_src_reg;
|
||||||
|
result.alu.op2_src := alu_src_imm;
|
||||||
|
result.reg_write := '1';
|
||||||
|
|
||||||
|
-- when op_sb =>
|
||||||
|
when 40 =>
|
||||||
|
result.dmem_en := '1';
|
||||||
|
result.dmem_we := '1';
|
||||||
|
-- result.imm_src := src_imm32;
|
||||||
|
result.shift_byp := '0';
|
||||||
|
result.byte_en_byp := '0';
|
||||||
|
result.word4_en := '1';
|
||||||
|
|
||||||
|
-- when op_sh =>
|
||||||
|
when 41 =>
|
||||||
|
result.dmem_en := '1';
|
||||||
|
result.dmem_we := '1';
|
||||||
|
-- result.imm_src := src_imm32;
|
||||||
|
result.shift_byp := '0';
|
||||||
|
result.byte_en_byp := '0';
|
||||||
|
result.word2_en := '1';
|
||||||
|
result.except_en := '1';
|
||||||
|
|
||||||
|
-- when op_slti =>
|
||||||
|
when 10 =>
|
||||||
|
result.alu.outsel := alu_lts;
|
||||||
|
result.alu.add := '0';
|
||||||
|
result.alu.op1_src := alu_src_reg;
|
||||||
|
result.alu.op2_src := alu_src_imm;
|
||||||
|
result.imm_src := src_imm32;
|
||||||
|
result.reg_write := '1';
|
||||||
|
|
||||||
|
-- when op_sltiu =>
|
||||||
|
when 11 =>
|
||||||
|
result.alu.outsel := alu_ltu;
|
||||||
|
result.alu.add := '0';
|
||||||
|
result.alu.op1_src := alu_src_reg;
|
||||||
|
result.alu.op2_src := alu_src_imm;
|
||||||
|
result.imm_src := src_imm32;
|
||||||
|
result.reg_write := '1';
|
||||||
|
|
||||||
|
-- when op_sw =>
|
||||||
|
when 43 =>
|
||||||
|
result.dmem_en := '1';
|
||||||
|
result.dmem_we := '1';
|
||||||
|
-- result.imm_src := src_imm32;
|
||||||
|
result.except_en := '1';
|
||||||
|
|
||||||
|
-- when op_swl =>
|
||||||
|
when 42 =>
|
||||||
|
result.dmem_en := '1';
|
||||||
|
result.dmem_we := '1';
|
||||||
|
-- result.imm_src := src_imm32;
|
||||||
|
result.shift_byp := '0';
|
||||||
|
result.byte_en_byp := '0';
|
||||||
|
result.shift_offset := "01";
|
||||||
|
|
||||||
|
-- when op_swr =>
|
||||||
|
when 46 =>
|
||||||
|
result.dmem_en := '1';
|
||||||
|
result.dmem_we := '1';
|
||||||
|
-- result.imm_src := src_imm32;
|
||||||
|
result.shift_byp := '0';
|
||||||
|
result.byte_en_byp := '0';
|
||||||
|
result.align_left := '1';
|
||||||
|
|
||||||
|
-- when op_xori =>
|
||||||
|
when 14 =>
|
||||||
|
result.imm_src := src_imm16;
|
||||||
|
result.alu.outsel := alu_xor;
|
||||||
|
result.alu.op1_src := alu_src_reg;
|
||||||
|
result.alu.op2_src := alu_src_imm;
|
||||||
|
result.reg_write := '1';
|
||||||
|
|
||||||
|
when others =>
|
||||||
|
result.exc_illegal := '1';
|
||||||
|
|
||||||
|
end case;
|
||||||
|
|
||||||
|
return result;
|
||||||
|
|
||||||
|
end opcode_ctrl_lines;
|
||||||
|
|
||||||
|
function gen_rom_opcode return rom_opcode_t is
|
||||||
|
variable result : rom_opcode_t;
|
||||||
|
variable opc : opcode_t;
|
||||||
|
begin
|
||||||
|
|
||||||
|
for i in 0 to 2**opcode_t'length-1 loop
|
||||||
|
opc := to_unsigned(i, opcode_t'length);
|
||||||
|
result(i) := opcode_ctrl_lines(opc);
|
||||||
|
end loop;
|
||||||
|
|
||||||
|
return result;
|
||||||
|
end gen_rom_opcode;
|
||||||
|
|
||||||
|
end mips_instr;
|
||||||
|
|
||||||
|
--------------------------------------------------------------------------
|
||||||
|
--------------------------------------------------------------------------
|
||||||
|
|
||||||
@@ -0,0 +1,454 @@
|
|||||||
|
--------------------------------------------------------------------------
|
||||||
|
-- Project: JIPS, a portable 32-bit RISC CPU written in VHDL
|
||||||
|
-- This file: The arithmetic logic unit
|
||||||
|
--
|
||||||
|
-- Copyright (C) 2007 J. Ahrensfeld
|
||||||
|
--
|
||||||
|
-- This program is free software: you can redistribute it and/or modify
|
||||||
|
-- it under the terms of the GNU General Public License as published by
|
||||||
|
-- the Free Software Foundation, either version 3 of the License, or
|
||||||
|
-- (at your option) any later version.
|
||||||
|
--
|
||||||
|
-- This program 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 General Public License for more details.
|
||||||
|
--
|
||||||
|
-- You should have received a copy of the GNU General Public License
|
||||||
|
-- along with this program. If not, see <http://www.gnu.org/licenses/>.
|
||||||
|
--
|
||||||
|
-- For questions and ideas, please contact the author at jens@jayfield.org
|
||||||
|
--
|
||||||
|
--------------------------------------------------------------------------
|
||||||
|
|
||||||
|
library IEEE;
|
||||||
|
use IEEE.STD_LOGIC_1164.ALL;
|
||||||
|
use IEEE.numeric_std.ALL;
|
||||||
|
|
||||||
|
use work.mips_types.all;
|
||||||
|
|
||||||
|
entity muldiv is
|
||||||
|
Port
|
||||||
|
(
|
||||||
|
rst : in std_logic;
|
||||||
|
clk : in std_logic;
|
||||||
|
hilo_we : in std_logic;
|
||||||
|
din_hi : in word_t;
|
||||||
|
din_lo : in word_t;
|
||||||
|
mul_divn : in std_logic;
|
||||||
|
start : in std_logic;
|
||||||
|
s_un : in std_logic;
|
||||||
|
hilo_sel : in std_logic;
|
||||||
|
busy : out std_logic;
|
||||||
|
dout : out word_t
|
||||||
|
);
|
||||||
|
end muldiv;
|
||||||
|
|
||||||
|
architecture Behavioral of muldiv is
|
||||||
|
|
||||||
|
subtype pprod_t is unsigned (39 downto 0);
|
||||||
|
subtype prod_t is unsigned (63 downto 0);
|
||||||
|
subtype byte_t is unsigned (7 downto 0);
|
||||||
|
|
||||||
|
type pprod_array_t is array (natural range <>) of pprod_t;
|
||||||
|
type word_array_t is array (natural range <>) of word_t;
|
||||||
|
type byte_array_t is array (natural range <>) of byte_t;
|
||||||
|
|
||||||
|
signal pprod : pprod_array_t(0 to 3);
|
||||||
|
signal sign1 : std_logic;
|
||||||
|
signal sign2 : std_logic;
|
||||||
|
signal s1_r : std_logic;
|
||||||
|
signal s2_r : std_logic;
|
||||||
|
signal sr_r : std_logic;
|
||||||
|
signal cy : unsigned (3 downto 0);
|
||||||
|
signal mul_start : std_logic;
|
||||||
|
signal mul_en : std_logic;
|
||||||
|
signal sum_en : std_logic;
|
||||||
|
signal pre_sum_vld : std_logic;
|
||||||
|
signal pp_reg : unsigned (63 downto 8);
|
||||||
|
signal pre_const : word_array_t(0 to 1);
|
||||||
|
signal result : prod_t;
|
||||||
|
signal add_op1 : unsigned (39 downto 0);
|
||||||
|
signal add_op2 : unsigned (39 downto 0);
|
||||||
|
signal add_res : unsigned (39 downto 0);
|
||||||
|
signal ppadd_op1 : word_array_t(0 to 3);
|
||||||
|
signal ppadd_op2 : word_array_t(0 to 3);
|
||||||
|
signal ppadd_res : word_array_t(0 to 3);
|
||||||
|
signal ppadd_cyi : unsigned (3 downto 0);
|
||||||
|
signal ppadd_cyo : unsigned (3 downto 0);
|
||||||
|
|
||||||
|
signal pp_op1_r : word_t;
|
||||||
|
signal pp_op1 : word_t;
|
||||||
|
signal pp_op2 : word_t;
|
||||||
|
signal pp_op2_r : byte_array_t(0 to 3);
|
||||||
|
signal bsy : std_logic;
|
||||||
|
|
||||||
|
signal div_add_res : unsigned (32 downto 0);
|
||||||
|
signal div_add_op1 : unsigned (32 downto 0);
|
||||||
|
signal div_add_op2 : unsigned (32 downto 0);
|
||||||
|
signal div_add_cyi : std_logic;
|
||||||
|
signal div_qbit : std_logic;
|
||||||
|
signal div_start : std_logic;
|
||||||
|
signal div_en : std_logic;
|
||||||
|
|
||||||
|
signal div_A : unsigned (32 downto 0);
|
||||||
|
signal div_M : unsigned (32 downto 0);
|
||||||
|
signal div_M_n : unsigned (32 downto 0);
|
||||||
|
signal div_Q : word_t;
|
||||||
|
|
||||||
|
type md_state_t is (md_rdy, mul_pre1, mul_pre2, mul_pp, mul_sum, div_process, div_post1, div_post2, div_post3);
|
||||||
|
signal s, sn : md_state_t;
|
||||||
|
signal cycle_cnt : natural range 0 to 31;
|
||||||
|
signal cycle_cnt_preset : natural range 0 to 31;
|
||||||
|
signal cycle_cnt_load : std_logic;
|
||||||
|
signal div_fin_en : unsigned (2 downto 0);
|
||||||
|
|
||||||
|
--------------------------------------------------------------------------
|
||||||
|
begin
|
||||||
|
-- 9A0CD0570B88D78
|
||||||
|
|
||||||
|
busy <= bsy;
|
||||||
|
|
||||||
|
sign1 <= din_hi(din_hi'left) and s_un;
|
||||||
|
sign2 <= din_lo(din_lo'left) and s_un;
|
||||||
|
pp_op1 <= not din_hi when sign1 = '1' else din_hi;
|
||||||
|
pp_op2 <= not din_lo when sign2 = '1' else din_lo;
|
||||||
|
|
||||||
|
--------------------------------------------------------------------------
|
||||||
|
md_state:
|
||||||
|
process(s, start, mul_divn, cycle_cnt)
|
||||||
|
begin
|
||||||
|
|
||||||
|
bsy <= '1';
|
||||||
|
cycle_cnt_load <= '0';
|
||||||
|
cycle_cnt_preset <= 7;
|
||||||
|
|
||||||
|
mul_en <= '0';
|
||||||
|
div_en <= '0';
|
||||||
|
sum_en <= '0';
|
||||||
|
pre_sum_vld <= '0';
|
||||||
|
mul_start <= '0';
|
||||||
|
div_start <= '0';
|
||||||
|
div_fin_en <= "000";
|
||||||
|
sn <= s;
|
||||||
|
case s is
|
||||||
|
when md_rdy =>
|
||||||
|
bsy <= '0';
|
||||||
|
if start = '1' then
|
||||||
|
if mul_divn = '1' then
|
||||||
|
sn <= mul_pre1;
|
||||||
|
cycle_cnt_load <= '1';
|
||||||
|
cycle_cnt_preset <= 7;
|
||||||
|
mul_start <= '1';
|
||||||
|
else
|
||||||
|
sn <= div_process;
|
||||||
|
cycle_cnt_load <= '1';
|
||||||
|
cycle_cnt_preset <= 31;
|
||||||
|
div_start <= '1';
|
||||||
|
end if;
|
||||||
|
end if;
|
||||||
|
when mul_pre1 =>
|
||||||
|
pre_sum_vld <= '1';
|
||||||
|
mul_en <= '1';
|
||||||
|
sn <= mul_pre2;
|
||||||
|
when mul_pre2 =>
|
||||||
|
pre_sum_vld <= '1';
|
||||||
|
mul_en <= '1';
|
||||||
|
sn <= mul_pp;
|
||||||
|
when mul_pp =>
|
||||||
|
mul_en <= '1';
|
||||||
|
if cycle_cnt = 0 then
|
||||||
|
cycle_cnt_load <= '1';
|
||||||
|
cycle_cnt_preset <= 3;
|
||||||
|
sn <= mul_sum;
|
||||||
|
end if;
|
||||||
|
when mul_sum =>
|
||||||
|
sum_en <= '1';
|
||||||
|
if cycle_cnt = 0 then
|
||||||
|
bsy <= '0';
|
||||||
|
sn <= md_rdy;
|
||||||
|
end if;
|
||||||
|
when div_process =>
|
||||||
|
div_en <= '1';
|
||||||
|
if cycle_cnt = 0 then
|
||||||
|
sn <= div_post1;
|
||||||
|
end if;
|
||||||
|
when div_post1 =>
|
||||||
|
div_fin_en <= "001";
|
||||||
|
sn <= div_post2;
|
||||||
|
when div_post2 =>
|
||||||
|
div_fin_en <= "010";
|
||||||
|
sn <= div_post3;
|
||||||
|
when div_post3 =>
|
||||||
|
div_fin_en <= "100";
|
||||||
|
sn <= md_rdy;
|
||||||
|
bsy <= '0';
|
||||||
|
when others =>
|
||||||
|
sn <= md_rdy;
|
||||||
|
end case;
|
||||||
|
|
||||||
|
end process;
|
||||||
|
|
||||||
|
md_state_next:
|
||||||
|
process(clk)
|
||||||
|
begin
|
||||||
|
if rising_edge(clk) then
|
||||||
|
if rst = '1' then
|
||||||
|
s <= md_rdy;
|
||||||
|
else
|
||||||
|
s <= sn;
|
||||||
|
end if;
|
||||||
|
end if;
|
||||||
|
end process;
|
||||||
|
|
||||||
|
md_cycle_cnt:
|
||||||
|
process(clk)
|
||||||
|
begin
|
||||||
|
if rising_edge(clk) then
|
||||||
|
if rst = '1' then
|
||||||
|
cycle_cnt <= 0;
|
||||||
|
elsif cycle_cnt_load = '1' then
|
||||||
|
cycle_cnt <= cycle_cnt_preset;
|
||||||
|
elsif cycle_cnt /= 0 then
|
||||||
|
cycle_cnt <= cycle_cnt - 1;
|
||||||
|
end if;
|
||||||
|
end if;
|
||||||
|
end process;
|
||||||
|
|
||||||
|
proc_out_reg:
|
||||||
|
process(hilo_sel, result)
|
||||||
|
begin
|
||||||
|
if hilo_sel = '1' then
|
||||||
|
dout <= result(63 downto 32);
|
||||||
|
else
|
||||||
|
dout <= result(31 downto 0);
|
||||||
|
end if;
|
||||||
|
end process;
|
||||||
|
|
||||||
|
proc_in_reg:
|
||||||
|
process(clk)
|
||||||
|
variable pre_cond : unsigned(1 downto 0);
|
||||||
|
begin
|
||||||
|
if rising_edge(clk) then
|
||||||
|
if mul_start = '1' or div_start = '1' then
|
||||||
|
pp_op1_r <= pp_op1;
|
||||||
|
pre_const(0) <= (others => '0');
|
||||||
|
pre_const(1) <= (others => '0');
|
||||||
|
pre_cond := (din_hi(din_hi'left) and s_un) & (din_lo(din_lo'left) and s_un);
|
||||||
|
s1_r <= pre_cond(1);
|
||||||
|
s2_r <= pre_cond(0);
|
||||||
|
sr_r <= pre_cond(0) xor pre_cond(1);
|
||||||
|
case pre_cond is
|
||||||
|
when "01" =>
|
||||||
|
pre_const(0) <= din_hi;
|
||||||
|
pre_const(1) <= X"FFFF_FFFF";
|
||||||
|
when "10" =>
|
||||||
|
pre_const(0) <= X"0000_0000";
|
||||||
|
pre_const(1) <= X"FFFF_FFFF";
|
||||||
|
when "11" =>
|
||||||
|
pre_const(0) <= not din_hi;
|
||||||
|
pre_const(1) <= X"0000_0001";
|
||||||
|
when others => null;
|
||||||
|
end case;
|
||||||
|
elsif pre_sum_vld = '1' then
|
||||||
|
pre_const(0) <= pre_const(1);
|
||||||
|
end if;
|
||||||
|
end if;
|
||||||
|
end process;
|
||||||
|
|
||||||
|
proc_mul_sr:
|
||||||
|
process(clk)
|
||||||
|
begin
|
||||||
|
if rising_edge(clk) then
|
||||||
|
if mul_start = '1' then
|
||||||
|
for i in 0 to 3 loop
|
||||||
|
cy(i) <= '0';
|
||||||
|
pprod(i) <= ppadd_res(i) & X"00";
|
||||||
|
end loop;
|
||||||
|
elsif mul_en = '1' then
|
||||||
|
for i in 0 to 3 loop
|
||||||
|
cy(i) <= ppadd_cyo(i);
|
||||||
|
pprod(i) <= ppadd_res(i) & pprod(i)(8 downto 1);
|
||||||
|
end loop;
|
||||||
|
elsif sum_en = '1' then
|
||||||
|
for i in 1 to 3 loop
|
||||||
|
pprod(i-1) <= pprod(i);
|
||||||
|
end loop;
|
||||||
|
end if;
|
||||||
|
end if;
|
||||||
|
end process;
|
||||||
|
|
||||||
|
gen_mul32x8pp:
|
||||||
|
for i in 0 to 3 generate
|
||||||
|
begin
|
||||||
|
|
||||||
|
pp_adder_mux:
|
||||||
|
process(mul_start, pp_op1, pp_op2, pp_op1_r, pp_op2_r(i), s1_r, sign1, pprod(i), cy(i))
|
||||||
|
variable v2 : unsigned(7 downto 0);
|
||||||
|
begin
|
||||||
|
ppadd_cyi(i) <= '0';
|
||||||
|
ppadd_op1(i) <= (others => '0');
|
||||||
|
if mul_start = '1' then
|
||||||
|
ppadd_op2(i) <= (others => '0');
|
||||||
|
v2 := pp_op2(8*(i+1)-1 downto 8*i);
|
||||||
|
if v2(0) = '1' then
|
||||||
|
ppadd_cyi(i) <= sign1;
|
||||||
|
ppadd_op1(i) <= pp_op1;
|
||||||
|
end if;
|
||||||
|
else
|
||||||
|
ppadd_op2(i) <= cy(i) & pprod(i)(39 downto 9);
|
||||||
|
v2 := pp_op2_r(i);
|
||||||
|
if v2(0) = '1' then
|
||||||
|
ppadd_cyi(i) <= s1_r;
|
||||||
|
ppadd_op1(i) <= pp_op1_r;
|
||||||
|
end if;
|
||||||
|
end if;
|
||||||
|
end process;
|
||||||
|
|
||||||
|
pp_adder:
|
||||||
|
process(ppadd_op1(i), ppadd_op2(i), ppadd_cyi(i))
|
||||||
|
variable sum_pp : unsigned(33 downto 0);
|
||||||
|
begin
|
||||||
|
sum_pp := ('0' & ppadd_op1(i) & ppadd_cyi(i)) + ('0' & ppadd_op2(i) & ppadd_cyi(i));
|
||||||
|
ppadd_res(i) <= sum_pp(sum_pp'left-1 downto 1);
|
||||||
|
ppadd_cyo(i) <= sum_pp(sum_pp'left);
|
||||||
|
end process;
|
||||||
|
|
||||||
|
proc_mul_ctrl:
|
||||||
|
process(clk)
|
||||||
|
begin
|
||||||
|
if rising_edge(clk) then
|
||||||
|
if mul_start = '1' then
|
||||||
|
pp_op2_r(i) <= '0' & pp_op2(8*(i+1)-1 downto 8*i+1);
|
||||||
|
elsif mul_en = '1' then
|
||||||
|
pp_op2_r(i) <= '0' & pp_op2_r(i)(7 downto 1);
|
||||||
|
end if;
|
||||||
|
end if;
|
||||||
|
end process;
|
||||||
|
|
||||||
|
end generate;
|
||||||
|
|
||||||
|
comb_mul_adder:
|
||||||
|
process(add_op1, add_op2)
|
||||||
|
variable sum_mul : unsigned(39 downto 0);
|
||||||
|
begin
|
||||||
|
sum_mul := (add_op1) + (add_op2);
|
||||||
|
add_res <= sum_mul(sum_mul'left downto 0);
|
||||||
|
end process;
|
||||||
|
|
||||||
|
comb_mul_adder_mux:
|
||||||
|
process(pre_const, pre_sum_vld, pp_reg, pprod, sr_r)
|
||||||
|
variable s_ext : std_logic;
|
||||||
|
begin
|
||||||
|
if pre_sum_vld = '1' then
|
||||||
|
add_op1 <= pp_reg(63 downto 24);
|
||||||
|
add_op2 <= pre_const(0) & X"00";
|
||||||
|
else
|
||||||
|
s_ext := pp_reg(63) and sr_r;
|
||||||
|
add_op1 <= (7 downto 0 => s_ext) & pp_reg(63 downto 32);
|
||||||
|
add_op2 <= pprod(0);
|
||||||
|
end if;
|
||||||
|
end process;
|
||||||
|
|
||||||
|
comb_mul:
|
||||||
|
process(clk)
|
||||||
|
variable tmp : prod_t;
|
||||||
|
begin
|
||||||
|
if rising_edge(clk) then
|
||||||
|
if mul_start = '1' then
|
||||||
|
pp_reg <= (others => '0');
|
||||||
|
elsif pre_sum_vld = '1' then
|
||||||
|
pp_reg <= add_res & X"0000";
|
||||||
|
elsif sum_en = '1' then
|
||||||
|
tmp := add_res & pp_reg(31 downto 8);
|
||||||
|
pp_reg <= tmp(63 downto 8);
|
||||||
|
result <= tmp;
|
||||||
|
if sr_r = '1' then
|
||||||
|
result <= not tmp;
|
||||||
|
end if;
|
||||||
|
elsif div_fin_en(1) = '1' then
|
||||||
|
result(63 downto 32) <= div_A(31 downto 0);
|
||||||
|
if s1_r = '1' then
|
||||||
|
result(63 downto 32) <= div_add_res(31 downto 0);
|
||||||
|
end if;
|
||||||
|
elsif div_fin_en(2) = '1' then
|
||||||
|
result(31 downto 0) <= div_Q;
|
||||||
|
if sr_r = '1' then
|
||||||
|
result(31 downto 0) <= div_add_res(31 downto 0);
|
||||||
|
end if;
|
||||||
|
elsif hilo_we = '1' then
|
||||||
|
if hilo_sel = '1' then
|
||||||
|
result(63 downto 32) <= din_hi;
|
||||||
|
else
|
||||||
|
result(31 downto 0) <= din_hi;
|
||||||
|
end if;
|
||||||
|
end if;
|
||||||
|
end if;
|
||||||
|
end process;
|
||||||
|
|
||||||
|
div_adder:
|
||||||
|
process(div_add_op1, div_add_op2, div_add_cyi)
|
||||||
|
variable sum_div : unsigned(33 downto 0);
|
||||||
|
begin
|
||||||
|
sum_div := (div_add_op1 & div_add_cyi) + (div_add_op2 & div_add_cyi);
|
||||||
|
div_add_res <= sum_div(sum_div'left downto 1);
|
||||||
|
end process;
|
||||||
|
|
||||||
|
div_adder_mux:
|
||||||
|
process(div_start, div_en, div_fin_en, div_A, div_Q, pp_op1, sign1, s1_r, s2_r, sr_r, div_qbit, div_M, div_M_n)
|
||||||
|
begin
|
||||||
|
|
||||||
|
div_add_cyi <= s2_r xor div_qbit;
|
||||||
|
div_add_op1 <= div_A(31 downto 0) & div_Q(31);
|
||||||
|
div_add_op2 <= (others => '0');
|
||||||
|
if div_start = '1' then
|
||||||
|
div_add_op1 <= '0' & pp_op1;
|
||||||
|
div_add_cyi <= sign1;
|
||||||
|
elsif div_en = '1' then
|
||||||
|
div_add_op2 <= div_M;
|
||||||
|
if div_qbit = '1' then
|
||||||
|
div_add_op2 <= div_M_n;
|
||||||
|
end if;
|
||||||
|
elsif div_fin_en(0) = '1' then
|
||||||
|
div_add_op2 <= div_M;
|
||||||
|
div_add_cyi <= s2_r;
|
||||||
|
div_add_op1 <= '0' & div_A(31 downto 0);
|
||||||
|
elsif div_fin_en(1) = '1' then
|
||||||
|
div_add_cyi <= s1_r;
|
||||||
|
div_add_op1 <= '0' & not div_A(31 downto 0);
|
||||||
|
elsif div_fin_en(2) = '1' then
|
||||||
|
div_add_cyi <= sr_r;
|
||||||
|
div_add_op1 <= '0' & not div_Q;
|
||||||
|
end if;
|
||||||
|
end process;
|
||||||
|
|
||||||
|
divide:
|
||||||
|
process(clk)
|
||||||
|
variable quo : std_logic;
|
||||||
|
begin
|
||||||
|
if rising_edge(clk) then
|
||||||
|
if div_start = '1' then
|
||||||
|
div_qbit <= '1';
|
||||||
|
div_Q <= div_add_res(31 downto 0);
|
||||||
|
div_A <= (others => '0');
|
||||||
|
if sign2 = '1' then
|
||||||
|
div_M_n <= '1' & din_lo;
|
||||||
|
div_M <= '0' & not din_lo;
|
||||||
|
else
|
||||||
|
div_M_n <= '1' & not din_lo;
|
||||||
|
div_M <= '0' & din_lo;
|
||||||
|
end if;
|
||||||
|
elsif div_en = '1' then
|
||||||
|
div_qbit <= not div_add_res(32);
|
||||||
|
div_A <= div_add_res(32 downto 0);
|
||||||
|
div_Q <= div_Q(30 downto 0) & not div_add_res(32);
|
||||||
|
elsif div_fin_en(0) = '1' then
|
||||||
|
if div_A(32) = '1' then
|
||||||
|
div_A <= '0' & div_add_res(31 downto 0);
|
||||||
|
end if;
|
||||||
|
end if;
|
||||||
|
end if;
|
||||||
|
end process;
|
||||||
|
|
||||||
|
--------------------------------------------------------------------------
|
||||||
|
end Behavioral;
|
||||||
@@ -0,0 +1,918 @@
|
|||||||
|
--------------------------------------------------------------------------
|
||||||
|
-- Project: JIPS, a portable 32-bit RISC CPU written in VHDL
|
||||||
|
-- This file: The pipeline
|
||||||
|
--
|
||||||
|
-- Copyright (C) 2008 J. Ahrensfeld
|
||||||
|
--
|
||||||
|
-- This program is free software: you can redistribute it and/or modify
|
||||||
|
-- it under the terms of the GNU General Public License as published by
|
||||||
|
-- the Free Software Foundation, either version 3 of the License, or
|
||||||
|
-- (at your option) any later version.
|
||||||
|
--
|
||||||
|
-- This program 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 General Public License for more details.
|
||||||
|
--
|
||||||
|
-- You should have received a copy of the GNU General Public License
|
||||||
|
-- along with this program. If not, see <http://www.gnu.org/licenses/>.
|
||||||
|
--
|
||||||
|
-- For questions and ideas, please contact the author at jens@jayfield.org
|
||||||
|
--
|
||||||
|
--------------------------------------------------------------------------
|
||||||
|
library IEEE;
|
||||||
|
use IEEE.STD_LOGIC_1164.ALL;
|
||||||
|
use IEEE.numeric_std.ALL;
|
||||||
|
|
||||||
|
library work;
|
||||||
|
use work.mips_types.all;
|
||||||
|
use work.mips_instr.all;
|
||||||
|
|
||||||
|
entity pipeline is
|
||||||
|
Port
|
||||||
|
(
|
||||||
|
rst : in STD_LOGIC;
|
||||||
|
clk : in STD_LOGIC;
|
||||||
|
halt : in STD_LOGIC;
|
||||||
|
int : in unsigned(5 downto 0);
|
||||||
|
imem_err : in STD_LOGIC;
|
||||||
|
imem_rdy : in STD_LOGIC;
|
||||||
|
imem_en : out STD_LOGIC;
|
||||||
|
imem_addr : out word_t;
|
||||||
|
imem_data : in word_t;
|
||||||
|
dmem_err : in STD_LOGIC;
|
||||||
|
dmem_rdy : in STD_LOGIC;
|
||||||
|
dmem_en : out STD_LOGIC;
|
||||||
|
dmem_we : out STD_LOGIC;
|
||||||
|
dmem_be : out unsigned(3 downto 0);
|
||||||
|
dmem_addr : out word_t;
|
||||||
|
dmem_din : in word_t;
|
||||||
|
dmem_dout : out word_t
|
||||||
|
);
|
||||||
|
end pipeline;
|
||||||
|
|
||||||
|
architecture Behavioral of pipeline is
|
||||||
|
|
||||||
|
--------------------------------------------------------------------------
|
||||||
|
COMPONENT reg_dual is
|
||||||
|
Generic
|
||||||
|
(
|
||||||
|
addr_width : integer := 3;
|
||||||
|
data_width : integer := 8
|
||||||
|
);
|
||||||
|
Port
|
||||||
|
(
|
||||||
|
clk_w : in STD_LOGIC;
|
||||||
|
en : in STD_LOGIC;
|
||||||
|
we : in STD_LOGIC;
|
||||||
|
wptr : in unsigned (addr_width-1 downto 0);
|
||||||
|
din : in unsigned (data_width-1 downto 0);
|
||||||
|
rptr_a : in unsigned (addr_width-1 downto 0);
|
||||||
|
rptr_b : in unsigned (addr_width-1 downto 0);
|
||||||
|
dout_a : out unsigned (data_width-1 downto 0);
|
||||||
|
dout_b : out unsigned (data_width-1 downto 0)
|
||||||
|
);
|
||||||
|
END COMPONENT;
|
||||||
|
|
||||||
|
--------------------------------------------------------------------------
|
||||||
|
COMPONENT idecode_rom is
|
||||||
|
Port
|
||||||
|
(
|
||||||
|
nop : in std_logic;
|
||||||
|
inst_in : in word_t;
|
||||||
|
ctrl_out : out ctrl_lines_t
|
||||||
|
);
|
||||||
|
END COMPONENT;
|
||||||
|
|
||||||
|
--------------------------------------------------------------------------
|
||||||
|
COMPONENT shifter is
|
||||||
|
Generic
|
||||||
|
(
|
||||||
|
data_width : integer
|
||||||
|
);
|
||||||
|
Port
|
||||||
|
(
|
||||||
|
shift_ctrl : in shift_ctrl_t;
|
||||||
|
din : in unsigned (data_width-1 downto 0);
|
||||||
|
dout : out unsigned (data_width-1 downto 0)
|
||||||
|
);
|
||||||
|
END COMPONENT;
|
||||||
|
|
||||||
|
--------------------------------------------------------------------------
|
||||||
|
COMPONENT alu is
|
||||||
|
Generic
|
||||||
|
(
|
||||||
|
data_width : integer
|
||||||
|
);
|
||||||
|
Port
|
||||||
|
(
|
||||||
|
op1_in : in unsigned (data_width-1 downto 0);
|
||||||
|
op2_in : in unsigned (data_width-1 downto 0);
|
||||||
|
op2_shifted : in unsigned (data_width-1 downto 0);
|
||||||
|
ctrl : in alu_ctrl_t;
|
||||||
|
result : out unsigned (data_width-1 downto 0);
|
||||||
|
flags : out alu_flags_t
|
||||||
|
);
|
||||||
|
END COMPONENT;
|
||||||
|
|
||||||
|
--------------------------------------------------------------------------
|
||||||
|
COMPONENT bcu is
|
||||||
|
Generic
|
||||||
|
(
|
||||||
|
data_width : integer
|
||||||
|
);
|
||||||
|
Port
|
||||||
|
(
|
||||||
|
op1_in : in unsigned (data_width-1 downto 0);
|
||||||
|
op2_in : in unsigned (data_width-1 downto 0);
|
||||||
|
flags : out bcu_flags_t
|
||||||
|
);
|
||||||
|
END COMPONENT;
|
||||||
|
|
||||||
|
--------------------------------------------------------------------------
|
||||||
|
COMPONENT cop is
|
||||||
|
Port
|
||||||
|
(
|
||||||
|
rst : in STD_LOGIC;
|
||||||
|
clk : in STD_LOGIC;
|
||||||
|
sdu : in sdu_t;
|
||||||
|
IR_valid : in STD_LOGIC;
|
||||||
|
IR : in word_t;
|
||||||
|
events : in event_t;
|
||||||
|
ctrl_in : in cop_ctrl_in_t;
|
||||||
|
ctrl_out : out cop_ctrl_out_t;
|
||||||
|
din : in word_t;
|
||||||
|
dout : out word_t
|
||||||
|
);
|
||||||
|
END COMPONENT;
|
||||||
|
|
||||||
|
--------------------------------------------------------------------------
|
||||||
|
COMPONENT muldiv is
|
||||||
|
Port
|
||||||
|
(
|
||||||
|
rst : in std_logic;
|
||||||
|
clk : in std_logic;
|
||||||
|
hilo_we : in std_logic;
|
||||||
|
din_hi : in word_t;
|
||||||
|
din_lo : in word_t;
|
||||||
|
mul_divn : in std_logic;
|
||||||
|
start : in std_logic;
|
||||||
|
s_un : in std_logic;
|
||||||
|
hilo_sel : in std_logic;
|
||||||
|
busy : out std_logic;
|
||||||
|
dout : out word_t
|
||||||
|
);
|
||||||
|
END COMPONENT;
|
||||||
|
|
||||||
|
--------------------------------------------------------------------------
|
||||||
|
constant RESET_VECTOR : word_t := X"BFC00000";
|
||||||
|
|
||||||
|
signal ID_stage : ID_t;
|
||||||
|
signal EX_stage : EX_t;
|
||||||
|
signal MEM_stage : MEM_t;
|
||||||
|
signal WB_stage : WB_t;
|
||||||
|
signal clk_2, clk_1 : STD_LOGIC;
|
||||||
|
signal hdu : hdu_t;
|
||||||
|
signal sdu : sdu_t;
|
||||||
|
signal cpu_rst : STD_LOGIC;
|
||||||
|
signal reg_a : word_t;
|
||||||
|
signal reg_b : word_t;
|
||||||
|
signal ctrl_lines : ctrl_lines_t;
|
||||||
|
signal cpu_run : STD_LOGIC;
|
||||||
|
signal branch_ce : STD_LOGIC;
|
||||||
|
signal run_en : STD_LOGIC;
|
||||||
|
signal mul_dep : STD_LOGIC;
|
||||||
|
signal imem_dep : STD_LOGIC;
|
||||||
|
signal dmem_dep : STD_LOGIC;
|
||||||
|
signal cop_ctrl : cop_ctrl_in_t;
|
||||||
|
signal cop_stat : cop_ctrl_out_t;
|
||||||
|
signal cop_din : word_t;
|
||||||
|
signal cop_dout : word_t;
|
||||||
|
signal alu_result : word_t;
|
||||||
|
signal mul_result : word_t;
|
||||||
|
signal mul_busy : STD_LOGIC;
|
||||||
|
signal EX_events_instr : event_t;
|
||||||
|
signal EX_events_alu : event_t;
|
||||||
|
signal EX_events_mem : event_t;
|
||||||
|
signal EX_events : event_t;
|
||||||
|
signal MEM_events : event_t;
|
||||||
|
signal bcu_op_a : word_t;
|
||||||
|
signal bcu_op_b : word_t;
|
||||||
|
signal bcu_flags : bcu_flags_t;
|
||||||
|
signal vaddr : word_t;
|
||||||
|
|
||||||
|
attribute ram_style : string;
|
||||||
|
|
||||||
|
attribute ram_style of reg_a: signal is "distributed";
|
||||||
|
attribute ram_style of reg_b: signal is "distributed";
|
||||||
|
|
||||||
|
signal pc : pc_t;
|
||||||
|
|
||||||
|
--------------------------------------------------------------------------
|
||||||
|
begin
|
||||||
|
|
||||||
|
clk_1 <= clk;
|
||||||
|
clk_2 <= not clk;
|
||||||
|
cpu_run <= run_en;
|
||||||
|
|
||||||
|
-- Stall Detection Unit ---------------------------------------------------
|
||||||
|
sdu.ID_nop <= imem_dep or cop_stat.exc_pending or EX_stage.exc or MEM_stage.exc;
|
||||||
|
sdu.EX_nop <= mul_dep or ID_stage.nop or ID_stage.exc;
|
||||||
|
sdu.MEM_nop <= EX_stage.nop or EX_stage.exc;
|
||||||
|
sdu.WB_nop <= dmem_dep or MEM_stage.nop;
|
||||||
|
|
||||||
|
sdu.ID_stall <= dmem_dep or imem_dep or mul_dep or ID_stage.exc;
|
||||||
|
sdu.EX_stall <= dmem_dep;
|
||||||
|
sdu.MEM_stall <= dmem_dep;
|
||||||
|
sdu.WB_stall <= '0';
|
||||||
|
|
||||||
|
mul_dep <= ID_stage.ctrl.mul_access and (EX_stage.ctrl.mul_start or mul_busy);
|
||||||
|
imem_dep <= not imem_rdy;
|
||||||
|
dmem_dep <= not dmem_rdy and MEM_stage.ctrl.dmem_en;
|
||||||
|
---------------------------------------------------------------------------
|
||||||
|
imem_en <= cpu_run and not (mul_dep or dmem_dep or cop_stat.exc_commit);
|
||||||
|
|
||||||
|
--------------------------------------------------------------------------
|
||||||
|
-- Muldiv
|
||||||
|
--------------------------------------------------------------------------
|
||||||
|
inst_muldiv: muldiv
|
||||||
|
PORT MAP
|
||||||
|
(
|
||||||
|
rst => cpu_rst,
|
||||||
|
clk => clk,
|
||||||
|
hilo_we => EX_stage.ctrl.mul_hilo_we,
|
||||||
|
din_hi => EX_stage.reg_a,
|
||||||
|
din_lo => EX_stage.reg_b,
|
||||||
|
mul_divn => EX_stage.ctrl.mul_mul_divn,
|
||||||
|
start => EX_stage.ctrl.mul_start,
|
||||||
|
s_un => EX_stage.ctrl.mul_s_un,
|
||||||
|
hilo_sel => EX_stage.ctrl.mul_hilo_sel,
|
||||||
|
busy => mul_busy,
|
||||||
|
dout => mul_result
|
||||||
|
);
|
||||||
|
|
||||||
|
--------------------------------------------------------------------------
|
||||||
|
-- Coprocessor
|
||||||
|
--------------------------------------------------------------------------
|
||||||
|
inst_cop: cop
|
||||||
|
PORT MAP
|
||||||
|
(
|
||||||
|
rst => cpu_rst,
|
||||||
|
clk => clk,
|
||||||
|
sdu => sdu,
|
||||||
|
events => MEM_stage.events,
|
||||||
|
IR_valid => ID_stage.ctrl.cop_instr_en,
|
||||||
|
IR => ID_stage.IR,
|
||||||
|
ctrl_in => cop_ctrl,
|
||||||
|
ctrl_out => cop_stat,
|
||||||
|
dout => cop_dout,
|
||||||
|
din => cop_din
|
||||||
|
);
|
||||||
|
|
||||||
|
cop_ctrl.bd_wb <= WB_stage.bd;
|
||||||
|
cop_ctrl.epc_mem <= MEM_stage.pcn;
|
||||||
|
cop_ctrl.epc_wb <= MEM_stage.epc;
|
||||||
|
cop_ctrl.imem_addr <= pc.nxt;
|
||||||
|
cop_ctrl.dmem_addr <= MEM_stage.va;
|
||||||
|
|
||||||
|
--------------------------------------------------------------------------
|
||||||
|
-- IF stage
|
||||||
|
--------------------------------------------------------------------------
|
||||||
|
imem_addr <= pc.curr;
|
||||||
|
|
||||||
|
proc_stage_pc:
|
||||||
|
process(pc, rst, cop_stat)
|
||||||
|
begin
|
||||||
|
if rst = '1' then
|
||||||
|
pc.curr <= RESET_VECTOR after 2 ns;
|
||||||
|
else
|
||||||
|
if pc.is_branch and cop_stat.exc_pending = '0' then
|
||||||
|
pc.curr <= pc.pc_branch after 2 ns;
|
||||||
|
else
|
||||||
|
pc.curr <= pc.nxt after 2 ns;
|
||||||
|
end if;
|
||||||
|
end if;
|
||||||
|
end process;
|
||||||
|
|
||||||
|
proc_stage_pc_branch:
|
||||||
|
process(clk_1)
|
||||||
|
begin
|
||||||
|
if rising_edge(clk_1) then
|
||||||
|
if sdu.ID_stall = '0' then
|
||||||
|
pc.pc_branch <= pc.curr + ID_stage.bimm18;
|
||||||
|
end if;
|
||||||
|
end if;
|
||||||
|
end process;
|
||||||
|
|
||||||
|
proc_stage_pc_next:
|
||||||
|
process(clk_1)
|
||||||
|
begin
|
||||||
|
if rising_edge(clk_1) then
|
||||||
|
branch_ce <= '0';
|
||||||
|
cop_ctrl.exc_left <= '0';
|
||||||
|
if rst = '1' then
|
||||||
|
pc.nxt <= pc.curr;
|
||||||
|
pc.last <= pc.curr;
|
||||||
|
else
|
||||||
|
if cop_stat.exc_commit = '1' then
|
||||||
|
pc.nxt <= cop_stat.exc_vec;
|
||||||
|
elsif sdu.ID_stall = '0' then
|
||||||
|
cop_ctrl.exc_left <= cop_stat.exc_exit;
|
||||||
|
branch_ce <= '1';
|
||||||
|
pc.last <= pc.curr;
|
||||||
|
if ID_stage.ctrl.jump = '1' then
|
||||||
|
pc.nxt <= ID_stage.jimm32;
|
||||||
|
elsif ID_stage.ctrl.jump_long = '1' then
|
||||||
|
pc.nxt <= ID_stage.reg_a;
|
||||||
|
else
|
||||||
|
pc.nxt <= pc.curr + 4;
|
||||||
|
end if;
|
||||||
|
end if;
|
||||||
|
end if;
|
||||||
|
end if;
|
||||||
|
end process;
|
||||||
|
|
||||||
|
proc_stage_branch:
|
||||||
|
process(clk_2)
|
||||||
|
begin
|
||||||
|
if rising_edge(clk_2) and branch_ce = '1' then
|
||||||
|
pc.is_branch <= false;
|
||||||
|
if EX_stage.ctrl.branch = '1' then
|
||||||
|
|
||||||
|
case EX_stage.ctrl.bc_src is
|
||||||
|
|
||||||
|
when bc_eq_ne =>
|
||||||
|
if (EX_stage.ctrl.bc_not xor bcu_flags.eq) = '1' then
|
||||||
|
pc.is_branch <= true;
|
||||||
|
end if;
|
||||||
|
|
||||||
|
when bc_lez_gtz =>
|
||||||
|
if (EX_stage.ctrl.bc_not xor (bcu_flags.eq or bcu_flags.ltz)) = '1' then
|
||||||
|
pc.is_branch <= true;
|
||||||
|
end if;
|
||||||
|
|
||||||
|
when bc_ltz_gez =>
|
||||||
|
if (EX_stage.ctrl.bc_not xor bcu_flags.ltz) = '1' then
|
||||||
|
pc.is_branch <= true;
|
||||||
|
end if;
|
||||||
|
|
||||||
|
when others => null;
|
||||||
|
end case;
|
||||||
|
end if;
|
||||||
|
end if;
|
||||||
|
end process;
|
||||||
|
|
||||||
|
process(rst, clk_1)
|
||||||
|
variable reset_delay : unsigned (5 downto 0);
|
||||||
|
begin
|
||||||
|
if rising_edge(clk_1) then
|
||||||
|
if rst = '1' then
|
||||||
|
reset_delay := (others => '1');
|
||||||
|
cpu_rst <= '1';
|
||||||
|
run_en <= '0';
|
||||||
|
elsif reset_delay /= (5 downto 0 => '0') then
|
||||||
|
reset_delay := reset_delay - 1;
|
||||||
|
else
|
||||||
|
cpu_rst <= '0';
|
||||||
|
end if;
|
||||||
|
if reset_delay(reset_delay'left-1) = '0' then
|
||||||
|
run_en <= '1';
|
||||||
|
end if;
|
||||||
|
end if;
|
||||||
|
end process;
|
||||||
|
|
||||||
|
--------------------------------------------------------------------------
|
||||||
|
-- ID stage
|
||||||
|
--------------------------------------------------------------------------
|
||||||
|
ID_stage.IR <= to_01(imem_data);
|
||||||
|
ID_stage.pcn <= pc.curr;
|
||||||
|
ID_stage.op <= decode_op(ID_stage.IR);
|
||||||
|
ID_stage.jimm32 <= extract_jimm32(ID_stage.IR, ID_stage.pcn);
|
||||||
|
ID_stage.bimm18 <= extract_bimm18(ID_stage.IR, ID_stage.pcn);
|
||||||
|
ID_stage.shamt <= extract_shamt(ID_stage.IR);
|
||||||
|
ID_stage.reg_a_rptr <= extract_rs(ID_stage.IR);
|
||||||
|
ID_stage.reg_b_rptr <= extract_rt(ID_stage.IR);
|
||||||
|
ID_stage.ctrl <= ctrl_lines;
|
||||||
|
ID_stage.reg_write <= ID_stage.ctrl.reg_write or cop_stat.reg_write;
|
||||||
|
ID_stage.epc <= pc.last;
|
||||||
|
ID_stage.exc <= event_is_active(ID_stage.events); -- Todo: works
|
||||||
|
ID_stage.nop <= sdu.ID_nop;
|
||||||
|
|
||||||
|
proc_ID_except:
|
||||||
|
process(ID_stage, cop_stat, pc)
|
||||||
|
begin
|
||||||
|
ID_stage.events <= events_clr;
|
||||||
|
ID_stage.events.inst_load_err <= pc.nxt(1) or pc.nxt(0);
|
||||||
|
ID_stage.events.inst_priv_addr <= pc.nxt(word_t'left) and cop_stat.user_mode;
|
||||||
|
end process;
|
||||||
|
|
||||||
|
proc_stage_hdu:
|
||||||
|
process(ID_stage, EX_stage, MEM_stage, WB_stage)
|
||||||
|
variable read_a, read_b : boolean;
|
||||||
|
variable raw_a_EX, raw_a_MEM, raw_a_WB : boolean;
|
||||||
|
variable raw_b_EX, raw_b_MEM, raw_b_WB : boolean;
|
||||||
|
variable reg_ptr_a : reg_ptr_t;
|
||||||
|
variable reg_ptr_b : reg_ptr_t;
|
||||||
|
begin
|
||||||
|
|
||||||
|
reg_ptr_a := ID_stage.reg_a_rptr;
|
||||||
|
reg_ptr_b := ID_stage.reg_b_rptr;
|
||||||
|
raw_a_EX := reg_ptr_a = EX_stage.reg_wptr and EX_stage.wreg_we = '1';
|
||||||
|
raw_a_MEM := reg_ptr_a = MEM_stage.reg_wptr and MEM_stage.wreg_we = '1';
|
||||||
|
raw_a_WB := reg_ptr_a = WB_stage.reg_wptr and WB_stage.wreg_we = '1';
|
||||||
|
raw_b_EX := reg_ptr_b = EX_stage.reg_wptr and EX_stage.wreg_we = '1';
|
||||||
|
raw_b_MEM := reg_ptr_b = MEM_stage.reg_wptr and MEM_stage.wreg_we = '1';
|
||||||
|
raw_b_WB := reg_ptr_b = WB_stage.reg_wptr and WB_stage.wreg_we = '1';
|
||||||
|
|
||||||
|
hdu.alu_fwd_a_ex <= raw_a_EX after 1 ns;
|
||||||
|
hdu.alu_fwd_a_mem <= raw_a_MEM after 1 ns;
|
||||||
|
hdu.alu_fwd_a_wb <= raw_a_WB after 1 ns;
|
||||||
|
hdu.alu_fwd_b_ex <= raw_b_EX after 1 ns;
|
||||||
|
hdu.alu_fwd_b_mem <= raw_b_MEM after 1 ns;
|
||||||
|
hdu.alu_fwd_b_wb <= raw_b_WB after 1 ns;
|
||||||
|
|
||||||
|
end process;
|
||||||
|
|
||||||
|
proc_stage_fwd_a:
|
||||||
|
process(reg_a, hdu, EX_stage, MEM_stage, WB_stage)
|
||||||
|
variable data : word_t;
|
||||||
|
begin
|
||||||
|
data := reg_a;
|
||||||
|
if hdu.alu_fwd_a_ex then
|
||||||
|
data := EX_stage.result;
|
||||||
|
elsif hdu.alu_fwd_a_mem then
|
||||||
|
data := MEM_stage.data;
|
||||||
|
elsif hdu.alu_fwd_a_wb then
|
||||||
|
data := WB_stage.data;
|
||||||
|
end if;
|
||||||
|
ID_stage.reg_a <= to_01(data) after 2 ns;
|
||||||
|
end process;
|
||||||
|
|
||||||
|
proc_stage_fwd_b:
|
||||||
|
process(reg_b, hdu, EX_stage, MEM_stage, WB_stage)
|
||||||
|
variable data : word_t;
|
||||||
|
begin
|
||||||
|
data := reg_b;
|
||||||
|
if hdu.alu_fwd_b_ex then
|
||||||
|
data := EX_stage.result;
|
||||||
|
elsif hdu.alu_fwd_b_mem then
|
||||||
|
data := MEM_stage.data;
|
||||||
|
elsif hdu.alu_fwd_b_wb then
|
||||||
|
data := WB_stage.data;
|
||||||
|
end if;
|
||||||
|
ID_stage.reg_b <= to_01(data) after 2 ns;
|
||||||
|
end process;
|
||||||
|
|
||||||
|
proc_imm_mux:
|
||||||
|
process(ID_stage)
|
||||||
|
variable data : word_t;
|
||||||
|
begin
|
||||||
|
data := extract_uimm16(ID_stage.IR);
|
||||||
|
|
||||||
|
case ID_stage.ctrl.imm_src is
|
||||||
|
|
||||||
|
when src_imm32 =>
|
||||||
|
data := extract_simm32(ID_stage.IR);
|
||||||
|
|
||||||
|
when src_imm16 =>
|
||||||
|
data := extract_uimm16(ID_stage.IR);
|
||||||
|
|
||||||
|
when src_imm16_high =>
|
||||||
|
data := ID_stage.IR(word_t'length/2-1 downto 0) & (word_t'length/2-1 downto 0 => '0');
|
||||||
|
|
||||||
|
when others => null;
|
||||||
|
|
||||||
|
end case;
|
||||||
|
|
||||||
|
ID_stage.imm <= data after 2 ns;
|
||||||
|
|
||||||
|
end process;
|
||||||
|
|
||||||
|
--------------------------------------------------------------------------
|
||||||
|
inst_idecode_rom: idecode_rom
|
||||||
|
PORT MAP
|
||||||
|
(
|
||||||
|
nop => sdu.ID_nop,
|
||||||
|
inst_in => ID_stage.IR,
|
||||||
|
ctrl_out => ctrl_lines
|
||||||
|
);
|
||||||
|
|
||||||
|
inst_reg_dual: reg_dual
|
||||||
|
GENERIC MAP
|
||||||
|
(
|
||||||
|
addr_width => reg_ptr_t'length,
|
||||||
|
data_width => word_t'length
|
||||||
|
)
|
||||||
|
PORT MAP
|
||||||
|
(
|
||||||
|
clk_w => clk_1,
|
||||||
|
we => WB_stage.wreg_we,
|
||||||
|
en => '1',
|
||||||
|
wptr => WB_stage.reg_wptr,
|
||||||
|
din => WB_stage.data,
|
||||||
|
rptr_a => ID_stage.reg_a_rptr,
|
||||||
|
rptr_b => ID_stage.reg_b_rptr,
|
||||||
|
dout_a => reg_a,
|
||||||
|
dout_b => reg_b
|
||||||
|
);
|
||||||
|
|
||||||
|
--------------------------------------------------------------------------
|
||||||
|
-- EX stage
|
||||||
|
--------------------------------------------------------------------------
|
||||||
|
EX_stage.reg_a_rptr <= extract_rs(EX_stage.IR);
|
||||||
|
EX_stage.reg_b_rptr <= extract_rt(EX_stage.IR);
|
||||||
|
EX_stage.result <= alu_result when EX_stage.ctrl.mul_access = '0' else mul_result;
|
||||||
|
|
||||||
|
proc_stage_ID_EX_1:
|
||||||
|
process(clk_1)
|
||||||
|
begin
|
||||||
|
if rising_edge(clk_1) then
|
||||||
|
if rst = '1' then
|
||||||
|
EX_stage.op <= NOP;
|
||||||
|
EX_stage.IR <= (others => '0');
|
||||||
|
EX_stage.ctrl <= ctrl_lines_default;
|
||||||
|
EX_stage.reg_write <= '0';
|
||||||
|
EX_stage.epc <= (others => '0');
|
||||||
|
EX_stage.pcn <= (others => '0');
|
||||||
|
EX_stage.events_in <= events_clr;
|
||||||
|
elsif sdu.EX_stall = '0' then
|
||||||
|
EX_stage.reg_a <= ID_stage.reg_a;
|
||||||
|
EX_stage.reg_b <= ID_stage.reg_b;
|
||||||
|
EX_stage.events_in <= ID_stage.events;
|
||||||
|
EX_stage.op <= ID_stage.op;
|
||||||
|
EX_stage.ctrl <= ID_stage.ctrl;
|
||||||
|
EX_stage.reg_write <= ID_stage.reg_write;
|
||||||
|
EX_stage.nop <= sdu.EX_nop;
|
||||||
|
EX_stage.IR <= ID_stage.IR;
|
||||||
|
EX_stage.pcn <= ID_stage.pcn;
|
||||||
|
if sdu.EX_nop = '1' then
|
||||||
|
EX_stage.op <= NOP;
|
||||||
|
EX_stage.IR <= (others => '0');
|
||||||
|
EX_stage.ctrl <= ctrl_lines_default;
|
||||||
|
EX_stage.reg_write <= '0';
|
||||||
|
else
|
||||||
|
EX_stage.epc <= ID_stage.epc;
|
||||||
|
end if;
|
||||||
|
end if;
|
||||||
|
end if;
|
||||||
|
end process;
|
||||||
|
|
||||||
|
proc_stage_EX_instr_except:
|
||||||
|
process(EX_stage)
|
||||||
|
begin
|
||||||
|
EX_events_instr <= events_clr;
|
||||||
|
EX_events_instr.illegal <= EX_stage.ctrl.exc_illegal;
|
||||||
|
EX_events_instr.break <= EX_stage.ctrl.exc_break;
|
||||||
|
EX_events_instr.syscall <= EX_stage.ctrl.exc_syscall;
|
||||||
|
end process;
|
||||||
|
|
||||||
|
proc_stage_EX_alu_except:
|
||||||
|
process(EX_stage)
|
||||||
|
begin
|
||||||
|
EX_events_alu <= events_clr;
|
||||||
|
if EX_stage.ctrl.alu_exc_en = '1' then
|
||||||
|
if EX_stage.alu_flags.ovf = '1' then
|
||||||
|
EX_events_alu.alu_ovf <= '1';
|
||||||
|
end if;
|
||||||
|
if EX_stage.alu_flags.uvf = '1' then
|
||||||
|
EX_events_alu.alu_uvf <= '1';
|
||||||
|
end if;
|
||||||
|
end if;
|
||||||
|
end process;
|
||||||
|
|
||||||
|
vaddr <= ID_stage.reg_a + extract_simm32(ID_stage.IR);
|
||||||
|
|
||||||
|
proc_stage_EX_mem_except:
|
||||||
|
process(clk_1)
|
||||||
|
begin
|
||||||
|
if rising_edge(clk_1) then
|
||||||
|
if rst = '1' then
|
||||||
|
dmem_en <= '0';
|
||||||
|
elsif sdu.EX_stall = '0' then
|
||||||
|
EX_events_mem <= events_clr;
|
||||||
|
dmem_en <= '0';
|
||||||
|
if ID_stage.ctrl.dmem_en = '1' then
|
||||||
|
dmem_en <= '1';
|
||||||
|
if ID_stage.ctrl.except_en = '1' then
|
||||||
|
if ID_stage.ctrl.word2_en = '1' then
|
||||||
|
if vaddr(0) = '1' then
|
||||||
|
EX_events_mem.data_load_err <= not ID_stage.ctrl.dmem_we;
|
||||||
|
EX_events_mem.data_store_err <= ID_stage.ctrl.dmem_we;
|
||||||
|
dmem_en <= '0';
|
||||||
|
end if;
|
||||||
|
elsif vaddr(1 downto 0) /= "00" then
|
||||||
|
EX_events_mem.data_load_err <= not ID_stage.ctrl.dmem_we;
|
||||||
|
EX_events_mem.data_store_err <= ID_stage.ctrl.dmem_we;
|
||||||
|
dmem_en <= '0';
|
||||||
|
end if;
|
||||||
|
end if;
|
||||||
|
end if;
|
||||||
|
end if;
|
||||||
|
end if;
|
||||||
|
end process;
|
||||||
|
|
||||||
|
proc_stage_DMEM_ADDR:
|
||||||
|
process(clk_1)
|
||||||
|
begin
|
||||||
|
if rising_edge(clk_1) then
|
||||||
|
if sdu.EX_stall = '0' then --and ID_stage.ctrl.dmem_en = '1' then
|
||||||
|
EX_stage.va <= vaddr;
|
||||||
|
if cop_stat.RE = '1' then
|
||||||
|
EX_stage.pa_off <= not vaddr(1 downto 0);
|
||||||
|
else
|
||||||
|
EX_stage.pa_off <= vaddr(1 downto 0);
|
||||||
|
end if;
|
||||||
|
end if;
|
||||||
|
end if;
|
||||||
|
end process;
|
||||||
|
dmem_be <= store_be(EX_stage.pa_off, EX_stage.ctrl.dmem_we, EX_stage.ctrl.word2_en, EX_stage.ctrl.word4_en, EX_stage.ctrl.align_left, EX_stage.ctrl.byte_en_byp) after 1 ns;
|
||||||
|
dmem_we <= EX_stage.ctrl.dmem_we;
|
||||||
|
dmem_dout <= store_shift(EX_stage.reg_b, EX_stage.pa_off, EX_stage.ctrl.shift_offset, EX_stage.ctrl.shift_byp) after 1ns;
|
||||||
|
dmem_addr <= EX_stage.va;
|
||||||
|
cop_din <= EX_stage.reg_b;
|
||||||
|
EX_stage.events <= EX_events_instr or EX_events_mem or EX_events_alu or EX_stage.events_in;
|
||||||
|
EX_stage.exc <= event_is_active(EX_stage.events);
|
||||||
|
|
||||||
|
--------------------------------------------------------------------------
|
||||||
|
proc_wptr_mux:
|
||||||
|
process(EX_stage)
|
||||||
|
variable opclass : opcode_t;
|
||||||
|
variable reg_wptr : reg_ptr_t;
|
||||||
|
begin
|
||||||
|
|
||||||
|
opclass := extract_opc(EX_stage.IR);
|
||||||
|
case opclass is
|
||||||
|
when "000000" =>
|
||||||
|
reg_wptr := extract_rd(EX_stage.IR);
|
||||||
|
when others =>
|
||||||
|
reg_wptr := extract_rt(EX_stage.IR);
|
||||||
|
end case;
|
||||||
|
|
||||||
|
EX_stage.wreg_we <= EX_stage.reg_write after 1 ns;
|
||||||
|
if reg_wptr = "00000" then
|
||||||
|
EX_stage.wreg_we <= '0' after 1 ns;
|
||||||
|
end if;
|
||||||
|
|
||||||
|
EX_stage.reg_wptr <= reg_wptr after 1 ns;
|
||||||
|
case EX_stage.ctrl.wptr_srcsel is
|
||||||
|
when wptr_src_imm =>
|
||||||
|
EX_stage.reg_wptr <= reg_wptr after 1 ns;
|
||||||
|
|
||||||
|
when wptr_src_const =>
|
||||||
|
EX_stage.reg_wptr <= to_unsigned(31, reg_ptr_t'length) after 1 ns;
|
||||||
|
EX_stage.wreg_we <= '1' after 1 ns;
|
||||||
|
|
||||||
|
when others => null;
|
||||||
|
end case;
|
||||||
|
|
||||||
|
end process;
|
||||||
|
|
||||||
|
--------------------------------------------------------------------------
|
||||||
|
proc_stage_bcu_op:
|
||||||
|
process(clk_1)
|
||||||
|
begin
|
||||||
|
if rising_edge(clk_1) and sdu.EX_stall = '0' then
|
||||||
|
bcu_op_a <= ID_stage.reg_a;
|
||||||
|
bcu_op_b <= ID_stage.reg_b;
|
||||||
|
end if;
|
||||||
|
end process;
|
||||||
|
|
||||||
|
alu_op1_mux:
|
||||||
|
process(EX_stage)
|
||||||
|
variable data : word_t;
|
||||||
|
begin
|
||||||
|
|
||||||
|
data := EX_stage.reg_a;
|
||||||
|
|
||||||
|
-- case EX_stage.ctrl.alu.op1_src is
|
||||||
|
--
|
||||||
|
-- when alu_src_reg =>
|
||||||
|
-- data := EX_stage.reg_a;
|
||||||
|
--
|
||||||
|
-- when alu_src_muldiv =>
|
||||||
|
-- data := mul_result;
|
||||||
|
--
|
||||||
|
-- when others => null;
|
||||||
|
--
|
||||||
|
-- end case;
|
||||||
|
|
||||||
|
EX_stage.alu_op1 <= data;
|
||||||
|
|
||||||
|
end process;
|
||||||
|
|
||||||
|
alu_op2_mux:
|
||||||
|
process(clk_1)
|
||||||
|
variable data : word_t;
|
||||||
|
begin
|
||||||
|
|
||||||
|
if rising_edge(clk_1) and sdu.EX_stall = '0' then
|
||||||
|
data := ID_stage.reg_b;
|
||||||
|
|
||||||
|
case ID_stage.ctrl.alu.op2_src is
|
||||||
|
|
||||||
|
when alu_src_reg =>
|
||||||
|
data := ID_stage.reg_b;
|
||||||
|
|
||||||
|
when alu_src_imm =>
|
||||||
|
data := ID_stage.imm;
|
||||||
|
|
||||||
|
when others => null;
|
||||||
|
|
||||||
|
end case;
|
||||||
|
|
||||||
|
EX_stage.alu_op2 <= data;
|
||||||
|
end if;
|
||||||
|
|
||||||
|
end process;
|
||||||
|
|
||||||
|
shifter_sa_mux:
|
||||||
|
process(clk_1)
|
||||||
|
variable data : shamt_t;
|
||||||
|
variable data_inv : shamt_t;
|
||||||
|
|
||||||
|
begin
|
||||||
|
if rising_edge(clk_1) and sdu.EX_stall = '0' then
|
||||||
|
data := ID_stage.reg_a(4 downto 0);
|
||||||
|
case ID_stage.ctrl.shamt2_srcsel is
|
||||||
|
|
||||||
|
when sa_src_reg =>
|
||||||
|
data := ID_stage.reg_a(4 downto 0);
|
||||||
|
|
||||||
|
when sa_src_imm =>
|
||||||
|
data := ID_stage.shamt;
|
||||||
|
|
||||||
|
when others => null;
|
||||||
|
|
||||||
|
end case;
|
||||||
|
data_inv := not data + 1;
|
||||||
|
if ID_stage.ctrl.alu.shift_right = '0' then
|
||||||
|
EX_stage.shift_ctrl.shamt_rnd <= data_inv after 2 ns;
|
||||||
|
else
|
||||||
|
EX_stage.shift_ctrl.shamt_rnd <= data after 2 ns;
|
||||||
|
end if;
|
||||||
|
EX_stage.shift_ctrl.shamt_nrm <= data after 1 ns;
|
||||||
|
EX_stage.shift_ctrl.shift_right <= ID_stage.ctrl.alu.shift_right;
|
||||||
|
EX_stage.shift_ctrl.shift_arith <= ID_stage.ctrl.alu.shift_arith;
|
||||||
|
end if;
|
||||||
|
|
||||||
|
end process;
|
||||||
|
|
||||||
|
--------------------------------------------------------------------------
|
||||||
|
inst_shifter: shifter
|
||||||
|
GENERIC MAP
|
||||||
|
(
|
||||||
|
data_width => word_t'length
|
||||||
|
)
|
||||||
|
PORT MAP
|
||||||
|
(
|
||||||
|
shift_ctrl => EX_stage.shift_ctrl,
|
||||||
|
din => EX_stage.reg_b,
|
||||||
|
dout => EX_stage.alu_op2_s
|
||||||
|
);
|
||||||
|
|
||||||
|
inst_alu: alu
|
||||||
|
GENERIC MAP
|
||||||
|
(
|
||||||
|
data_width => word_t'length
|
||||||
|
)
|
||||||
|
PORT MAP
|
||||||
|
(
|
||||||
|
op1_in => EX_stage.alu_op1,
|
||||||
|
op2_in => EX_stage.alu_op2,
|
||||||
|
op2_shifted => EX_stage.alu_op2_s,
|
||||||
|
ctrl => EX_stage.ctrl.alu,
|
||||||
|
result => alu_result,
|
||||||
|
flags => EX_stage.alu_flags
|
||||||
|
);
|
||||||
|
|
||||||
|
inst_bcu: bcu
|
||||||
|
GENERIC MAP
|
||||||
|
(
|
||||||
|
data_width => word_t'length
|
||||||
|
)
|
||||||
|
PORT MAP
|
||||||
|
(
|
||||||
|
op1_in => bcu_op_a,
|
||||||
|
op2_in => bcu_op_b,
|
||||||
|
flags => bcu_flags
|
||||||
|
);
|
||||||
|
|
||||||
|
--------------------------------------------------------------------------
|
||||||
|
-- MEM stage
|
||||||
|
--------------------------------------------------------------------------
|
||||||
|
proc_stage_MEM_n:
|
||||||
|
process(clk_1)
|
||||||
|
begin
|
||||||
|
if rising_edge(clk_1) then
|
||||||
|
if rst = '1' then
|
||||||
|
MEM_stage.op <= NOP;
|
||||||
|
MEM_stage.wreg_we <= '0';
|
||||||
|
MEM_stage.ctrl <= ctrl_lines_default;
|
||||||
|
MEM_stage.pa_off <= (others => '0');
|
||||||
|
MEM_stage.events_in <= events_clr;
|
||||||
|
-- MEM_stage.epc <= (others => '0');
|
||||||
|
-- MEM_stage.pcn <= (others => '0');
|
||||||
|
-- MEM_stage.va <= (others => '0');
|
||||||
|
-- MEM_stage.reg_wptr <= (others => '0');
|
||||||
|
-- MEM_stage.ex_result <= (others => '0');
|
||||||
|
elsif sdu.MEM_stall = '0' then
|
||||||
|
MEM_stage.events_in <= EX_stage.events;
|
||||||
|
MEM_stage.op <= EX_stage.op;
|
||||||
|
MEM_stage.wreg_we <= EX_stage.wreg_we;
|
||||||
|
MEM_stage.ctrl <= EX_stage.ctrl;
|
||||||
|
MEM_stage.va <= EX_stage.va;
|
||||||
|
MEM_stage.pa_off <= EX_stage.pa_off;
|
||||||
|
MEM_stage.reg_wptr <= EX_stage.reg_wptr;
|
||||||
|
MEM_stage.nop <= sdu.MEM_nop;
|
||||||
|
if EX_stage.ctrl.dmem_en = '1' then
|
||||||
|
MEM_stage.ex_result <= EX_stage.reg_b;
|
||||||
|
else
|
||||||
|
MEM_stage.ex_result <= EX_stage.result;
|
||||||
|
if cop_stat.cop_read = '1' then
|
||||||
|
MEM_stage.ex_result <= cop_dout;
|
||||||
|
end if;
|
||||||
|
end if;
|
||||||
|
if sdu.MEM_nop = '1' then
|
||||||
|
MEM_stage.op <= NOP;
|
||||||
|
MEM_stage.wreg_we <= '0';
|
||||||
|
MEM_stage.ctrl <= ctrl_lines_default;
|
||||||
|
else
|
||||||
|
MEM_stage.pcn <= EX_stage.pcn;
|
||||||
|
MEM_stage.epc <= EX_stage.epc;
|
||||||
|
end if;
|
||||||
|
end if;
|
||||||
|
end if;
|
||||||
|
end process;
|
||||||
|
|
||||||
|
proc_stage_MEM_mux:
|
||||||
|
process(MEM_stage, dmem_din)
|
||||||
|
variable temp1 : word_t;
|
||||||
|
variable temp2 : word_t;
|
||||||
|
variable data : word_t;
|
||||||
|
variable be : unsigned(3 downto 0);
|
||||||
|
begin
|
||||||
|
data := MEM_stage.ex_result;
|
||||||
|
be := load_be(MEM_stage.pa_off, MEM_stage.ctrl.align_left, MEM_stage.ctrl.byte_en_byp);
|
||||||
|
if MEM_stage.ctrl.reg_link = '1' then
|
||||||
|
data := MEM_stage.pcn + 4;
|
||||||
|
elsif MEM_stage.ctrl.dmem_en = '1' then
|
||||||
|
temp1 := load_shift(dmem_din, MEM_stage.pa_off, MEM_stage.ctrl.shift_offset, MEM_stage.ctrl.shift_byp);
|
||||||
|
temp2 := load_sign_ext(temp1, MEM_stage.ctrl.sign_ext_byp, MEM_stage.ctrl.load_signed, MEM_stage.ctrl.word2_en, MEM_stage.ctrl.word4_en);
|
||||||
|
if be(0) = '1' then
|
||||||
|
data(7 downto 0) := temp2(7 downto 0);
|
||||||
|
end if;
|
||||||
|
if be(1) = '1' then
|
||||||
|
data(15 downto 8) := temp2(15 downto 8);
|
||||||
|
end if;
|
||||||
|
if be(2) = '1' then
|
||||||
|
data(23 downto 16) := temp2(23 downto 16);
|
||||||
|
end if;
|
||||||
|
if be(3) = '1' then
|
||||||
|
data(31 downto 24) := temp2(31 downto 24);
|
||||||
|
end if;
|
||||||
|
end if;
|
||||||
|
MEM_stage.data <= data after 1 ns;
|
||||||
|
|
||||||
|
end process;
|
||||||
|
|
||||||
|
proc_stage_MEM_except:
|
||||||
|
process(MEM_stage, int)
|
||||||
|
begin
|
||||||
|
MEM_stage.events <= MEM_stage.events_in;
|
||||||
|
MEM_stage.events.Int <= int;
|
||||||
|
end process;
|
||||||
|
|
||||||
|
MEM_stage.exc <= cop_stat.int or event_is_active(MEM_stage.events_in);
|
||||||
|
|
||||||
|
--------------------------------------------------------------------------
|
||||||
|
-- WB stage
|
||||||
|
--------------------------------------------------------------------------
|
||||||
|
proc_stage_WB_p:
|
||||||
|
process(clk_1)
|
||||||
|
begin
|
||||||
|
if rising_edge(clk_1) then
|
||||||
|
if rst = '1' then
|
||||||
|
WB_stage.op <= NOP;
|
||||||
|
WB_stage.wreg_we <= '0';
|
||||||
|
-- WB_stage.epc <= (others => '0');
|
||||||
|
-- WB_stage.reg_wptr <= (others => '0');
|
||||||
|
-- WB_stage.data <= (others => '0');
|
||||||
|
elsif sdu.WB_stall = '0' then
|
||||||
|
WB_stage.op <= MEM_stage.op;
|
||||||
|
WB_stage.wreg_we <= MEM_stage.wreg_we;
|
||||||
|
WB_stage.reg_wptr <= MEM_stage.reg_wptr;
|
||||||
|
WB_stage.data <= MEM_stage.data;
|
||||||
|
WB_stage.nop <= sdu.WB_nop;
|
||||||
|
if sdu.WB_nop = '1' then
|
||||||
|
WB_stage.op <= NOP;
|
||||||
|
WB_stage.wreg_we <= '0';
|
||||||
|
else
|
||||||
|
WB_stage.epc <= MEM_stage.epc;
|
||||||
|
WB_stage.bd <= MEM_stage.ctrl.branch or MEM_stage.ctrl.jump or MEM_stage.ctrl.jump_long; -- Todo: works
|
||||||
|
end if;
|
||||||
|
end if;
|
||||||
|
end if;
|
||||||
|
end process;
|
||||||
|
|
||||||
|
--------------------------------------------------------------------------
|
||||||
|
end Behavioral;
|
||||||
@@ -0,0 +1,81 @@
|
|||||||
|
--------------------------------------------------------------------------
|
||||||
|
-- Project: JIPS, a portable 32-bit RISC CPU written in VHDL
|
||||||
|
-- This file: On-Chip work registers
|
||||||
|
--
|
||||||
|
-- Copyright (C) 2008 J. Ahrensfeld
|
||||||
|
--
|
||||||
|
-- This program is free software: you can redistribute it and/or modify
|
||||||
|
-- it under the terms of the GNU General Public License as published by
|
||||||
|
-- the Free Software Foundation, either version 3 of the License, or
|
||||||
|
-- (at your option) any later version.
|
||||||
|
--
|
||||||
|
-- This program 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 General Public License for more details.
|
||||||
|
--
|
||||||
|
-- You should have received a copy of the GNU General Public License
|
||||||
|
-- along with this program. If not, see <http://www.gnu.org/licenses/>.
|
||||||
|
--
|
||||||
|
-- For questions and ideas, please contact the author at jens@jayfield.org
|
||||||
|
--
|
||||||
|
--------------------------------------------------------------------------
|
||||||
|
|
||||||
|
library IEEE;
|
||||||
|
use IEEE.STD_LOGIC_1164.ALL;
|
||||||
|
use IEEE.numeric_std.ALL;
|
||||||
|
|
||||||
|
use work.mips_types.all;
|
||||||
|
|
||||||
|
entity reg_dual is
|
||||||
|
Generic
|
||||||
|
(
|
||||||
|
addr_width : integer := 3;
|
||||||
|
data_width : integer := 8
|
||||||
|
);
|
||||||
|
Port (
|
||||||
|
clk_w : in STD_LOGIC;
|
||||||
|
we : in STD_LOGIC;
|
||||||
|
en : in STD_LOGIC;
|
||||||
|
wptr : in unsigned (addr_width-1 downto 0);
|
||||||
|
din : in unsigned (data_width-1 downto 0);
|
||||||
|
rptr_a : in unsigned (addr_width-1 downto 0);
|
||||||
|
rptr_b : in unsigned (addr_width-1 downto 0);
|
||||||
|
dout_a : out unsigned (data_width-1 downto 0);
|
||||||
|
dout_b : out unsigned (data_width-1 downto 0)
|
||||||
|
);
|
||||||
|
end reg_dual;
|
||||||
|
|
||||||
|
architecture Behavioral of reg_dual is
|
||||||
|
|
||||||
|
constant depth : integer := 2**addr_width;
|
||||||
|
type mem_t is array (0 to depth-1) of unsigned (data_width-1 downto 0);
|
||||||
|
|
||||||
|
function mem_clear(depth : natural) return mem_t is
|
||||||
|
variable result : mem_t;
|
||||||
|
begin
|
||||||
|
for i in 0 to depth-1 loop
|
||||||
|
result(i) := (others => '0');
|
||||||
|
end loop;
|
||||||
|
return result;
|
||||||
|
end mem_clear;
|
||||||
|
|
||||||
|
signal reg_mem : mem_t := mem_clear(depth);
|
||||||
|
|
||||||
|
begin
|
||||||
|
|
||||||
|
reg_in:
|
||||||
|
process(clk_w)
|
||||||
|
begin
|
||||||
|
if rising_edge(clk_w) then
|
||||||
|
if we = '1' and en = '1' then
|
||||||
|
reg_mem(to_integer(wptr)) <= din;
|
||||||
|
end if;
|
||||||
|
end if;
|
||||||
|
end process;
|
||||||
|
|
||||||
|
dout_a <= reg_mem(to_integer(rptr_a)) after 2 ns;
|
||||||
|
dout_b <= reg_mem(to_integer(rptr_b)) after 2 ns;
|
||||||
|
|
||||||
|
end Behavioral;
|
||||||
|
|
||||||
@@ -0,0 +1,114 @@
|
|||||||
|
--------------------------------------------------------------------------
|
||||||
|
-- Project: JIPS, a portable 32-bit RISC CPU written in VHDL
|
||||||
|
-- This file: The shifter unit
|
||||||
|
--
|
||||||
|
-- Copyright (C) 2008 J. Ahrensfeld
|
||||||
|
--
|
||||||
|
-- This program is free software: you can redistribute it and/or modify
|
||||||
|
-- it under the terms of the GNU General Public License as published by
|
||||||
|
-- the Free Software Foundation, either version 3 of the License, or
|
||||||
|
-- (at your option) any later version.
|
||||||
|
--
|
||||||
|
-- This program 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 General Public License for more details.
|
||||||
|
--
|
||||||
|
-- You should have received a copy of the GNU General Public License
|
||||||
|
-- along with this program. If not, see <http://www.gnu.org/licenses/>.
|
||||||
|
--
|
||||||
|
-- For questions and ideas, please contact the author at jens@jayfield.org
|
||||||
|
--
|
||||||
|
--------------------------------------------------------------------------
|
||||||
|
|
||||||
|
library IEEE;
|
||||||
|
use IEEE.STD_LOGIC_1164.ALL;
|
||||||
|
use IEEE.numeric_std.ALL;
|
||||||
|
|
||||||
|
use work.mips_types.all;
|
||||||
|
|
||||||
|
entity shifter is
|
||||||
|
Generic
|
||||||
|
(
|
||||||
|
data_width : integer := 8
|
||||||
|
);
|
||||||
|
Port
|
||||||
|
(
|
||||||
|
shift_ctrl : in shift_ctrl_t;
|
||||||
|
din : in unsigned (data_width-1 downto 0);
|
||||||
|
dout : out unsigned (data_width-1 downto 0)
|
||||||
|
);
|
||||||
|
end shifter;
|
||||||
|
|
||||||
|
architecture Behavioral of shifter is
|
||||||
|
|
||||||
|
subtype word_t is unsigned(data_width-1 downto 0);
|
||||||
|
type word_array_t is array (0 to 5) of word_t;
|
||||||
|
|
||||||
|
signal rot_data : word_array_t;
|
||||||
|
signal sa_rnd : unsigned (4 downto 0);
|
||||||
|
signal fill : std_logic;
|
||||||
|
|
||||||
|
--------------------------------------------------------------------------
|
||||||
|
function rot_stage(x : unsigned; en : std_logic; stage_num : natural) return unsigned is
|
||||||
|
variable result : unsigned(x'range);
|
||||||
|
constant sa : natural := 2**stage_num;
|
||||||
|
begin
|
||||||
|
if en = '1' then
|
||||||
|
result := x(sa-1 downto 0) & x(x'left downto sa);
|
||||||
|
else
|
||||||
|
result := x;
|
||||||
|
end if;
|
||||||
|
return result;
|
||||||
|
|
||||||
|
end rot_stage;
|
||||||
|
|
||||||
|
function rot_fill(x : unsigned; fill : std_logic; shift_right : std_logic; sa : natural) return unsigned is
|
||||||
|
variable result : unsigned(x'range) := (others => '0');
|
||||||
|
variable j : integer;
|
||||||
|
begin
|
||||||
|
|
||||||
|
if shift_right = '0' then
|
||||||
|
for i in 0 to x'left loop
|
||||||
|
if i >= sa then
|
||||||
|
result(i) := x(i);
|
||||||
|
else
|
||||||
|
result(i) := fill;
|
||||||
|
end if;
|
||||||
|
end loop;
|
||||||
|
else
|
||||||
|
j := x'left;
|
||||||
|
for i in 0 to x'left loop
|
||||||
|
if i < sa then
|
||||||
|
result(j) := fill;
|
||||||
|
else
|
||||||
|
result(j) := x(j);
|
||||||
|
end if;
|
||||||
|
j := j - 1;
|
||||||
|
end loop;
|
||||||
|
end if;
|
||||||
|
return result;
|
||||||
|
|
||||||
|
end rot_fill;
|
||||||
|
|
||||||
|
--------------------------------------------------------------------------
|
||||||
|
begin
|
||||||
|
|
||||||
|
rot_data(0) <= din;
|
||||||
|
|
||||||
|
gen_rotate_right:
|
||||||
|
for stage in 0 to 4 generate
|
||||||
|
begin
|
||||||
|
rot_data(stage+1) <= rot_stage(rot_data(stage), sa_rnd(stage), stage);
|
||||||
|
end generate;
|
||||||
|
|
||||||
|
sa_rnd <= shift_ctrl.shamt_rnd;
|
||||||
|
fill <= shift_ctrl.shift_arith and din(data_width-1);
|
||||||
|
dout <= rot_fill(rot_data(5), fill, shift_ctrl.shift_right, to_integer(shift_ctrl.shamt_nrm)) after 5 ns;
|
||||||
|
-- dout <= rot_data(5);
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
--------------------------------------------------------------------------
|
||||||
|
end Behavioral;
|
||||||
|
|
||||||
@@ -0,0 +1,190 @@
|
|||||||
|
--------------------------------------------------------------------------
|
||||||
|
-- Project: JIPS, a portable 32-bit RISC CPU written in VHDL
|
||||||
|
-- This file: JIPS top file
|
||||||
|
--
|
||||||
|
-- Copyright (C) 2008 J. Ahrensfeld
|
||||||
|
--
|
||||||
|
-- This program is free software: you can redistribute it and/or modify
|
||||||
|
-- it under the terms of the GNU General Public License as published by
|
||||||
|
-- the Free Software Foundation, either version 3 of the License, or
|
||||||
|
-- (at your option) any later version.
|
||||||
|
--
|
||||||
|
-- This program 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 General Public License for more details.
|
||||||
|
--
|
||||||
|
-- You should have received a copy of the GNU General Public License
|
||||||
|
-- along with this program. If not, see <http://www.gnu.org/licenses/>.
|
||||||
|
--
|
||||||
|
-- For questions and ideas, please contact the author at jens@jayfield.org
|
||||||
|
--
|
||||||
|
--------------------------------------------------------------------------
|
||||||
|
|
||||||
|
library IEEE;
|
||||||
|
use IEEE.STD_LOGIC_1164.ALL;
|
||||||
|
use IEEE.numeric_std.ALL;
|
||||||
|
|
||||||
|
library work;
|
||||||
|
use work.mips_types.all;
|
||||||
|
|
||||||
|
entity mips_top is
|
||||||
|
Port
|
||||||
|
(
|
||||||
|
debug : out unsigned(1 downto 0);
|
||||||
|
RST_I : in STD_LOGIC;
|
||||||
|
CLK_I : in STD_LOGIC;
|
||||||
|
ACK_I : in STD_LOGIC;
|
||||||
|
SRDY_I : in STD_LOGIC;
|
||||||
|
ADDR_O : out word_t;
|
||||||
|
DAT_I : in word_t;
|
||||||
|
DAT_O : out word_t;
|
||||||
|
WE_O : out STD_LOGIC;
|
||||||
|
SEL_O : out unsigned(3 downto 0);
|
||||||
|
CYC_O : out STD_LOGIC;
|
||||||
|
STB_O : out STD_LOGIC;
|
||||||
|
MRDY_O : out STD_LOGIC;
|
||||||
|
INT : in unsigned (5 downto 0)
|
||||||
|
);
|
||||||
|
|
||||||
|
end mips_top;
|
||||||
|
|
||||||
|
architecture rtl of mips_top is
|
||||||
|
|
||||||
|
COMPONENT pipeline is
|
||||||
|
Port
|
||||||
|
(
|
||||||
|
rst : in STD_LOGIC;
|
||||||
|
clk : in STD_LOGIC;
|
||||||
|
halt : in STD_LOGIC;
|
||||||
|
int : in unsigned (5 downto 0);
|
||||||
|
imem_err : in STD_LOGIC;
|
||||||
|
imem_rdy : in STD_LOGIC;
|
||||||
|
imem_en : out STD_LOGIC;
|
||||||
|
imem_addr : out word_t;
|
||||||
|
imem_data : in word_t;
|
||||||
|
dmem_err : in STD_LOGIC;
|
||||||
|
dmem_rdy : in STD_LOGIC;
|
||||||
|
dmem_en : out STD_LOGIC;
|
||||||
|
dmem_we : out STD_LOGIC;
|
||||||
|
dmem_be : out unsigned(3 downto 0);
|
||||||
|
dmem_addr : out word_t;
|
||||||
|
dmem_din : in word_t;
|
||||||
|
dmem_dout : out word_t
|
||||||
|
);
|
||||||
|
END COMPONENT;
|
||||||
|
signal imem_err : std_logic;
|
||||||
|
signal imem_rdy : std_logic;
|
||||||
|
signal imem_en : std_logic;
|
||||||
|
signal imem_addr : word_t;
|
||||||
|
signal imem_din : word_t;
|
||||||
|
signal dmem_err : std_logic;
|
||||||
|
signal dmem_rdy : std_logic;
|
||||||
|
signal dmem_en : std_logic;
|
||||||
|
signal dmem_we : std_logic;
|
||||||
|
signal dmem_addr : word_t;
|
||||||
|
signal dmem_dout : word_t;
|
||||||
|
signal dmem_din : word_t;
|
||||||
|
signal dmem_be : unsigned(3 downto 0);
|
||||||
|
|
||||||
|
|
||||||
|
COMPONENT biu
|
||||||
|
GENERIC
|
||||||
|
(
|
||||||
|
icache_size : natural;
|
||||||
|
dcache_size : natural
|
||||||
|
);
|
||||||
|
PORT
|
||||||
|
(
|
||||||
|
RST_I : in STD_LOGIC;
|
||||||
|
CLK_I : in STD_LOGIC;
|
||||||
|
ACK_I : in STD_LOGIC;
|
||||||
|
SRDY_I : in STD_LOGIC;
|
||||||
|
ADDR_O : out word_t;
|
||||||
|
DAT_I : in word_t;
|
||||||
|
DAT_O : out word_t;
|
||||||
|
WE_O : out STD_LOGIC;
|
||||||
|
SEL_O : out unsigned(3 downto 0);
|
||||||
|
CYC_O : out STD_LOGIC;
|
||||||
|
STB_O : out STD_LOGIC;
|
||||||
|
MRDY_O : out STD_LOGIC;
|
||||||
|
cpu_imem_err : out STD_LOGIC;
|
||||||
|
cpu_imem_rdy : out STD_LOGIC;
|
||||||
|
cpu_imem_en : in STD_LOGIC;
|
||||||
|
cpu_imem_addr : in word_t;
|
||||||
|
cpu_imem_din : out word_t;
|
||||||
|
cpu_dmem_err : out STD_LOGIC;
|
||||||
|
cpu_dmem_rdy : out STD_LOGIC;
|
||||||
|
cpu_dmem_en : in STD_LOGIC;
|
||||||
|
cpu_dmem_we : in STD_LOGIC;
|
||||||
|
cpu_dmem_be : in unsigned(3 downto 0);
|
||||||
|
cpu_dmem_dout : in word_t;
|
||||||
|
cpu_dmem_din : out word_t;
|
||||||
|
cpu_dmem_addr : in word_t
|
||||||
|
);
|
||||||
|
END COMPONENT;
|
||||||
|
|
||||||
|
begin
|
||||||
|
|
||||||
|
-------------------------------------------------------------------
|
||||||
|
debug(0) <= imem_err;
|
||||||
|
debug(1) <= dmem_err;
|
||||||
|
|
||||||
|
inst_pipeline: pipeline
|
||||||
|
PORT MAP
|
||||||
|
(
|
||||||
|
rst => RST_I,
|
||||||
|
clk => CLK_I,
|
||||||
|
halt => '0',
|
||||||
|
int => INT,
|
||||||
|
imem_err => imem_err,
|
||||||
|
imem_rdy => imem_rdy,
|
||||||
|
imem_en => imem_en,
|
||||||
|
imem_addr => imem_addr,
|
||||||
|
imem_data => imem_din,
|
||||||
|
dmem_err => dmem_err,
|
||||||
|
dmem_rdy => dmem_rdy,
|
||||||
|
dmem_en => dmem_en,
|
||||||
|
dmem_we => dmem_we,
|
||||||
|
dmem_be => dmem_be,
|
||||||
|
dmem_addr => dmem_addr,
|
||||||
|
dmem_din => dmem_din,
|
||||||
|
dmem_dout => dmem_dout
|
||||||
|
);
|
||||||
|
|
||||||
|
inst_biu: biu
|
||||||
|
GENERIC MAP
|
||||||
|
(
|
||||||
|
icache_size => 4096, -- words
|
||||||
|
dcache_size => 4096 -- words
|
||||||
|
)
|
||||||
|
PORT MAP
|
||||||
|
(
|
||||||
|
RST_I => RST_I,
|
||||||
|
CLK_I => CLK_I,
|
||||||
|
ACK_I => ACK_I,
|
||||||
|
SRDY_I => SRDY_I,
|
||||||
|
ADDR_O => ADDR_O,
|
||||||
|
DAT_I => DAT_I,
|
||||||
|
DAT_O => DAT_O,
|
||||||
|
WE_O => WE_O,
|
||||||
|
SEL_O => SEL_O,
|
||||||
|
CYC_O => CYC_O,
|
||||||
|
STB_O => STB_O,
|
||||||
|
MRDY_O => MRDY_O,
|
||||||
|
cpu_imem_err => imem_err,
|
||||||
|
cpu_imem_rdy => imem_rdy,
|
||||||
|
cpu_imem_en => imem_en,
|
||||||
|
cpu_imem_addr => imem_addr,
|
||||||
|
cpu_imem_din => imem_din,
|
||||||
|
cpu_dmem_err => dmem_err,
|
||||||
|
cpu_dmem_rdy => dmem_rdy,
|
||||||
|
cpu_dmem_en => dmem_en,
|
||||||
|
cpu_dmem_we => dmem_we,
|
||||||
|
cpu_dmem_be => dmem_be,
|
||||||
|
cpu_dmem_addr => dmem_addr,
|
||||||
|
cpu_dmem_din => dmem_din,
|
||||||
|
cpu_dmem_dout => dmem_dout
|
||||||
|
);
|
||||||
|
|
||||||
|
end rtl;
|
||||||
@@ -0,0 +1,619 @@
|
|||||||
|
--------------------------------------------------------------------------
|
||||||
|
-- Project: JIPS, a portable 32-bit RISC CPU written in VHDL
|
||||||
|
-- This file: Types, constants and functions for JIPS
|
||||||
|
--
|
||||||
|
-- Copyright (C) 2008 J. Ahrensfeld
|
||||||
|
--
|
||||||
|
-- This program is free software: you can redistribute it and/or modify
|
||||||
|
-- it under the terms of the GNU General Public License as published by
|
||||||
|
-- the Free Software Foundation, either version 3 of the License, or
|
||||||
|
-- (at your option) any later version.
|
||||||
|
--
|
||||||
|
-- This program 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 General Public License for more details.
|
||||||
|
--
|
||||||
|
-- You should have received a copy of the GNU General Public License
|
||||||
|
-- along with this program. If not, see <http://www.gnu.org/licenses/>.
|
||||||
|
--
|
||||||
|
-- For questions and ideas, please contact the author at jens@jayfield.org
|
||||||
|
--
|
||||||
|
--------------------------------------------------------------------------
|
||||||
|
|
||||||
|
library IEEE;
|
||||||
|
use IEEE.STD_LOGIC_1164.ALL;
|
||||||
|
use IEEE.numeric_std.ALL;
|
||||||
|
|
||||||
|
|
||||||
|
--------------------------------------------------------------------------
|
||||||
|
package mips_types is
|
||||||
|
|
||||||
|
-- Revision of the CPU
|
||||||
|
constant REVISION : integer := 1;
|
||||||
|
constant WORD_WIDTH : integer := 32;
|
||||||
|
|
||||||
|
--Types
|
||||||
|
subtype instr_name_t is string(1 to 12);
|
||||||
|
type instr_name_array_t is array (0 to 63) of instr_name_t;
|
||||||
|
subtype opcode_t is unsigned (5 downto 0);
|
||||||
|
subtype word_t is unsigned (WORD_WIDTH-1 downto 0);
|
||||||
|
subtype reg_ptr_t is unsigned (4 downto 0);
|
||||||
|
subtype shamt_t is unsigned(4 downto 0);
|
||||||
|
subtype sa_t is natural range 0 to 63;
|
||||||
|
subtype func_t is unsigned(5 downto 0);
|
||||||
|
|
||||||
|
type opclass_t is (special, regimm, opcode);
|
||||||
|
|
||||||
|
type op_t is
|
||||||
|
(
|
||||||
|
nop,
|
||||||
|
op_sll,
|
||||||
|
op_srl,
|
||||||
|
op_sra,
|
||||||
|
op_sllv,
|
||||||
|
op_srlv,
|
||||||
|
op_srav,
|
||||||
|
op_jr,
|
||||||
|
op_jalr,
|
||||||
|
op_syscall,
|
||||||
|
op_break,
|
||||||
|
op_mfhi,
|
||||||
|
op_mthi,
|
||||||
|
op_mflo,
|
||||||
|
op_mtlo,
|
||||||
|
op_mult,
|
||||||
|
op_multu,
|
||||||
|
op_div,
|
||||||
|
op_divu,
|
||||||
|
op_add,
|
||||||
|
op_addu,
|
||||||
|
op_sub,
|
||||||
|
op_subu,
|
||||||
|
op_and,
|
||||||
|
op_or,
|
||||||
|
op_xor,
|
||||||
|
op_nor,
|
||||||
|
op_slt,
|
||||||
|
op_sltu,
|
||||||
|
op_bltz,
|
||||||
|
op_bgez,
|
||||||
|
op_bltzal,
|
||||||
|
op_bgezal,
|
||||||
|
op_j,
|
||||||
|
op_jal,
|
||||||
|
op_beq,
|
||||||
|
op_bne,
|
||||||
|
op_blez,
|
||||||
|
op_bgtz,
|
||||||
|
op_addi,
|
||||||
|
op_addiu,
|
||||||
|
op_slti,
|
||||||
|
op_sltiu,
|
||||||
|
op_andi,
|
||||||
|
op_ori,
|
||||||
|
op_xori,
|
||||||
|
op_lui,
|
||||||
|
op_lb,
|
||||||
|
op_lh,
|
||||||
|
op_lwl,
|
||||||
|
op_lw,
|
||||||
|
op_lbu,
|
||||||
|
op_lhu,
|
||||||
|
op_lwr,
|
||||||
|
op_sb,
|
||||||
|
op_sh,
|
||||||
|
op_swl,
|
||||||
|
op_sw,
|
||||||
|
op_swr,
|
||||||
|
op_cop0,
|
||||||
|
op_cop1,
|
||||||
|
op_cop2,
|
||||||
|
op_cop3,
|
||||||
|
op_lwc1,
|
||||||
|
op_lwc2,
|
||||||
|
op_lwc3,
|
||||||
|
op_swc1,
|
||||||
|
op_swc2,
|
||||||
|
op_swc3
|
||||||
|
);
|
||||||
|
|
||||||
|
attribute ENUM_ENCODING : string;
|
||||||
|
|
||||||
|
type imm_src_t is (src_imm32, src_imm16, src_imm16_high);
|
||||||
|
type sa_src_t is (sa_src_reg, sa_src_imm);
|
||||||
|
type alu_src1_t is (alu_src_reg);
|
||||||
|
type alu_src2_t is (alu_src_reg, alu_src_imm);
|
||||||
|
type bc_src_t is (bc_eq_ne, bc_lez_gtz, bc_ltz_gez);
|
||||||
|
type shift_opsel_t is (shift_sll, shift_srl, shift_sra);
|
||||||
|
type wptr_src_t is (wptr_src_imm, wptr_src_const);
|
||||||
|
|
||||||
|
-- attribute ENUM_ENCODING of itype_t: type is "ONE-HOT";
|
||||||
|
|
||||||
|
type pc_t is record
|
||||||
|
curr : word_t;
|
||||||
|
last : word_t;
|
||||||
|
nxt : word_t;
|
||||||
|
pc_branch : word_t;
|
||||||
|
is_branch : boolean;
|
||||||
|
end record;
|
||||||
|
|
||||||
|
type alu_outsel_t is
|
||||||
|
(
|
||||||
|
alu_adder,
|
||||||
|
alu_shift2,
|
||||||
|
alu_and,
|
||||||
|
alu_or,
|
||||||
|
alu_xor,
|
||||||
|
alu_nor,
|
||||||
|
alu_ltu,
|
||||||
|
alu_lts
|
||||||
|
);
|
||||||
|
|
||||||
|
type alu_flags_t is record
|
||||||
|
c : STD_LOGIC;
|
||||||
|
uvf : STD_LOGIC;
|
||||||
|
ovf : STD_LOGIC;
|
||||||
|
ltu : STD_LOGIC;
|
||||||
|
lts : STD_LOGIC;
|
||||||
|
end record;
|
||||||
|
|
||||||
|
type bcu_flags_t is record
|
||||||
|
eq : STD_LOGIC;
|
||||||
|
ltz : STD_LOGIC;
|
||||||
|
end record;
|
||||||
|
|
||||||
|
type event_t is record
|
||||||
|
Int : unsigned(5 downto 0);
|
||||||
|
data_load_err : STD_LOGIC;
|
||||||
|
data_store_err : STD_LOGIC;
|
||||||
|
inst_load_err : STD_LOGIC;
|
||||||
|
inst_priv_addr : STD_LOGIC;
|
||||||
|
alu_ovf : STD_LOGIC;
|
||||||
|
alu_uvf : STD_LOGIC;
|
||||||
|
syscall : STD_LOGIC;
|
||||||
|
break : STD_LOGIC;
|
||||||
|
illegal : STD_LOGIC;
|
||||||
|
end record;
|
||||||
|
|
||||||
|
type exc_flags_t is record
|
||||||
|
Int : STD_LOGIC;
|
||||||
|
DAdEL : STD_LOGIC;
|
||||||
|
DAdES : STD_LOGIC;
|
||||||
|
IAdEL : STD_LOGIC;
|
||||||
|
IAdEK : STD_LOGIC;
|
||||||
|
Ov : STD_LOGIC;
|
||||||
|
Sys : STD_LOGIC;
|
||||||
|
Bp : STD_LOGIC;
|
||||||
|
RI : STD_LOGIC;
|
||||||
|
IBE : STD_LOGIC;
|
||||||
|
DBE : STD_LOGIC;
|
||||||
|
end record;
|
||||||
|
|
||||||
|
type except_t is record
|
||||||
|
act : STD_LOGIC;
|
||||||
|
epc : word_t;
|
||||||
|
cause : word_t;
|
||||||
|
end record;
|
||||||
|
|
||||||
|
type cop_ctrl_in_t is record
|
||||||
|
bd_wb : STD_LOGIC;
|
||||||
|
epc_mem : word_t;
|
||||||
|
epc_wb : word_t;
|
||||||
|
imem_addr : word_t;
|
||||||
|
dmem_addr : word_t;
|
||||||
|
exc_left : STD_LOGIC;
|
||||||
|
end record;
|
||||||
|
|
||||||
|
type cop_ctrl_out_t is record
|
||||||
|
RE : STD_LOGIC;
|
||||||
|
ee : STD_LOGIC;
|
||||||
|
ec : STD_LOGIC;
|
||||||
|
exc_commit : STD_LOGIC;
|
||||||
|
exc_pending : STD_LOGIC;
|
||||||
|
exc_exit : STD_LOGIC;
|
||||||
|
reg_write : STD_LOGIC;
|
||||||
|
cop_read : STD_LOGIC;
|
||||||
|
user_mode : STD_LOGIC;
|
||||||
|
int : STD_LOGIC;
|
||||||
|
exc_vec : word_t;
|
||||||
|
end record;
|
||||||
|
|
||||||
|
type sdu_t is record
|
||||||
|
ID_nop : STD_LOGIC;
|
||||||
|
EX_nop : STD_LOGIC;
|
||||||
|
MEM_nop : STD_LOGIC;
|
||||||
|
WB_nop : STD_LOGIC;
|
||||||
|
ID_stall : STD_LOGIC;
|
||||||
|
EX_stall : STD_LOGIC;
|
||||||
|
MEM_stall : STD_LOGIC;
|
||||||
|
WB_stall : STD_LOGIC;
|
||||||
|
end record;
|
||||||
|
|
||||||
|
type hdu_t is record
|
||||||
|
alu_fwd_a_ex : boolean;
|
||||||
|
alu_fwd_a_mem : boolean;
|
||||||
|
alu_fwd_a_wb : boolean;
|
||||||
|
alu_fwd_b_ex : boolean;
|
||||||
|
alu_fwd_b_mem : boolean;
|
||||||
|
alu_fwd_b_wb : boolean;
|
||||||
|
end record;
|
||||||
|
|
||||||
|
type alu_ctrl_t is record
|
||||||
|
outsel : alu_outsel_t;
|
||||||
|
add : STD_LOGIC;
|
||||||
|
shift_right : STD_LOGIC;
|
||||||
|
shift_arith : STD_LOGIC;
|
||||||
|
op1_src : alu_src1_t;
|
||||||
|
op2_src : alu_src2_t;
|
||||||
|
end record;
|
||||||
|
|
||||||
|
type shift_ctrl_t is record
|
||||||
|
shamt_nrm : shamt_t;
|
||||||
|
shamt_rnd : shamt_t;
|
||||||
|
shift_right : STD_LOGIC;
|
||||||
|
shift_arith : STD_LOGIC;
|
||||||
|
end record;
|
||||||
|
|
||||||
|
type ctrl_lines_t is record
|
||||||
|
branch : STD_LOGIC;
|
||||||
|
jump_long : STD_LOGIC;
|
||||||
|
jump : STD_LOGIC;
|
||||||
|
bc_not : STD_LOGIC;
|
||||||
|
bc_src : bc_src_t;
|
||||||
|
imm_src : imm_src_t;
|
||||||
|
alu : alu_ctrl_t;
|
||||||
|
reg_write : STD_LOGIC;
|
||||||
|
reg_link : STD_LOGIC;
|
||||||
|
dmem_we : STD_LOGIC;
|
||||||
|
dmem_en : STD_LOGIC;
|
||||||
|
shamt2_srcsel : sa_src_t;
|
||||||
|
wptr_srcsel : wptr_src_t;
|
||||||
|
cop_instr_en : STD_LOGIC;
|
||||||
|
shift_offset : unsigned(1 downto 0);
|
||||||
|
shift_byp : STD_LOGIC;
|
||||||
|
byte_en_byp : STD_LOGIC;
|
||||||
|
sign_ext_byp : STD_LOGIC;
|
||||||
|
word4_en : STD_LOGIC;
|
||||||
|
word2_en : STD_LOGIC;
|
||||||
|
align_left : STD_LOGIC;
|
||||||
|
load_signed : STD_LOGIC;
|
||||||
|
mul_access : STD_LOGIC;
|
||||||
|
mul_hilo_we : STD_LOGIC;
|
||||||
|
mul_mul_divn : STD_LOGIC;
|
||||||
|
mul_start : STD_LOGIC;
|
||||||
|
mul_s_un : STD_LOGIC;
|
||||||
|
mul_hilo_sel : STD_LOGIC;
|
||||||
|
exc_break : STD_LOGIC;
|
||||||
|
exc_syscall : STD_LOGIC;
|
||||||
|
exc_illegal : STD_LOGIC;
|
||||||
|
except_en : STD_LOGIC;
|
||||||
|
alu_exc_en : STD_LOGIC;
|
||||||
|
end record;
|
||||||
|
|
||||||
|
type ID_t is record
|
||||||
|
nop : STD_LOGIC;
|
||||||
|
exc : std_logic;
|
||||||
|
IR : word_t;
|
||||||
|
op : op_t;
|
||||||
|
pcn : word_t;
|
||||||
|
epc : word_t;
|
||||||
|
jimm32 : word_t;
|
||||||
|
bimm18 : word_t;
|
||||||
|
imm : word_t;
|
||||||
|
shamt : shamt_t;
|
||||||
|
ctrl : ctrl_lines_t;
|
||||||
|
reg_write : STD_LOGIC;
|
||||||
|
reg_a_rptr : reg_ptr_t;
|
||||||
|
reg_b_rptr : reg_ptr_t;
|
||||||
|
reg_a : word_t;
|
||||||
|
reg_b : word_t;
|
||||||
|
events : event_t;
|
||||||
|
end record;
|
||||||
|
|
||||||
|
type EX_t is record
|
||||||
|
nop : STD_LOGIC;
|
||||||
|
exc : std_logic;
|
||||||
|
IR : word_t;
|
||||||
|
op : op_t;
|
||||||
|
pcn : word_t;
|
||||||
|
epc : word_t;
|
||||||
|
reg_a : word_t;
|
||||||
|
reg_b : word_t;
|
||||||
|
ctrl : ctrl_lines_t;
|
||||||
|
shift_ctrl : shift_ctrl_t;
|
||||||
|
alu_op1 : word_t;
|
||||||
|
alu_op2 : word_t;
|
||||||
|
alu_op2_s : word_t;
|
||||||
|
alu_flags : alu_flags_t;
|
||||||
|
result : word_t;
|
||||||
|
reg_write : STD_LOGIC;
|
||||||
|
wreg_we : STD_LOGIC;
|
||||||
|
reg_wptr : reg_ptr_t;
|
||||||
|
reg_a_rptr : reg_ptr_t;
|
||||||
|
reg_b_rptr : reg_ptr_t;
|
||||||
|
va : word_t;
|
||||||
|
pa_off : unsigned(1 downto 0);
|
||||||
|
events_in : event_t;
|
||||||
|
events : event_t;
|
||||||
|
end record;
|
||||||
|
|
||||||
|
type MEM_t is record
|
||||||
|
nop : STD_LOGIC;
|
||||||
|
exc : std_logic;
|
||||||
|
op : op_t;
|
||||||
|
pcn : word_t;
|
||||||
|
epc : word_t;
|
||||||
|
ctrl : ctrl_lines_t;
|
||||||
|
ex_result : word_t;
|
||||||
|
reg_wptr : reg_ptr_t;
|
||||||
|
wreg_we : STD_LOGIC;
|
||||||
|
data : word_t;
|
||||||
|
va : word_t;
|
||||||
|
pa_off : unsigned(1 downto 0);
|
||||||
|
events_in : event_t;
|
||||||
|
events : event_t;
|
||||||
|
end record;
|
||||||
|
|
||||||
|
type WB_t is record
|
||||||
|
nop : STD_LOGIC;
|
||||||
|
op : op_t;
|
||||||
|
epc : word_t;
|
||||||
|
reg_wptr : reg_ptr_t;
|
||||||
|
wreg_we : STD_LOGIC;
|
||||||
|
data : word_t;
|
||||||
|
bd : STD_LOGIC;
|
||||||
|
end record;
|
||||||
|
|
||||||
|
|
||||||
|
type rom_special_t is array (0 to 2**func_t'length-1) of ctrl_lines_t;
|
||||||
|
type rom_regimm_t is array (0 to 2**reg_ptr_t'length-1) of ctrl_lines_t;
|
||||||
|
type rom_opcode_t is array (0 to 2**opcode_t'length-1) of ctrl_lines_t;
|
||||||
|
|
||||||
|
function store_shift(x : word_t; va, shift_off : unsigned(1 downto 0); bypass : std_logic) return word_t;
|
||||||
|
function store_be(va : unsigned(1 downto 0); be_src, word2_en, word4_en, align_left, bypass : std_logic) return unsigned;
|
||||||
|
function load_shift(x : word_t; va, shift_off : unsigned(1 downto 0); bypass : std_logic) return word_t;
|
||||||
|
function load_be(va : unsigned(1 downto 0); align_left, bypass : std_logic) return unsigned;
|
||||||
|
function load_sign_ext(x : word_t; bypass, signed, word2_en, word4_en : std_logic) return word_t;
|
||||||
|
function events_clr return event_t;
|
||||||
|
function event_is_active(e : event_t) return std_logic;
|
||||||
|
function "or" (a, b : event_t) return event_t;
|
||||||
|
|
||||||
|
end mips_types;
|
||||||
|
|
||||||
|
--------------------------------------------------------------------------
|
||||||
|
package body mips_types is
|
||||||
|
|
||||||
|
function store_shift(x : word_t; va, shift_off : unsigned(1 downto 0); bypass : std_logic) return word_t is
|
||||||
|
variable stage1 : word_t;
|
||||||
|
variable result : word_t;
|
||||||
|
variable sa : unsigned(1 downto 0);
|
||||||
|
begin
|
||||||
|
|
||||||
|
if bypass = '1' then
|
||||||
|
sa := "00";
|
||||||
|
else
|
||||||
|
sa := va + shift_off;
|
||||||
|
end if;
|
||||||
|
|
||||||
|
stage1 := x;
|
||||||
|
if sa(0) = '1' then
|
||||||
|
stage1 := x(23 downto 0) & x(31 downto 24);
|
||||||
|
end if;
|
||||||
|
result := stage1;
|
||||||
|
if sa(1) = '1' then
|
||||||
|
result := stage1(15 downto 0) & stage1(31 downto 16);
|
||||||
|
end if;
|
||||||
|
|
||||||
|
return result;
|
||||||
|
end store_shift;
|
||||||
|
|
||||||
|
--------------------------------------------------------------------------
|
||||||
|
function store_be(va : unsigned(1 downto 0); be_src, word2_en, word4_en, align_left, bypass : std_logic) return unsigned is
|
||||||
|
variable result : unsigned(3 downto 0);
|
||||||
|
begin
|
||||||
|
if bypass = '1' then
|
||||||
|
result := (3 downto 0 => be_src);
|
||||||
|
elsif word2_en = '1' then
|
||||||
|
case va is
|
||||||
|
when "00" | "01" =>
|
||||||
|
result := "00" & be_src & be_src;
|
||||||
|
when "10" | "11" =>
|
||||||
|
result := be_src & be_src & "00";
|
||||||
|
when others =>
|
||||||
|
result := "0000";
|
||||||
|
end case;
|
||||||
|
elsif word4_en = '1' then
|
||||||
|
case va is
|
||||||
|
when "00" =>
|
||||||
|
result := "000" & be_src;
|
||||||
|
when "01" =>
|
||||||
|
result := "00" & be_src & '0';
|
||||||
|
when "10" =>
|
||||||
|
result := '0' & be_src & "00";
|
||||||
|
when "11" =>
|
||||||
|
result := be_src & "000";
|
||||||
|
when others =>
|
||||||
|
result := "0000";
|
||||||
|
end case;
|
||||||
|
elsif align_left = '1' then
|
||||||
|
case va is
|
||||||
|
when "00" =>
|
||||||
|
result := be_src & be_src & be_src & be_src;
|
||||||
|
when "01" =>
|
||||||
|
result := be_src & be_src & be_src & '0';
|
||||||
|
when "10" =>
|
||||||
|
result := be_src & be_src & "00";
|
||||||
|
when "11" =>
|
||||||
|
result := be_src & "000";
|
||||||
|
when others =>
|
||||||
|
result := "0000";
|
||||||
|
end case;
|
||||||
|
else
|
||||||
|
case va is
|
||||||
|
when "00" =>
|
||||||
|
result := "000" & be_src;
|
||||||
|
when "01" =>
|
||||||
|
result := "00" & be_src & be_src;
|
||||||
|
when "10" =>
|
||||||
|
result := '0' & be_src & be_src & be_src;
|
||||||
|
when "11" =>
|
||||||
|
result := be_src & be_src & be_src & be_src;
|
||||||
|
when others =>
|
||||||
|
result := "0000";
|
||||||
|
end case;
|
||||||
|
end if;
|
||||||
|
|
||||||
|
return result;
|
||||||
|
|
||||||
|
end store_be;
|
||||||
|
|
||||||
|
--------------------------------------------------------------------------
|
||||||
|
function load_shift(x : word_t; va, shift_off : unsigned(1 downto 0); bypass : std_logic) return word_t is
|
||||||
|
variable stage1 : word_t;
|
||||||
|
variable result : word_t;
|
||||||
|
variable sa : unsigned(1 downto 0);
|
||||||
|
|
||||||
|
begin
|
||||||
|
if bypass = '1' then
|
||||||
|
sa := "00";
|
||||||
|
else
|
||||||
|
sa := va + shift_off;
|
||||||
|
end if;
|
||||||
|
|
||||||
|
stage1 := x;
|
||||||
|
if sa(0) = '1' then
|
||||||
|
stage1 := x(7 downto 0) & x(31 downto 8);
|
||||||
|
end if;
|
||||||
|
result := stage1;
|
||||||
|
if sa(1) = '1' then
|
||||||
|
result := stage1(15 downto 0) & stage1(31 downto 16);
|
||||||
|
end if;
|
||||||
|
|
||||||
|
return result;
|
||||||
|
end load_shift;
|
||||||
|
|
||||||
|
--------------------------------------------------------------------------
|
||||||
|
function load_be(va : unsigned(1 downto 0); align_left, bypass : std_logic) return unsigned is
|
||||||
|
variable result : unsigned(3 downto 0);
|
||||||
|
begin
|
||||||
|
if bypass = '1' then
|
||||||
|
result := (3 downto 0 => '1');
|
||||||
|
elsif align_left = '1' then
|
||||||
|
case va is
|
||||||
|
when "00" =>
|
||||||
|
result := "1000";
|
||||||
|
when "01" =>
|
||||||
|
result := "1100";
|
||||||
|
when "10" =>
|
||||||
|
result := "1110";
|
||||||
|
when "11" =>
|
||||||
|
result := "1111";
|
||||||
|
when others =>
|
||||||
|
result := "0000";
|
||||||
|
end case;
|
||||||
|
else
|
||||||
|
case va is
|
||||||
|
when "00" =>
|
||||||
|
result := "1111";
|
||||||
|
when "01" =>
|
||||||
|
result := "0111";
|
||||||
|
when "10" =>
|
||||||
|
result := "0011";
|
||||||
|
when "11" =>
|
||||||
|
result := "0001";
|
||||||
|
when others =>
|
||||||
|
result := "0000";
|
||||||
|
end case;
|
||||||
|
end if;
|
||||||
|
|
||||||
|
return result;
|
||||||
|
|
||||||
|
end load_be;
|
||||||
|
|
||||||
|
--------------------------------------------------------------------------
|
||||||
|
function load_sign_ext(x : word_t; bypass, signed, word2_en, word4_en : std_logic) return word_t is
|
||||||
|
variable result : word_t;
|
||||||
|
variable sign : std_logic;
|
||||||
|
|
||||||
|
begin
|
||||||
|
if bypass = '1' then
|
||||||
|
result := x;
|
||||||
|
elsif word2_en = '1' then
|
||||||
|
sign := signed and x(15);
|
||||||
|
result := (31 downto 16 => sign) & x(15 downto 0);
|
||||||
|
else
|
||||||
|
sign := signed and x(7);
|
||||||
|
result := (31 downto 8 => sign) & x(7 downto 0);
|
||||||
|
end if;
|
||||||
|
|
||||||
|
return result;
|
||||||
|
end load_sign_ext;
|
||||||
|
|
||||||
|
--------------------------------------------------------------------------
|
||||||
|
function events_clr return event_t is
|
||||||
|
variable result : event_t;
|
||||||
|
begin
|
||||||
|
result.Int := (others => '0');
|
||||||
|
result.data_load_err := '0';
|
||||||
|
result.data_store_err := '0';
|
||||||
|
result.inst_load_err := '0';
|
||||||
|
result.inst_priv_addr := '0';
|
||||||
|
result.alu_ovf := '0';
|
||||||
|
result.alu_uvf := '0';
|
||||||
|
result.syscall := '0';
|
||||||
|
result.break := '0';
|
||||||
|
result.illegal := '0';
|
||||||
|
|
||||||
|
return result;
|
||||||
|
|
||||||
|
end events_clr;
|
||||||
|
|
||||||
|
function event_is_active(e : event_t) return std_logic is
|
||||||
|
variable result : std_logic;
|
||||||
|
begin
|
||||||
|
result := '0';
|
||||||
|
|
||||||
|
for i in e.Int'range loop
|
||||||
|
result := result or e.Int(i);
|
||||||
|
end loop;
|
||||||
|
|
||||||
|
result := result or e.data_load_err;
|
||||||
|
result := result or e.data_store_err;
|
||||||
|
result := result or e.inst_load_err;
|
||||||
|
result := result or e.inst_priv_addr;
|
||||||
|
result := result or e.alu_ovf;
|
||||||
|
result := result or e.alu_uvf;
|
||||||
|
result := result or e.syscall;
|
||||||
|
result := result or e.break;
|
||||||
|
result := result or e.illegal;
|
||||||
|
|
||||||
|
return result;
|
||||||
|
|
||||||
|
end event_is_active;
|
||||||
|
|
||||||
|
function "or" (a, b : event_t) return event_t is
|
||||||
|
variable result : event_t;
|
||||||
|
begin
|
||||||
|
for i in a.Int'range loop
|
||||||
|
result.Int(i) := a.Int(i) or b.Int(i);
|
||||||
|
end loop;
|
||||||
|
result.data_load_err := a.data_load_err or b.data_load_err;
|
||||||
|
result.data_store_err := a.data_store_err or b.data_store_err;
|
||||||
|
result.inst_load_err := a.inst_load_err or b.inst_load_err;
|
||||||
|
result.inst_priv_addr := a.inst_priv_addr or b.inst_priv_addr;
|
||||||
|
result.alu_ovf := a.alu_ovf or b.alu_ovf;
|
||||||
|
result.alu_uvf := a.alu_uvf or b.alu_uvf;
|
||||||
|
result.syscall := a.syscall or b.syscall;
|
||||||
|
result.break := a.break or b.break;
|
||||||
|
result.illegal := a.illegal or b.illegal;
|
||||||
|
|
||||||
|
return result;
|
||||||
|
|
||||||
|
end "or";
|
||||||
|
|
||||||
|
--------------------------------------------------------------------------
|
||||||
|
end mips_types;
|
||||||
|
|
||||||
|
--------------------------------------------------------------------------
|
||||||
|
--------------------------------------------------------------------------
|
||||||
File diff suppressed because it is too large
Load Diff
@@ -0,0 +1,320 @@
|
|||||||
|
-------------------------------------------------------------------------
|
||||||
|
-- Project: JIPS, a portable 32-bit RISC CPU written in VHDL
|
||||||
|
-- This file: The ROM file for use in your VHDL design
|
||||||
|
--
|
||||||
|
-- Copyright (C) 2008 J. Ahrensfeld
|
||||||
|
--
|
||||||
|
-- This program is free software: you can redistribute it and/or modify
|
||||||
|
-- it under the terms of the GNU General Public License as published by
|
||||||
|
-- the Free Software Foundation, either version 3 of the License, or
|
||||||
|
-- (at your option) any later version.
|
||||||
|
--
|
||||||
|
-- This program 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 General Public License for more details.
|
||||||
|
--
|
||||||
|
-- You should have received a copy of the GNU General Public License
|
||||||
|
-- along with this program. If not, see <http://www.gnu.org/licenses/>.
|
||||||
|
--
|
||||||
|
-- For questions and ideas, please contact the author at jens@jayfield.org
|
||||||
|
--
|
||||||
|
--------------------------------------------------------------------------
|
||||||
|
|
||||||
|
LIBRARY ieee;
|
||||||
|
use IEEE.STD_LOGIC_1164.ALL;
|
||||||
|
USE ieee.numeric_std.ALL;
|
||||||
|
|
||||||
|
|
||||||
|
ENTITY rom IS
|
||||||
|
Generic
|
||||||
|
(
|
||||||
|
addr_width : integer := 2;
|
||||||
|
data_width : integer := 32
|
||||||
|
);
|
||||||
|
Port
|
||||||
|
(
|
||||||
|
clk : in STD_LOGIC;
|
||||||
|
addr : in unsigned(addr_width-1 downto 0);
|
||||||
|
dout : out unsigned(data_width-1 downto 0)
|
||||||
|
);
|
||||||
|
END rom;
|
||||||
|
|
||||||
|
ARCHITECTURE itest OF rom IS
|
||||||
|
|
||||||
|
subtype word_t is unsigned(data_width-1 downto 0);
|
||||||
|
type word_array_t is array (0 to 2**addr_width-1) of word_t;
|
||||||
|
|
||||||
|
-- Assembled from itest.jsm
|
||||||
|
constant word_array : word_array_t :=
|
||||||
|
(
|
||||||
|
X"3C1D7FFF", -- 00000000
|
||||||
|
X"0C100014", -- 00000004
|
||||||
|
X"37BDEFFC", -- 00000008
|
||||||
|
X"24080002", -- 0000000C
|
||||||
|
X"0107102A", -- 00000010
|
||||||
|
X"ACC40000", -- 00000014
|
||||||
|
X"1040000B", -- 00000018
|
||||||
|
X"ACC50004", -- 0000001C
|
||||||
|
X"24C60008", -- 00000020
|
||||||
|
X"24E8FFFE", -- 00000024
|
||||||
|
X"8CC2FFF8", -- 00000028
|
||||||
|
X"8CC3FFFC", -- 0000002C
|
||||||
|
X"2508FFFF", -- 00000030
|
||||||
|
X"00431021", -- 00000034
|
||||||
|
X"ACC20000", -- 00000038
|
||||||
|
X"1500FFFA", -- 0000003C
|
||||||
|
X"24C60004", -- 00000040
|
||||||
|
X"00E04021", -- 00000044
|
||||||
|
X"03E00008", -- 00000048
|
||||||
|
X"01001021", -- 0000004C
|
||||||
|
X"27BDFF78", -- 00000050
|
||||||
|
X"3C021003", -- 00000054
|
||||||
|
X"3C030001", -- 00000058
|
||||||
|
X"AFB60078", -- 0000005C
|
||||||
|
X"3456FFFC", -- 00000060
|
||||||
|
X"3C02AAAA", -- 00000064
|
||||||
|
X"AFB7007C", -- 00000068
|
||||||
|
X"AFB50074", -- 0000006C
|
||||||
|
X"AFB40070", -- 00000070
|
||||||
|
X"AFB20068", -- 00000074
|
||||||
|
X"AFB00060", -- 00000078
|
||||||
|
X"AFBF0080", -- 0000007C
|
||||||
|
X"AFB3006C", -- 00000080
|
||||||
|
X"AFB10064", -- 00000084
|
||||||
|
X"AEC00000", -- 00000088
|
||||||
|
X"3450AAAA", -- 0000008C
|
||||||
|
X"347786A0", -- 00000090
|
||||||
|
X"27B20010", -- 00000094
|
||||||
|
X"24150014", -- 00000098
|
||||||
|
X"3474869F", -- 0000009C
|
||||||
|
X"00009821", -- 000000A0
|
||||||
|
X"00002021", -- 000000A4
|
||||||
|
X"02401021", -- 000000A8
|
||||||
|
X"24060013", -- 000000AC
|
||||||
|
X"24C6FFFF", -- 000000B0
|
||||||
|
X"AC500000", -- 000000B4
|
||||||
|
X"04C1FFFD", -- 000000B8
|
||||||
|
X"24420004", -- 000000BC
|
||||||
|
X"02041026", -- 000000C0
|
||||||
|
X"24910001", -- 000000C4
|
||||||
|
X"24420001", -- 000000C8
|
||||||
|
X"02202821", -- 000000CC
|
||||||
|
X"27A60010", -- 000000D0
|
||||||
|
X"24070014", -- 000000D4
|
||||||
|
X"0C100003", -- 000000D8
|
||||||
|
X"00028040", -- 000000DC
|
||||||
|
X"24070002", -- 000000E0
|
||||||
|
X"26450008", -- 000000E4
|
||||||
|
X"0810003E", -- 000000E8
|
||||||
|
X"24060011", -- 000000EC
|
||||||
|
X"04C0000A", -- 000000F0
|
||||||
|
X"00000000", -- 000000F4
|
||||||
|
X"8CA20000", -- 000000F8
|
||||||
|
X"8CA3FFFC", -- 000000FC
|
||||||
|
X"8CA4FFF8", -- 00000100
|
||||||
|
X"00431023", -- 00000104
|
||||||
|
X"24C6FFFF", -- 00000108
|
||||||
|
X"1482FFF8", -- 0000010C
|
||||||
|
X"24A50004", -- 00000110
|
||||||
|
X"04C1FFF8", -- 00000114
|
||||||
|
X"24E70001", -- 00000118
|
||||||
|
X"10F5000C", -- 0000011C
|
||||||
|
X"00000000", -- 00000120
|
||||||
|
X"0291102A", -- 00000124
|
||||||
|
X"1040FFDF", -- 00000128
|
||||||
|
X"02202021", -- 0000012C
|
||||||
|
X"1677FFDB", -- 00000130
|
||||||
|
X"00009821", -- 00000134
|
||||||
|
X"8EC20000", -- 00000138
|
||||||
|
X"00000000", -- 0000013C
|
||||||
|
X"24420001", -- 00000140
|
||||||
|
X"AEC20000", -- 00000144
|
||||||
|
X"0810002A", -- 00000148
|
||||||
|
X"00002021", -- 0000014C
|
||||||
|
X"08100049", -- 00000150
|
||||||
|
X"26730001", -- 00000154
|
||||||
|
X"00000000", -- 00000158
|
||||||
|
X"00000000", -- 0000015C
|
||||||
|
X"00000000", -- 00000160
|
||||||
|
X"00000000", -- 00000164
|
||||||
|
X"00000000", -- 00000168
|
||||||
|
X"00000000", -- 0000016C
|
||||||
|
X"00000000", -- 00000170
|
||||||
|
X"00000000", -- 00000174
|
||||||
|
X"00000000", -- 00000178
|
||||||
|
X"00000000", -- 0000017C
|
||||||
|
X"00000000", -- 00000180
|
||||||
|
X"00000000", -- 00000184
|
||||||
|
X"00000000", -- 00000188
|
||||||
|
X"00000000", -- 0000018C
|
||||||
|
X"00000000", -- 00000190
|
||||||
|
X"00000000", -- 00000194
|
||||||
|
X"00000000", -- 00000198
|
||||||
|
X"00000000", -- 0000019C
|
||||||
|
X"00000000", -- 000001A0
|
||||||
|
X"00000000", -- 000001A4
|
||||||
|
X"00000000", -- 000001A8
|
||||||
|
X"00000000", -- 000001AC
|
||||||
|
X"00000000", -- 000001B0
|
||||||
|
X"00000000", -- 000001B4
|
||||||
|
X"00000000", -- 000001B8
|
||||||
|
X"00000000", -- 000001BC
|
||||||
|
X"00000000", -- 000001C0
|
||||||
|
X"00000000", -- 000001C4
|
||||||
|
X"00000000", -- 000001C8
|
||||||
|
X"00000000", -- 000001CC
|
||||||
|
X"00000000", -- 000001D0
|
||||||
|
X"00000000", -- 000001D4
|
||||||
|
X"00000000", -- 000001D8
|
||||||
|
X"00000000", -- 000001DC
|
||||||
|
X"00000000", -- 000001E0
|
||||||
|
X"00000000", -- 000001E4
|
||||||
|
X"00000000", -- 000001E8
|
||||||
|
X"00000000", -- 000001EC
|
||||||
|
X"00000000", -- 000001F0
|
||||||
|
X"00000000", -- 000001F4
|
||||||
|
X"00000000", -- 000001F8
|
||||||
|
X"00000000", -- 000001FC
|
||||||
|
X"00000000", -- 00000200
|
||||||
|
X"00000000", -- 00000204
|
||||||
|
X"00000000", -- 00000208
|
||||||
|
X"00000000", -- 0000020C
|
||||||
|
X"00000000", -- 00000210
|
||||||
|
X"00000000", -- 00000214
|
||||||
|
X"00000000", -- 00000218
|
||||||
|
X"00000000", -- 0000021C
|
||||||
|
X"00000000", -- 00000220
|
||||||
|
X"00000000", -- 00000224
|
||||||
|
X"00000000", -- 00000228
|
||||||
|
X"00000000", -- 0000022C
|
||||||
|
X"00000000", -- 00000230
|
||||||
|
X"00000000", -- 00000234
|
||||||
|
X"00000000", -- 00000238
|
||||||
|
X"00000000", -- 0000023C
|
||||||
|
X"00000000", -- 00000240
|
||||||
|
X"00000000", -- 00000244
|
||||||
|
X"00000000", -- 00000248
|
||||||
|
X"00000000", -- 0000024C
|
||||||
|
X"00000000", -- 00000250
|
||||||
|
X"00000000", -- 00000254
|
||||||
|
X"00000000", -- 00000258
|
||||||
|
X"00000000", -- 0000025C
|
||||||
|
X"00000000", -- 00000260
|
||||||
|
X"00000000", -- 00000264
|
||||||
|
X"00000000", -- 00000268
|
||||||
|
X"00000000", -- 0000026C
|
||||||
|
X"00000000", -- 00000270
|
||||||
|
X"00000000", -- 00000274
|
||||||
|
X"00000000", -- 00000278
|
||||||
|
X"00000000", -- 0000027C
|
||||||
|
X"00000000", -- 00000280
|
||||||
|
X"00000000", -- 00000284
|
||||||
|
X"00000000", -- 00000288
|
||||||
|
X"00000000", -- 0000028C
|
||||||
|
X"00000000", -- 00000290
|
||||||
|
X"00000000", -- 00000294
|
||||||
|
X"00000000", -- 00000298
|
||||||
|
X"00000000", -- 0000029C
|
||||||
|
X"00000000", -- 000002A0
|
||||||
|
X"00000000", -- 000002A4
|
||||||
|
X"00000000", -- 000002A8
|
||||||
|
X"00000000", -- 000002AC
|
||||||
|
X"00000000", -- 000002B0
|
||||||
|
X"00000000", -- 000002B4
|
||||||
|
X"00000000", -- 000002B8
|
||||||
|
X"00000000", -- 000002BC
|
||||||
|
X"00000000", -- 000002C0
|
||||||
|
X"00000000", -- 000002C4
|
||||||
|
X"00000000", -- 000002C8
|
||||||
|
X"00000000", -- 000002CC
|
||||||
|
X"00000000", -- 000002D0
|
||||||
|
X"00000000", -- 000002D4
|
||||||
|
X"00000000", -- 000002D8
|
||||||
|
X"00000000", -- 000002DC
|
||||||
|
X"00000000", -- 000002E0
|
||||||
|
X"00000000", -- 000002E4
|
||||||
|
X"00000000", -- 000002E8
|
||||||
|
X"00000000", -- 000002EC
|
||||||
|
X"00000000", -- 000002F0
|
||||||
|
X"00000000", -- 000002F4
|
||||||
|
X"00000000", -- 000002F8
|
||||||
|
X"00000000", -- 000002FC
|
||||||
|
X"00000000", -- 00000300
|
||||||
|
X"00000000", -- 00000304
|
||||||
|
X"00000000", -- 00000308
|
||||||
|
X"00000000", -- 0000030C
|
||||||
|
X"00000000", -- 00000310
|
||||||
|
X"00000000", -- 00000314
|
||||||
|
X"00000000", -- 00000318
|
||||||
|
X"00000000", -- 0000031C
|
||||||
|
X"00000000", -- 00000320
|
||||||
|
X"00000000", -- 00000324
|
||||||
|
X"00000000", -- 00000328
|
||||||
|
X"00000000", -- 0000032C
|
||||||
|
X"00000000", -- 00000330
|
||||||
|
X"00000000", -- 00000334
|
||||||
|
X"00000000", -- 00000338
|
||||||
|
X"00000000", -- 0000033C
|
||||||
|
X"00000000", -- 00000340
|
||||||
|
X"00000000", -- 00000344
|
||||||
|
X"00000000", -- 00000348
|
||||||
|
X"00000000", -- 0000034C
|
||||||
|
X"00000000", -- 00000350
|
||||||
|
X"00000000", -- 00000354
|
||||||
|
X"00000000", -- 00000358
|
||||||
|
X"00000000", -- 0000035C
|
||||||
|
X"00000000", -- 00000360
|
||||||
|
X"00000000", -- 00000364
|
||||||
|
X"00000000", -- 00000368
|
||||||
|
X"00000000", -- 0000036C
|
||||||
|
X"00000000", -- 00000370
|
||||||
|
X"00000000", -- 00000374
|
||||||
|
X"00000000", -- 00000378
|
||||||
|
X"00000000", -- 0000037C
|
||||||
|
X"00000000", -- 00000380
|
||||||
|
X"00000000", -- 00000384
|
||||||
|
X"00000000", -- 00000388
|
||||||
|
X"00000000", -- 0000038C
|
||||||
|
X"00000000", -- 00000390
|
||||||
|
X"00000000", -- 00000394
|
||||||
|
X"00000000", -- 00000398
|
||||||
|
X"00000000", -- 0000039C
|
||||||
|
X"00000000", -- 000003A0
|
||||||
|
X"00000000", -- 000003A4
|
||||||
|
X"00000000", -- 000003A8
|
||||||
|
X"00000000", -- 000003AC
|
||||||
|
X"00000000", -- 000003B0
|
||||||
|
X"00000000", -- 000003B4
|
||||||
|
X"00000000", -- 000003B8
|
||||||
|
X"00000000", -- 000003BC
|
||||||
|
X"00000000", -- 000003C0
|
||||||
|
X"00000000", -- 000003C4
|
||||||
|
X"00000000", -- 000003C8
|
||||||
|
X"00000000", -- 000003CC
|
||||||
|
X"00000000", -- 000003D0
|
||||||
|
X"00000000", -- 000003D4
|
||||||
|
X"00000000", -- 000003D8
|
||||||
|
X"00000000", -- 000003DC
|
||||||
|
X"00000000", -- 000003E0
|
||||||
|
X"00000000", -- 000003E4
|
||||||
|
X"00000000", -- 000003E8
|
||||||
|
X"00000000", -- 000003EC
|
||||||
|
X"00000000", -- 000003F0
|
||||||
|
X"00000000", -- 000003F4
|
||||||
|
X"00000000", -- 000003F8
|
||||||
|
X"00000000" -- 000003FC
|
||||||
|
);
|
||||||
|
|
||||||
|
begin
|
||||||
|
|
||||||
|
PROM_READ:
|
||||||
|
process(clk)
|
||||||
|
begin
|
||||||
|
if rising_edge(clk) then
|
||||||
|
dout <= word_array(to_integer(addr));
|
||||||
|
end if;
|
||||||
|
end process;
|
||||||
|
|
||||||
|
|
||||||
|
end itest;
|
||||||
@@ -0,0 +1,121 @@
|
|||||||
|
-------------------------------------------------------------------------
|
||||||
|
-- Project: JCPU, a portable 8-bit RISC CPU written in VHDL
|
||||||
|
-- This file: The ROM file for use in your VHDL design
|
||||||
|
--
|
||||||
|
-- Copyright (C) 2007 J. Ahrensfeld
|
||||||
|
--
|
||||||
|
-- This program is free software: you can redistribute it and/or modify
|
||||||
|
-- it under the terms of the GNU General Public License as published by
|
||||||
|
-- the Free Software Foundation, either version 3 of the License, or
|
||||||
|
-- (at your option) any later version.
|
||||||
|
--
|
||||||
|
-- This program 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 General Public License for more details.
|
||||||
|
--
|
||||||
|
-- You should have received a copy of the GNU General Public License
|
||||||
|
-- along with this program. If not, see <http://www.gnu.org/licenses/>.
|
||||||
|
--
|
||||||
|
-- For questions and ideas, please contact the author at jens@jayfield.org
|
||||||
|
--
|
||||||
|
--------------------------------------------------------------------------
|
||||||
|
|
||||||
|
LIBRARY ieee;
|
||||||
|
use IEEE.STD_LOGIC_1164.ALL;
|
||||||
|
USE ieee.numeric_std.ALL;
|
||||||
|
|
||||||
|
|
||||||
|
ENTITY rom IS
|
||||||
|
Generic
|
||||||
|
(
|
||||||
|
addr_width : integer := 2;
|
||||||
|
data_width : integer := 32
|
||||||
|
);
|
||||||
|
Port
|
||||||
|
(
|
||||||
|
addr : in unsigned(addr_width-1 downto 0);
|
||||||
|
dout : out unsigned(data_width-1 downto 0)
|
||||||
|
);
|
||||||
|
END rom;
|
||||||
|
|
||||||
|
ARCHITECTURE itest OF rom IS
|
||||||
|
|
||||||
|
subtype word_t is unsigned(data_width-1 downto 0);
|
||||||
|
type word_array_t is array (0 to 2**addr_width-1) of word_t;
|
||||||
|
|
||||||
|
-- Assembled from itest.jsm
|
||||||
|
constant word_array : word_array_t :=
|
||||||
|
(
|
||||||
|
X"08100001", -- [0x00400000] j 0x00400004 [main]
|
||||||
|
X"3c011234", -- [0x00400004] lui $1, 4660
|
||||||
|
X"34215678", -- [0x00400008] ori $1, $1, 22136
|
||||||
|
X"3021f00f", -- [0x0040000c] andi $1, $1, -4081
|
||||||
|
X"2021affc", -- [0x00400010] addi $1, $1, -20484
|
||||||
|
X"2021ffff", -- [0x00400014] addi $1, $1, -1
|
||||||
|
X"1c20fffe", -- [0x00400018] bgtz $1 -8 [loop-0x00400018]
|
||||||
|
X"3c020000", -- [0x0040001c] lui $2, 0
|
||||||
|
X"34420001", -- [0x00400020] ori $2, $2, 1
|
||||||
|
X"3c010000", -- [0x00400024] lui $1, 0
|
||||||
|
X"34210004", -- [0x00400028] ori $1, $1, 4
|
||||||
|
X"00220822", -- [0x0040002c] sub $1, $1, $2
|
||||||
|
X"1c20fffe", -- [0x00400030] bgtz $1 -8 [loop2-0x00400030]
|
||||||
|
X"3c1f0040", -- [0x00400034] lui $31, 64
|
||||||
|
X"03e00008", -- [0x00400038] jr $31
|
||||||
|
X"00000000", -- [0x0040003c] nop
|
||||||
|
X"00000000", -- [0x00400040] nop
|
||||||
|
X"00000000", -- [0x00400044] nop
|
||||||
|
X"00000000", -- [0x00400048] nop
|
||||||
|
X"00000000", -- [0x0040004c] nop
|
||||||
|
X"00000000", -- [0x00400050] nop
|
||||||
|
X"00000000", -- [0x00400054] nop
|
||||||
|
X"00000000", -- [0x00400058] nop
|
||||||
|
X"00000000", -- [0x0040005c] nop
|
||||||
|
X"00000000", -- [0x00400060] nop
|
||||||
|
X"00000000", -- [0x00400064] nop
|
||||||
|
X"00000000", -- [0x00400068] nop
|
||||||
|
X"00000000", -- [0x0040006c] nop
|
||||||
|
X"00000000", -- [0x00400070] nop
|
||||||
|
X"00000000", -- [0x00400074] nop
|
||||||
|
X"00000000", -- [0x00400078] nop
|
||||||
|
X"00000000", -- [0x0040007c] nop
|
||||||
|
X"00000000", -- [0x00400080] nop
|
||||||
|
X"00000000", -- [0x00400084] nop
|
||||||
|
X"00000000", -- [0x00400088] nop
|
||||||
|
X"00000000", -- [0x0040008c] nop
|
||||||
|
X"00000000", -- [0x00400090] nop
|
||||||
|
X"00000000", -- [0x00400094] nop
|
||||||
|
X"00000000", -- [0x00400098] nop
|
||||||
|
X"00000000", -- [0x0040009c] nop
|
||||||
|
X"00000000", -- [0x004000a0] nop
|
||||||
|
X"00000000", -- [0x004000a4] nop
|
||||||
|
X"00000000", -- [0x004000a8] nop
|
||||||
|
X"00000000", -- [0x004000ac] nop
|
||||||
|
X"00000000", -- [0x004000b0] nop
|
||||||
|
X"00000000", -- [0x004000b4] nop
|
||||||
|
X"00000000", -- [0x004000b8] nop
|
||||||
|
X"00000000", -- [0x004000bc] nop
|
||||||
|
X"00000000", -- [0x004000c0] nop
|
||||||
|
X"00000000", -- [0x004000c4] nop
|
||||||
|
X"00000000", -- [0x004000c8] nop
|
||||||
|
X"00000000", -- [0x004000cc] nop
|
||||||
|
X"00000000", -- [0x004000d0] nop
|
||||||
|
X"00000000", -- [0x004000d4] nop
|
||||||
|
X"00000000", -- [0x004000d8] nop
|
||||||
|
X"00000000", -- [0x004000dc] nop
|
||||||
|
X"00000000", -- [0x004000e0] nop
|
||||||
|
X"00000000", -- [0x004000e4] nop
|
||||||
|
X"00000000", -- [0x004000e8] nop
|
||||||
|
X"00000000", -- [0x004000ec] nop
|
||||||
|
X"00000000", -- [0x004000f0] nop
|
||||||
|
X"00000000", -- [0x004000f4] nop
|
||||||
|
X"00000000", -- [0x004000f8] nop
|
||||||
|
X"00000000" -- [0x004000fc] nop
|
||||||
|
);
|
||||||
|
|
||||||
|
begin
|
||||||
|
|
||||||
|
PROM_READ:
|
||||||
|
dout <= word_array(to_integer(addr));
|
||||||
|
|
||||||
|
end itest;
|
||||||
@@ -0,0 +1,73 @@
|
|||||||
|
-------------------------------------------------------------------------
|
||||||
|
-- Project: JCPU, a portable 8-bit RISC CPU written in VHDL
|
||||||
|
-- This file: The ROM file for use in your VHDL design
|
||||||
|
--
|
||||||
|
-- Copyright (C) 2007 J. Ahrensfeld
|
||||||
|
--
|
||||||
|
-- This program is free software: you can redistribute it and/or modify
|
||||||
|
-- it under the terms of the GNU General Public License as published by
|
||||||
|
-- the Free Software Foundation, either version 3 of the License, or
|
||||||
|
-- (at your option) any later version.
|
||||||
|
--
|
||||||
|
-- This program 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 General Public License for more details.
|
||||||
|
--
|
||||||
|
-- You should have received a copy of the GNU General Public License
|
||||||
|
-- along with this program. If not, see <http://www.gnu.org/licenses/>.
|
||||||
|
--
|
||||||
|
-- For questions and ideas, please contact the author at jens@jayfield.org
|
||||||
|
--
|
||||||
|
--------------------------------------------------------------------------
|
||||||
|
|
||||||
|
LIBRARY ieee;
|
||||||
|
use IEEE.STD_LOGIC_1164.ALL;
|
||||||
|
USE ieee.numeric_std.ALL;
|
||||||
|
|
||||||
|
|
||||||
|
ENTITY rom IS
|
||||||
|
Generic
|
||||||
|
(
|
||||||
|
addr_width : integer := 2;
|
||||||
|
data_width : integer := 32
|
||||||
|
);
|
||||||
|
Port
|
||||||
|
(
|
||||||
|
addr : in unsigned(addr_width-1 downto 0);
|
||||||
|
dout : out unsigned(data_width-1 downto 0)
|
||||||
|
);
|
||||||
|
END rom;
|
||||||
|
|
||||||
|
ARCHITECTURE itest OF rom IS
|
||||||
|
|
||||||
|
subtype word_t is unsigned(data_width-1 downto 0);
|
||||||
|
type word_array_t is array (0 to 2**addr_width-1) of word_t;
|
||||||
|
|
||||||
|
-- Assembled from itest.jsm
|
||||||
|
constant word_array : word_array_t :=
|
||||||
|
(
|
||||||
|
X"08100001", -- j 0x00400004 [main] ; 5: j main
|
||||||
|
X"3c011234", -- lui $1, 4660 ; 7: lui $1, 0x1234
|
||||||
|
X"34215678", -- ori $1, $1, 22136 ; 8: ori $1, $1, 0x5678
|
||||||
|
X"3c035555", -- lui $3, 21845 ; 9: lui $3, 0x5555
|
||||||
|
X"3463aaaa", -- ori $3, $3, -21846 ; 10: ori $3, $3, 0xAAAA
|
||||||
|
X"3c021000", -- lui $2, 4096 ; 11: lui $2, 0x1000
|
||||||
|
X"ac410000", -- sw $1, 0($2) ; 12: sw $1, 0($2)
|
||||||
|
X"ac430004", -- sw $3, 4($2) ; 13: sw $3, 4($2)
|
||||||
|
X"00000000", -- nop ; 14: sll $0, $0, 0
|
||||||
|
X"ac400000", -- sw $0, 0($2) ; 15: sw $0, 0($2)
|
||||||
|
X"ac400004", -- sw $0, 4($2) ; 16: sw $0, 4($2)
|
||||||
|
X"8c410000", -- lw $1, 0($2) ; 17: lw $1, 0($2)
|
||||||
|
X"8c430004", -- lw $3, 4($2) ; 18: lw $3, 4($2)
|
||||||
|
X"00000000", -- nop ; 19: sll $0, $0, 0
|
||||||
|
X"00000000", -- nop ; 20: sll $0, $0, 0
|
||||||
|
X"08100001" -- j 0x00400004 [main] ; 21: j main
|
||||||
|
);
|
||||||
|
|
||||||
|
begin
|
||||||
|
|
||||||
|
PROM_READ:
|
||||||
|
dout <= word_array(to_integer(addr));
|
||||||
|
|
||||||
|
end itest;
|
||||||
@@ -0,0 +1,122 @@
|
|||||||
|
-------------------------------------------------------------------------
|
||||||
|
-- Project: JCPU, a portable 8-bit RISC CPU written in VHDL
|
||||||
|
-- This file: The ROM file for use in your VHDL design
|
||||||
|
--
|
||||||
|
-- Copyright (C) 2007 J. Ahrensfeld
|
||||||
|
--
|
||||||
|
-- This program is free software: you can redistribute it and/or modify
|
||||||
|
-- it under the terms of the GNU General Public License as published by
|
||||||
|
-- the Free Software Foundation, either version 3 of the License, or
|
||||||
|
-- (at your option) any later version.
|
||||||
|
--
|
||||||
|
-- This program 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 General Public License for more details.
|
||||||
|
--
|
||||||
|
-- You should have received a copy of the GNU General Public License
|
||||||
|
-- along with this program. If not, see <http://www.gnu.org/licenses/>.
|
||||||
|
--
|
||||||
|
-- For questions and ideas, please contact the author at jens@jayfield.org
|
||||||
|
--
|
||||||
|
--------------------------------------------------------------------------
|
||||||
|
|
||||||
|
LIBRARY ieee;
|
||||||
|
use IEEE.STD_LOGIC_1164.ALL;
|
||||||
|
USE ieee.numeric_std.ALL;
|
||||||
|
|
||||||
|
|
||||||
|
ENTITY rom IS
|
||||||
|
Generic
|
||||||
|
(
|
||||||
|
addr_width : integer := 2;
|
||||||
|
data_width : integer := 32
|
||||||
|
);
|
||||||
|
Port
|
||||||
|
(
|
||||||
|
addr : in unsigned(addr_width-1 downto 0);
|
||||||
|
dout : out unsigned(data_width-1 downto 0)
|
||||||
|
);
|
||||||
|
END rom;
|
||||||
|
|
||||||
|
ARCHITECTURE itest OF rom IS
|
||||||
|
|
||||||
|
subtype word_t is unsigned(data_width-1 downto 0);
|
||||||
|
type word_array_t is array (0 to 2**addr_width-1) of word_t;
|
||||||
|
|
||||||
|
-- Assembled from itest.jsm
|
||||||
|
constant word_array : word_array_t :=
|
||||||
|
(
|
||||||
|
|
||||||
|
X"08100001", -- [0x00400000] j 0x00400004 [main]
|
||||||
|
X"3c011234", -- [0x00400004] lui $1, 4660
|
||||||
|
X"34215a5a", -- [0x00400008] ori $1, $1, 23130
|
||||||
|
X"00010840", -- [0x0040000c] sll $1, $1, 1
|
||||||
|
X"00010900", -- [0x00400010] sll $1, $1, 4
|
||||||
|
X"00010880", -- [0x00400014] sll $1, $1, 2
|
||||||
|
X"00010840", -- [0x00400018] sll $1, $1, 1
|
||||||
|
X"00010a00", -- [0x0040001c] sll $1, $1, 8
|
||||||
|
X"00010882", -- [0x00400020] srl $1, $1, 2
|
||||||
|
X"00010942", -- [0x00400024] srl $1, $1, 5
|
||||||
|
X"00010842", -- [0x00400028] srl $1, $1, 1
|
||||||
|
X"00010a02", -- [0x0040002c] srl $1, $1, 8
|
||||||
|
X"3821ffff", -- [0x00400030] xori $1, $1, -1
|
||||||
|
X"3c1f0040", -- [0x00400034] lui $31, 64
|
||||||
|
X"03e00008", -- [0x00400038] jr $31
|
||||||
|
X"003f0826", -- [0x0040003c] xor $1, $1, $31
|
||||||
|
X"00000000", -- [0x00400040] nop
|
||||||
|
X"00000000", -- [0x00400044] nop
|
||||||
|
X"00000000", -- [0x00400048] nop
|
||||||
|
X"00000000", -- [0x0040004c] nop
|
||||||
|
X"00000000", -- [0x00400050] nop
|
||||||
|
X"00000000", -- [0x00400054] nop
|
||||||
|
X"00000000", -- [0x00400058] nop
|
||||||
|
X"00000000", -- [0x0040005c] nop
|
||||||
|
X"00000000", -- [0x00400060] nop
|
||||||
|
X"00000000", -- [0x00400064] nop
|
||||||
|
X"00000000", -- [0x00400068] nop
|
||||||
|
X"00000000", -- [0x0040006c] nop
|
||||||
|
X"00000000", -- [0x00400070] nop
|
||||||
|
X"00000000", -- [0x00400074] nop
|
||||||
|
X"00000000", -- [0x00400078] nop
|
||||||
|
X"00000000", -- [0x0040007c] nop
|
||||||
|
X"00000000", -- [0x00400080] nop
|
||||||
|
X"00000000", -- [0x00400084] nop
|
||||||
|
X"00000000", -- [0x00400088] nop
|
||||||
|
X"00000000", -- [0x0040008c] nop
|
||||||
|
X"00000000", -- [0x00400090] nop
|
||||||
|
X"00000000", -- [0x00400094] nop
|
||||||
|
X"00000000", -- [0x00400098] nop
|
||||||
|
X"00000000", -- [0x0040009c] nop
|
||||||
|
X"00000000", -- [0x004000a0] nop
|
||||||
|
X"00000000", -- [0x004000a4] nop
|
||||||
|
X"00000000", -- [0x004000a8] nop
|
||||||
|
X"00000000", -- [0x004000ac] nop
|
||||||
|
X"00000000", -- [0x004000b0] nop
|
||||||
|
X"00000000", -- [0x004000b4] nop
|
||||||
|
X"00000000", -- [0x004000b8]
|
||||||
|
X"00000000", -- [0x004000bc]
|
||||||
|
X"00000000", -- [0x004000c0]
|
||||||
|
X"00000000", -- [0x004000c4]
|
||||||
|
X"00000000", -- [0x004000c8]
|
||||||
|
X"00000000", -- [0x004000cc]
|
||||||
|
X"00000000", -- [0x004000d0]
|
||||||
|
X"00000000", -- [0x004000d4]
|
||||||
|
X"00000000", -- [0x004000d8]
|
||||||
|
X"00000000", -- [0x004000dc]
|
||||||
|
X"00000000", -- [0x004000e0]
|
||||||
|
X"00000000", -- [0x004000e4]
|
||||||
|
X"00000000", -- [0x004000e8]
|
||||||
|
X"00000000", -- [0x004000ec]
|
||||||
|
X"00000000", -- [0x004000f0]
|
||||||
|
X"00000000", -- [0x004000f4]
|
||||||
|
X"00000000", -- [0x004000f8]
|
||||||
|
X"00000000" -- [0x004000fc]
|
||||||
|
);
|
||||||
|
|
||||||
|
begin
|
||||||
|
|
||||||
|
PROM_READ:
|
||||||
|
dout <= word_array(to_integer(addr));
|
||||||
|
|
||||||
|
end itest;
|
||||||
@@ -0,0 +1,122 @@
|
|||||||
|
-------------------------------------------------------------------------
|
||||||
|
-- Project: JCPU, a portable 8-bit RISC CPU written in VHDL
|
||||||
|
-- This file: The ROM file for use in your VHDL design
|
||||||
|
--
|
||||||
|
-- Copyright (C) 2007 J. Ahrensfeld
|
||||||
|
--
|
||||||
|
-- This program is free software: you can redistribute it and/or modify
|
||||||
|
-- it under the terms of the GNU General Public License as published by
|
||||||
|
-- the Free Software Foundation, either version 3 of the License, or
|
||||||
|
-- (at your option) any later version.
|
||||||
|
--
|
||||||
|
-- This program 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 General Public License for more details.
|
||||||
|
--
|
||||||
|
-- You should have received a copy of the GNU General Public License
|
||||||
|
-- along with this program. If not, see <http://www.gnu.org/licenses/>.
|
||||||
|
--
|
||||||
|
-- For questions and ideas, please contact the author at jens@jayfield.org
|
||||||
|
--
|
||||||
|
--------------------------------------------------------------------------
|
||||||
|
|
||||||
|
LIBRARY ieee;
|
||||||
|
use IEEE.STD_LOGIC_1164.ALL;
|
||||||
|
USE ieee.numeric_std.ALL;
|
||||||
|
|
||||||
|
|
||||||
|
ENTITY rom IS
|
||||||
|
Generic
|
||||||
|
(
|
||||||
|
addr_width : integer := 2;
|
||||||
|
data_width : integer := 32
|
||||||
|
);
|
||||||
|
Port
|
||||||
|
(
|
||||||
|
addr : in unsigned(addr_width-1 downto 0);
|
||||||
|
dout : out unsigned(data_width-1 downto 0)
|
||||||
|
);
|
||||||
|
END rom;
|
||||||
|
|
||||||
|
ARCHITECTURE itest OF rom IS
|
||||||
|
|
||||||
|
subtype word_t is unsigned(data_width-1 downto 0);
|
||||||
|
type word_array_t is array (0 to 2**addr_width-1) of word_t;
|
||||||
|
|
||||||
|
-- Assembled from itest.jsm
|
||||||
|
constant word_array : word_array_t :=
|
||||||
|
(
|
||||||
|
|
||||||
|
X"08100001", -- [0x00400000] j 0x00400004 [main] ; 5: j main
|
||||||
|
X"00000000", -- [0x00400004] nop ; 7: sll $0, $0, 0
|
||||||
|
X"3c011000", -- [0x00400008] lui $1, 4096 ; 8: lui $1, 0x1000
|
||||||
|
X"20220000", -- [0x0040000c] addi $2, $1, 0 ; 9: addi $2, $1, 0
|
||||||
|
X"3c071234", -- [0x00400010] lui $7, 4660 ; 10: lui $7, 0x1234
|
||||||
|
X"3c050001", -- [0x00400014] lui $5, 1 ; 11: lui $5, 0x0001
|
||||||
|
X"ac270000", -- [0x00400018] sw $7, 0($1) ; 12: sw $7, 0($1)
|
||||||
|
X"8c430000", -- [0x0040001c] lw $3, 0($2) ; 13: lw $3, 0($2)
|
||||||
|
X"00654020", -- [0x00400020] add $8, $3, $5 ; 14: add $8, $3, $5
|
||||||
|
X"00654820", -- [0x00400024] add $9, $3, $5 ; 15: add $9, $3, $5
|
||||||
|
X"00655020", -- [0x00400028] add $10, $3, $5 ; 16: add $10, $3, $5
|
||||||
|
X"00655820", -- [0x0040002c] add $11, $3, $5 ; 17: add $11, $3, $5
|
||||||
|
X"00000000", -- [0x00400030] nop ; 18: sll $0, $0, 0
|
||||||
|
X"00000000", -- [0x00400034] nop ; 19: sll $0, $0, 0
|
||||||
|
X"08100001", -- [0x00400038] j 0x00400004 [main] ; 20: j main
|
||||||
|
X"00000000", -- [0x0040003c] nop ; 21: sll $0, $0, 0
|
||||||
|
X"00000000", -- [0x00400040] nop ; 21: sll $0, $0, 0
|
||||||
|
X"00000000", -- [0x00400044] nop ; 21: sll $0, $0, 0
|
||||||
|
X"00000000", -- [0x00400048] nop ; 21: sll $0, $0, 0
|
||||||
|
X"00000000", -- [0x0040004c] nop ; 21: sll $0, $0, 0
|
||||||
|
X"00000000", -- [0x00400050] nop ; 21: sll $0, $0, 0
|
||||||
|
X"00000000", -- [0x00400054] nop ; 21: sll $0, $0, 0
|
||||||
|
X"00000000", -- [0x00400058] nop ; 21: sll $0, $0, 0
|
||||||
|
X"00000000", -- [0x0040005c] nop ; 21: sll $0, $0, 0
|
||||||
|
X"00000000", -- [0x00400060] nop ; 21: sll $0, $0, 0
|
||||||
|
X"00000000", -- [0x00400064] nop ; 21: sll $0, $0, 0
|
||||||
|
X"00000000", -- [0x00400068] nop ; 21: sll $0, $0, 0
|
||||||
|
X"00000000", -- [0x0040006c] nop ; 21: sll $0, $0, 0
|
||||||
|
X"00000000", -- [0x00400070] nop ; 21: sll $0, $0, 0
|
||||||
|
X"00000000", -- [0x00400074] nop ; 21: sll $0, $0, 0
|
||||||
|
X"00000000", -- [0x00400078] nop ; 21: sll $0, $0, 0
|
||||||
|
X"00000000", -- [0x0040007c] nop ; 21: sll $0, $0, 0
|
||||||
|
X"00000000", -- [0x00400080] nop ; 21: sll $0, $0, 0
|
||||||
|
X"00000000", -- [0x00400084] nop ; 21: sll $0, $0, 0
|
||||||
|
X"00000000", -- [0x00400088] nop ; 21: sll $0, $0, 0
|
||||||
|
X"00000000", -- [0x0040008c] nop ; 21: sll $0, $0, 0
|
||||||
|
X"00000000", -- [0x00400090] nop ; 21: sll $0, $0, 0
|
||||||
|
X"00000000", -- [0x00400094] nop ; 21: sll $0, $0, 0
|
||||||
|
X"00000000", -- [0x00400098] nop ; 21: sll $0, $0, 0
|
||||||
|
X"00000000", -- [0x0040009c] nop ; 21: sll $0, $0, 0
|
||||||
|
X"00000000", -- [0x004000a0] nop ; 21: sll $0, $0, 0
|
||||||
|
X"00000000", -- [0x004000a4] nop ; 21: sll $0, $0, 0
|
||||||
|
X"00000000", -- [0x004000a8] nop ; 21: sll $0, $0, 0
|
||||||
|
X"00000000", -- [0x004000ac] nop ; 21: sll $0, $0, 0
|
||||||
|
X"00000000", -- [0x004000b0] nop ; 21: sll $0, $0, 0
|
||||||
|
X"00000000", -- [0x004000b4] nop ; 21: sll $0, $0, 0
|
||||||
|
X"00000000", -- [0x004000b8] nop ; 21: sll $0, $0, 0
|
||||||
|
X"00000000", -- [0x004000bc] nop ; 21: sll $0, $0, 0
|
||||||
|
X"00000000", -- [0x004000c0] nop ; 21: sll $0, $0, 0
|
||||||
|
X"00000000", -- [0x004000c4] nop ; 21: sll $0, $0, 0
|
||||||
|
X"00000000", -- [0x004000c8] nop ; 21: sll $0, $0, 0
|
||||||
|
X"00000000", -- [0x004000cc] nop ; 21: sll $0, $0, 0
|
||||||
|
X"00000000", -- [0x004000d0] nop ; 21: sll $0, $0, 0
|
||||||
|
X"00000000", -- [0x004000d4] nop ; 21: sll $0, $0, 0
|
||||||
|
X"00000000", -- [0x004000d8] nop ; 21: sll $0, $0, 0
|
||||||
|
X"00000000", -- [0x004000dc] nop ; 21: sll $0, $0, 0
|
||||||
|
X"00000000", -- [0x004000e0] nop ; 21: sll $0, $0, 0
|
||||||
|
X"00000000", -- [0x004000e4] nop ; 21: sll $0, $0, 0
|
||||||
|
X"00000000", -- [0x004000e8] nop ; 21: sll $0, $0, 0
|
||||||
|
X"00000000", -- [0x004000ec] nop ; 21: sll $0, $0, 0
|
||||||
|
X"00000000", -- [0x004000f0] nop ; 21: sll $0, $0, 0
|
||||||
|
X"00000000", -- [0x004000f4] nop ; 21: sll $0, $0, 0
|
||||||
|
X"00000000", -- [0x004000f8] nop ; 21: sll $0, $0, 0
|
||||||
|
X"00000000" -- [0x004000fc] nop ; 21: sll $0, $0, 0
|
||||||
|
);
|
||||||
|
|
||||||
|
begin
|
||||||
|
|
||||||
|
PROM_READ:
|
||||||
|
dout <= word_array(to_integer(addr));
|
||||||
|
|
||||||
|
end itest;
|
||||||
@@ -0,0 +1,122 @@
|
|||||||
|
-------------------------------------------------------------------------
|
||||||
|
-- Project: JCPU, a portable 8-bit RISC CPU written in VHDL
|
||||||
|
-- This file: The ROM file for use in your VHDL design
|
||||||
|
--
|
||||||
|
-- Copyright (C) 2007 J. Ahrensfeld
|
||||||
|
--
|
||||||
|
-- This program is free software: you can redistribute it and/or modify
|
||||||
|
-- it under the terms of the GNU General Public License as published by
|
||||||
|
-- the Free Software Foundation, either version 3 of the License, or
|
||||||
|
-- (at your option) any later version.
|
||||||
|
--
|
||||||
|
-- This program 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 General Public License for more details.
|
||||||
|
--
|
||||||
|
-- You should have received a copy of the GNU General Public License
|
||||||
|
-- along with this program. If not, see <http://www.gnu.org/licenses/>.
|
||||||
|
--
|
||||||
|
-- For questions and ideas, please contact the author at jens@jayfield.org
|
||||||
|
--
|
||||||
|
--------------------------------------------------------------------------
|
||||||
|
|
||||||
|
LIBRARY ieee;
|
||||||
|
use IEEE.STD_LOGIC_1164.ALL;
|
||||||
|
USE ieee.numeric_std.ALL;
|
||||||
|
|
||||||
|
|
||||||
|
ENTITY rom IS
|
||||||
|
Generic
|
||||||
|
(
|
||||||
|
addr_width : integer := 2;
|
||||||
|
data_width : integer := 32
|
||||||
|
);
|
||||||
|
Port
|
||||||
|
(
|
||||||
|
addr : in unsigned(addr_width-1 downto 0);
|
||||||
|
dout : out unsigned(data_width-1 downto 0)
|
||||||
|
);
|
||||||
|
END rom;
|
||||||
|
|
||||||
|
ARCHITECTURE itest OF rom IS
|
||||||
|
|
||||||
|
subtype word_t is unsigned(data_width-1 downto 0);
|
||||||
|
type word_array_t is array (0 to 2**addr_width-1) of word_t;
|
||||||
|
|
||||||
|
-- Assembled from itest.jsm
|
||||||
|
constant word_array : word_array_t :=
|
||||||
|
(
|
||||||
|
|
||||||
|
X"08100001", -- [0x00400000] j 0x00400004 [main]
|
||||||
|
X"3c018000", -- [0x00400004] lui $1, -32768
|
||||||
|
X"3c020000", -- [0x00400008] lui $2, 0
|
||||||
|
X"3c030000", -- [0x0040000c] lui $3, 0
|
||||||
|
X"34420001", -- [0x00400010] ori $2, $2, 1
|
||||||
|
X"34630003", -- [0x00400014] ori $3, $3, 3
|
||||||
|
X"00010842", -- [0x00400018] srl $1, $1, 1
|
||||||
|
X"00010840", -- [0x0040001c] sll $1, $1, 1
|
||||||
|
X"00010843", -- [0x00400020] sra $1, $1, 1
|
||||||
|
X"000108c3", -- [0x00400024] sra $1, $1, 3
|
||||||
|
X"00612004", -- [0x00400028] sllv $4, $1, $3
|
||||||
|
X"00412807", -- [0x0040002c] srav $5, $1, $2
|
||||||
|
X"00613007", -- [0x00400030] srav $6, $1, $3
|
||||||
|
X"3c1f0040", -- [0x00400034] lui $31, 64
|
||||||
|
X"03e00008", -- [0x00400038] jr $31
|
||||||
|
X"00000000", -- [0x0040003c] nop
|
||||||
|
X"00000000", -- [0x00400040] nop
|
||||||
|
X"00000000", -- [0x00400044] nop
|
||||||
|
X"00000000", -- [0x00400048] nop
|
||||||
|
X"00000000", -- [0x0040004c] nop
|
||||||
|
X"00000000", -- [0x00400050] nop
|
||||||
|
X"00000000", -- [0x00400054] nop
|
||||||
|
X"00000000", -- [0x00400058] nop
|
||||||
|
X"00000000", -- [0x0040005c] nop
|
||||||
|
X"00000000", -- [0x00400060] nop
|
||||||
|
X"00000000", -- [0x00400064] nop
|
||||||
|
X"00000000", -- [0x00400068] nop
|
||||||
|
X"00000000", -- [0x0040006c] nop
|
||||||
|
X"00000000", -- [0x00400070] nop
|
||||||
|
X"00000000", -- [0x00400074] nop
|
||||||
|
X"00000000", -- [0x00400078] nop
|
||||||
|
X"00000000", -- [0x0040007c] nop
|
||||||
|
X"00000000", -- [0x00400080] nop
|
||||||
|
X"00000000", -- [0x00400084] nop
|
||||||
|
X"00000000", -- [0x00400088] nop
|
||||||
|
X"00000000", -- [0x0040008c] nop
|
||||||
|
X"00000000", -- [0x00400090] nop
|
||||||
|
X"00000000", -- [0x00400094] nop
|
||||||
|
X"00000000", -- [0x00400098] nop
|
||||||
|
X"00000000", -- [0x0040009c] nop
|
||||||
|
X"00000000", -- [0x004000a0] nop
|
||||||
|
X"00000000", -- [0x004000a4] nop
|
||||||
|
X"00000000", -- [0x004000a8] nop
|
||||||
|
X"00000000", -- [0x004000ac] nop
|
||||||
|
X"00000000", -- [0x004000b0] nop
|
||||||
|
X"00000000", -- [0x004000b4] nop
|
||||||
|
X"00000000", -- [0x004000b8] nop
|
||||||
|
X"00000000", -- [0x004000bc] nop
|
||||||
|
X"00000000", -- [0x004000c0] nop
|
||||||
|
X"00000000", -- [0x004000c4] nop
|
||||||
|
X"00000000", -- [0x004000c8] nop
|
||||||
|
X"00000000", -- [0x004000cc] nop
|
||||||
|
X"00000000", -- [0x004000d0] nop
|
||||||
|
X"00000000", -- [0x004000d4] nop
|
||||||
|
X"00000000", -- [0x004000d8] nop
|
||||||
|
X"00000000", -- [0x004000dc] nop
|
||||||
|
X"00000000", -- [0x004000e0] nop
|
||||||
|
X"00000000", -- [0x004000e4] nop
|
||||||
|
X"00000000", -- [0x004000e8] nop
|
||||||
|
X"00000000", -- [0x004000ec] nop
|
||||||
|
X"00000000", -- [0x004000f0] nop
|
||||||
|
X"00000000", -- [0x004000f4] nop
|
||||||
|
X"00000000", -- [0x004000f8] nop
|
||||||
|
X"00000000" -- [0x004000fc] nop
|
||||||
|
);
|
||||||
|
|
||||||
|
begin
|
||||||
|
|
||||||
|
PROM_READ:
|
||||||
|
dout <= word_array(to_integer(addr));
|
||||||
|
|
||||||
|
end itest;
|
||||||
@@ -0,0 +1,121 @@
|
|||||||
|
-------------------------------------------------------------------------
|
||||||
|
-- Project: JCPU, a portable 8-bit RISC CPU written in VHDL
|
||||||
|
-- This file: The ROM file for use in your VHDL design
|
||||||
|
--
|
||||||
|
-- Copyright (C) 2007 J. Ahrensfeld
|
||||||
|
--
|
||||||
|
-- This program is free software: you can redistribute it and/or modify
|
||||||
|
-- it under the terms of the GNU General Public License as published by
|
||||||
|
-- the Free Software Foundation, either version 3 of the License, or
|
||||||
|
-- (at your option) any later version.
|
||||||
|
--
|
||||||
|
-- This program 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 General Public License for more details.
|
||||||
|
--
|
||||||
|
-- You should have received a copy of the GNU General Public License
|
||||||
|
-- along with this program. If not, see <http://www.gnu.org/licenses/>.
|
||||||
|
--
|
||||||
|
-- For questions and ideas, please contact the author at jens@jayfield.org
|
||||||
|
--
|
||||||
|
--------------------------------------------------------------------------
|
||||||
|
|
||||||
|
LIBRARY ieee;
|
||||||
|
use IEEE.STD_LOGIC_1164.ALL;
|
||||||
|
USE ieee.numeric_std.ALL;
|
||||||
|
|
||||||
|
|
||||||
|
ENTITY rom IS
|
||||||
|
Generic
|
||||||
|
(
|
||||||
|
addr_width : integer := 2;
|
||||||
|
data_width : integer := 32
|
||||||
|
);
|
||||||
|
Port
|
||||||
|
(
|
||||||
|
addr : in unsigned(addr_width-1 downto 0);
|
||||||
|
dout : out unsigned(data_width-1 downto 0)
|
||||||
|
);
|
||||||
|
END rom;
|
||||||
|
|
||||||
|
ARCHITECTURE itest OF rom IS
|
||||||
|
|
||||||
|
subtype word_t is unsigned(data_width-1 downto 0);
|
||||||
|
type word_array_t is array (0 to 2**addr_width-1) of word_t;
|
||||||
|
|
||||||
|
-- Assembled from itest.jsm
|
||||||
|
constant word_array : word_array_t :=
|
||||||
|
(
|
||||||
|
X"08100001", -- [0x00400000] j 0x00400004 [main] ; 5: j main
|
||||||
|
X"3c080000", -- [0x00400004] lui $8, 0 ; 7: lui $8, 0
|
||||||
|
X"00000000", -- [0x00400008] nop ; 8: sll $0, $0, 0
|
||||||
|
X"0c100009", -- [0x0040000c] jal 0x00400024 [subr1] ; 9: jal subr1
|
||||||
|
X"3c010040", -- [0x00400010] lui $1, 64 [subr2] ; 10: la $2, subr2
|
||||||
|
X"34220030", -- [0x00400014] ori $2, $1, 48 [subr2]
|
||||||
|
X"00407809", -- [0x00400018] jalr $15, $2 ; 11: jalr $15, $2
|
||||||
|
X"00000000", -- [0x0040001c] nop ; 12: sll $0, $0, 0
|
||||||
|
X"08100002", -- [0x00400020] j 0x00400008 [loop] ; 13: j loop
|
||||||
|
X"21080001", -- [0x00400024] addi $8, $8, 1 ; 15: addi $8, 1
|
||||||
|
X"00000000", -- [0x00400028] nop ; 16: sll $0, $0, 0
|
||||||
|
X"03e00008", -- [0x0040002c] jr $31 ; 17: jr $31
|
||||||
|
X"21080010", -- [0x00400030] addi $8, $8, 16 ; 18: addi $8, 16
|
||||||
|
X"00000000", -- [0x00400034] nop ; 19: sll $0, $0, 0
|
||||||
|
X"01e00008", -- [0x00400038] jr $15 ; 20: jr $15
|
||||||
|
X"00000000", -- [0x0040003c] nop ; 21: sll $0, $0, 0
|
||||||
|
X"00000000", -- [0x00400040] nop ; 21: sll $0, $0, 0
|
||||||
|
X"00000000", -- [0x00400044] nop ; 21: sll $0, $0, 0
|
||||||
|
X"00000000", -- [0x00400048] nop ; 21: sll $0, $0, 0
|
||||||
|
X"00000000", -- [0x0040004c] nop ; 21: sll $0, $0, 0
|
||||||
|
X"00000000", -- [0x00400050] nop ; 21: sll $0, $0, 0
|
||||||
|
X"00000000", -- [0x00400054] nop ; 21: sll $0, $0, 0
|
||||||
|
X"00000000", -- [0x00400058] nop ; 21: sll $0, $0, 0
|
||||||
|
X"00000000", -- [0x0040005c] nop ; 21: sll $0, $0, 0
|
||||||
|
X"00000000", -- [0x00400060] nop ; 21: sll $0, $0, 0
|
||||||
|
X"00000000", -- [0x00400064] nop ; 21: sll $0, $0, 0
|
||||||
|
X"00000000", -- [0x00400068] nop ; 21: sll $0, $0, 0
|
||||||
|
X"00000000", -- [0x0040006c] nop ; 21: sll $0, $0, 0
|
||||||
|
X"00000000", -- [0x00400070] nop ; 21: sll $0, $0, 0
|
||||||
|
X"00000000", -- [0x00400074] nop ; 21: sll $0, $0, 0
|
||||||
|
X"00000000", -- [0x00400078] nop ; 21: sll $0, $0, 0
|
||||||
|
X"00000000", -- [0x0040007c] nop ; 21: sll $0, $0, 0
|
||||||
|
X"00000000", -- [0x00400080] nop ; 21: sll $0, $0, 0
|
||||||
|
X"00000000", -- [0x00400084] nop ; 21: sll $0, $0, 0
|
||||||
|
X"00000000", -- [0x00400088] nop ; 21: sll $0, $0, 0
|
||||||
|
X"00000000", -- [0x0040008c] nop ; 21: sll $0, $0, 0
|
||||||
|
X"00000000", -- [0x00400090] nop ; 21: sll $0, $0, 0
|
||||||
|
X"00000000", -- [0x00400094] nop ; 21: sll $0, $0, 0
|
||||||
|
X"00000000", -- [0x00400098] nop ; 21: sll $0, $0, 0
|
||||||
|
X"00000000", -- [0x0040009c] nop ; 21: sll $0, $0, 0
|
||||||
|
X"00000000", -- [0x004000a0] nop ; 21: sll $0, $0, 0
|
||||||
|
X"00000000", -- [0x004000a4] nop ; 21: sll $0, $0, 0
|
||||||
|
X"00000000", -- [0x004000a8] nop ; 21: sll $0, $0, 0
|
||||||
|
X"00000000", -- [0x004000ac] nop ; 21: sll $0, $0, 0
|
||||||
|
X"00000000", -- [0x004000b0] nop ; 21: sll $0, $0, 0
|
||||||
|
X"00000000", -- [0x004000b4] nop ; 21: sll $0, $0, 0
|
||||||
|
X"00000000", -- [0x004000b8] nop ; 21: sll $0, $0, 0
|
||||||
|
X"00000000", -- [0x004000bc] nop ; 21: sll $0, $0, 0
|
||||||
|
X"00000000", -- [0x004000c0] nop ; 21: sll $0, $0, 0
|
||||||
|
X"00000000", -- [0x004000c4] nop ; 21: sll $0, $0, 0
|
||||||
|
X"00000000", -- [0x004000c8] nop ; 21: sll $0, $0, 0
|
||||||
|
X"00000000", -- [0x004000cc] nop ; 21: sll $0, $0, 0
|
||||||
|
X"00000000", -- [0x004000d0] nop ; 21: sll $0, $0, 0
|
||||||
|
X"00000000", -- [0x004000d4] nop ; 21: sll $0, $0, 0
|
||||||
|
X"00000000", -- [0x004000d8] nop ; 21: sll $0, $0, 0
|
||||||
|
X"00000000", -- [0x004000dc] nop ; 21: sll $0, $0, 0
|
||||||
|
X"00000000", -- [0x004000e0] nop ; 21: sll $0, $0, 0
|
||||||
|
X"00000000", -- [0x004000e4] nop ; 21: sll $0, $0, 0
|
||||||
|
X"00000000", -- [0x004000e8] nop ; 21: sll $0, $0, 0
|
||||||
|
X"00000000", -- [0x004000ec] nop ; 21: sll $0, $0, 0
|
||||||
|
X"00000000", -- [0x004000f0] nop ; 21: sll $0, $0, 0
|
||||||
|
X"00000000", -- [0x004000f4] nop ; 21: sll $0, $0, 0
|
||||||
|
X"00000000", -- [0x004000f8] nop ; 21: sll $0, $0, 0
|
||||||
|
X"00000000" -- [0x004000fc] nop ; 21: sll $0, $0, 0
|
||||||
|
);
|
||||||
|
|
||||||
|
begin
|
||||||
|
|
||||||
|
PROM_READ:
|
||||||
|
dout <= word_array(to_integer(addr));
|
||||||
|
|
||||||
|
end itest;
|
||||||
@@ -0,0 +1,121 @@
|
|||||||
|
-------------------------------------------------------------------------
|
||||||
|
-- Project: JCPU, a portable 8-bit RISC CPU written in VHDL
|
||||||
|
-- This file: The ROM file for use in your VHDL design
|
||||||
|
--
|
||||||
|
-- Copyright (C) 2007 J. Ahrensfeld
|
||||||
|
--
|
||||||
|
-- This program is free software: you can redistribute it and/or modify
|
||||||
|
-- it under the terms of the GNU General Public License as published by
|
||||||
|
-- the Free Software Foundation, either version 3 of the License, or
|
||||||
|
-- (at your option) any later version.
|
||||||
|
--
|
||||||
|
-- This program 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 General Public License for more details.
|
||||||
|
--
|
||||||
|
-- You should have received a copy of the GNU General Public License
|
||||||
|
-- along with this program. If not, see <http://www.gnu.org/licenses/>.
|
||||||
|
--
|
||||||
|
-- For questions and ideas, please contact the author at jens@jayfield.org
|
||||||
|
--
|
||||||
|
--------------------------------------------------------------------------
|
||||||
|
|
||||||
|
LIBRARY ieee;
|
||||||
|
use IEEE.STD_LOGIC_1164.ALL;
|
||||||
|
USE ieee.numeric_std.ALL;
|
||||||
|
|
||||||
|
|
||||||
|
ENTITY rom IS
|
||||||
|
Generic
|
||||||
|
(
|
||||||
|
addr_width : integer := 2;
|
||||||
|
data_width : integer := 32
|
||||||
|
);
|
||||||
|
Port
|
||||||
|
(
|
||||||
|
addr : in unsigned(addr_width-1 downto 0);
|
||||||
|
dout : out unsigned(data_width-1 downto 0)
|
||||||
|
);
|
||||||
|
END rom;
|
||||||
|
|
||||||
|
ARCHITECTURE itest OF rom IS
|
||||||
|
|
||||||
|
subtype word_t is unsigned(data_width-1 downto 0);
|
||||||
|
type word_array_t is array (0 to 2**addr_width-1) of word_t;
|
||||||
|
|
||||||
|
-- Assembled from itest.jsm
|
||||||
|
constant word_array : word_array_t :=
|
||||||
|
(
|
||||||
|
X"3c011234", -- [0x00400000] lui $1, 4660
|
||||||
|
X"34225678", -- [0x00400004] ori $2, $1, 22136
|
||||||
|
X"3c012345", -- [0x00400008] lui $1, 9029
|
||||||
|
X"34236789", -- [0x0040000c] ori $3, $1, 26505
|
||||||
|
X"3c018765", -- [0x00400010] lui $1, -30875
|
||||||
|
X"34244321", -- [0x00400014] ori $4, $1, 17185
|
||||||
|
X"3c019876", -- [0x00400018] lui $1, -26506
|
||||||
|
X"34255432", -- [0x0040001c] ori $5, $1, 21554
|
||||||
|
X"00000000", -- [0x00400020] nop
|
||||||
|
X"00427823", -- [0x00400024] subu $15, $2, $2
|
||||||
|
X"00437823", -- [0x00400028] subu $15, $2, $3
|
||||||
|
X"00447823", -- [0x0040002c] subu $15, $2, $4
|
||||||
|
X"00457823", -- [0x00400030] subu $15, $2, $5
|
||||||
|
X"00627823", -- [0x00400034] subu $15, $3, $2
|
||||||
|
X"00637823", -- [0x00400038] subu $15, $3, $3
|
||||||
|
X"00647823", -- [0x0040003c] subu $15, $3, $4
|
||||||
|
X"00657823", -- [0x00400040] subu $15, $3, $5
|
||||||
|
X"00827823", -- [0x00400044] subu $15, $4, $2
|
||||||
|
X"00837823", -- [0x00400048] subu $15, $4, $3
|
||||||
|
X"00847823", -- [0x0040004c] subu $15, $4, $4
|
||||||
|
X"00857823", -- [0x00400050] subu $15, $4, $5
|
||||||
|
X"00a27823", -- [0x00400054] subu $15, $5, $2
|
||||||
|
X"00a37823", -- [0x00400058] subu $15, $5, $3
|
||||||
|
X"00a47823", -- [0x0040005c] subu $15, $5, $4
|
||||||
|
X"00a57823", -- [0x00400060] subu $15, $5, $5
|
||||||
|
X"00000000", -- [0x00400064] nop
|
||||||
|
X"00427822", -- [0x00400068] sub $15, $2, $2
|
||||||
|
X"00437822", -- [0x0040006c] sub $15, $2, $3
|
||||||
|
X"00447822", -- [0x00400070] sub $15, $2, $4
|
||||||
|
X"00457822", -- [0x00400074] sub $15, $2, $5
|
||||||
|
X"00627822", -- [0x00400078] sub $15, $3, $2
|
||||||
|
X"00637822", -- [0x0040007c] sub $15, $3, $3
|
||||||
|
X"00647822", -- [0x00400080] sub $15, $3, $4
|
||||||
|
X"00657822", -- [0x00400084] sub $15, $3, $5
|
||||||
|
X"00827822", -- [0x00400088] sub $15, $4, $2
|
||||||
|
X"00837822", -- [0x0040008c] sub $15, $4, $3
|
||||||
|
X"00847822", -- [0x00400090] sub $15, $4, $4
|
||||||
|
X"00857822", -- [0x00400094] sub $15, $4, $5
|
||||||
|
X"00a27822", -- [0x00400098] sub $15, $5, $2
|
||||||
|
X"00a37822", -- [0x0040009c] sub $15, $5, $3
|
||||||
|
X"00a47822", -- [0x004000a0] sub $15, $5, $4
|
||||||
|
X"00a57822", -- [0x004000a4] sub $15, $5, $5
|
||||||
|
X"00000000", -- [0x004000a8] nop
|
||||||
|
X"08104000", -- [0x004000ac] j 0x00410000 [main]
|
||||||
|
X"00000000", -- [0x004000b0] nop
|
||||||
|
X"00000000", -- [0x004000b4]
|
||||||
|
X"00000000", -- [0x004000b8]
|
||||||
|
X"00000000", -- [0x004000bc]
|
||||||
|
X"00000000", -- [0x004000c0]
|
||||||
|
X"00000000", -- [0x004000c4]
|
||||||
|
X"00000000", -- [0x004000c8]
|
||||||
|
X"00000000", -- [0x004000cc]
|
||||||
|
X"00000000", -- [0x004000d0]
|
||||||
|
X"00000000", -- [0x004000d4]
|
||||||
|
X"00000000", -- [0x004000d8]
|
||||||
|
X"00000000", -- [0x004000dc]
|
||||||
|
X"00000000", -- [0x004000e0]
|
||||||
|
X"00000000", -- [0x004000e4]
|
||||||
|
X"00000000", -- [0x004000e8]
|
||||||
|
X"00000000", -- [0x004000ec]
|
||||||
|
X"00000000", -- [0x004000f0]
|
||||||
|
X"00000000", -- [0x004000f4]
|
||||||
|
X"00000000", -- [0x004000f8]
|
||||||
|
X"00000000" -- [0x004000fc]
|
||||||
|
);
|
||||||
|
|
||||||
|
begin
|
||||||
|
|
||||||
|
PROM_READ:
|
||||||
|
dout <= word_array(to_integer(addr));
|
||||||
|
|
||||||
|
end itest;
|
||||||
@@ -0,0 +1,121 @@
|
|||||||
|
-------------------------------------------------------------------------
|
||||||
|
-- Project: JCPU, a portable 8-bit RISC CPU written in VHDL
|
||||||
|
-- This file: The ROM file for use in your VHDL design
|
||||||
|
--
|
||||||
|
-- Copyright (C) 2007 J. Ahrensfeld
|
||||||
|
--
|
||||||
|
-- This program is free software: you can redistribute it and/or modify
|
||||||
|
-- it under the terms of the GNU General Public License as published by
|
||||||
|
-- the Free Software Foundation, either version 3 of the License, or
|
||||||
|
-- (at your option) any later version.
|
||||||
|
--
|
||||||
|
-- This program 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 General Public License for more details.
|
||||||
|
--
|
||||||
|
-- You should have received a copy of the GNU General Public License
|
||||||
|
-- along with this program. If not, see <http://www.gnu.org/licenses/>.
|
||||||
|
--
|
||||||
|
-- For questions and ideas, please contact the author at jens@jayfield.org
|
||||||
|
--
|
||||||
|
--------------------------------------------------------------------------
|
||||||
|
|
||||||
|
LIBRARY ieee;
|
||||||
|
use IEEE.STD_LOGIC_1164.ALL;
|
||||||
|
USE ieee.numeric_std.ALL;
|
||||||
|
|
||||||
|
|
||||||
|
ENTITY rom IS
|
||||||
|
Generic
|
||||||
|
(
|
||||||
|
addr_width : integer := 2;
|
||||||
|
data_width : integer := 32
|
||||||
|
);
|
||||||
|
Port
|
||||||
|
(
|
||||||
|
addr : in unsigned(addr_width-1 downto 0);
|
||||||
|
dout : out unsigned(data_width-1 downto 0)
|
||||||
|
);
|
||||||
|
END rom;
|
||||||
|
|
||||||
|
ARCHITECTURE itest OF rom IS
|
||||||
|
|
||||||
|
subtype word_t is unsigned(data_width-1 downto 0);
|
||||||
|
type word_array_t is array (0 to 2**addr_width-1) of word_t;
|
||||||
|
|
||||||
|
-- Assembled from itest.jsm
|
||||||
|
constant word_array : word_array_t :=
|
||||||
|
(
|
||||||
|
X"3c011234", -- [0x00400000] lui $1, 4660
|
||||||
|
X"34225678", -- [0x00400004] ori $2, $1, 22136
|
||||||
|
X"3c012345", -- [0x00400008] lui $1, 9029
|
||||||
|
X"34236789", -- [0x0040000c] ori $3, $1, 26505
|
||||||
|
X"3c018765", -- [0x00400010] lui $1, -30875
|
||||||
|
X"34244321", -- [0x00400014] ori $4, $1, 17185
|
||||||
|
X"3c019876", -- [0x00400018] lui $1, -26506
|
||||||
|
X"34255432", -- [0x0040001c] ori $5, $1, 21554
|
||||||
|
X"3c081000", -- [0x00400020] lui $8, 4096
|
||||||
|
X"00000000", -- [0x00400024] nop
|
||||||
|
X"0042782b", -- [0x00400028] sltu $15, $2, $2
|
||||||
|
X"0043782b", -- [0x0040002c] sltu $15, $2, $3
|
||||||
|
X"0044782b", -- [0x00400030] sltu $15, $2, $4
|
||||||
|
X"0045782b", -- [0x00400034] sltu $15, $2, $5
|
||||||
|
X"0062782b", -- [0x00400038] sltu $15, $3, $2
|
||||||
|
X"0063782b", -- [0x0040003c] sltu $15, $3, $3
|
||||||
|
X"0064782b", -- [0x00400040] sltu $15, $3, $4
|
||||||
|
X"0065782b", -- [0x00400044] sltu $15, $3, $5
|
||||||
|
X"0082782b", -- [0x00400048] sltu $15, $4, $2
|
||||||
|
X"0083782b", -- [0x0040004c] sltu $15, $4, $3
|
||||||
|
X"0084782b", -- [0x00400050] sltu $15, $4, $4
|
||||||
|
X"0085782b", -- [0x00400054] sltu $15, $4, $5
|
||||||
|
X"00a2782b", -- [0x00400058] sltu $15, $5, $2
|
||||||
|
X"00a3782b", -- [0x0040005c] sltu $15, $5, $3
|
||||||
|
X"00a4782b", -- [0x00400060] sltu $15, $5, $4
|
||||||
|
X"00a5782b", -- [0x00400064] sltu $15, $5, $5
|
||||||
|
X"00000000", -- [0x00400068] nop
|
||||||
|
X"0042782a", -- [0x0040006c] slt $15, $2, $2
|
||||||
|
X"0043782a", -- [0x00400070] slt $15, $2, $3
|
||||||
|
X"0044782a", -- [0x00400074] slt $15, $2, $4
|
||||||
|
X"0045782a", -- [0x00400078] slt $15, $2, $5
|
||||||
|
X"0062782a", -- [0x0040007c] slt $15, $3, $2
|
||||||
|
X"0063782a", -- [0x00400080] slt $15, $3, $3
|
||||||
|
X"0064782a", -- [0x00400084] slt $15, $3, $4
|
||||||
|
X"0065782a", -- [0x00400088] slt $15, $3, $5
|
||||||
|
X"0082782a", -- [0x0040008c] slt $15, $4, $2
|
||||||
|
X"0083782a", -- [0x00400090] slt $15, $4, $3
|
||||||
|
X"0084782a", -- [0x00400094] slt $15, $4, $4
|
||||||
|
X"0085782a", -- [0x00400098] slt $15, $4, $5
|
||||||
|
X"00a2782a", -- [0x0040009c] slt $15, $5, $2
|
||||||
|
X"00a3782a", -- [0x004000a0] slt $15, $5, $3
|
||||||
|
X"00a4782a", -- [0x004000a4] slt $15, $5, $4
|
||||||
|
X"00a5782a", -- [0x004000a8] slt $15, $5, $5
|
||||||
|
X"00000000", -- [0x004000ac] nop
|
||||||
|
X"08104000", -- [0x004000b0] j 0x00410000 [main]
|
||||||
|
X"00000000", -- [0x004000b4] nop
|
||||||
|
X"00000000", -- [0x004000b8]
|
||||||
|
X"00000000", -- [0x004000bc]
|
||||||
|
X"00000000", -- [0x004000c0]
|
||||||
|
X"00000000", -- [0x004000c4]
|
||||||
|
X"00000000", -- [0x004000c8]
|
||||||
|
X"00000000", -- [0x004000cc]
|
||||||
|
X"00000000", -- [0x004000d0]
|
||||||
|
X"00000000", -- [0x004000d4]
|
||||||
|
X"00000000", -- [0x004000d8]
|
||||||
|
X"00000000", -- [0x004000dc]
|
||||||
|
X"00000000", -- [0x004000e0]
|
||||||
|
X"00000000", -- [0x004000e4]
|
||||||
|
X"00000000", -- [0x004000e8]
|
||||||
|
X"00000000", -- [0x004000ec]
|
||||||
|
X"00000000", -- [0x004000f0]
|
||||||
|
X"00000000", -- [0x004000f4]
|
||||||
|
X"00000000", -- [0x004000f8]
|
||||||
|
X"00000000" -- [0x004000fc]
|
||||||
|
);
|
||||||
|
|
||||||
|
begin
|
||||||
|
|
||||||
|
PROM_READ:
|
||||||
|
dout <= word_array(to_integer(addr));
|
||||||
|
|
||||||
|
end itest;
|
||||||
@@ -0,0 +1,121 @@
|
|||||||
|
-------------------------------------------------------------------------
|
||||||
|
-- Project: JCPU, a portable 8-bit RISC CPU written in VHDL
|
||||||
|
-- This file: The ROM file for use in your VHDL design
|
||||||
|
--
|
||||||
|
-- Copyright (C) 2007 J. Ahrensfeld
|
||||||
|
--
|
||||||
|
-- This program is free software: you can redistribute it and/or modify
|
||||||
|
-- it under the terms of the GNU General Public License as published by
|
||||||
|
-- the Free Software Foundation, either version 3 of the License, or
|
||||||
|
-- (at your option) any later version.
|
||||||
|
--
|
||||||
|
-- This program 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 General Public License for more details.
|
||||||
|
--
|
||||||
|
-- You should have received a copy of the GNU General Public License
|
||||||
|
-- along with this program. If not, see <http://www.gnu.org/licenses/>.
|
||||||
|
--
|
||||||
|
-- For questions and ideas, please contact the author at jens@jayfield.org
|
||||||
|
--
|
||||||
|
--------------------------------------------------------------------------
|
||||||
|
|
||||||
|
LIBRARY ieee;
|
||||||
|
use IEEE.STD_LOGIC_1164.ALL;
|
||||||
|
USE ieee.numeric_std.ALL;
|
||||||
|
|
||||||
|
|
||||||
|
ENTITY rom IS
|
||||||
|
Generic
|
||||||
|
(
|
||||||
|
addr_width : integer := 2;
|
||||||
|
data_width : integer := 32
|
||||||
|
);
|
||||||
|
Port
|
||||||
|
(
|
||||||
|
addr : in unsigned(addr_width-1 downto 0);
|
||||||
|
dout : out unsigned(data_width-1 downto 0)
|
||||||
|
);
|
||||||
|
END rom;
|
||||||
|
|
||||||
|
ARCHITECTURE itest OF rom IS
|
||||||
|
|
||||||
|
subtype word_t is unsigned(data_width-1 downto 0);
|
||||||
|
type word_array_t is array (0 to 2**addr_width-1) of word_t;
|
||||||
|
|
||||||
|
-- Assembled from itest.jsm
|
||||||
|
constant word_array : word_array_t :=
|
||||||
|
(
|
||||||
|
X"3c011234", -- [0x00400000] lui $1, 4660
|
||||||
|
X"34225678", -- [0x00400004] ori $2, $1, 22136
|
||||||
|
X"3c012345", -- [0x00400008] lui $1, 9029
|
||||||
|
X"34236789", -- [0x0040000c] ori $3, $1, 26505
|
||||||
|
X"3c018765", -- [0x00400010] lui $1, -30875
|
||||||
|
X"34244321", -- [0x00400014] ori $4, $1, 17185
|
||||||
|
X"3c019876", -- [0x00400018] lui $1, -26506
|
||||||
|
X"34255432", -- [0x0040001c] ori $5, $1, 21554
|
||||||
|
X"3c081000", -- [0x00400020] lui $8, 4096
|
||||||
|
X"00000000", -- [0x00400024] nop
|
||||||
|
X"2c4f1234", -- [0x00400028] sltiu $15, $2, 4660
|
||||||
|
X"2c4f2345", -- [0x0040002c] sltiu $15, $2, 9029
|
||||||
|
X"2c4fedcc", -- [0x00400030] sltiu $15, $2, -4660
|
||||||
|
X"2c4fdcbb", -- [0x00400034] sltiu $15, $2, -9029
|
||||||
|
X"2c6f1234", -- [0x00400038] sltiu $15, $3, 4660
|
||||||
|
X"2c6f2345", -- [0x0040003c] sltiu $15, $3, 9029
|
||||||
|
X"2c6fedcc", -- [0x00400040] sltiu $15, $3, -4660
|
||||||
|
X"2c6fdcbb", -- [0x00400044] sltiu $15, $3, -9029
|
||||||
|
X"2c8f1234", -- [0x00400048] sltiu $15, $4, 4660
|
||||||
|
X"2c8f2345", -- [0x0040004c] sltiu $15, $4, 9029
|
||||||
|
X"2c8fedcc", -- [0x00400050] sltiu $15, $4, -4660
|
||||||
|
X"2c8fdcbb", -- [0x00400054] sltiu $15, $4, -9029
|
||||||
|
X"2caf1234", -- [0x00400058] sltiu $15, $5, 4660
|
||||||
|
X"2caf2345", -- [0x0040005c] sltiu $15, $5, 9029
|
||||||
|
X"2cafedcc", -- [0x00400060] sltiu $15, $5, -4660
|
||||||
|
X"2cafdcbb", -- [0x00400064] sltiu $15, $5, -9029
|
||||||
|
X"00000000", -- [0x00400068] nop
|
||||||
|
X"284f1234", -- [0x0040006c] slti $15, $2, 4660
|
||||||
|
X"284f2345", -- [0x00400070] slti $15, $2, 9029
|
||||||
|
X"284fedcc", -- [0x00400074] slti $15, $2, -4660
|
||||||
|
X"284fdcbb", -- [0x00400078] slti $15, $2, -9029
|
||||||
|
X"286f1234", -- [0x0040007c] slti $15, $3, 4660
|
||||||
|
X"286f2345", -- [0x00400080] slti $15, $3, 9029
|
||||||
|
X"286fedcc", -- [0x00400084] slti $15, $3, -4660
|
||||||
|
X"286fdcbb", -- [0x00400088] slti $15, $3, -9029
|
||||||
|
X"288f1234", -- [0x0040008c] slti $15, $4, 4660
|
||||||
|
X"288f2345", -- [0x00400090] slti $15, $4, 9029
|
||||||
|
X"288fedcc", -- [0x00400094] slti $15, $4, -4660
|
||||||
|
X"288fdcbb", -- [0x00400098] slti $15, $4, -9029
|
||||||
|
X"28af1234", -- [0x0040009c] slti $15, $5, 4660
|
||||||
|
X"28af2345", -- [0x004000a0] slti $15, $5, 9029
|
||||||
|
X"28afedcc", -- [0x004000a4] slti $15, $5, -4660
|
||||||
|
X"28afdcbb", -- [0x004000a8] slti $15, $5, -9029
|
||||||
|
X"00000000", -- [0x004000ac] nop
|
||||||
|
X"08104000", -- [0x004000b0] j 0x00410000 [main]
|
||||||
|
X"00000000", -- [0x004000b4] nop
|
||||||
|
X"00000000", -- [0x004000b8]
|
||||||
|
X"00000000", -- [0x004000bc]
|
||||||
|
X"00000000", -- [0x004000c0]
|
||||||
|
X"00000000", -- [0x004000c4]
|
||||||
|
X"00000000", -- [0x004000c8]
|
||||||
|
X"00000000", -- [0x004000cc]
|
||||||
|
X"00000000", -- [0x004000d0]
|
||||||
|
X"00000000", -- [0x004000d4]
|
||||||
|
X"00000000", -- [0x004000d8]
|
||||||
|
X"00000000", -- [0x004000dc]
|
||||||
|
X"00000000", -- [0x004000e0]
|
||||||
|
X"00000000", -- [0x004000e4]
|
||||||
|
X"00000000", -- [0x004000e8]
|
||||||
|
X"00000000", -- [0x004000ec]
|
||||||
|
X"00000000", -- [0x004000f0]
|
||||||
|
X"00000000", -- [0x004000f4]
|
||||||
|
X"00000000", -- [0x004000f8]
|
||||||
|
X"00000000" -- [0x004000fc]
|
||||||
|
);
|
||||||
|
|
||||||
|
begin
|
||||||
|
|
||||||
|
PROM_READ:
|
||||||
|
dout <= word_array(to_integer(addr));
|
||||||
|
|
||||||
|
end itest;
|
||||||
@@ -0,0 +1,121 @@
|
|||||||
|
-------------------------------------------------------------------------
|
||||||
|
-- Project: JCPU, a portable 8-bit RISC CPU written in VHDL
|
||||||
|
-- This file: The ROM file for use in your VHDL design
|
||||||
|
--
|
||||||
|
-- Copyright (C) 2007 J. Ahrensfeld
|
||||||
|
--
|
||||||
|
-- This program is free software: you can redistribute it and/or modify
|
||||||
|
-- it under the terms of the GNU General Public License as published by
|
||||||
|
-- the Free Software Foundation, either version 3 of the License, or
|
||||||
|
-- (at your option) any later version.
|
||||||
|
--
|
||||||
|
-- This program 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 General Public License for more details.
|
||||||
|
--
|
||||||
|
-- You should have received a copy of the GNU General Public License
|
||||||
|
-- along with this program. If not, see <http://www.gnu.org/licenses/>.
|
||||||
|
--
|
||||||
|
-- For questions and ideas, please contact the author at jens@jayfield.org
|
||||||
|
--
|
||||||
|
--------------------------------------------------------------------------
|
||||||
|
|
||||||
|
LIBRARY ieee;
|
||||||
|
use IEEE.STD_LOGIC_1164.ALL;
|
||||||
|
USE ieee.numeric_std.ALL;
|
||||||
|
|
||||||
|
|
||||||
|
ENTITY rom IS
|
||||||
|
Generic
|
||||||
|
(
|
||||||
|
addr_width : integer := 2;
|
||||||
|
data_width : integer := 32
|
||||||
|
);
|
||||||
|
Port
|
||||||
|
(
|
||||||
|
addr : in unsigned(addr_width-1 downto 0);
|
||||||
|
dout : out unsigned(data_width-1 downto 0)
|
||||||
|
);
|
||||||
|
END rom;
|
||||||
|
|
||||||
|
ARCHITECTURE itest OF rom IS
|
||||||
|
|
||||||
|
subtype word_t is unsigned(data_width-1 downto 0);
|
||||||
|
type word_array_t is array (0 to 2**addr_width-1) of word_t;
|
||||||
|
|
||||||
|
-- Assembled from itest.jsm
|
||||||
|
constant word_array : word_array_t :=
|
||||||
|
(
|
||||||
|
X"3c011234", -- [0x00400000] lui $1, 4660
|
||||||
|
X"34225678", -- [0x00400004] ori $2, $1, 22136
|
||||||
|
X"3c012345", -- [0x00400008] lui $1, 9029
|
||||||
|
X"34236789", -- [0x0040000c] ori $3, $1, 26505
|
||||||
|
X"3c018765", -- [0x00400010] lui $1, -30875
|
||||||
|
X"34244321", -- [0x00400014] ori $4, $1, 17185
|
||||||
|
X"3c019876", -- [0x00400018] lui $1, -26506
|
||||||
|
X"34255432", -- [0x0040001c] ori $5, $1, 21554
|
||||||
|
X"00000000", -- [0x00400020] nop
|
||||||
|
X"00427823", -- [0x00400024] subu $15, $2, $2
|
||||||
|
X"00437823", -- [0x00400028] subu $15, $2, $3
|
||||||
|
X"00447823", -- [0x0040002c] subu $15, $2, $4
|
||||||
|
X"00457823", -- [0x00400030] subu $15, $2, $5
|
||||||
|
X"00627823", -- [0x00400034] subu $15, $3, $2
|
||||||
|
X"00637823", -- [0x00400038] subu $15, $3, $3
|
||||||
|
X"00647823", -- [0x0040003c] subu $15, $3, $4
|
||||||
|
X"00657823", -- [0x00400040] subu $15, $3, $5
|
||||||
|
X"00827823", -- [0x00400044] subu $15, $4, $2
|
||||||
|
X"00837823", -- [0x00400048] subu $15, $4, $3
|
||||||
|
X"00847823", -- [0x0040004c] subu $15, $4, $4
|
||||||
|
X"00857823", -- [0x00400050] subu $15, $4, $5
|
||||||
|
X"00a27823", -- [0x00400054] subu $15, $5, $2
|
||||||
|
X"00a37823", -- [0x00400058] subu $15, $5, $3
|
||||||
|
X"00a47823", -- [0x0040005c] subu $15, $5, $4
|
||||||
|
X"00a57823", -- [0x00400060] subu $15, $5, $5
|
||||||
|
X"00000000", -- [0x00400064] nop
|
||||||
|
X"00427822", -- [0x00400068] sub $15, $2, $2
|
||||||
|
X"00437822", -- [0x0040006c] sub $15, $2, $3
|
||||||
|
X"00447822", -- [0x00400070] sub $15, $2, $4
|
||||||
|
X"00457822", -- [0x00400074] sub $15, $2, $5
|
||||||
|
X"00627822", -- [0x00400078] sub $15, $3, $2
|
||||||
|
X"00637822", -- [0x0040007c] sub $15, $3, $3
|
||||||
|
X"00647822", -- [0x00400080] sub $15, $3, $4
|
||||||
|
X"00657822", -- [0x00400084] sub $15, $3, $5
|
||||||
|
X"00827822", -- [0x00400088] sub $15, $4, $2
|
||||||
|
X"00837822", -- [0x0040008c] sub $15, $4, $3
|
||||||
|
X"00847822", -- [0x00400090] sub $15, $4, $4
|
||||||
|
X"00857822", -- [0x00400094] sub $15, $4, $5
|
||||||
|
X"00a27822", -- [0x00400098] sub $15, $5, $2
|
||||||
|
X"00a37822", -- [0x0040009c] sub $15, $5, $3
|
||||||
|
X"00a47822", -- [0x004000a0] sub $15, $5, $4
|
||||||
|
X"00a57822", -- [0x004000a4] sub $15, $5, $5
|
||||||
|
X"00000000", -- [0x004000a8] nop
|
||||||
|
X"08104000", -- [0x004000ac] j 0x00410000 [main]
|
||||||
|
X"00000000", -- [0x004000b0] nop
|
||||||
|
X"00000000", -- [0x004000b4]
|
||||||
|
X"00000000", -- [0x004000b8]
|
||||||
|
X"00000000", -- [0x004000bc]
|
||||||
|
X"00000000", -- [0x004000c0]
|
||||||
|
X"00000000", -- [0x004000c4]
|
||||||
|
X"00000000", -- [0x004000c8]
|
||||||
|
X"00000000", -- [0x004000cc]
|
||||||
|
X"00000000", -- [0x004000d0]
|
||||||
|
X"00000000", -- [0x004000d4]
|
||||||
|
X"00000000", -- [0x004000d8]
|
||||||
|
X"00000000", -- [0x004000dc]
|
||||||
|
X"00000000", -- [0x004000e0]
|
||||||
|
X"00000000", -- [0x004000e4]
|
||||||
|
X"00000000", -- [0x004000e8]
|
||||||
|
X"00000000", -- [0x004000ec]
|
||||||
|
X"00000000", -- [0x004000f0]
|
||||||
|
X"00000000", -- [0x004000f4]
|
||||||
|
X"00000000", -- [0x004000f8]
|
||||||
|
X"00000000" -- [0x004000fc]
|
||||||
|
);
|
||||||
|
|
||||||
|
begin
|
||||||
|
|
||||||
|
PROM_READ:
|
||||||
|
dout <= word_array(to_integer(addr));
|
||||||
|
|
||||||
|
end itest;
|
||||||
@@ -0,0 +1,332 @@
|
|||||||
|
-------------------------------------------------------------------------
|
||||||
|
-- Project: JCPU, a portable 8-bit RISC CPU written in VHDL
|
||||||
|
-- This file: cpu_embedded using cpu_core and rom
|
||||||
|
--
|
||||||
|
-- Copyright (C) 2007 J. Ahrensfeld
|
||||||
|
--
|
||||||
|
-- This program is free software: you can redistribute it and/or modify
|
||||||
|
-- it under the terms of the GNU General Public License as published by
|
||||||
|
-- the Free Software Foundation, either version 3 of the License, or
|
||||||
|
-- (at your option) any later version.
|
||||||
|
--
|
||||||
|
-- This program 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 General Public License for more details.
|
||||||
|
--
|
||||||
|
-- You should have received a copy of the GNU General Public License
|
||||||
|
-- along with this program. If not, see <http://www.gnu.org/licenses/>.
|
||||||
|
--
|
||||||
|
-- For questions and ideas, please contact the author at jens@jayfield.org
|
||||||
|
--
|
||||||
|
--------------------------------------------------------------------------
|
||||||
|
|
||||||
|
library IEEE;
|
||||||
|
use IEEE.STD_LOGIC_1164.ALL;
|
||||||
|
use IEEE.numeric_std.ALL;
|
||||||
|
|
||||||
|
library work;
|
||||||
|
use work.mips_types.all;
|
||||||
|
|
||||||
|
entity mips_embedded is
|
||||||
|
Port
|
||||||
|
(
|
||||||
|
rst : in STD_LOGIC;
|
||||||
|
clk : in STD_LOGIC;
|
||||||
|
halt : in STD_LOGIC;
|
||||||
|
int : in unsigned(5 downto 0);
|
||||||
|
rxd : in STD_LOGIC;
|
||||||
|
txd : out STD_LOGIC;
|
||||||
|
dout : out word_t
|
||||||
|
);
|
||||||
|
end mips_embedded;
|
||||||
|
|
||||||
|
architecture rtl of mips_embedded is
|
||||||
|
|
||||||
|
COMPONENT mips_top
|
||||||
|
Port
|
||||||
|
(
|
||||||
|
rst : in STD_LOGIC;
|
||||||
|
clk : in STD_LOGIC;
|
||||||
|
int : in unsigned(5 downto 0);
|
||||||
|
mem_rdy : in STD_LOGIC;
|
||||||
|
mem_re : out STD_LOGIC;
|
||||||
|
mem_en : out STD_LOGIC;
|
||||||
|
mem_we : out unsigned(3 downto 0);
|
||||||
|
mem_din : in word_t;
|
||||||
|
mem_dout : out word_t;
|
||||||
|
mem_addr : out word_t
|
||||||
|
|
||||||
|
);
|
||||||
|
END COMPONENT;
|
||||||
|
|
||||||
|
signal mem_din : word_t;
|
||||||
|
signal mem_dout : word_t;
|
||||||
|
signal mem_addr : word_t;
|
||||||
|
signal mem_re : std_logic;
|
||||||
|
signal mem_en : std_logic;
|
||||||
|
signal mem_we : unsigned(3 downto 0);
|
||||||
|
signal mem_rdy : std_logic;
|
||||||
|
|
||||||
|
subtype tick_usec_t is natural range 0 to 99;
|
||||||
|
signal tick_usec : tick_usec_t;
|
||||||
|
signal cnt_usec : word_t;
|
||||||
|
signal cnt_sec : word_t;
|
||||||
|
signal cnt_usec_preset : word_t;
|
||||||
|
signal cnt_sec_preset : word_t;
|
||||||
|
signal cnt_usec_en : std_logic;
|
||||||
|
signal cnt_usec_we : std_logic;
|
||||||
|
signal cnt_sec_en : std_logic;
|
||||||
|
signal cnt_sec_we : std_logic;
|
||||||
|
|
||||||
|
COMPONENT uart_tx
|
||||||
|
Port
|
||||||
|
(
|
||||||
|
data_in : in std_logic_vector(7 downto 0);
|
||||||
|
write_buffer : in std_logic;
|
||||||
|
reset_buffer : in std_logic;
|
||||||
|
en_16_x_baud : in std_logic;
|
||||||
|
serial_out : out std_logic;
|
||||||
|
buffer_full : out std_logic;
|
||||||
|
buffer_half_full : out std_logic;
|
||||||
|
clk : in std_logic
|
||||||
|
);
|
||||||
|
END COMPONENT;
|
||||||
|
|
||||||
|
COMPONENT uart_rx
|
||||||
|
Port
|
||||||
|
(
|
||||||
|
serial_in : in std_logic;
|
||||||
|
data_out : out std_logic_vector(7 downto 0);
|
||||||
|
read_buffer : in std_logic;
|
||||||
|
reset_buffer : in std_logic;
|
||||||
|
en_16_x_baud : in std_logic;
|
||||||
|
buffer_data_present : out std_logic;
|
||||||
|
buffer_full : out std_logic;
|
||||||
|
buffer_half_full : out std_logic;
|
||||||
|
clk : in std_logic
|
||||||
|
);
|
||||||
|
END COMPONENT;
|
||||||
|
|
||||||
|
signal baud_count : unsigned(7 downto 0);
|
||||||
|
signal en_16_x_baud : std_logic;
|
||||||
|
signal reg_we_uart_tx : std_logic;
|
||||||
|
signal tx_full : std_logic;
|
||||||
|
signal tx_half_full : std_logic;
|
||||||
|
signal reg_uart_tx : unsigned(7 downto 0);
|
||||||
|
signal reg_re_uart_rx : std_logic;
|
||||||
|
signal reg_uart_rx : std_logic_vector(7 downto 0);
|
||||||
|
signal rx_data_present : std_logic;
|
||||||
|
signal rx_full : std_logic;
|
||||||
|
signal rx_half_full : std_logic;
|
||||||
|
signal uart_status_port : unsigned(7 downto 0);
|
||||||
|
signal reg_uart_ctrl : unsigned(7 downto 0);
|
||||||
|
signal reg_uart_baud : unsigned(7 downto 0);
|
||||||
|
|
||||||
|
begin
|
||||||
|
|
||||||
|
registers_write:
|
||||||
|
process(clk)
|
||||||
|
begin
|
||||||
|
if rising_edge(clk) then
|
||||||
|
reg_we_uart_tx <= '0';
|
||||||
|
cnt_usec_we <= '0';
|
||||||
|
cnt_sec_we <= '0';
|
||||||
|
if rst = '1' then
|
||||||
|
dout <= (others => '0');
|
||||||
|
reg_uart_baud <= to_unsigned(53, 8);
|
||||||
|
reg_uart_ctrl <= to_unsigned(0, 8);
|
||||||
|
elsif mem_en = '1' then
|
||||||
|
case mem_addr(5 downto 2) is
|
||||||
|
|
||||||
|
when "0000" =>
|
||||||
|
if mem_we(0) = '1' then
|
||||||
|
dout(7 downto 0) <= mem_dout(7 downto 0);
|
||||||
|
end if;
|
||||||
|
if mem_we(1) = '1' then
|
||||||
|
dout(15 downto 8) <= mem_dout(15 downto 8);
|
||||||
|
end if;
|
||||||
|
if mem_we(2) = '1' then
|
||||||
|
dout(23 downto 16) <= mem_dout(23 downto 16);
|
||||||
|
end if;
|
||||||
|
if mem_we(3) = '1' then
|
||||||
|
dout(31 downto 24) <= mem_dout(31 downto 24);
|
||||||
|
end if;
|
||||||
|
|
||||||
|
when "0001" =>
|
||||||
|
if mem_we(0) = '1' then
|
||||||
|
reg_we_uart_tx <= '1';
|
||||||
|
reg_uart_tx <= mem_dout(7 downto 0);
|
||||||
|
end if;
|
||||||
|
|
||||||
|
when "0010" =>
|
||||||
|
if mem_we(0) = '1' then
|
||||||
|
reg_uart_ctrl <= mem_dout(7 downto 0);
|
||||||
|
end if;
|
||||||
|
if mem_we(1) = '1' then
|
||||||
|
reg_uart_baud <= mem_dout(15 downto 8);
|
||||||
|
end if;
|
||||||
|
|
||||||
|
when "0100" =>
|
||||||
|
if mem_we(3) = '1' then
|
||||||
|
cnt_usec_we <= '1';
|
||||||
|
cnt_usec_preset <= mem_dout;
|
||||||
|
end if;
|
||||||
|
|
||||||
|
when "0101" =>
|
||||||
|
if mem_we(3) = '1' then
|
||||||
|
cnt_sec_we <= '1';
|
||||||
|
cnt_sec_preset <= mem_dout;
|
||||||
|
end if;
|
||||||
|
|
||||||
|
when others => null;
|
||||||
|
end case;
|
||||||
|
end if;
|
||||||
|
end if;
|
||||||
|
end process;
|
||||||
|
|
||||||
|
registers_read:
|
||||||
|
process(clk)
|
||||||
|
begin
|
||||||
|
if rising_edge(clk) then
|
||||||
|
reg_re_uart_rx <= '0';
|
||||||
|
if mem_en = '1' then
|
||||||
|
mem_din <= (others => '0');
|
||||||
|
case mem_addr(5 downto 2) is
|
||||||
|
|
||||||
|
when "0000" => null;
|
||||||
|
|
||||||
|
when "0001" =>
|
||||||
|
reg_re_uart_rx <= '1';
|
||||||
|
mem_din(7 downto 0) <= unsigned(reg_uart_rx);
|
||||||
|
|
||||||
|
when "0010" =>
|
||||||
|
mem_din(7 downto 0) <= uart_status_port;
|
||||||
|
mem_din(15 downto 8) <= reg_uart_baud;
|
||||||
|
|
||||||
|
when "0100" =>
|
||||||
|
mem_din <= cnt_usec;
|
||||||
|
|
||||||
|
when "0101" =>
|
||||||
|
mem_din <= cnt_sec;
|
||||||
|
|
||||||
|
when others => null;
|
||||||
|
end case;
|
||||||
|
end if;
|
||||||
|
end if;
|
||||||
|
end process;
|
||||||
|
|
||||||
|
mem_rdy <= not halt;
|
||||||
|
|
||||||
|
inst_mips_top: mips_top
|
||||||
|
PORT MAP
|
||||||
|
(
|
||||||
|
rst => rst,
|
||||||
|
clk => clk,
|
||||||
|
int => int,
|
||||||
|
mem_rdy => mem_rdy,
|
||||||
|
mem_en => mem_en,
|
||||||
|
mem_we => mem_we,
|
||||||
|
mem_din => mem_din,
|
||||||
|
mem_dout => mem_dout,
|
||||||
|
mem_addr => mem_addr
|
||||||
|
);
|
||||||
|
|
||||||
|
inst_uart_tx: uart_tx
|
||||||
|
port map
|
||||||
|
(
|
||||||
|
data_in => std_logic_vector(reg_uart_tx),
|
||||||
|
write_buffer => reg_we_uart_tx,
|
||||||
|
reset_buffer => rst,
|
||||||
|
en_16_x_baud => en_16_x_baud,
|
||||||
|
serial_out => txd,
|
||||||
|
buffer_full => tx_full,
|
||||||
|
buffer_half_full => tx_half_full,
|
||||||
|
clk => clk
|
||||||
|
);
|
||||||
|
|
||||||
|
inst_uart_rx: uart_rx
|
||||||
|
port map
|
||||||
|
(
|
||||||
|
serial_in => rxd,
|
||||||
|
data_out => reg_uart_rx,
|
||||||
|
read_buffer => reg_re_uart_rx,
|
||||||
|
reset_buffer => rst,
|
||||||
|
en_16_x_baud => en_16_x_baud,
|
||||||
|
buffer_data_present => rx_data_present,
|
||||||
|
buffer_full => rx_full,
|
||||||
|
buffer_half_full => rx_half_full,
|
||||||
|
clk => clk
|
||||||
|
);
|
||||||
|
|
||||||
|
uart_status_port <= (7 downto 5 => '0') & rx_data_present & rx_full & rx_half_full & tx_full & tx_half_full;
|
||||||
|
|
||||||
|
tick_usec_timer:
|
||||||
|
process(clk)
|
||||||
|
begin
|
||||||
|
if clk'event and clk='1' then
|
||||||
|
cnt_usec_en <= '0';
|
||||||
|
if rst = '1' then
|
||||||
|
tick_usec <= 0;
|
||||||
|
cnt_usec_en <= '0';
|
||||||
|
elsif tick_usec = tick_usec_t'high then
|
||||||
|
tick_usec <= 0;
|
||||||
|
cnt_usec_en <= '1';
|
||||||
|
else
|
||||||
|
tick_usec <= tick_usec + 1;
|
||||||
|
end if;
|
||||||
|
end if;
|
||||||
|
end process;
|
||||||
|
|
||||||
|
cnt_usec_timer:
|
||||||
|
process(clk)
|
||||||
|
begin
|
||||||
|
if clk'event and clk='1' then
|
||||||
|
cnt_sec_en <= '0';
|
||||||
|
if rst = '1' then
|
||||||
|
cnt_usec <= (others => '0');
|
||||||
|
cnt_sec_en <= '0';
|
||||||
|
elsif cnt_usec_we = '1' then
|
||||||
|
cnt_usec <= cnt_usec_preset;
|
||||||
|
elsif cnt_usec_en = '1' then
|
||||||
|
if cnt_usec = to_unsigned(1E6 - 1, word_t'length) then
|
||||||
|
cnt_usec <= (others => '0');
|
||||||
|
cnt_sec_en <= '1';
|
||||||
|
else
|
||||||
|
cnt_usec <= cnt_usec + 1;
|
||||||
|
end if;
|
||||||
|
end if;
|
||||||
|
end if;
|
||||||
|
end process;
|
||||||
|
|
||||||
|
cnt_sec_timer:
|
||||||
|
process(clk)
|
||||||
|
begin
|
||||||
|
if clk'event and clk='1' then
|
||||||
|
if rst = '1' then
|
||||||
|
cnt_sec <= (others => '0');
|
||||||
|
elsif cnt_sec_we = '1' then
|
||||||
|
cnt_sec <= cnt_sec_preset;
|
||||||
|
elsif cnt_sec_en = '1' then
|
||||||
|
cnt_sec <= cnt_sec + 1;
|
||||||
|
end if;
|
||||||
|
end if;
|
||||||
|
end process;
|
||||||
|
|
||||||
|
baud_timer:
|
||||||
|
process(clk)
|
||||||
|
begin
|
||||||
|
if clk'event and clk='1' then
|
||||||
|
if rst = '1' then
|
||||||
|
baud_count <= (others => '0');
|
||||||
|
elsif baud_count = reg_uart_baud then
|
||||||
|
baud_count <= (others => '0');
|
||||||
|
en_16_x_baud <= '1';
|
||||||
|
else
|
||||||
|
baud_count <= baud_count + 1;
|
||||||
|
en_16_x_baud <= '0';
|
||||||
|
end if;
|
||||||
|
end if;
|
||||||
|
end process;
|
||||||
|
|
||||||
|
end rtl;
|
||||||
@@ -0,0 +1,137 @@
|
|||||||
|
--------------------------------------------------------------------------
|
||||||
|
-- Project: JIPS, a portable 32-bit RISC CPU written in VHDL
|
||||||
|
-- This file: JIPS top file
|
||||||
|
--
|
||||||
|
-- Copyright (C) 2007 J. Ahrensfeld
|
||||||
|
--
|
||||||
|
-- This program is free software: you can redistribute it and/or modify
|
||||||
|
-- it under the terms of the GNU General Public License as published by
|
||||||
|
-- the Free Software Foundation, either version 3 of the License, or
|
||||||
|
-- (at your option) any later version.
|
||||||
|
--
|
||||||
|
-- This program 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 General Public License for more details.
|
||||||
|
--
|
||||||
|
-- You should have received a copy of the GNU General Public License
|
||||||
|
-- along with this program. If not, see <http://www.gnu.org/licenses/>.
|
||||||
|
--
|
||||||
|
-- For questions and ideas, please contact the author at jens@jayfield.org
|
||||||
|
--
|
||||||
|
--------------------------------------------------------------------------
|
||||||
|
|
||||||
|
library IEEE;
|
||||||
|
use IEEE.STD_LOGIC_1164.ALL;
|
||||||
|
use IEEE.numeric_std.ALL;
|
||||||
|
|
||||||
|
library work;
|
||||||
|
use work.mips_types.all;
|
||||||
|
|
||||||
|
entity mips_embedded_syn is
|
||||||
|
Port
|
||||||
|
(
|
||||||
|
sys_rst_n_in : in STD_LOGIC;
|
||||||
|
sys_clk_in : in STD_LOGIC;
|
||||||
|
sys_dip : in STD_LOGIC_VECTOR (7 downto 0);
|
||||||
|
sys_btn : in STD_LOGIC_VECTOR (8 downto 0);
|
||||||
|
sys_led : out STD_LOGIC_VECTOR (7 downto 0);
|
||||||
|
sys_rx : in STD_LOGIC;
|
||||||
|
sys_tx : out STD_LOGIC;
|
||||||
|
sys_error : out STD_LOGIC_VECTOR (1 downto 0)
|
||||||
|
);
|
||||||
|
|
||||||
|
end mips_embedded_syn;
|
||||||
|
|
||||||
|
architecture struct of mips_embedded_syn is
|
||||||
|
|
||||||
|
COMPONENT mips_embedded
|
||||||
|
Port
|
||||||
|
(
|
||||||
|
rst : in STD_LOGIC;
|
||||||
|
clk : in STD_LOGIC;
|
||||||
|
halt : in STD_LOGIC;
|
||||||
|
int : in unsigned(5 downto 0);
|
||||||
|
rxd : in STD_LOGIC;
|
||||||
|
txd : out STD_LOGIC;
|
||||||
|
dout : out word_t
|
||||||
|
);
|
||||||
|
END COMPONENT;
|
||||||
|
|
||||||
|
signal dout : word_t;
|
||||||
|
signal rst : STD_LOGIC;
|
||||||
|
signal clk : STD_LOGIC;
|
||||||
|
signal halt : STD_LOGIC;
|
||||||
|
signal int : unsigned(5 downto 0);
|
||||||
|
signal btn_r : unsigned (8 downto 0);
|
||||||
|
signal dip_r : unsigned (7 downto 0);
|
||||||
|
|
||||||
|
begin
|
||||||
|
|
||||||
|
-------------------------------------------------------------------
|
||||||
|
inst_mips_embedded: mips_embedded
|
||||||
|
PORT MAP
|
||||||
|
(
|
||||||
|
rst => rst,
|
||||||
|
clk => clk,
|
||||||
|
halt => halt,
|
||||||
|
int => int,
|
||||||
|
rxd => sys_rx,
|
||||||
|
txd => sys_tx,
|
||||||
|
dout => dout
|
||||||
|
);
|
||||||
|
|
||||||
|
clk <= sys_clk_in;
|
||||||
|
rst <= not sys_rst_n_in;
|
||||||
|
|
||||||
|
ERR_LED_reg:
|
||||||
|
process(rst, clk)
|
||||||
|
begin
|
||||||
|
if rst = '1' then
|
||||||
|
sys_error <= (others => '1');
|
||||||
|
elsif rising_edge(clk) then
|
||||||
|
sys_error <= STD_LOGIC_VECTOR(dout(31 downto 30));
|
||||||
|
end if;
|
||||||
|
end process;
|
||||||
|
|
||||||
|
LED_reg:
|
||||||
|
process(rst, clk)
|
||||||
|
begin
|
||||||
|
if rst = '1' then
|
||||||
|
sys_led <= (others => '0');
|
||||||
|
elsif rising_edge(clk) then
|
||||||
|
sys_led <= STD_LOGIC_VECTOR(dout(7 downto 0));
|
||||||
|
end if;
|
||||||
|
end process;
|
||||||
|
|
||||||
|
DIP_reg:
|
||||||
|
process(rst, clk)
|
||||||
|
begin
|
||||||
|
if rst = '1' then
|
||||||
|
dip_r <= (others => '0');
|
||||||
|
elsif rising_edge(clk) then
|
||||||
|
dip_r <= unsigned(sys_dip);
|
||||||
|
end if;
|
||||||
|
end process;
|
||||||
|
|
||||||
|
BTN_reg:
|
||||||
|
process(rst, clk)
|
||||||
|
begin
|
||||||
|
if rst = '1' then
|
||||||
|
btn_r <= (others => '0');
|
||||||
|
elsif rising_edge(clk) then
|
||||||
|
btn_r <= unsigned(sys_btn);
|
||||||
|
end if;
|
||||||
|
end process;
|
||||||
|
|
||||||
|
halt <= btn_r(4) after 6.5 ns;
|
||||||
|
int(0) <= dip_r(0) and btn_r(3) after 1 ns;
|
||||||
|
int(1) <= dip_r(1) and btn_r(3) after 1 ns;
|
||||||
|
int(2) <= dip_r(2) and btn_r(3) after 1 ns;
|
||||||
|
int(3) <= dip_r(3) and btn_r(3) after 1 ns;
|
||||||
|
int(4) <= dip_r(4) and btn_r(3) after 1 ns;
|
||||||
|
int(5) <= dip_r(5) and btn_r(3) after 1 ns;
|
||||||
|
|
||||||
|
-------------------------------------------------------------------
|
||||||
|
|
||||||
|
end struct;
|
||||||
@@ -0,0 +1,115 @@
|
|||||||
|
-------------------------------------------------------------------------
|
||||||
|
-- Project: JCPU, a portable 8-bit RISC CPU written in VHDL
|
||||||
|
-- This file: The ROM file for use in your VHDL design
|
||||||
|
--
|
||||||
|
-- Copyright (C) 2007 J. Ahrensfeld
|
||||||
|
--
|
||||||
|
-- This program is free software: you can redistribute it and/or modify
|
||||||
|
-- it under the terms of the GNU General Public License as published by
|
||||||
|
-- the Free Software Foundation, either version 3 of the License, or
|
||||||
|
-- (at your option) any later version.
|
||||||
|
--
|
||||||
|
-- This program 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 General Public License for more details.
|
||||||
|
--
|
||||||
|
-- You should have received a copy of the GNU General Public License
|
||||||
|
-- along with this program. If not, see <http://www.gnu.org/licenses/>.
|
||||||
|
--
|
||||||
|
-- For questions and ideas, please contact the author at jens@jayfield.org
|
||||||
|
--
|
||||||
|
--------------------------------------------------------------------------
|
||||||
|
|
||||||
|
LIBRARY ieee;
|
||||||
|
use IEEE.STD_LOGIC_1164.ALL;
|
||||||
|
USE ieee.numeric_std.ALL;
|
||||||
|
|
||||||
|
|
||||||
|
ENTITY ram IS
|
||||||
|
Generic
|
||||||
|
(
|
||||||
|
word_addr_width : integer := 6
|
||||||
|
);
|
||||||
|
Port
|
||||||
|
(
|
||||||
|
clk : in STD_LOGIC;
|
||||||
|
we : in unsigned(3 downto 0);
|
||||||
|
ce : in STD_LOGIC;
|
||||||
|
addr : in unsigned(31 downto 0);
|
||||||
|
din : in unsigned(31 downto 0);
|
||||||
|
dout : out unsigned(31 downto 0)
|
||||||
|
);
|
||||||
|
END ram;
|
||||||
|
|
||||||
|
ARCHITECTURE behavior OF ram IS
|
||||||
|
|
||||||
|
constant depth : natural := 2**word_addr_width;
|
||||||
|
|
||||||
|
type sram_t is array (0 to depth-1) of unsigned(7 downto 0);
|
||||||
|
|
||||||
|
function sram_clear return sram_t is
|
||||||
|
|
||||||
|
variable result : sram_t;
|
||||||
|
begin
|
||||||
|
for i in 0 to sram_t'length-1 loop
|
||||||
|
result(i) := (others => '0');
|
||||||
|
end loop;
|
||||||
|
return result;
|
||||||
|
end sram_clear;
|
||||||
|
|
||||||
|
signal sram0, sram1, sram2, sram3 : sram_t := sram_clear;
|
||||||
|
|
||||||
|
BEGIN
|
||||||
|
|
||||||
|
|
||||||
|
SRAM_RW:
|
||||||
|
process(clk)
|
||||||
|
variable index : natural range 0 to depth-1;
|
||||||
|
begin
|
||||||
|
if rising_edge(clk) and ce = '1' then
|
||||||
|
index := to_integer(addr(word_addr_width+1 downto 2));
|
||||||
|
if we(0) = '1' then
|
||||||
|
sram0(index)<= din(7 downto 0);
|
||||||
|
end if;
|
||||||
|
dout(7 downto 0) <= sram0(index);
|
||||||
|
end if;
|
||||||
|
end process;
|
||||||
|
|
||||||
|
process(clk)
|
||||||
|
variable index : natural range 0 to depth-1;
|
||||||
|
begin
|
||||||
|
if rising_edge(clk) and ce = '1' then
|
||||||
|
index := to_integer(addr(word_addr_width+1 downto 2));
|
||||||
|
if we(1) = '1' then
|
||||||
|
sram1(index)<= din(15 downto 8);
|
||||||
|
end if;
|
||||||
|
dout(15 downto 8) <= sram1(index);
|
||||||
|
end if;
|
||||||
|
end process;
|
||||||
|
|
||||||
|
process(clk)
|
||||||
|
variable index : natural range 0 to depth-1;
|
||||||
|
begin
|
||||||
|
if rising_edge(clk) and ce = '1' then
|
||||||
|
index := to_integer(addr(word_addr_width+1 downto 2));
|
||||||
|
if we(2) = '1' then
|
||||||
|
sram2(index)<= din(23 downto 16);
|
||||||
|
end if;
|
||||||
|
dout(23 downto 16) <= sram2(index);
|
||||||
|
end if;
|
||||||
|
end process;
|
||||||
|
|
||||||
|
process(clk)
|
||||||
|
variable index : natural range 0 to depth-1;
|
||||||
|
begin
|
||||||
|
if rising_edge(clk) and ce = '1' then
|
||||||
|
index := to_integer(addr(word_addr_width+1 downto 2));
|
||||||
|
if we(3) = '1' then
|
||||||
|
sram3(index)<= din(31 downto 24);
|
||||||
|
end if;
|
||||||
|
dout(31 downto 24) <= sram3(index);
|
||||||
|
end if;
|
||||||
|
end process;
|
||||||
|
|
||||||
|
end behavior;
|
||||||
@@ -0,0 +1,177 @@
|
|||||||
|
-------------------------------------------------------------------------
|
||||||
|
-- Project: JCPU, a portable 8-bit RISC CPU written in VHDL
|
||||||
|
-- This file: The ROM file for use in your VHDL design
|
||||||
|
--
|
||||||
|
-- Copyright (C) 2007 J. Ahrensfeld
|
||||||
|
--
|
||||||
|
-- This program is free software: you can redistribute it and/or modify
|
||||||
|
-- it under the terms of the GNU General Public License as published by
|
||||||
|
-- the Free Software Foundation, either version 3 of the License, or
|
||||||
|
-- (at your option) any later version.
|
||||||
|
--
|
||||||
|
-- This program 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 General Public License for more details.
|
||||||
|
--
|
||||||
|
-- You should have received a copy of the GNU General Public License
|
||||||
|
-- along with this program. If not, see <http://www.gnu.org/licenses/>.
|
||||||
|
--
|
||||||
|
-- For questions and ideas, please contact the author at jens@jayfield.org
|
||||||
|
--
|
||||||
|
--------------------------------------------------------------------------
|
||||||
|
|
||||||
|
LIBRARY ieee;
|
||||||
|
use IEEE.STD_LOGIC_1164.ALL;
|
||||||
|
USE ieee.numeric_std.ALL;
|
||||||
|
|
||||||
|
library UNISIM;
|
||||||
|
use UNISIM.VComponents.all;
|
||||||
|
|
||||||
|
ENTITY ram IS
|
||||||
|
Generic
|
||||||
|
(
|
||||||
|
word_addr_width : integer := 6
|
||||||
|
);
|
||||||
|
Port
|
||||||
|
(
|
||||||
|
clk : in STD_LOGIC;
|
||||||
|
ce : in STD_LOGIC;
|
||||||
|
we : in unsigned(3 downto 0);
|
||||||
|
addr : in unsigned(31 downto 0);
|
||||||
|
din : in unsigned(31 downto 0);
|
||||||
|
dout : out unsigned(31 downto 0)
|
||||||
|
);
|
||||||
|
END ram;
|
||||||
|
|
||||||
|
ARCHITECTURE behavior OF ram IS
|
||||||
|
|
||||||
|
COMPONENT dpram_2w2r
|
||||||
|
Generic
|
||||||
|
(
|
||||||
|
addr_width : integer;
|
||||||
|
data_width : integer
|
||||||
|
);
|
||||||
|
Port
|
||||||
|
(
|
||||||
|
clk_a : in STD_LOGIC;
|
||||||
|
clk_b : in STD_LOGIC;
|
||||||
|
en_a : in STD_LOGIC;
|
||||||
|
en_b : in STD_LOGIC;
|
||||||
|
we_a : in STD_LOGIC;
|
||||||
|
we_b : in STD_LOGIC;
|
||||||
|
addr_a : in unsigned (addr_width-1 downto 0);
|
||||||
|
addr_b : in unsigned (addr_width-1 downto 0);
|
||||||
|
din_a : in unsigned (data_width-1 downto 0);
|
||||||
|
din_b : in unsigned (data_width-1 downto 0);
|
||||||
|
dout_a : out unsigned (data_width-1 downto 0);
|
||||||
|
dout_b : out unsigned (data_width-1 downto 0)
|
||||||
|
);
|
||||||
|
END COMPONENT;
|
||||||
|
|
||||||
|
signal jtag_clk : STD_LOGIC;
|
||||||
|
signal jtag_we : unsigned(3 downto 0);
|
||||||
|
signal jtag_addr : unsigned (15 downto 0);
|
||||||
|
signal jtag_dout : unsigned (31 downto 0);
|
||||||
|
signal jtag_din : unsigned (31 downto 0);
|
||||||
|
signal bs_rst, bs_sel, bs_shift, bs_tdi, bs_tdo : std_logic;
|
||||||
|
signal bs_capture, bs_clk0, bs_clk1, bs_update0, bs_update1 : std_logic;
|
||||||
|
signal user_regi, user_rego : unsigned (47 downto 0);
|
||||||
|
|
||||||
|
BEGIN
|
||||||
|
|
||||||
|
gen_sram:
|
||||||
|
for i in 0 to 3 generate
|
||||||
|
begin
|
||||||
|
inst_dpram_2w2r : dpram_2w2r
|
||||||
|
GENERIC MAP
|
||||||
|
(
|
||||||
|
addr_width => word_addr_width,
|
||||||
|
data_width => 8
|
||||||
|
)
|
||||||
|
PORT MAP
|
||||||
|
(
|
||||||
|
clk_a => clk,
|
||||||
|
en_a => ce,
|
||||||
|
we_a => we(i),
|
||||||
|
addr_a => addr(word_addr_width+1 downto 2),
|
||||||
|
din_a => din((i+1)*8-1 downto i*8),
|
||||||
|
dout_a => dout((i+1)*8-1 downto i*8),
|
||||||
|
|
||||||
|
clk_b => jtag_clk,
|
||||||
|
en_b => jtag_we(i),
|
||||||
|
we_b => jtag_we(i),
|
||||||
|
addr_b => jtag_addr(word_addr_width-1 downto 0),
|
||||||
|
din_b => jtag_din((i+1)*8-1 downto i*8),
|
||||||
|
dout_b => jtag_dout((i+1)*8-1 downto i*8)
|
||||||
|
);
|
||||||
|
end generate;
|
||||||
|
|
||||||
|
--------------------------------------------------------------------------
|
||||||
|
-- Virtex-4: JTAG Loader
|
||||||
|
--------------------------------------------------------------------------
|
||||||
|
i00_BUFG : BUFG
|
||||||
|
port map
|
||||||
|
(
|
||||||
|
O => bs_clk1,
|
||||||
|
I => bs_clk0
|
||||||
|
);
|
||||||
|
|
||||||
|
i01_BUFG : BUFG
|
||||||
|
port map
|
||||||
|
(
|
||||||
|
O => bs_update1,
|
||||||
|
I => bs_update0
|
||||||
|
);
|
||||||
|
|
||||||
|
BSCAN_VIRTEX4_inst2 : BSCAN_VIRTEX4
|
||||||
|
generic map
|
||||||
|
(
|
||||||
|
JTAG_CHAIN => 2 -- Value to set BSCAN site of device. Possible values: (1,2,3 or 4)
|
||||||
|
)
|
||||||
|
port map
|
||||||
|
(
|
||||||
|
CAPTURE => bs_capture, -- CAPTURE output from TAP controller
|
||||||
|
DRCK => bs_clk0, -- Data register output for USER functions
|
||||||
|
RESET => bs_rst, -- Reset output from TAP controller
|
||||||
|
SEL => bs_sel, -- USER active output
|
||||||
|
SHIFT => bs_shift, -- SHIFT output from TAP controller
|
||||||
|
TDI => bs_tdi, -- TDI output from TAP controller
|
||||||
|
UPDATE => bs_update0, -- UPDATE output from TAP controller
|
||||||
|
TDO => bs_tdo -- Data input for USER function
|
||||||
|
);
|
||||||
|
|
||||||
|
jtag_addr <= user_regi(user_regi'left downto jtag_dout'length);
|
||||||
|
jtag_din <= user_regi(jtag_dout'length-1 downto 0);
|
||||||
|
jtag_clk <= bs_update1;
|
||||||
|
jtag_we <= (3 downto 0 => bs_sel);
|
||||||
|
|
||||||
|
sipo:
|
||||||
|
process (bs_rst, bs_clk1, bs_tdi, bs_shift)
|
||||||
|
begin
|
||||||
|
if bs_rst = '1' then
|
||||||
|
user_regi <= (others => '0');
|
||||||
|
elsif rising_edge(bs_clk1) then
|
||||||
|
if bs_shift = '1' then
|
||||||
|
user_regi <= bs_tdi & user_regi(user_regi'left downto 1);
|
||||||
|
end if;
|
||||||
|
end if;
|
||||||
|
end process;
|
||||||
|
|
||||||
|
piso:
|
||||||
|
process (bs_rst, bs_clk1, bs_shift, user_rego)
|
||||||
|
begin
|
||||||
|
bs_tdo <= user_rego(0);
|
||||||
|
if bs_rst = '1' then
|
||||||
|
user_rego <= (others => '0');
|
||||||
|
elsif rising_edge(bs_clk1) then
|
||||||
|
if bs_shift = '1' then
|
||||||
|
user_rego <= user_rego(0) & user_rego(user_rego'left downto 1);
|
||||||
|
else
|
||||||
|
user_rego <= (user_rego'left downto jtag_dout'length => '0') & jtag_dout;
|
||||||
|
end if;
|
||||||
|
end if;
|
||||||
|
end process;
|
||||||
|
|
||||||
|
--------------------------------------------------------------------------
|
||||||
|
end behavior;
|
||||||
@@ -0,0 +1,88 @@
|
|||||||
|
-------------------------------------------------------------------------
|
||||||
|
-- Project: JCPU, a portable 8-bit RISC CPU written in VHDL
|
||||||
|
-- This file: The ROM file for use in your VHDL design
|
||||||
|
--
|
||||||
|
-- Copyright (C) 2007 J. Ahrensfeld
|
||||||
|
--
|
||||||
|
-- This program is free software: you can redistribute it and/or modify
|
||||||
|
-- it under the terms of the GNU General Public License as published by
|
||||||
|
-- the Free Software Foundation, either version 3 of the License, or
|
||||||
|
-- (at your option) any later version.
|
||||||
|
--
|
||||||
|
-- This program 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 General Public License for more details.
|
||||||
|
--
|
||||||
|
-- You should have received a copy of the GNU General Public License
|
||||||
|
-- along with this program. If not, see <http://www.gnu.org/licenses/>.
|
||||||
|
--
|
||||||
|
-- For questions and ideas, please contact the author at jens@jayfield.org
|
||||||
|
--
|
||||||
|
--------------------------------------------------------------------------
|
||||||
|
|
||||||
|
LIBRARY ieee;
|
||||||
|
use IEEE.STD_LOGIC_1164.ALL;
|
||||||
|
USE ieee.numeric_std.ALL;
|
||||||
|
|
||||||
|
|
||||||
|
ENTITY ram IS
|
||||||
|
Generic
|
||||||
|
(
|
||||||
|
word_addr_width : integer := 6
|
||||||
|
);
|
||||||
|
Port
|
||||||
|
(
|
||||||
|
clk : in STD_LOGIC;
|
||||||
|
ce : in STD_LOGIC;
|
||||||
|
we : in unsigned(3 downto 0);
|
||||||
|
addr : in unsigned(31 downto 0);
|
||||||
|
din : in unsigned(31 downto 0);
|
||||||
|
dout : out unsigned(31 downto 0)
|
||||||
|
);
|
||||||
|
END ram;
|
||||||
|
|
||||||
|
ARCHITECTURE behavior OF ram IS
|
||||||
|
|
||||||
|
constant depth : natural := 2**word_addr_width;
|
||||||
|
|
||||||
|
type sram_t is array (0 to depth-1) of unsigned(31 downto 0);
|
||||||
|
|
||||||
|
function sram_clear return sram_t is
|
||||||
|
|
||||||
|
variable result : sram_t;
|
||||||
|
begin
|
||||||
|
for i in 0 to sram_t'length-1 loop
|
||||||
|
result(i) := (others => '0');
|
||||||
|
end loop;
|
||||||
|
return result;
|
||||||
|
end sram_clear;
|
||||||
|
|
||||||
|
signal sram : sram_t := sram_clear;
|
||||||
|
|
||||||
|
BEGIN
|
||||||
|
|
||||||
|
|
||||||
|
SRAM_RW:
|
||||||
|
process(clk)
|
||||||
|
variable index : natural range 0 to depth-1;
|
||||||
|
begin
|
||||||
|
if rising_edge(clk) and ce = '1' then
|
||||||
|
index := to_integer(addr(word_addr_width+1 downto 2));
|
||||||
|
if we(0) = '1' then
|
||||||
|
sram(index)(7 downto 0) <= din(7 downto 0);
|
||||||
|
end if;
|
||||||
|
if we(1) = '1' then
|
||||||
|
sram(index)(15 downto 8) <= din(15 downto 8);
|
||||||
|
end if;
|
||||||
|
if we(2) = '1' then
|
||||||
|
sram(index)(23 downto 16) <= din(23 downto 16);
|
||||||
|
end if;
|
||||||
|
if we(3) = '1' then
|
||||||
|
sram(index)(31 downto 24) <= din(31 downto 24);
|
||||||
|
end if;
|
||||||
|
dout <= sram(index);
|
||||||
|
end if;
|
||||||
|
end process;
|
||||||
|
|
||||||
|
end behavior;
|
||||||
File diff suppressed because it is too large
Load Diff
@@ -0,0 +1,82 @@
|
|||||||
|
-------------------------------------------------------------------------
|
||||||
|
-- Project: JIPS, a portable 32-bit RISC CPU written in VHDL
|
||||||
|
-- This file: Testbench for JCPU
|
||||||
|
-- also writes 'opc.lst' for JASM-assembler
|
||||||
|
--
|
||||||
|
-- Copyright (C) 2007 J. Ahrensfeld
|
||||||
|
--
|
||||||
|
-- This program is free software: you can redistribute it and/or modify
|
||||||
|
-- it under the terms of the GNU General Public License as published by
|
||||||
|
-- the Free Software Foundation, either version 3 of the License, or
|
||||||
|
-- (at your option) any later version.
|
||||||
|
--
|
||||||
|
-- This program 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 General Public License for more details.
|
||||||
|
--
|
||||||
|
-- You should have received a copy of the GNU General Public License
|
||||||
|
-- along with this program. If not, see <http://www.gnu.org/licenses/>.
|
||||||
|
--
|
||||||
|
-- For questions and ideas, please contact the author at jens@jayfield.org
|
||||||
|
--
|
||||||
|
--------------------------------------------------------------------------
|
||||||
|
|
||||||
|
LIBRARY ieee;
|
||||||
|
use IEEE.STD_LOGIC_1164.ALL;
|
||||||
|
USE ieee.numeric_std.ALL;
|
||||||
|
use std.textio.all; -- Imports the standard textio package.
|
||||||
|
|
||||||
|
library work;
|
||||||
|
use work.mips_types.all;
|
||||||
|
|
||||||
|
ENTITY tb_mips_embedded IS
|
||||||
|
END tb_mips_embedded;
|
||||||
|
|
||||||
|
ARCHITECTURE behavior OF tb_mips_embedded IS
|
||||||
|
|
||||||
|
COMPONENT mips_embedded
|
||||||
|
Port
|
||||||
|
(
|
||||||
|
rst : in STD_LOGIC;
|
||||||
|
clk : in STD_LOGIC;
|
||||||
|
halt : in STD_LOGIC;
|
||||||
|
dout : out word_t
|
||||||
|
);
|
||||||
|
END COMPONENT;
|
||||||
|
|
||||||
|
constant CLK_PERIOD : time := 10 ns;
|
||||||
|
|
||||||
|
signal rst : std_logic := '1';
|
||||||
|
signal clk : std_logic := '1';
|
||||||
|
signal halt : std_logic := '0';
|
||||||
|
signal dout : word_t;
|
||||||
|
|
||||||
|
BEGIN
|
||||||
|
|
||||||
|
uut: mips_embedded
|
||||||
|
PORT MAP(
|
||||||
|
rst => rst,
|
||||||
|
clk => clk,
|
||||||
|
halt => halt,
|
||||||
|
dout => dout
|
||||||
|
);
|
||||||
|
|
||||||
|
CLK_GEN: process
|
||||||
|
begin
|
||||||
|
wait for CLK_PERIOD/2;
|
||||||
|
clk <= not clk;
|
||||||
|
end process;
|
||||||
|
|
||||||
|
STIMULUS: process
|
||||||
|
begin
|
||||||
|
|
||||||
|
wait for 3*CLK_PERIOD;
|
||||||
|
wait until rising_edge(clk);
|
||||||
|
rst <= '0';
|
||||||
|
|
||||||
|
wait;
|
||||||
|
|
||||||
|
end process;
|
||||||
|
|
||||||
|
END;
|
||||||
@@ -0,0 +1,123 @@
|
|||||||
|
-------------------------------------------------------------------------
|
||||||
|
-- Project: JIPS, a portable 32-bit RISC CPU written in VHDL
|
||||||
|
-- This file: Testbench for JCPU
|
||||||
|
-- also writes 'opc.lst' for JASM-assembler
|
||||||
|
--
|
||||||
|
-- Copyright (C) 2007 J. Ahrensfeld
|
||||||
|
--
|
||||||
|
-- This program is free software: you can redistribute it and/or modify
|
||||||
|
-- it under the terms of the GNU General Public License as published by
|
||||||
|
-- the Free Software Foundation, either version 3 of the License, or
|
||||||
|
-- (at your option) any later version.
|
||||||
|
--
|
||||||
|
-- This program 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 General Public License for more details.
|
||||||
|
--
|
||||||
|
-- You should have received a copy of the GNU General Public License
|
||||||
|
-- along with this program. If not, see <http://www.gnu.org/licenses/>.
|
||||||
|
--
|
||||||
|
-- For questions and ideas, please contact the author at jens@jayfield.org
|
||||||
|
--
|
||||||
|
--------------------------------------------------------------------------
|
||||||
|
|
||||||
|
LIBRARY ieee;
|
||||||
|
use IEEE.STD_LOGIC_1164.ALL;
|
||||||
|
USE ieee.numeric_std.ALL;
|
||||||
|
use std.textio.all; -- Imports the standard textio package.
|
||||||
|
|
||||||
|
ENTITY tb_mips_embedded_syn IS
|
||||||
|
END tb_mips_embedded_syn;
|
||||||
|
|
||||||
|
ARCHITECTURE behavior OF tb_mips_embedded_syn IS
|
||||||
|
|
||||||
|
COMPONENT mips_embedded_syn
|
||||||
|
Port
|
||||||
|
(
|
||||||
|
sys_rst_n_in : in STD_LOGIC;
|
||||||
|
sys_clk_in : in STD_LOGIC;
|
||||||
|
sys_dip : in STD_LOGIC_VECTOR (7 downto 0);
|
||||||
|
sys_btn : in STD_LOGIC_VECTOR (8 downto 0);
|
||||||
|
sys_led : out STD_LOGIC_VECTOR (7 downto 0);
|
||||||
|
sys_rx : in STD_LOGIC;
|
||||||
|
sys_tx : out STD_LOGIC;
|
||||||
|
sys_error : out STD_LOGIC_VECTOR (1 downto 0)
|
||||||
|
);
|
||||||
|
END COMPONENT;
|
||||||
|
|
||||||
|
constant CLK_PERIOD : time := 10.0 ns;
|
||||||
|
|
||||||
|
signal sys_rst_n_in : std_logic := '0';
|
||||||
|
signal sys_clk_in : std_logic := '1';
|
||||||
|
signal sys_led : STD_LOGIC_VECTOR (7 downto 0);
|
||||||
|
signal sys_btn : STD_LOGIC_VECTOR (8 downto 0) := "000000000";
|
||||||
|
signal sys_dip : STD_LOGIC_VECTOR (7 downto 0) := "10001001";
|
||||||
|
signal sys_error : STD_LOGIC_VECTOR (1 downto 0);
|
||||||
|
signal sys_rx : std_logic := '1';
|
||||||
|
signal sys_tx : std_logic;
|
||||||
|
|
||||||
|
BEGIN
|
||||||
|
|
||||||
|
uut: mips_embedded_syn
|
||||||
|
PORT MAP
|
||||||
|
(
|
||||||
|
sys_rst_n_in => sys_rst_n_in,
|
||||||
|
sys_clk_in => sys_clk_in,
|
||||||
|
sys_btn => sys_btn,
|
||||||
|
sys_dip => sys_dip,
|
||||||
|
sys_led => sys_led,
|
||||||
|
sys_rx => sys_rx,
|
||||||
|
sys_tx => sys_tx,
|
||||||
|
sys_error => sys_error
|
||||||
|
);
|
||||||
|
|
||||||
|
CLK_GEN: process
|
||||||
|
begin
|
||||||
|
wait for CLK_PERIOD/2;
|
||||||
|
sys_clk_in <= not sys_clk_in;
|
||||||
|
end process;
|
||||||
|
|
||||||
|
STIMULUS1: process
|
||||||
|
begin
|
||||||
|
|
||||||
|
wait for 3*CLK_PERIOD;
|
||||||
|
wait until rising_edge(sys_clk_in);
|
||||||
|
sys_rst_n_in <= '1';
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
-- wait for 9994999*CLK_PERIOD;
|
||||||
|
-- for i in 1 to 10000 loop
|
||||||
|
-- wait for 100*CLK_PERIOD;
|
||||||
|
-- sys_btn(3) <= '1';
|
||||||
|
-- wait for 10*CLK_PERIOD;
|
||||||
|
-- sys_btn(3) <= '0';
|
||||||
|
-- end loop;
|
||||||
|
|
||||||
|
wait until rising_edge(sys_clk_in) and now = 38980 ns;
|
||||||
|
sys_btn <= "000001000";
|
||||||
|
wait until rising_edge(sys_clk_in);
|
||||||
|
sys_btn <= "000000000";
|
||||||
|
|
||||||
|
wait;
|
||||||
|
|
||||||
|
end process;
|
||||||
|
|
||||||
|
STIMULUS2: process
|
||||||
|
begin
|
||||||
|
|
||||||
|
|
||||||
|
wait for 9999999*CLK_PERIOD;
|
||||||
|
for i in 1 to 10000 loop
|
||||||
|
wait for 137*CLK_PERIOD;
|
||||||
|
sys_btn(4) <= '1';
|
||||||
|
wait for 21*CLK_PERIOD;
|
||||||
|
sys_btn(4) <= '0';
|
||||||
|
end loop;
|
||||||
|
|
||||||
|
wait;
|
||||||
|
|
||||||
|
end process;
|
||||||
|
|
||||||
|
END;
|
||||||
@@ -0,0 +1,332 @@
|
|||||||
|
-------------------------------------------------------------------------
|
||||||
|
-- Project: JIPS, a portable 32-bit RISC CPU written in VHDL
|
||||||
|
-- This file: Testbench for JCPU
|
||||||
|
-- also writes 'opc.lst' for JASM-assembler
|
||||||
|
--
|
||||||
|
-- Copyright (C) 2007 J. Ahrensfeld
|
||||||
|
--
|
||||||
|
-- This program is free software: you can redistribute it and/or modify
|
||||||
|
-- it under the terms of the GNU General Public License as published by
|
||||||
|
-- the Free Software Foundation, either version 3 of the License, or
|
||||||
|
-- (at your option) any later version.
|
||||||
|
--
|
||||||
|
-- This program 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 General Public License for more details.
|
||||||
|
--
|
||||||
|
-- You should have received a copy of the GNU General Public License
|
||||||
|
-- along with this program. If not, see <http://www.gnu.org/licenses/>.
|
||||||
|
--
|
||||||
|
-- For questions and ideas, please contact the author at jens@jayfield.org
|
||||||
|
--
|
||||||
|
--------------------------------------------------------------------------
|
||||||
|
|
||||||
|
LIBRARY ieee;
|
||||||
|
use IEEE.STD_LOGIC_1164.ALL;
|
||||||
|
USE ieee.numeric_std.ALL;
|
||||||
|
|
||||||
|
library work;
|
||||||
|
use work.mips_types.all;
|
||||||
|
use work.mips_instr.all;
|
||||||
|
|
||||||
|
ENTITY tb_mips_muldiv IS
|
||||||
|
END tb_mips_muldiv;
|
||||||
|
|
||||||
|
ARCHITECTURE behavior OF tb_mips_muldiv IS
|
||||||
|
|
||||||
|
COMPONENT muldiv is
|
||||||
|
Port
|
||||||
|
(
|
||||||
|
rst : in std_logic;
|
||||||
|
clk : in std_logic;
|
||||||
|
hilo_we : in std_logic;
|
||||||
|
din_hi : in word_t;
|
||||||
|
din_lo : in word_t;
|
||||||
|
mul_divn : in std_logic;
|
||||||
|
s_un : in std_logic;
|
||||||
|
start : in std_logic;
|
||||||
|
hilo_sel : in std_logic;
|
||||||
|
busy : out std_logic;
|
||||||
|
dout : out word_t
|
||||||
|
);
|
||||||
|
END COMPONENT;
|
||||||
|
|
||||||
|
constant CLK_PERIOD : time := 10 ns;
|
||||||
|
signal ENABLE_FAIL_REPORT : boolean := true;
|
||||||
|
signal rst : std_logic := '1';
|
||||||
|
signal clk : std_logic := '1';
|
||||||
|
signal busy : std_logic;
|
||||||
|
signal mul_divn : std_logic := '0';
|
||||||
|
signal s_un : std_logic := '1';
|
||||||
|
signal hilo_we : std_logic := '0';
|
||||||
|
signal start : std_logic := '0';
|
||||||
|
signal din_hi : word_t := (others => '-');
|
||||||
|
signal din_lo : word_t := (others => '-');
|
||||||
|
signal dout : word_t;
|
||||||
|
signal hilo_sel : std_logic := '0';
|
||||||
|
signal md_result : unsigned (2*word_t'length-1 downto 0) := (others => '0');
|
||||||
|
signal ref_result : unsigned (2*word_t'length-1 downto 0);
|
||||||
|
signal ref_hi : unsigned (word_t'length-1 downto 0);
|
||||||
|
signal rtmp : unsigned (2*word_t'length-1 downto 0);
|
||||||
|
signal tmp2 : unsigned (word_t'length-1 downto 0);
|
||||||
|
signal check : std_logic;
|
||||||
|
|
||||||
|
type word_array_t is array (natural range <>) of word_t;
|
||||||
|
|
||||||
|
constant operands : word_array_t(0 to 63) :=
|
||||||
|
(
|
||||||
|
X"00000000",
|
||||||
|
X"00000001",
|
||||||
|
X"00000010",
|
||||||
|
X"00000100",
|
||||||
|
X"00001000",
|
||||||
|
X"00010000",
|
||||||
|
X"00100000",
|
||||||
|
X"01000000",
|
||||||
|
X"10000000",
|
||||||
|
X"0000000F",
|
||||||
|
X"000000FF",
|
||||||
|
X"00000FFF",
|
||||||
|
X"0000FFFF",
|
||||||
|
X"000FFFFF",
|
||||||
|
X"00FFFFFF",
|
||||||
|
X"0FFFFFFF",
|
||||||
|
X"12345678",
|
||||||
|
X"23456789",
|
||||||
|
X"7FFFFFFF",
|
||||||
|
X"80000000",
|
||||||
|
X"A541B3B9",
|
||||||
|
X"80000001",
|
||||||
|
X"80000010",
|
||||||
|
X"80000100",
|
||||||
|
X"80001000",
|
||||||
|
X"80010000",
|
||||||
|
X"80100000",
|
||||||
|
X"81000000",
|
||||||
|
X"87654321",
|
||||||
|
X"98765432",
|
||||||
|
X"FFFFFFFF",
|
||||||
|
X"FFFFFFFE",
|
||||||
|
X"FFFFFFFD",
|
||||||
|
X"FFFFFFFB",
|
||||||
|
X"FFFFFFF7",
|
||||||
|
X"FFFFFFEF",
|
||||||
|
X"FFFFFFDF",
|
||||||
|
X"FFFFFFBF",
|
||||||
|
X"FFFFFF7F",
|
||||||
|
X"FFFFFEFF",
|
||||||
|
X"FFFFFDFF",
|
||||||
|
X"FFFFFBFF",
|
||||||
|
X"FFFFF7FF",
|
||||||
|
X"FFFFEFFF",
|
||||||
|
X"FFFFDFFF",
|
||||||
|
X"FFFFBFFF",
|
||||||
|
X"FFFF7FFF",
|
||||||
|
X"FFFEFFFF",
|
||||||
|
X"FFFDFFFF",
|
||||||
|
X"FFFBFFFF",
|
||||||
|
X"FFF7FFFF",
|
||||||
|
X"FFEFFFFF",
|
||||||
|
X"FFDFFFFF",
|
||||||
|
X"FFBFFFFF",
|
||||||
|
X"FF7FFFFF",
|
||||||
|
X"FEFFFFFF",
|
||||||
|
X"FDFFFFFF",
|
||||||
|
X"FBFFFFFF",
|
||||||
|
X"F7FFFFFF",
|
||||||
|
X"EFFFFFFF",
|
||||||
|
X"DFFFFFFF",
|
||||||
|
X"BFFFFFFF",
|
||||||
|
X"CFFFFFFF",
|
||||||
|
X"7FFFFFFF"
|
||||||
|
);
|
||||||
|
|
||||||
|
BEGIN
|
||||||
|
|
||||||
|
uut: muldiv
|
||||||
|
PORT MAP(
|
||||||
|
rst => rst,
|
||||||
|
clk => clk,
|
||||||
|
hilo_we => hilo_we,
|
||||||
|
din_hi => din_hi,
|
||||||
|
din_lo => din_lo,
|
||||||
|
mul_divn => mul_divn,
|
||||||
|
s_un => s_un,
|
||||||
|
start => start,
|
||||||
|
hilo_sel => hilo_sel,
|
||||||
|
busy => busy,
|
||||||
|
dout => dout
|
||||||
|
);
|
||||||
|
|
||||||
|
CLK_GEN: process
|
||||||
|
begin
|
||||||
|
wait for CLK_PERIOD/2;
|
||||||
|
clk <= not clk;
|
||||||
|
end process;
|
||||||
|
|
||||||
|
REF_GEN: process
|
||||||
|
begin
|
||||||
|
if mul_divn = '0' then
|
||||||
|
wait until rising_edge(clk) and check = '1';
|
||||||
|
if s_un = '1' then
|
||||||
|
rtmp <= unsigned(signed(md_result(31 downto 0)) * signed(din_lo));
|
||||||
|
wait until rising_edge(clk);
|
||||||
|
tmp2 <= unsigned(signed(rtmp(31 downto 0)) + signed(md_result(63 downto 32)));
|
||||||
|
wait until rising_edge(clk);
|
||||||
|
ref_hi <= tmp2(31 downto 0);
|
||||||
|
else
|
||||||
|
rtmp <= md_result(31 downto 0) * din_lo;
|
||||||
|
wait until rising_edge(clk);
|
||||||
|
tmp2 <= rtmp(31 downto 0) + md_result(63 downto 32);
|
||||||
|
wait until rising_edge(clk);
|
||||||
|
ref_hi <= tmp2(31 downto 0);
|
||||||
|
end if;
|
||||||
|
wait until rising_edge(clk);
|
||||||
|
|
||||||
|
if din_lo /= X"00000000" then
|
||||||
|
if ENABLE_FAIL_REPORT then
|
||||||
|
assert din_hi = ref_hi report "Error on divison" severity failure;
|
||||||
|
end if;
|
||||||
|
end if;
|
||||||
|
else
|
||||||
|
wait until rising_edge(clk) and check = '1';
|
||||||
|
if s_un = '1' then
|
||||||
|
ref_result <= unsigned(signed(din_hi) * signed(din_lo));
|
||||||
|
else
|
||||||
|
ref_result <= unsigned(din_hi) * unsigned(din_lo);
|
||||||
|
end if;
|
||||||
|
wait until rising_edge(clk);
|
||||||
|
wait until rising_edge(clk);
|
||||||
|
wait until rising_edge(clk);
|
||||||
|
if ENABLE_FAIL_REPORT then
|
||||||
|
assert ref_result = md_result report "Error on multiplication" severity failure;
|
||||||
|
end if;
|
||||||
|
end if;
|
||||||
|
|
||||||
|
end process;
|
||||||
|
|
||||||
|
STIMULUS: process
|
||||||
|
|
||||||
|
begin
|
||||||
|
|
||||||
|
wait for 3*CLK_PERIOD;
|
||||||
|
wait until rising_edge(clk);
|
||||||
|
rst <= '0';
|
||||||
|
wait for 2*CLK_PERIOD;
|
||||||
|
|
||||||
|
mul_divn <= '0';
|
||||||
|
s_un <= '0';
|
||||||
|
for i in 0 to operands'length-1 loop
|
||||||
|
for j in 0 to operands'length-1 loop
|
||||||
|
check <= '0';
|
||||||
|
wait until rising_edge(clk) and busy = '0';
|
||||||
|
din_hi <= operands(i);
|
||||||
|
din_lo <= operands(j);
|
||||||
|
start <= '1';
|
||||||
|
wait until rising_edge(clk);
|
||||||
|
start <= '0';
|
||||||
|
hilo_sel <= '0';
|
||||||
|
|
||||||
|
-- Read result
|
||||||
|
wait until rising_edge(clk) and busy = '0';
|
||||||
|
wait until rising_edge(clk);
|
||||||
|
md_result(31 downto 0) <= dout;
|
||||||
|
wait until rising_edge(clk);
|
||||||
|
hilo_sel <= '1';
|
||||||
|
wait until rising_edge(clk);
|
||||||
|
md_result(63 downto 32) <= dout;
|
||||||
|
check <= '1';
|
||||||
|
wait until rising_edge(clk);
|
||||||
|
check <= '0';
|
||||||
|
wait for 8*CLK_PERIOD;
|
||||||
|
end loop;
|
||||||
|
end loop;
|
||||||
|
|
||||||
|
s_un <= '1';
|
||||||
|
for i in 0 to operands'length-1 loop
|
||||||
|
for j in 0 to operands'length-1 loop
|
||||||
|
check <= '0';
|
||||||
|
wait until rising_edge(clk) and busy = '0';
|
||||||
|
din_hi <= operands(i);
|
||||||
|
din_lo <= operands(j);
|
||||||
|
start <= '1';
|
||||||
|
wait until rising_edge(clk);
|
||||||
|
start <= '0';
|
||||||
|
hilo_sel <= '0';
|
||||||
|
|
||||||
|
-- Read result
|
||||||
|
wait until rising_edge(clk) and busy = '0';
|
||||||
|
wait until rising_edge(clk);
|
||||||
|
md_result(31 downto 0) <= dout;
|
||||||
|
wait until rising_edge(clk);
|
||||||
|
hilo_sel <= '1';
|
||||||
|
wait until rising_edge(clk);
|
||||||
|
md_result(63 downto 32) <= dout;
|
||||||
|
check <= '1';
|
||||||
|
wait until rising_edge(clk);
|
||||||
|
check <= '0';
|
||||||
|
wait for 8*CLK_PERIOD;
|
||||||
|
end loop;
|
||||||
|
end loop;
|
||||||
|
|
||||||
|
mul_divn <= '1';
|
||||||
|
s_un <= '0';
|
||||||
|
for i in 0 to operands'length-1 loop
|
||||||
|
for j in 0 to operands'length-1 loop
|
||||||
|
check <= '0';
|
||||||
|
wait until rising_edge(clk) and busy = '0';
|
||||||
|
din_hi <= operands(i);
|
||||||
|
din_lo <= operands(j);
|
||||||
|
start <= '1';
|
||||||
|
wait until rising_edge(clk);
|
||||||
|
start <= '0';
|
||||||
|
hilo_sel <= '0';
|
||||||
|
|
||||||
|
-- Read result
|
||||||
|
wait until rising_edge(clk) and busy = '0';
|
||||||
|
wait until rising_edge(clk);
|
||||||
|
md_result(31 downto 0) <= dout;
|
||||||
|
wait until rising_edge(clk);
|
||||||
|
hilo_sel <= '1';
|
||||||
|
wait until rising_edge(clk);
|
||||||
|
md_result(63 downto 32) <= dout;
|
||||||
|
check <= '1';
|
||||||
|
wait until rising_edge(clk);
|
||||||
|
check <= '0';
|
||||||
|
wait for 8*CLK_PERIOD;
|
||||||
|
end loop;
|
||||||
|
end loop;
|
||||||
|
|
||||||
|
s_un <= '1';
|
||||||
|
for i in 0 to operands'length-1 loop
|
||||||
|
for j in 0 to operands'length-1 loop
|
||||||
|
check <= '0';
|
||||||
|
wait until rising_edge(clk) and busy = '0';
|
||||||
|
din_hi <= operands(i);
|
||||||
|
din_lo <= operands(j);
|
||||||
|
start <= '1';
|
||||||
|
wait until rising_edge(clk);
|
||||||
|
start <= '0';
|
||||||
|
hilo_sel <= '0';
|
||||||
|
|
||||||
|
-- Read result
|
||||||
|
wait until rising_edge(clk) and busy = '0';
|
||||||
|
wait until rising_edge(clk);
|
||||||
|
md_result(31 downto 0) <= dout;
|
||||||
|
wait until rising_edge(clk);
|
||||||
|
hilo_sel <= '1';
|
||||||
|
wait until rising_edge(clk);
|
||||||
|
md_result(63 downto 32) <= dout;
|
||||||
|
check <= '1';
|
||||||
|
wait until rising_edge(clk);
|
||||||
|
check <= '0';
|
||||||
|
wait for 8*CLK_PERIOD;
|
||||||
|
end loop;
|
||||||
|
end loop;
|
||||||
|
|
||||||
|
wait;
|
||||||
|
|
||||||
|
end process;
|
||||||
|
|
||||||
|
END;
|
||||||
@@ -0,0 +1,116 @@
|
|||||||
|
-------------------------------------------------------------------------
|
||||||
|
-- Project: JIPS, a portable 32-bit RISC CPU written in VHDL
|
||||||
|
-- This file: Testbench for JCPU
|
||||||
|
-- also writes 'opc.lst' for JASM-assembler
|
||||||
|
--
|
||||||
|
-- Copyright (C) 2007 J. Ahrensfeld
|
||||||
|
--
|
||||||
|
-- This program is free software: you can redistribute it and/or modify
|
||||||
|
-- it under the terms of the GNU General Public License as published by
|
||||||
|
-- the Free Software Foundation, either version 3 of the License, or
|
||||||
|
-- (at your option) any later version.
|
||||||
|
--
|
||||||
|
-- This program 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 General Public License for more details.
|
||||||
|
--
|
||||||
|
-- You should have received a copy of the GNU General Public License
|
||||||
|
-- along with this program. If not, see <http://www.gnu.org/licenses/>.
|
||||||
|
--
|
||||||
|
-- For questions and ideas, please contact the author at jens@jayfield.org
|
||||||
|
--
|
||||||
|
--------------------------------------------------------------------------
|
||||||
|
|
||||||
|
LIBRARY ieee;
|
||||||
|
use IEEE.STD_LOGIC_1164.ALL;
|
||||||
|
USE ieee.numeric_std.ALL;
|
||||||
|
use std.textio.all; -- Imports the standard textio package.
|
||||||
|
|
||||||
|
library work;
|
||||||
|
use work.mips_types.all;
|
||||||
|
use work.mips_instr.all;
|
||||||
|
|
||||||
|
ENTITY tb_mips_top IS
|
||||||
|
END tb_mips_top;
|
||||||
|
|
||||||
|
ARCHITECTURE behavior OF tb_mips_top IS
|
||||||
|
|
||||||
|
COMPONENT mips_top
|
||||||
|
PORT
|
||||||
|
(
|
||||||
|
debug : out unsigned(1 downto 0);
|
||||||
|
RST_I : in STD_LOGIC;
|
||||||
|
CLK_I : in STD_LOGIC;
|
||||||
|
ACK_I : in STD_LOGIC;
|
||||||
|
SRDY_I : in STD_LOGIC;
|
||||||
|
ADDR_O : out word_t;
|
||||||
|
DAT_I : in word_t;
|
||||||
|
DAT_O : out word_t;
|
||||||
|
WE_O : out STD_LOGIC;
|
||||||
|
SEL_O : out unsigned(3 downto 0);
|
||||||
|
CYC_O : out STD_LOGIC;
|
||||||
|
STB_O : out STD_LOGIC;
|
||||||
|
MRDY_O : out STD_LOGIC;
|
||||||
|
INT : in unsigned (5 downto 0)
|
||||||
|
);
|
||||||
|
END COMPONENT;
|
||||||
|
|
||||||
|
constant CLK_PERIOD : time := 10 ns;
|
||||||
|
|
||||||
|
signal debug : unsigned(1 downto 0);
|
||||||
|
signal RST_I : STD_LOGIC := '1';
|
||||||
|
signal CLK_I : STD_LOGIC := '0';
|
||||||
|
signal ACK_I : STD_LOGIC := '0';
|
||||||
|
signal SRDY_I : STD_LOGIC := '0';
|
||||||
|
signal ADDR_O : word_t;
|
||||||
|
signal DAT_I : word_t := (others => '0');
|
||||||
|
signal DAT_O : word_t;
|
||||||
|
signal WE_O : STD_LOGIC;
|
||||||
|
signal SEL_O : unsigned(3 downto 0);
|
||||||
|
signal CYC_O : STD_LOGIC;
|
||||||
|
signal STB_O : STD_LOGIC;
|
||||||
|
signal MRDY_O : STD_LOGIC;
|
||||||
|
signal INT : unsigned (5 downto 0) := (others => '0');
|
||||||
|
|
||||||
|
BEGIN
|
||||||
|
|
||||||
|
uut: mips_top
|
||||||
|
PORT MAP
|
||||||
|
(
|
||||||
|
debug => debug,
|
||||||
|
RST_I => RST_I,
|
||||||
|
CLK_I => CLK_I,
|
||||||
|
ACK_I => ACK_I,
|
||||||
|
SRDY_I => SRDY_I,
|
||||||
|
ADDR_O => ADDR_O,
|
||||||
|
DAT_I => DAT_I,
|
||||||
|
DAT_O => DAT_O,
|
||||||
|
WE_O => WE_O,
|
||||||
|
SEL_O => SEL_O,
|
||||||
|
CYC_O => CYC_O,
|
||||||
|
STB_O => STB_O,
|
||||||
|
MRDY_O => MRDY_O,
|
||||||
|
INT => INT
|
||||||
|
);
|
||||||
|
|
||||||
|
CLK_GEN: process
|
||||||
|
begin
|
||||||
|
wait for CLK_PERIOD/2;
|
||||||
|
CLK_I <= not CLK_I;
|
||||||
|
end process;
|
||||||
|
|
||||||
|
STIMULUS: process
|
||||||
|
|
||||||
|
begin
|
||||||
|
|
||||||
|
|
||||||
|
wait for 3*CLK_PERIOD;
|
||||||
|
wait until rising_edge(CLK_I);
|
||||||
|
RST_I <= '0';
|
||||||
|
|
||||||
|
wait;
|
||||||
|
|
||||||
|
end process;
|
||||||
|
|
||||||
|
END;
|
||||||
File diff suppressed because it is too large
Load Diff
@@ -0,0 +1,20 @@
|
|||||||
|
vhdl work "../../src/core/mips_types.vhd"
|
||||||
|
vhdl work "../../../../misc/dpram_2w2r.vhd"
|
||||||
|
vhdl work "../../../../misc/dpram_1w1r_dist.vhd"
|
||||||
|
vhdl work "../../../../misc/dpram_1w1r.vhd"
|
||||||
|
vhdl work "../../../../FIFO/src/sync_fifo_ctrl.vhd"
|
||||||
|
vhdl work "../../../../FIFO/src/fifo_ctrl_pkg.vhd"
|
||||||
|
vhdl work "../../src/core/mips_instr.vhd"
|
||||||
|
vhdl work "../../../../FIFO/src/fifo_sync_dist.vhd"
|
||||||
|
vhdl work "../../src/core/mips_shifter.vhd"
|
||||||
|
vhdl work "../../src/core/mips_reg.vhd"
|
||||||
|
vhdl work "../../src/core/mips_muldiv.vhd"
|
||||||
|
vhdl work "../../src/core/mips_idecode_rom.vhd"
|
||||||
|
vhdl work "../../src/core/mips_icache.vhd"
|
||||||
|
vhdl work "../../src/core/mips_dcache.vhd"
|
||||||
|
vhdl work "../../src/core/mips_cop.vhd"
|
||||||
|
vhdl work "../../src/core/mips_bcu.vhd"
|
||||||
|
vhdl work "../../src/core/mips_alu.vhd"
|
||||||
|
vhdl work "../../src/core/mips_pipeline.vhd"
|
||||||
|
vhdl work "../../src/core/mips_biu.vhd"
|
||||||
|
vhdl work "../../src/core/mips_top.vhd"
|
||||||
@@ -0,0 +1,20 @@
|
|||||||
|
vhdl work "W:\vhdl\lib\CPUs\MIPS\src\core\mips_types.vhd"
|
||||||
|
vhdl work "W:\vhdl\lib\misc\dpram_2w2r.vhd"
|
||||||
|
vhdl work "W:\vhdl\lib\misc\dpram_1w1r_dist.vhd"
|
||||||
|
vhdl work "W:\vhdl\lib\misc\dpram_1w1r.vhd"
|
||||||
|
vhdl work "W:\vhdl\lib\FIFO\src\sync_fifo_ctrl.vhd"
|
||||||
|
vhdl work "W:\vhdl\lib\FIFO\src\fifo_ctrl_pkg.vhd"
|
||||||
|
vhdl work "W:\vhdl\lib\CPUs\MIPS\src\core\mips_instr.vhd"
|
||||||
|
vhdl work "W:\vhdl\lib\FIFO\src\fifo_sync_dist.vhd"
|
||||||
|
vhdl work "W:\vhdl\lib\CPUs\MIPS\src\core\mips_shifter.vhd"
|
||||||
|
vhdl work "W:\vhdl\lib\CPUs\MIPS\src\core\mips_reg.vhd"
|
||||||
|
vhdl work "W:\vhdl\lib\CPUs\MIPS\src\core\mips_muldiv.vhd"
|
||||||
|
vhdl work "W:\vhdl\lib\CPUs\MIPS\src\core\mips_idecode_rom.vhd"
|
||||||
|
vhdl work "W:\vhdl\lib\CPUs\MIPS\src\core\mips_icache.vhd"
|
||||||
|
vhdl work "W:\vhdl\lib\CPUs\MIPS\src\core\mips_dcache.vhd"
|
||||||
|
vhdl work "W:\vhdl\lib\CPUs\MIPS\src\core\mips_cop.vhd"
|
||||||
|
vhdl work "W:\vhdl\lib\CPUs\MIPS\src\core\mips_bcu.vhd"
|
||||||
|
vhdl work "W:\vhdl\lib\CPUs\MIPS\src\core\mips_alu.vhd"
|
||||||
|
vhdl work "W:\vhdl\lib\CPUs\MIPS\src\core\mips_pipeline.vhd"
|
||||||
|
vhdl work "W:\vhdl\lib\CPUs\MIPS\src\core\mips_biu.vhd"
|
||||||
|
vhdl work "W:\vhdl\lib\CPUs\MIPS\src\core\mips_top.vhd"
|
||||||
@@ -0,0 +1,5 @@
|
|||||||
|
2008-10-26
|
||||||
|
- Optimierung: MUL32x32 primitive für Virtex-4
|
||||||
|
- External COP 1..3 interface
|
||||||
|
- FPU (COP1)
|
||||||
|
- MMU
|
||||||
@@ -0,0 +1,8 @@
|
|||||||
|
all: ramgen romgen
|
||||||
|
|
||||||
|
ramgen: src/ramgen.c
|
||||||
|
gcc -o ./ramgen.exe src/ramgen.c
|
||||||
|
|
||||||
|
romgen: src/romgen.c
|
||||||
|
gcc -o ./romgen.exe src/romgen.c
|
||||||
|
|
||||||
@@ -0,0 +1,46 @@
|
|||||||
|
#!/usr/bin/env ruby
|
||||||
|
|
||||||
|
# ----------------------------------------------------------------------
|
||||||
|
# Project: JIPS, a portable 32-bit RISC CPU written in VHDL
|
||||||
|
# This file: Insertion of code fragments into templates
|
||||||
|
#
|
||||||
|
# Copyright (C) 2008 J. Ahrensfeld
|
||||||
|
#
|
||||||
|
# This program is free software: you can redistribute it and/or modify
|
||||||
|
# it under the terms of the GNU General Public License as published by
|
||||||
|
# the Free Software Foundation, either version 3 of the License, or
|
||||||
|
# (at your option) any later version.
|
||||||
|
#
|
||||||
|
# This program 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 General Public License for more details.
|
||||||
|
#
|
||||||
|
# You should have received a copy of the GNU General Public License
|
||||||
|
# along with this program. If not, see <http://www.gnu.org/licenses/>.
|
||||||
|
#
|
||||||
|
# For questions and ideas, please contact the author at jens@jayfield.org
|
||||||
|
#
|
||||||
|
# ---------------------------------------------------------------------
|
||||||
|
|
||||||
|
arg = $*
|
||||||
|
rom_filename = arg[0].to_s
|
||||||
|
tpl_filename = arg[1].to_s
|
||||||
|
|
||||||
|
subst_pattern = "ROM_INSERT_HERE"
|
||||||
|
|
||||||
|
# --------------------------------------------------------
|
||||||
|
# Open file
|
||||||
|
# --------------------------------------------------------
|
||||||
|
romfile = File.open(rom_filename, "r")
|
||||||
|
tplfile = File.open(tpl_filename, "r")
|
||||||
|
re = Regexp.new(subst_pattern)
|
||||||
|
|
||||||
|
while (line = tplfile.gets)
|
||||||
|
puts line
|
||||||
|
line.scan(re).each do |word|
|
||||||
|
romfile.each do |raw_line|
|
||||||
|
puts raw_line
|
||||||
|
end
|
||||||
|
end
|
||||||
|
end
|
||||||
@@ -0,0 +1,29 @@
|
|||||||
|
-------------------------------------------------------------------------
|
||||||
|
-- Project: JIPS, a portable 32-bit RISC CPU written in VHDL
|
||||||
|
-- This file: The ROM file for use in your VHDL design
|
||||||
|
--
|
||||||
|
-- Copyright (C) 2008 J. Ahrensfeld
|
||||||
|
--
|
||||||
|
-- This program is free software: you can redistribute it and/or modify
|
||||||
|
-- it under the terms of the GNU General Public License as published by
|
||||||
|
-- the Free Software Foundation, either version 3 of the License, or
|
||||||
|
-- (at your option) any later version.
|
||||||
|
--
|
||||||
|
-- This program 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 General Public License for more details.
|
||||||
|
--
|
||||||
|
-- You should have received a copy of the GNU General Public License
|
||||||
|
-- along with this program. If not, see <http://www.gnu.org/licenses/>.
|
||||||
|
--
|
||||||
|
-- For questions and ideas, please contact the author at jens@jayfield.org
|
||||||
|
--
|
||||||
|
--------------------------------------------------------------------------
|
||||||
|
|
||||||
|
LIBRARY ieee;
|
||||||
|
use IEEE.STD_LOGIC_1164.ALL;
|
||||||
|
USE ieee.numeric_std.ALL;
|
||||||
|
|
||||||
|
-- ROM_INSERT_HERE
|
||||||
|
|
||||||
@@ -0,0 +1,147 @@
|
|||||||
|
-------------------------------------------------------------------------
|
||||||
|
-- Project: JIPS, a portable 32-bit RISC CPU written in VHDL
|
||||||
|
-- This file: loadable ROM
|
||||||
|
--
|
||||||
|
-- Copyright (C) 2008 J. Ahrensfeld
|
||||||
|
--
|
||||||
|
-- This program is free software: you can redistribute it and/or modify
|
||||||
|
-- it under the terms of the GNU General Public License as published by
|
||||||
|
-- the Free Software Foundation, either version 3 of the License, or
|
||||||
|
-- (at your option) any later version.
|
||||||
|
--
|
||||||
|
-- This program 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 General Public License for more details.
|
||||||
|
--
|
||||||
|
-- You should have received a copy of the GNU General Public License
|
||||||
|
-- along with this program. If not, see <http://www.gnu.org/licenses/>.
|
||||||
|
--
|
||||||
|
-- For questions and ideas, please contact the author at jens@jayfield.org
|
||||||
|
--
|
||||||
|
--------------------------------------------------------------------------
|
||||||
|
|
||||||
|
LIBRARY ieee;
|
||||||
|
use IEEE.STD_LOGIC_1164.ALL;
|
||||||
|
USE ieee.numeric_std.ALL;
|
||||||
|
|
||||||
|
library UNISIM;
|
||||||
|
use UNISIM.VComponents.all;
|
||||||
|
|
||||||
|
ENTITY irom IS
|
||||||
|
Port (
|
||||||
|
clk : in STD_LOGIC;
|
||||||
|
addr : in inst_addr_t;
|
||||||
|
dout : out inst_t
|
||||||
|
);
|
||||||
|
|
||||||
|
END irom;
|
||||||
|
|
||||||
|
ARCHITECTURE loadable OF irom IS
|
||||||
|
|
||||||
|
-- JASM_ROM_INSERT_HERE
|
||||||
|
|
||||||
|
signal jtag_ld_clk : STD_LOGIC;
|
||||||
|
signal jtag_ld_we : STD_LOGIC;
|
||||||
|
signal jtag_ld_addr : unsigned (15 downto 0);
|
||||||
|
signal jtag_ld_dout : unsigned (31 downto 0);
|
||||||
|
signal jtag_ld_din : unsigned (31 downto 0);
|
||||||
|
signal bs_rst, bs_sel, bs_shift, bs_tdi, bs_tdo : std_logic;
|
||||||
|
signal bs_capture, bs_clk0, bs_clk1, bs_update0, bs_update1 : std_logic;
|
||||||
|
signal user_regi, user_rego : unsigned (47 downto 0);
|
||||||
|
constant id : unsigned (47 downto 0) := X"DEAD" & X"BEEF" & "X"BABE";
|
||||||
|
|
||||||
|
begin
|
||||||
|
|
||||||
|
--------------------------------------------------------------------------
|
||||||
|
-- Virtex-4: JTAG Loader
|
||||||
|
--------------------------------------------------------------------------
|
||||||
|
i00_BUFG : BUFG
|
||||||
|
port map
|
||||||
|
(
|
||||||
|
O => bs_clk1,
|
||||||
|
I => bs_clk0
|
||||||
|
);
|
||||||
|
|
||||||
|
i01_BUFG : BUFG
|
||||||
|
port map
|
||||||
|
(
|
||||||
|
O => bs_update1,
|
||||||
|
I => bs_update0
|
||||||
|
);
|
||||||
|
|
||||||
|
BSCAN_VIRTEX4_inst1 : BSCAN_VIRTEX4
|
||||||
|
generic map
|
||||||
|
(
|
||||||
|
JTAG_CHAIN => 1 -- Value to set BSCAN site of device. Possible values: (1,2,3 or 4)
|
||||||
|
)
|
||||||
|
port map
|
||||||
|
(
|
||||||
|
CAPTURE => bs_capture, -- CAPTURE output from TAP controller
|
||||||
|
DRCK => bs_clk0, -- Data register output for USER functions
|
||||||
|
RESET => bs_rst, -- Reset output from TAP controller
|
||||||
|
SEL => bs_sel, -- USER active output
|
||||||
|
SHIFT => bs_shift, -- SHIFT output from TAP controller
|
||||||
|
TDI => bs_tdi, -- TDI output from TAP controller
|
||||||
|
UPDATE => bs_update0, -- UPDATE output from TAP controller
|
||||||
|
TDO => bs_tdo -- Data input for USER function
|
||||||
|
);
|
||||||
|
|
||||||
|
jtag_ld_addr <= user_regi(user_regi'left downto jtag_ld_dout'length);
|
||||||
|
jtag_ld_din <= user_regi(jtag_ld_dout'length-1 downto 0);
|
||||||
|
jtag_ld_clk <= bs_update1;
|
||||||
|
jtag_ld_we <= bs_sel;
|
||||||
|
|
||||||
|
sipo:
|
||||||
|
process (bs_rst, bs_clk1, bs_tdi, bs_shift)
|
||||||
|
begin
|
||||||
|
if bs_rst = '1' then
|
||||||
|
user_regi <= (others => '0');
|
||||||
|
elsif rising_edge(bs_clk1) then
|
||||||
|
if bs_shift = '1' then
|
||||||
|
user_regi <= bs_tdi & user_regi(user_regi'left downto 1);
|
||||||
|
end if;
|
||||||
|
end if;
|
||||||
|
end process;
|
||||||
|
|
||||||
|
piso:
|
||||||
|
process (bs_rst, bs_clk1, bs_shift, user_rego)
|
||||||
|
begin
|
||||||
|
bs_tdo <= user_rego(0);
|
||||||
|
if bs_rst = '1' then
|
||||||
|
user_rego <= (others => '0');
|
||||||
|
elsif rising_edge(bs_clk1) then
|
||||||
|
if bs_shift = '1' then
|
||||||
|
user_rego <= user_rego(0) & user_rego(user_rego'left downto 1);
|
||||||
|
else
|
||||||
|
user_rego <= (user_rego'left downto jtag_ld_dout'length => '0') & jtag_ld_dout;
|
||||||
|
-- user_rego <= id;
|
||||||
|
end if;
|
||||||
|
end if;
|
||||||
|
end process;
|
||||||
|
|
||||||
|
PROM_WRITE:
|
||||||
|
process(jtag_ld_clk, jtag_ld_we)
|
||||||
|
begin
|
||||||
|
if rising_edge(jtag_ld_clk) then
|
||||||
|
if jtag_ld_we = '1' then
|
||||||
|
imem_rom(to_integer(jtag_ld_addr)) <= jtag_ld_din;
|
||||||
|
else
|
||||||
|
jtag_ld_dout <= imem_rom(to_integer(jtag_ld_addr));
|
||||||
|
end if;
|
||||||
|
end if;
|
||||||
|
end process;
|
||||||
|
|
||||||
|
--------------------------------------------------------------------------
|
||||||
|
-- ROM Read/Write
|
||||||
|
--------------------------------------------------------------------------
|
||||||
|
PROM_READ:
|
||||||
|
process(clk)
|
||||||
|
begin
|
||||||
|
if rising_edge(clk) then
|
||||||
|
dout <= imem_rom(to_integer(addr));
|
||||||
|
end if;
|
||||||
|
end process;
|
||||||
|
|
||||||
|
--------------------------------------------------------------------------
|
||||||
|
end loadable;
|
||||||
@@ -0,0 +1,51 @@
|
|||||||
|
#!/bin/sh
|
||||||
|
|
||||||
|
# ----------------------------------------------------------------------
|
||||||
|
# Project: JCPU, a portable 8-bit RISC CPU written in VHDL
|
||||||
|
# This file: rom-file generation for cpu_core
|
||||||
|
#
|
||||||
|
# Copyright (C) 2007 J. Ahrensfeld
|
||||||
|
#
|
||||||
|
# This program is free software: you can redistribute it and/or modify
|
||||||
|
# it under the terms of the GNU General Public License as published by
|
||||||
|
# the Free Software Foundation, either version 3 of the License, or
|
||||||
|
# (at your option) any later version.
|
||||||
|
#
|
||||||
|
# This program 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 General Public License for more details.
|
||||||
|
#
|
||||||
|
# You should have received a copy of the GNU General Public License
|
||||||
|
# along with this program. If not, see <http://www.gnu.org/licenses/>.
|
||||||
|
#
|
||||||
|
# For questions and ideas, please contact the author at jens@jayfield.org
|
||||||
|
#
|
||||||
|
# ---------------------------------------------------------------------
|
||||||
|
# $Header: /tmp/cvsroot/VHDL/lib/CPUs/MIPS/tools/make.sh,v 1.1 2008-08-25 08:29:55 Jens Exp $
|
||||||
|
# ----------------------------------------------------------------------
|
||||||
|
TARGET=$2
|
||||||
|
DSTDIR=$1
|
||||||
|
|
||||||
|
JASM_HOME=/cygdrive/w/vhdl/lib/CPUs/JCpu/tools
|
||||||
|
|
||||||
|
$JASM_HOME/jasm.rb $TARGET.jsm
|
||||||
|
|
||||||
|
irom_tcl_snippet="$TARGET.irom.tcl.snip"
|
||||||
|
irom_vhdl_snippet="$TARGET.irom.vhdl.snip"
|
||||||
|
irom_ld_vhdl_snippet="$TARGET.irom_ld.vhdl.snip"
|
||||||
|
xrom_tcl_snippet="$TARGET.xrom.tcl.snip"
|
||||||
|
xrom_vhdl_snippet="$TARGET.xrom.vhdl.snip"
|
||||||
|
xrom_ld_vhdl_snippet="$TARGET.xrom_ld.vhdl.snip"
|
||||||
|
|
||||||
|
$JASM_HOME/insrom.rb $irom_vhdl_snippet $JASM_HOME/irom.vhd.tpl >$DSTDIR/$TARGET\_irom.vhdl
|
||||||
|
$JASM_HOME/insrom.rb $irom_ld_vhdl_snippet $JASM_HOME/irom_ld.vhd.tpl >$DSTDIR/$TARGET\_irom_ld.vhdl
|
||||||
|
|
||||||
|
$JASM_HOME/insrom.rb $xrom_vhdl_snippet $JASM_HOME/xrom.vhd.tpl >$DSTDIR/$TARGET\_xrom.vhdl
|
||||||
|
$JASM_HOME/insrom.rb $xrom_ld_vhdl_snippet $JASM_HOME/xrom_ld.vhd.tpl >$DSTDIR/$TARGET\_xrom_ld.vhdl
|
||||||
|
|
||||||
|
cat $irom_tcl_snippet > $TARGET.tcl.snip.snip
|
||||||
|
cat $xrom_tcl_snippet >> $TARGET.tcl.snip.snip
|
||||||
|
$JASM_HOME/insrom.rb $TARGET.tcl.snip.snip $JASM_HOME/rom.tcl.tpl >$TARGET.tcl
|
||||||
|
|
||||||
|
rm -f *.snip
|
||||||
@@ -0,0 +1,61 @@
|
|||||||
|
# ----------------------------------------------------------------------
|
||||||
|
# Project: JCPU, a portable 8-bit RISC CPU written in VHDL
|
||||||
|
# This file: The ROM file for upload to target over JTAG
|
||||||
|
#
|
||||||
|
# Copyright (C) 2007 J. Ahrensfeld
|
||||||
|
#
|
||||||
|
# This program is free software: you can redistribute it and/or modify
|
||||||
|
# it under the terms of the GNU General Public License as published by
|
||||||
|
# the Free Software Foundation, either version 3 of the License, or
|
||||||
|
# (at your option) any later version.
|
||||||
|
#
|
||||||
|
# This program 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 General Public License for more details.
|
||||||
|
#
|
||||||
|
# You should have received a copy of the GNU General Public License
|
||||||
|
# along with this program. If not, see <http://www.gnu.org/licenses/>.
|
||||||
|
#
|
||||||
|
# For questions and ideas, please contact the author at jens@jayfield.org
|
||||||
|
#
|
||||||
|
# ---------------------------------------------------------------------
|
||||||
|
|
||||||
|
# ---------------------------------------------------------------------
|
||||||
|
# For Chipscope 9.1
|
||||||
|
# ---------------------------------------------------------------------
|
||||||
|
# Source JTAG/TCL frame work
|
||||||
|
cd $env(CHIPSCOPE)\\bin\\nt
|
||||||
|
source csejtag.tcl
|
||||||
|
|
||||||
|
namespace import ::chipscope::*
|
||||||
|
|
||||||
|
# Platform USB Cable
|
||||||
|
set PLATFORM_USB_CABLE_ARGS [list "port=USB2" "frequency=6000000"]
|
||||||
|
# frequency="24000000 | 12000000 | 6000000 | 3000000 | 1500000 | 750000"
|
||||||
|
|
||||||
|
# Create session
|
||||||
|
set handle [::chipscope::csejtag_session create 0]
|
||||||
|
|
||||||
|
# Open JTAG and lock
|
||||||
|
set open_result [::chipscope::csejtag_target open $handle $CSEJTAG_TARGET_PLATFORMUSB 0 $PLATFORM_USB_CABLE_ARGS]
|
||||||
|
set lock_result [::chipscope::csejtag_target lock $handle 1000]
|
||||||
|
|
||||||
|
set devlist [::chipscope::csejtag_tap autodetect_chain $handle $CSEJTAG_SCAN_DEFAULT]
|
||||||
|
|
||||||
|
# Get Device ID
|
||||||
|
set devtype "Virtex-4SX"
|
||||||
|
set devid 2
|
||||||
|
set irlength [::chipscope::csejtag_tap get_irlength $handle $devid]
|
||||||
|
set idcode [::chipscope::csejtag_tap get_device_idcode $handle $devid]
|
||||||
|
|
||||||
|
set CSE_OP $CSEJTAG_SHIFT_READWRITE
|
||||||
|
set CSE_ES $CSEJTAG_RUN_TEST_IDLE
|
||||||
|
|
||||||
|
# Write Program
|
||||||
|
# JASM_ROM_INSERT_HERE
|
||||||
|
|
||||||
|
::chipscope::csejtag_target unlock $handle
|
||||||
|
::chipscope::csejtag_target close $handle
|
||||||
|
::chipscope::csejtag_session destroy $handle
|
||||||
|
exit
|
||||||
@@ -0,0 +1,125 @@
|
|||||||
|
#include <stdio.h>
|
||||||
|
#include <stdlib.h>
|
||||||
|
#include <string.h>
|
||||||
|
#include <math.h>
|
||||||
|
|
||||||
|
#define ARCH_NAME "data"
|
||||||
|
#define ENT_NAME "ram"
|
||||||
|
#define JTAG_ADDR_WIDTH 16
|
||||||
|
|
||||||
|
// --------------------------------------------------------------
|
||||||
|
void basename(char *pSrc, char *pDst)
|
||||||
|
{
|
||||||
|
int i, size;
|
||||||
|
|
||||||
|
size = strlen(pSrc);
|
||||||
|
|
||||||
|
while(pSrc[size] != '.')
|
||||||
|
size--;
|
||||||
|
|
||||||
|
for (i=0; i < size; i++)
|
||||||
|
pDst[i] = pSrc[i];
|
||||||
|
|
||||||
|
pDst[i] = 0;
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
int SaveRAM_TCL(char *pFilenameIn, char *pFilenameOut, char *pArchName, char *pEntName, int nbits_addr, int nbits_data)
|
||||||
|
{
|
||||||
|
FILE *pFileIn, *pFileOut;
|
||||||
|
long start, end;
|
||||||
|
int i, word, word_addr, filesize, romsize;
|
||||||
|
char binstr_addr[33];
|
||||||
|
char binstr_data[33];
|
||||||
|
|
||||||
|
char tpl[] = {"# ---------------------------------------------------------------------\n# For Chipscope 9.1\n# ---------------------------------------------------------------------\n# Source JTAG/TCL frame work\ncd $env(CHIPSCOPE)\\\\bin\\\\nt\nsource csejtag.tcl\n\nnamespace import ::chipscope::*\n\n# Platform USB Cable\nset PLATFORM_USB_CABLE_ARGS [list \"port=USB2\" \"frequency=6000000\"]\n# frequency=\"24000000 | 12000000 | 6000000 | 3000000 | 1500000 | 750000\"\n\n# Create session\nset handle [::chipscope::csejtag_session create 0]\n\n# Open JTAG and lock\nset open_result [::chipscope::csejtag_target open $handle $CSEJTAG_TARGET_PLATFORMUSB 0 $PLATFORM_USB_CABLE_ARGS]\nset lock_result [::chipscope::csejtag_target lock $handle 1000]\n\nset devlist [::chipscope::csejtag_tap autodetect_chain $handle $CSEJTAG_SCAN_DEFAULT]\n\n# Get Device ID\nset devtype \"Virtex-4SX\"\nset devid 2\nset irlength [::chipscope::csejtag_tap get_irlength $handle $devid]\nset idcode [::chipscope::csejtag_tap get_device_idcode $handle $devid]\n\nset CSE_OP $CSEJTAG_SHIFT_READWRITE\nset CSE_ES $CSEJTAG_RUN_TEST_IDLE\n\n# Write Program\n"};
|
||||||
|
|
||||||
|
pFileIn = fopen(pFilenameIn, "rb");
|
||||||
|
if (!pFileIn)
|
||||||
|
{
|
||||||
|
fprintf(stderr, "Error opening file %s\n", pFilenameIn);
|
||||||
|
return 1;
|
||||||
|
}
|
||||||
|
|
||||||
|
pFileOut = fopen(pFilenameOut, "wb");
|
||||||
|
if (!pFileOut)
|
||||||
|
{
|
||||||
|
fprintf(stderr, "Error opening file %s\n", pFilenameOut);
|
||||||
|
return 1;
|
||||||
|
}
|
||||||
|
|
||||||
|
fseek(pFileIn, 0, SEEK_SET);
|
||||||
|
start = ftell(pFileIn);
|
||||||
|
fseek(pFileIn, 0, SEEK_END);
|
||||||
|
end = ftell(pFileIn);
|
||||||
|
fseek(pFileIn, 0, SEEK_SET);
|
||||||
|
|
||||||
|
filesize = (end-start);
|
||||||
|
romsize = (int)pow(2, nbits_addr+2);
|
||||||
|
|
||||||
|
// -------------------------------------------------------------------------
|
||||||
|
// Header
|
||||||
|
|
||||||
|
// -------------------------------------------------------------------------
|
||||||
|
fputs(tpl, pFileOut);
|
||||||
|
|
||||||
|
// -------------------------------------------------------------------------
|
||||||
|
// ROM part
|
||||||
|
// -------------------------------------------------------------------------
|
||||||
|
fprintf(pFileOut, "# Assembled from %s\n", pFilenameIn);
|
||||||
|
fprintf(pFileOut, "# ---------------------------------------------------------------\n");
|
||||||
|
fprintf(pFileOut, "# Shift the USER2 Instruction (b1111000011) into the Instruction Register of FPGA\n");
|
||||||
|
fprintf(pFileOut, "# User 2\n");
|
||||||
|
fprintf(pFileOut, "set result [::chipscope::csejtag_tap shift_device_ir $handle $devid $CSE_OP $CSE_ES 0 $irlength \"3C3\"]\n\n");
|
||||||
|
|
||||||
|
word_addr = 0;
|
||||||
|
for (i=0; i < filesize; i += sizeof(int))
|
||||||
|
{
|
||||||
|
fread(&word, 1, sizeof(int), pFileIn);
|
||||||
|
fprintf(pFileOut, "::chipscope::csejtag_tap shift_device_dr $handle $devid $CSE_OP $CSE_ES 0 %d \"%4.4X%8.8X\"\n", nbits_data + JTAG_ADDR_WIDTH, word_addr, word);
|
||||||
|
word_addr++;
|
||||||
|
}
|
||||||
|
fprintf(pFileOut, "\n");
|
||||||
|
|
||||||
|
// -------------------------------------------------------------------------
|
||||||
|
// Trailer
|
||||||
|
// -------------------------------------------------------------------------
|
||||||
|
fprintf(pFileOut, "::chipscope::csejtag_target unlock $handle\n");
|
||||||
|
fprintf(pFileOut, "::chipscope::csejtag_target close $handle\n");
|
||||||
|
fprintf(pFileOut, "::chipscope::csejtag_session destroy $handle\n");
|
||||||
|
fprintf(pFileOut, "exit\n");
|
||||||
|
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
int main(int argc, char *argv[])
|
||||||
|
{
|
||||||
|
char *pFilenameIn;
|
||||||
|
char name_prj[1024];
|
||||||
|
char name_rom_tcl[1024];
|
||||||
|
|
||||||
|
FILE *pFileIn;
|
||||||
|
int filesize, romsize, nbits_addr, nbits_data;
|
||||||
|
long start, end;
|
||||||
|
int word, i;
|
||||||
|
|
||||||
|
if (argc < 2)
|
||||||
|
{
|
||||||
|
fprintf(stderr, "Usage: romgen <input file> <num. word address bits>\n");
|
||||||
|
return 1;
|
||||||
|
}
|
||||||
|
|
||||||
|
pFilenameIn = argv[1];
|
||||||
|
if (argc == 3)
|
||||||
|
nbits_addr = atoi(argv[2]);
|
||||||
|
|
||||||
|
|
||||||
|
basename(pFilenameIn, name_prj);
|
||||||
|
sprintf(name_rom_tcl, "%s.tcl", name_prj);
|
||||||
|
|
||||||
|
SaveRAM_TCL(pFilenameIn, name_rom_tcl, ARCH_NAME, ENT_NAME, nbits_addr, 32);
|
||||||
|
|
||||||
|
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
|
||||||
@@ -0,0 +1,368 @@
|
|||||||
|
#include <stdio.h>
|
||||||
|
#include <stdlib.h>
|
||||||
|
#include <string.h>
|
||||||
|
#include <math.h>
|
||||||
|
|
||||||
|
#define ARCH_NAME "data"
|
||||||
|
#define ENT_NAME "icache"
|
||||||
|
#define JTAG_ADDR_WIDTH 16
|
||||||
|
|
||||||
|
// --------------------------------------------------------------
|
||||||
|
void basename(char *pSrc, char *pDst)
|
||||||
|
{
|
||||||
|
int i, size;
|
||||||
|
|
||||||
|
size = strlen(pSrc);
|
||||||
|
|
||||||
|
while(pSrc[size] != '.')
|
||||||
|
size--;
|
||||||
|
|
||||||
|
for (i=0; i < size; i++)
|
||||||
|
pDst[i] = pSrc[i];
|
||||||
|
|
||||||
|
pDst[i] = 0;
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
int SaveROM(char *pFilenameIn, char *pFilenameOut, char *pArchName, char *pEntName, int nbits_addr, int nbits_data)
|
||||||
|
{
|
||||||
|
FILE *pFileIn, *pFileOut;
|
||||||
|
long start, end;
|
||||||
|
int i, word, filesize, romsize;
|
||||||
|
|
||||||
|
pFileIn = fopen(pFilenameIn, "rb");
|
||||||
|
if (!pFileIn)
|
||||||
|
{
|
||||||
|
fprintf(stderr, "Error opening file %s\n", pFilenameIn);
|
||||||
|
return 1;
|
||||||
|
}
|
||||||
|
|
||||||
|
pFileOut = fopen(pFilenameOut, "wb");
|
||||||
|
if (!pFileOut)
|
||||||
|
{
|
||||||
|
fprintf(stderr, "Error opening file %s\n", pFilenameOut);
|
||||||
|
return 1;
|
||||||
|
}
|
||||||
|
|
||||||
|
fseek(pFileIn, 0, SEEK_SET);
|
||||||
|
start = ftell(pFileIn);
|
||||||
|
fseek(pFileIn, 0, SEEK_END);
|
||||||
|
end = ftell(pFileIn);
|
||||||
|
fseek(pFileIn, 0, SEEK_SET);
|
||||||
|
|
||||||
|
filesize = (end-start);
|
||||||
|
romsize = (int)pow(2, nbits_addr+2);
|
||||||
|
|
||||||
|
// -------------------------------------------------------------------------
|
||||||
|
// Header
|
||||||
|
|
||||||
|
// -------------------------------------------------------------------------
|
||||||
|
fprintf(pFileOut, "LIBRARY IEEE;\n");
|
||||||
|
fprintf(pFileOut, "USE IEEE.STD_LOGIC_1164.ALL;\n");
|
||||||
|
fprintf(pFileOut, "USE IEEE.NUMERIC_STD.ALL;\n");
|
||||||
|
fprintf(pFileOut, "\n");
|
||||||
|
|
||||||
|
fprintf(pFileOut, "ENTITY %s IS\n", ENT_NAME);
|
||||||
|
fprintf(pFileOut, "\tPort\n");
|
||||||
|
fprintf(pFileOut, "\t(\n");
|
||||||
|
fprintf(pFileOut, "\t\tclk\t\t: in STD_LOGIC;\n");
|
||||||
|
fprintf(pFileOut, "\t\tce\t\t: in STD_LOGIC;\n");
|
||||||
|
fprintf(pFileOut, "\t\taddr\t\t: in unsigned(%d downto 0);\n", nbits_data-1);
|
||||||
|
fprintf(pFileOut, "\t\tdout\t\t: out unsigned(%d downto 0)\n", nbits_data-1);
|
||||||
|
fprintf(pFileOut, "\t);\n");
|
||||||
|
fprintf(pFileOut, "END %s;\n", ENT_NAME);
|
||||||
|
fprintf(pFileOut, "\n");
|
||||||
|
|
||||||
|
|
||||||
|
fprintf(pFileOut, "ARCHITECTURE %s OF %s IS\n", ARCH_NAME, ENT_NAME);
|
||||||
|
fprintf(pFileOut, "\n");
|
||||||
|
|
||||||
|
fprintf(pFileOut, "\tsubtype word_t is unsigned(%d downto 0);\n", nbits_data-1);
|
||||||
|
fprintf(pFileOut, "\ttype word_array_t is array (0 to %d) of word_t;\n", romsize/4-1);
|
||||||
|
|
||||||
|
fprintf(pFileOut, "\tconstant word_array : word_array_t :=\n");
|
||||||
|
fprintf(pFileOut, "\t(\n");
|
||||||
|
fprintf(pFileOut, "\n");
|
||||||
|
|
||||||
|
// -------------------------------------------------------------------------
|
||||||
|
// ROM part
|
||||||
|
// -------------------------------------------------------------------------
|
||||||
|
for (i=0; i < filesize; i += sizeof(int))
|
||||||
|
{
|
||||||
|
fread(&word, 1, sizeof(int), pFileIn);
|
||||||
|
fprintf(pFileOut, "\t\tX\"%8.8X\"", word);
|
||||||
|
if (i < (romsize-sizeof(int)))
|
||||||
|
fprintf(pFileOut, ", -- %8.8X\n", i);
|
||||||
|
else
|
||||||
|
fprintf(pFileOut, " -- %8.8X\n", i);
|
||||||
|
}
|
||||||
|
word = 0;
|
||||||
|
for (; i < romsize; i += sizeof(int))
|
||||||
|
{
|
||||||
|
fprintf(pFileOut, "\t\tX\"%8.8X\"", word);
|
||||||
|
if (i < (romsize-sizeof(int)))
|
||||||
|
fprintf(pFileOut, ", -- %8.8X\n", i);
|
||||||
|
else
|
||||||
|
fprintf(pFileOut, " -- %8.8X\n", i);
|
||||||
|
}
|
||||||
|
fprintf(pFileOut, "\t);\n");
|
||||||
|
fprintf(pFileOut, "\n");
|
||||||
|
|
||||||
|
// -------------------------------------------------------------------------
|
||||||
|
// Trailer
|
||||||
|
// -------------------------------------------------------------------------
|
||||||
|
fprintf(pFileOut, "begin\n", ARCH_NAME);
|
||||||
|
fprintf(pFileOut, "\n");
|
||||||
|
fprintf(pFileOut, "PROM_READ:\n", ARCH_NAME);
|
||||||
|
fprintf(pFileOut, "\tprocess(clk)\n");
|
||||||
|
fprintf(pFileOut, "\tbegin\n");
|
||||||
|
fprintf(pFileOut, "\t\tif rising_edge(clk) and ce = '1' then\n");
|
||||||
|
fprintf(pFileOut, "\t\t\tdout <= word_array(to_integer(addr(%d downto 2)));\n", nbits_addr+1);
|
||||||
|
fprintf(pFileOut, "\t\tend if;\n");
|
||||||
|
fprintf(pFileOut, "\tend process;\n");
|
||||||
|
fprintf(pFileOut, "\n");
|
||||||
|
fprintf(pFileOut, "end %s;\n", ARCH_NAME);
|
||||||
|
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
int SaveROM_V4LD(char *pFilenameIn, char *pFilenameOut, char *pArchName, char *pEntName, int nbits_addr, int nbits_data)
|
||||||
|
{
|
||||||
|
FILE *pFileIn, *pFileOut;
|
||||||
|
long start, end;
|
||||||
|
int i, word, filesize, romsize;
|
||||||
|
|
||||||
|
char tpl[] = {"--------------------------------------------------------------------------\n-- Virtex-4: JTAG Loader\n--------------------------------------------------------------------------\n\ti00_BUFG : BUFG\n\tport map\n\t(\n\t\tO => bs_clk1,\n I => bs_clk0\n\t);\n\t\n\ti01_BUFG : BUFG\n\tport map\n\t(\n\t\tO => bs_update1,\n I => bs_update0\n\t);\n\n\tBSCAN_VIRTEX4_inst1 : BSCAN_VIRTEX4 \n\tgeneric map\n\t(\n\t\tJTAG_CHAIN => 1 -- Value to set BSCAN site of device. Possible values: (1,2,3 or 4)\n\t)\n\tport map \n\t(\n\t\tCAPTURE => bs_capture, -- CAPTURE output from TAP controller\n\t\tDRCK => bs_clk0, -- Data register output for USER functions\n\t\tRESET => bs_rst, -- Reset output from TAP controller\n\t\tSEL => bs_sel, -- USER active output\n\t\tSHIFT => bs_shift, -- SHIFT output from TAP controller\n\t\tTDI => bs_tdi, -- TDI output from TAP controller\n\t\tUPDATE => bs_update0, -- UPDATE output from TAP controller\n\t\tTDO => bs_tdo -- Data input for USER function\n\t);\n\n\tjtag_ld_addr <= user_regi(user_regi'left downto jtag_ld_dout'length);\n\tjtag_ld_din <= user_regi(jtag_ld_dout'length-1 downto 0);\n\tjtag_ld_clk <= bs_update1;\n\tjtag_ld_we <= bs_sel;\n\t\nsipo:\n\tprocess (bs_rst, bs_clk1, bs_tdi, bs_shift)\n\tbegin\n\t\tif bs_rst = '1' then\n\t\t\tuser_regi <= (others => '0');\n\t\telsif rising_edge(bs_clk1) then\n\t\t\tif bs_shift = '1' then\n\t\t\t\tuser_regi <= bs_tdi & user_regi(user_regi'left downto 1);\n\t\t\tend if;\n\t\tend if;\n\tend process;\t\n\npiso:\n\tprocess (bs_rst, bs_clk1, bs_shift, user_rego)\n\tbegin\n\t\tbs_tdo <= user_rego(0);\n\t\tif bs_rst = '1' then\n\t\t\tuser_rego <= (others => '0');\n\t\telsif rising_edge(bs_clk1) then\n\t\t\tif bs_shift = '1' then\n\t\t\t\tuser_rego <= user_rego(0) & user_rego(user_rego'left downto 1);\n\t\t\telse\n\t\t\t\tuser_rego <= (user_rego'left downto jtag_ld_dout'length => '0') & jtag_ld_dout;\t\n\t\n\t\t\tend if;\n\t\tend if;\n\tend process;\n\n"};
|
||||||
|
|
||||||
|
pFileIn = fopen(pFilenameIn, "rb");
|
||||||
|
if (!pFileIn)
|
||||||
|
{
|
||||||
|
fprintf(stderr, "Error opening file %s\n", pFilenameIn);
|
||||||
|
return 1;
|
||||||
|
}
|
||||||
|
|
||||||
|
pFileOut = fopen(pFilenameOut, "wb");
|
||||||
|
if (!pFileOut)
|
||||||
|
{
|
||||||
|
fprintf(stderr, "Error opening file %s\n", pFilenameOut);
|
||||||
|
return 1;
|
||||||
|
}
|
||||||
|
|
||||||
|
fseek(pFileIn, 0, SEEK_SET);
|
||||||
|
start = ftell(pFileIn);
|
||||||
|
fseek(pFileIn, 0, SEEK_END);
|
||||||
|
end = ftell(pFileIn);
|
||||||
|
fseek(pFileIn, 0, SEEK_SET);
|
||||||
|
|
||||||
|
filesize = (end-start);
|
||||||
|
romsize = (int)pow(2, nbits_addr+2);
|
||||||
|
|
||||||
|
// -------------------------------------------------------------------------
|
||||||
|
// Header
|
||||||
|
|
||||||
|
// -------------------------------------------------------------------------
|
||||||
|
fprintf(pFileOut, "LIBRARY IEEE;\n");
|
||||||
|
fprintf(pFileOut, "USE IEEE.STD_LOGIC_1164.ALL;\n");
|
||||||
|
fprintf(pFileOut, "USE IEEE.NUMERIC_STD.ALL;\n");
|
||||||
|
fprintf(pFileOut, "\n");
|
||||||
|
|
||||||
|
fprintf(pFileOut, "library UNISIM;\n");
|
||||||
|
fprintf(pFileOut, "use UNISIM.VComponents.all;\n");
|
||||||
|
fprintf(pFileOut, "\n");
|
||||||
|
|
||||||
|
fprintf(pFileOut, "ENTITY %s IS\n", ENT_NAME);
|
||||||
|
fprintf(pFileOut, "\tPort\n");
|
||||||
|
fprintf(pFileOut, "\t(\n");
|
||||||
|
fprintf(pFileOut, "\t\tclk\t\t: in STD_LOGIC;\n");
|
||||||
|
fprintf(pFileOut, "\t\tce\t\t: in STD_LOGIC;\n");
|
||||||
|
fprintf(pFileOut, "\t\taddr\t\t: in unsigned(%d downto 0);\n", nbits_data-1);
|
||||||
|
fprintf(pFileOut, "\t\tdout\t\t: out unsigned(%d downto 0)\n", nbits_data-1);
|
||||||
|
fprintf(pFileOut, "\t);\n");
|
||||||
|
fprintf(pFileOut, "END %s;\n", ENT_NAME);
|
||||||
|
fprintf(pFileOut, "\n");
|
||||||
|
|
||||||
|
|
||||||
|
fprintf(pFileOut, "ARCHITECTURE %s OF %s IS\n", ARCH_NAME, ENT_NAME);
|
||||||
|
fprintf(pFileOut, "\n");
|
||||||
|
|
||||||
|
fprintf(pFileOut, "\tsubtype word_t is unsigned(%d downto 0);\n", nbits_data-1);
|
||||||
|
fprintf(pFileOut, "\ttype word_array_t is array (0 to %d) of word_t;\n", romsize/4-1);
|
||||||
|
|
||||||
|
fprintf(pFileOut, "\tsignal jtag_ld_clk\t\t: STD_LOGIC;\n");
|
||||||
|
fprintf(pFileOut, "\tsignal jtag_ld_we\t\t: STD_LOGIC;\n");
|
||||||
|
fprintf(pFileOut, "\tsignal jtag_ld_addr\t\t: unsigned (%d downto 0);\n", JTAG_ADDR_WIDTH-1);
|
||||||
|
fprintf(pFileOut, "\tsignal jtag_ld_dout\t\t: unsigned (%d downto 0);\n", nbits_data-1);
|
||||||
|
fprintf(pFileOut, "\tsignal jtag_ld_din\t\t: unsigned (%d downto 0);\n", nbits_data-1);
|
||||||
|
fprintf(pFileOut, "\tsignal bs_rst, bs_sel, bs_shift, bs_tdi, bs_tdo : std_logic;\n");
|
||||||
|
fprintf(pFileOut, "\tsignal bs_capture, bs_clk0, bs_clk1, bs_update0, bs_update1 : std_logic;\n");
|
||||||
|
fprintf(pFileOut, "\tsignal user_regi, user_rego : unsigned (%d downto 0);\n", 31 + JTAG_ADDR_WIDTH);
|
||||||
|
fprintf(pFileOut, "\n");
|
||||||
|
|
||||||
|
fprintf(pFileOut, "\tsignal word_array : word_array_t :=\n");
|
||||||
|
fprintf(pFileOut, "\t(\n");
|
||||||
|
fprintf(pFileOut, "\n");
|
||||||
|
|
||||||
|
// -------------------------------------------------------------------------
|
||||||
|
// ROM part
|
||||||
|
// -------------------------------------------------------------------------
|
||||||
|
for (i=0; i < filesize; i += sizeof(int))
|
||||||
|
{
|
||||||
|
fread(&word, 1, sizeof(int), pFileIn);
|
||||||
|
fprintf(pFileOut, "\t\tX\"%8.8X\"", word);
|
||||||
|
if (i < (romsize-sizeof(int)))
|
||||||
|
fprintf(pFileOut, ", -- %8.8X\n", i);
|
||||||
|
else
|
||||||
|
fprintf(pFileOut, " -- %8.8X\n", i);
|
||||||
|
}
|
||||||
|
word = 0;
|
||||||
|
for (; i < romsize; i += sizeof(int))
|
||||||
|
{
|
||||||
|
fprintf(pFileOut, "\t\tX\"%8.8X\"", word);
|
||||||
|
if (i < (romsize-sizeof(int)))
|
||||||
|
fprintf(pFileOut, ", -- %8.8X\n", i);
|
||||||
|
else
|
||||||
|
fprintf(pFileOut, " -- %8.8X\n", i);
|
||||||
|
}
|
||||||
|
fprintf(pFileOut, "\t);\n");
|
||||||
|
fprintf(pFileOut, "\n");
|
||||||
|
|
||||||
|
fprintf(pFileOut, "begin\n", ARCH_NAME);
|
||||||
|
|
||||||
|
fprintf(pFileOut, "\n");
|
||||||
|
fprintf(pFileOut, "PROM_READ:\n", ARCH_NAME);
|
||||||
|
fprintf(pFileOut, "\tprocess(clk)\n");
|
||||||
|
fprintf(pFileOut, "\tbegin\n");
|
||||||
|
fprintf(pFileOut, "\t\tif rising_edge(clk) and ce = '1' then\n");
|
||||||
|
fprintf(pFileOut, "\t\t\tdout <= word_array(to_integer(addr(%d downto 2)));\n", nbits_addr+1);
|
||||||
|
fprintf(pFileOut, "\t\tend if;\n");
|
||||||
|
fprintf(pFileOut, "\tend process;\n");
|
||||||
|
fprintf(pFileOut, "\n");
|
||||||
|
|
||||||
|
// -------------------------------------------------------------------------
|
||||||
|
// Trailer
|
||||||
|
// -------------------------------------------------------------------------
|
||||||
|
fprintf(pFileOut, "\n");
|
||||||
|
fputs(tpl, pFileOut);
|
||||||
|
|
||||||
|
fprintf(pFileOut, "PROM_WRITE:\n", ARCH_NAME);
|
||||||
|
fprintf(pFileOut, "\tprocess(jtag_ld_clk, jtag_ld_we)\n");
|
||||||
|
fprintf(pFileOut, "\tbegin\n");
|
||||||
|
fprintf(pFileOut, "\t\tif rising_edge(jtag_ld_clk) then\n");
|
||||||
|
fprintf(pFileOut, "\t\t\tif jtag_ld_we = '1' then\n");
|
||||||
|
fprintf(pFileOut, "\t\t\t\tword_array(to_integer(jtag_ld_addr(%d downto 0))) <= jtag_ld_din;\n", nbits_addr-1);
|
||||||
|
fprintf(pFileOut, "\t\t\telse\n");
|
||||||
|
fprintf(pFileOut, "\t\t\t\tjtag_ld_dout <= word_array(to_integer(jtag_ld_addr(%d downto 0)));\n", nbits_addr-1);
|
||||||
|
fprintf(pFileOut, "\t\t\tend if;\n");
|
||||||
|
fprintf(pFileOut, "\t\tend if;\n");
|
||||||
|
fprintf(pFileOut, "\tend process;\n");
|
||||||
|
fprintf(pFileOut, "\n");
|
||||||
|
|
||||||
|
fprintf(pFileOut, "end %s;\n", ARCH_NAME);
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
int SaveROM_TCL(char *pFilenameIn, char *pFilenameOut, char *pArchName, char *pEntName, int nbits_addr, int nbits_data)
|
||||||
|
{
|
||||||
|
FILE *pFileIn, *pFileOut;
|
||||||
|
long start, end;
|
||||||
|
int i, word, word_addr, filesize, romsize;
|
||||||
|
char binstr_addr[33];
|
||||||
|
char binstr_data[33];
|
||||||
|
|
||||||
|
char tpl[] = {"# ---------------------------------------------------------------------\n# For Chipscope 9.1\n# ---------------------------------------------------------------------\n# Source JTAG/TCL frame work\ncd $env(CHIPSCOPE)\\\\bin\\\\nt\nsource csejtag.tcl\n\nnamespace import ::chipscope::*\n\n# Platform USB Cable\nset PLATFORM_USB_CABLE_ARGS [list \"port=USB2\" \"frequency=6000000\"]\n# frequency=\"24000000 | 12000000 | 6000000 | 3000000 | 1500000 | 750000\"\n\n# Create session\nset handle [::chipscope::csejtag_session create 0]\n\n# Open JTAG and lock\nset open_result [::chipscope::csejtag_target open $handle $CSEJTAG_TARGET_PLATFORMUSB 0 $PLATFORM_USB_CABLE_ARGS]\nset lock_result [::chipscope::csejtag_target lock $handle 1000]\n\nset devlist [::chipscope::csejtag_tap autodetect_chain $handle $CSEJTAG_SCAN_DEFAULT]\n\n# Get Device ID\nset devtype \"Virtex-4SX\"\nset devid 2\nset irlength [::chipscope::csejtag_tap get_irlength $handle $devid]\nset idcode [::chipscope::csejtag_tap get_device_idcode $handle $devid]\n\nset CSE_OP $CSEJTAG_SHIFT_READWRITE\nset CSE_ES $CSEJTAG_RUN_TEST_IDLE\n\n# Write Program\n"};
|
||||||
|
|
||||||
|
pFileIn = fopen(pFilenameIn, "rb");
|
||||||
|
if (!pFileIn)
|
||||||
|
{
|
||||||
|
fprintf(stderr, "Error opening file %s\n", pFilenameIn);
|
||||||
|
return 1;
|
||||||
|
}
|
||||||
|
|
||||||
|
pFileOut = fopen(pFilenameOut, "wb");
|
||||||
|
if (!pFileOut)
|
||||||
|
{
|
||||||
|
fprintf(stderr, "Error opening file %s\n", pFilenameOut);
|
||||||
|
return 1;
|
||||||
|
}
|
||||||
|
|
||||||
|
fseek(pFileIn, 0, SEEK_SET);
|
||||||
|
start = ftell(pFileIn);
|
||||||
|
fseek(pFileIn, 0, SEEK_END);
|
||||||
|
end = ftell(pFileIn);
|
||||||
|
fseek(pFileIn, 0, SEEK_SET);
|
||||||
|
|
||||||
|
filesize = (end-start);
|
||||||
|
romsize = (int)pow(2, nbits_addr+2);
|
||||||
|
|
||||||
|
// -------------------------------------------------------------------------
|
||||||
|
// Header
|
||||||
|
|
||||||
|
// -------------------------------------------------------------------------
|
||||||
|
fputs(tpl, pFileOut);
|
||||||
|
|
||||||
|
// -------------------------------------------------------------------------
|
||||||
|
// ROM part
|
||||||
|
// -------------------------------------------------------------------------
|
||||||
|
fprintf(pFileOut, "# Assembled from %s\n", pFilenameIn);
|
||||||
|
fprintf(pFileOut, "# ---------------------------------------------------------------\n");
|
||||||
|
fprintf(pFileOut, "# Shift the USER1 Instruction (b1111000010) into the Instruction Register of FPGA\n");
|
||||||
|
fprintf(pFileOut, "# User 1\n");
|
||||||
|
fprintf(pFileOut, "set result [::chipscope::csejtag_tap shift_device_ir $handle $devid $CSE_OP $CSE_ES 0 $irlength \"3C2\"]\n\n");
|
||||||
|
|
||||||
|
word_addr = 0;
|
||||||
|
for (i=0; i < filesize; i += sizeof(int))
|
||||||
|
{
|
||||||
|
fread(&word, 1, sizeof(int), pFileIn);
|
||||||
|
fprintf(pFileOut, "::chipscope::csejtag_tap shift_device_dr $handle $devid $CSE_OP $CSE_ES 0 %d \"%4.4X%8.8X\"\n", nbits_data + JTAG_ADDR_WIDTH, word_addr, word);
|
||||||
|
word_addr++;
|
||||||
|
}
|
||||||
|
fprintf(pFileOut, "\n");
|
||||||
|
|
||||||
|
// -------------------------------------------------------------------------
|
||||||
|
// Trailer
|
||||||
|
// -------------------------------------------------------------------------
|
||||||
|
fprintf(pFileOut, "::chipscope::csejtag_target unlock $handle\n");
|
||||||
|
fprintf(pFileOut, "::chipscope::csejtag_target close $handle\n");
|
||||||
|
fprintf(pFileOut, "::chipscope::csejtag_session destroy $handle\n");
|
||||||
|
fprintf(pFileOut, "exit\n");
|
||||||
|
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
int main(int argc, char *argv[])
|
||||||
|
{
|
||||||
|
char *pFilenameIn;
|
||||||
|
char name_prj[1024];
|
||||||
|
char name_rom[1024];
|
||||||
|
char name_rom_v4ld[1024];
|
||||||
|
char name_rom_tcl[1024];
|
||||||
|
|
||||||
|
FILE *pFileIn;
|
||||||
|
int filesize, romsize, nbits_addr, nbits_data;
|
||||||
|
long start, end;
|
||||||
|
int word, i;
|
||||||
|
|
||||||
|
if (argc < 2)
|
||||||
|
{
|
||||||
|
fprintf(stderr, "Usage: romgen <input file> <num. word address bits>\n");
|
||||||
|
return 1;
|
||||||
|
}
|
||||||
|
|
||||||
|
pFilenameIn = argv[1];
|
||||||
|
if (argc == 3)
|
||||||
|
nbits_addr = atoi(argv[2]);
|
||||||
|
|
||||||
|
|
||||||
|
basename(pFilenameIn, name_prj);
|
||||||
|
sprintf(name_rom, "%s.vhd", name_prj);
|
||||||
|
sprintf(name_rom_v4ld, "%s_ld.vhd", name_prj);
|
||||||
|
sprintf(name_rom_tcl, "%s.tcl", name_prj);
|
||||||
|
|
||||||
|
SaveROM(pFilenameIn, name_rom, ARCH_NAME, ENT_NAME, nbits_addr, 32);
|
||||||
|
SaveROM_V4LD(pFilenameIn, name_rom_v4ld, ARCH_NAME, ENT_NAME, nbits_addr, 32);
|
||||||
|
SaveROM_TCL(pFilenameIn, name_rom_tcl, ARCH_NAME, ENT_NAME, nbits_addr, 32);
|
||||||
|
|
||||||
|
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
|
||||||
@@ -0,0 +1,15 @@
|
|||||||
|
## NOTE: Do not edit this file.
|
||||||
|
##
|
||||||
|
vlib work
|
||||||
|
vcom -explicit -93 "../src/fifo_ctrl_pkg.vhd"
|
||||||
|
vcom -explicit -93 "../src/gray_counter.vhd"
|
||||||
|
vcom -explicit -93 "../src/dpram.vhd"
|
||||||
|
vcom -explicit -93 "../src/async_fifo_ctrl.vhd"
|
||||||
|
vcom -explicit -93 "../src/tb_async_fifo_ctrl.vhd"
|
||||||
|
vsim -t 1ps -lib work tb_async_fifo_ctrl
|
||||||
|
view wave
|
||||||
|
do {tb_async_fifo_ctrl.wdo}
|
||||||
|
view structure
|
||||||
|
view signals
|
||||||
|
|
||||||
|
run 10us
|
||||||
@@ -0,0 +1,36 @@
|
|||||||
|
onerror {resume}
|
||||||
|
quietly WaveActivateNextPane {} 0
|
||||||
|
add wave -noupdate -format Logic /tb_async_fifo_ctrl/rst
|
||||||
|
add wave -noupdate -format Logic /tb_async_fifo_ctrl/clk_w
|
||||||
|
add wave -noupdate -format Logic /tb_async_fifo_ctrl/we
|
||||||
|
add wave -noupdate -format Literal -radix hexadecimal /tb_async_fifo_ctrl/ptr_w
|
||||||
|
add wave -noupdate -format Logic /tb_async_fifo_ctrl/clk_r
|
||||||
|
add wave -noupdate -format Logic /tb_async_fifo_ctrl/re
|
||||||
|
add wave -noupdate -format Literal -radix hexadecimal /tb_async_fifo_ctrl/ptr_r
|
||||||
|
add wave -noupdate -format Logic /tb_async_fifo_ctrl/fifo_almost_empty
|
||||||
|
add wave -noupdate -format Logic /tb_async_fifo_ctrl/fifo_empty
|
||||||
|
add wave -noupdate -format Logic /tb_async_fifo_ctrl/fifo_almost_full
|
||||||
|
add wave -noupdate -format Logic /tb_async_fifo_ctrl/fifo_full
|
||||||
|
add wave -noupdate -format Literal -radix hexadecimal /tb_async_fifo_ctrl/din
|
||||||
|
add wave -noupdate -format Literal -radix hexadecimal /tb_async_fifo_ctrl/dout
|
||||||
|
add wave -noupdate -format Logic /tb_async_fifo_ctrl/uut/inst_gray_counter_w/ce
|
||||||
|
add wave -noupdate -format Literal -radix hexadecimal /tb_async_fifo_ctrl/uut/bnxt_w
|
||||||
|
add wave -noupdate -format Literal /tb_async_fifo_ctrl/uut/bcnt_r
|
||||||
|
add wave -noupdate -format Literal -radix decimal /tb_async_fifo_ctrl/uut/diffw
|
||||||
|
add wave -noupdate -format Literal -radix decimal /tb_async_fifo_ctrl/uut/diffr
|
||||||
|
TreeUpdate [SetDefaultTree]
|
||||||
|
WaveRestoreCursors {{Cursor 1} {250000 ps} 0}
|
||||||
|
configure wave -namecolwidth 190
|
||||||
|
configure wave -valuecolwidth 80
|
||||||
|
configure wave -justifyvalue left
|
||||||
|
configure wave -signalnamewidth 1
|
||||||
|
configure wave -snapdistance 10
|
||||||
|
configure wave -datasetprefix 0
|
||||||
|
configure wave -rowmargin 4
|
||||||
|
configure wave -childrowmargin 2
|
||||||
|
configure wave -gridoffset 0
|
||||||
|
configure wave -gridperiod 100
|
||||||
|
configure wave -griddelta 40
|
||||||
|
configure wave -timeline 1
|
||||||
|
update
|
||||||
|
WaveRestoreZoom {115874 ps} {612358 ps}
|
||||||
@@ -0,0 +1,13 @@
|
|||||||
|
## NOTE: Do not edit this file.
|
||||||
|
##
|
||||||
|
vlib work
|
||||||
|
vcom -explicit -93 "../src/fifo_ctrl_pkg.vhd"
|
||||||
|
vcom -explicit -93 "../src/gray_counter.vhd"
|
||||||
|
vcom -explicit -93 "../src/tb_gray_counter.vhd"
|
||||||
|
vsim -t 1ps -lib work tb_gray_counter
|
||||||
|
view wave
|
||||||
|
do {tb_gray_counter.wdo}
|
||||||
|
view structure
|
||||||
|
view signals
|
||||||
|
|
||||||
|
run 1us
|
||||||
@@ -0,0 +1,25 @@
|
|||||||
|
onerror {resume}
|
||||||
|
quietly WaveActivateNextPane {} 0
|
||||||
|
add wave -noupdate -format Logic /tb_gray_counter/rst
|
||||||
|
add wave -noupdate -format Logic /tb_gray_counter/ce
|
||||||
|
add wave -noupdate -format Logic /tb_gray_counter/clk
|
||||||
|
add wave -noupdate -format Literal /tb_gray_counter/bcnt
|
||||||
|
add wave -noupdate -format Literal /tb_gray_counter/bnxt
|
||||||
|
add wave -noupdate -format Literal /tb_gray_counter/gcnt
|
||||||
|
add wave -noupdate -format Literal /tb_gray_counter/gnxt
|
||||||
|
TreeUpdate [SetDefaultTree]
|
||||||
|
WaveRestoreCursors {{Cursor 1} {20898 ps} 0}
|
||||||
|
configure wave -namecolwidth 150
|
||||||
|
configure wave -valuecolwidth 100
|
||||||
|
configure wave -justifyvalue left
|
||||||
|
configure wave -signalnamewidth 1
|
||||||
|
configure wave -snapdistance 10
|
||||||
|
configure wave -datasetprefix 0
|
||||||
|
configure wave -rowmargin 4
|
||||||
|
configure wave -childrowmargin 2
|
||||||
|
configure wave -gridoffset 0
|
||||||
|
configure wave -gridperiod 1
|
||||||
|
configure wave -griddelta 40
|
||||||
|
configure wave -timeline 0
|
||||||
|
update
|
||||||
|
WaveRestoreZoom {0 ps} {134759 ps}
|
||||||
@@ -0,0 +1,15 @@
|
|||||||
|
## NOTE: Do not edit this file.
|
||||||
|
##
|
||||||
|
vlib work
|
||||||
|
vcom -explicit -93 "../src/fifo_ctrl_pkg.vhd"
|
||||||
|
vcom -explicit -93 "../src/gray_counter.vhd"
|
||||||
|
vcom -explicit -93 "../src/dpram.vhd"
|
||||||
|
vcom -explicit -93 "../src/sync_fifo_ctrl.vhd"
|
||||||
|
vcom -explicit -93 "../src/tb_sync_fifo_ctrl.vhd"
|
||||||
|
vsim -t 1ps -lib work tb_sync_fifo_ctrl
|
||||||
|
view wave
|
||||||
|
do {tb_sync_fifo_ctrl.wdo}
|
||||||
|
view structure
|
||||||
|
view signals
|
||||||
|
|
||||||
|
run 10us
|
||||||
@@ -0,0 +1,32 @@
|
|||||||
|
onerror {resume}
|
||||||
|
quietly WaveActivateNextPane {} 0
|
||||||
|
add wave -noupdate -format Logic /tb_sync_fifo_ctrl/rst
|
||||||
|
add wave -noupdate -format Logic /tb_sync_fifo_ctrl/we
|
||||||
|
add wave -noupdate -format Literal -radix hexadecimal /tb_sync_fifo_ctrl/ptr_w
|
||||||
|
add wave -noupdate -format Logic /tb_sync_fifo_ctrl/re
|
||||||
|
add wave -noupdate -format Literal -radix hexadecimal /tb_sync_fifo_ctrl/ptr_r
|
||||||
|
add wave -noupdate -format Logic /tb_sync_fifo_ctrl/fifo_almost_empty
|
||||||
|
add wave -noupdate -format Logic /tb_sync_fifo_ctrl/fifo_empty
|
||||||
|
add wave -noupdate -format Logic /tb_sync_fifo_ctrl/fifo_almost_full
|
||||||
|
add wave -noupdate -format Logic /tb_sync_fifo_ctrl/fifo_full
|
||||||
|
add wave -noupdate -format Literal -radix hexadecimal /tb_sync_fifo_ctrl/din
|
||||||
|
add wave -noupdate -format Literal -radix hexadecimal /tb_sync_fifo_ctrl/dout
|
||||||
|
add wave -noupdate -format Literal -radix unsigned /tb_sync_fifo_ctrl/uut/pw_next
|
||||||
|
add wave -noupdate -format Literal -radix unsigned /tb_sync_fifo_ctrl/uut/pr_next
|
||||||
|
add wave -noupdate -format Literal -radix unsigned /tb_sync_fifo_ctrl/uut/diff
|
||||||
|
TreeUpdate [SetDefaultTree]
|
||||||
|
WaveRestoreCursors {{Cursor 1} {290000 ps} 0}
|
||||||
|
configure wave -namecolwidth 190
|
||||||
|
configure wave -valuecolwidth 80
|
||||||
|
configure wave -justifyvalue left
|
||||||
|
configure wave -signalnamewidth 1
|
||||||
|
configure wave -snapdistance 10
|
||||||
|
configure wave -datasetprefix 0
|
||||||
|
configure wave -rowmargin 4
|
||||||
|
configure wave -childrowmargin 2
|
||||||
|
configure wave -gridoffset 0
|
||||||
|
configure wave -gridperiod 100
|
||||||
|
configure wave -griddelta 40
|
||||||
|
configure wave -timeline 1
|
||||||
|
update
|
||||||
|
WaveRestoreZoom {0 ps} {2166667 ps}
|
||||||
@@ -0,0 +1,244 @@
|
|||||||
|
-------------------------------------------------------------------------
|
||||||
|
-- Project: JCPU, a portable 8-bit RISC CPU written in VHDL
|
||||||
|
-- This file: The call/return/data stack
|
||||||
|
|
||||||
|
-- Copyright (C) 2007 J. Ahrensfeld
|
||||||
|
|
||||||
|
-- This library 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 2.1 of the License, or (at your option) any later version.
|
||||||
|
|
||||||
|
-- This library 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 this library; if not, write to the Free Software
|
||||||
|
-- Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
|
||||||
|
|
||||||
|
-- For questions and ideas, please contact the author at jens@jayfield.org
|
||||||
|
|
||||||
|
-----------------------------------------------------------------------
|
||||||
|
-- $Header: /tmp/cvsroot/VHDL/lib/FIFO/src/async_fifo_ctrl.vhd,v 1.2 2008-10-25 11:21:47 Jens Exp $
|
||||||
|
-----------------------------------------------------------------------
|
||||||
|
|
||||||
|
library IEEE;
|
||||||
|
use IEEE.STD_LOGIC_1164.ALL;
|
||||||
|
use IEEE.numeric_std.ALL;
|
||||||
|
|
||||||
|
LIBRARY WORK;
|
||||||
|
USE WORK.FIFO_CTRL_PKG.ALL;
|
||||||
|
|
||||||
|
entity async_fifo_ctrl is
|
||||||
|
Generic (
|
||||||
|
addr_width : integer := 3;
|
||||||
|
almost_full_thresh : integer := 6;
|
||||||
|
almost_empty_thresh : integer := 2
|
||||||
|
);
|
||||||
|
Port
|
||||||
|
(
|
||||||
|
rst : in STD_LOGIC;
|
||||||
|
clk_w : in STD_LOGIC;
|
||||||
|
clk_r : in STD_LOGIC;
|
||||||
|
we : in STD_LOGIC;
|
||||||
|
re : in STD_LOGIC;
|
||||||
|
ptr_w : out unsigned (addr_width-1 downto 0);
|
||||||
|
ptr_r : out unsigned (addr_width-1 downto 0);
|
||||||
|
fifo_full : out STD_LOGIC;
|
||||||
|
fifo_empty : out STD_LOGIC;
|
||||||
|
fifo_afull : out STD_LOGIC;
|
||||||
|
fifo_aempty : out STD_LOGIC
|
||||||
|
);
|
||||||
|
end async_fifo_ctrl;
|
||||||
|
|
||||||
|
architecture Behavioral of async_fifo_ctrl is
|
||||||
|
|
||||||
|
signal gcnt_w : unsigned (addr_width downto 0);
|
||||||
|
signal gcnt2_w : unsigned (addr_width downto 0);
|
||||||
|
signal bcnt2_aw : unsigned (addr_width downto 0);
|
||||||
|
signal bcnt_w : unsigned (addr_width downto 0);
|
||||||
|
signal gnxt_w : unsigned (addr_width downto 0);
|
||||||
|
signal bnxt_w : unsigned (addr_width downto 0);
|
||||||
|
signal gcnt_r : unsigned (addr_width downto 0);
|
||||||
|
signal gcnt2_r : unsigned (addr_width downto 0);
|
||||||
|
signal bcnt2_ar : unsigned (addr_width downto 0);
|
||||||
|
signal bcnt_r : unsigned (addr_width downto 0);
|
||||||
|
signal gnxt_r : unsigned (addr_width downto 0);
|
||||||
|
signal bnxt_r : unsigned (addr_width downto 0);
|
||||||
|
|
||||||
|
signal empty, full : std_logic;
|
||||||
|
signal write_inhibit, read_inhibit : std_logic;
|
||||||
|
signal winc, rinc : std_logic;
|
||||||
|
|
||||||
|
-- synthesis translate_off
|
||||||
|
signal diffw : signed (addr_width downto 0);
|
||||||
|
signal diffr : signed (addr_width downto 0);
|
||||||
|
-- synthesis translate_on
|
||||||
|
|
||||||
|
begin
|
||||||
|
|
||||||
|
ptr_w <= bcnt_w(addr_width-1 downto 0);
|
||||||
|
ptr_r <= bnxt_r(addr_width-1 downto 0);
|
||||||
|
winc <= we and (not write_inhibit);
|
||||||
|
rinc <= re and (not read_inhibit);
|
||||||
|
fifo_full <= write_inhibit;
|
||||||
|
fifo_empty <= read_inhibit;
|
||||||
|
|
||||||
|
proc_write_inhibit:
|
||||||
|
process(rst, clk_w)
|
||||||
|
begin
|
||||||
|
if rst = '1' then
|
||||||
|
write_inhibit <= '0';
|
||||||
|
elsif rising_edge(clk_w) then
|
||||||
|
write_inhibit <= full;
|
||||||
|
end if;
|
||||||
|
end process;
|
||||||
|
|
||||||
|
proc_read_inhibit:
|
||||||
|
process(rst, clk_r)
|
||||||
|
begin
|
||||||
|
if rst = '1' then
|
||||||
|
read_inhibit <= '1';
|
||||||
|
elsif rising_edge(clk_r) then
|
||||||
|
read_inhibit <= empty;
|
||||||
|
end if;
|
||||||
|
end process;
|
||||||
|
|
||||||
|
proc_sync_grptr:
|
||||||
|
process(clk_w)
|
||||||
|
variable p1, p2 : unsigned (addr_width downto 0);
|
||||||
|
begin
|
||||||
|
if rising_edge(clk_w) then
|
||||||
|
gcnt2_r <= p2;
|
||||||
|
p2 := p1;
|
||||||
|
p1 := gcnt_r;
|
||||||
|
end if;
|
||||||
|
end process;
|
||||||
|
|
||||||
|
proc_ptr_gwptr:
|
||||||
|
process(clk_r)
|
||||||
|
variable p1, p2 : unsigned (addr_width downto 0);
|
||||||
|
begin
|
||||||
|
if rising_edge(clk_r) then
|
||||||
|
gcnt2_w <= p2;
|
||||||
|
p2 := p1;
|
||||||
|
p1 := gcnt_w;
|
||||||
|
end if;
|
||||||
|
end process;
|
||||||
|
|
||||||
|
proc_status_full:
|
||||||
|
process(gnxt_w, gcnt2_r)
|
||||||
|
begin
|
||||||
|
if (gnxt_w = (not gcnt2_r(gcnt2_r'left downto gcnt2_r'left-1) & gcnt2_r(gcnt2_r'left-2 downto 0))) then
|
||||||
|
full <= '1';
|
||||||
|
else
|
||||||
|
full <= '0';
|
||||||
|
end if;
|
||||||
|
end process;
|
||||||
|
|
||||||
|
proc_status_empty:
|
||||||
|
process(gnxt_r, gcnt2_w)
|
||||||
|
begin
|
||||||
|
if (gnxt_r = gcnt2_w) then
|
||||||
|
empty <= '1';
|
||||||
|
else
|
||||||
|
empty <= '0';
|
||||||
|
end if;
|
||||||
|
end process;
|
||||||
|
|
||||||
|
proc_sync_arptr:
|
||||||
|
process(clk_w)
|
||||||
|
variable p1, p2 : unsigned (addr_width downto 0);
|
||||||
|
begin
|
||||||
|
if rising_edge(clk_w) then
|
||||||
|
bcnt2_ar <= p2;
|
||||||
|
p2 := p1;
|
||||||
|
p1 := bcnt_r;
|
||||||
|
end if;
|
||||||
|
end process;
|
||||||
|
|
||||||
|
proc_ptr_awptr:
|
||||||
|
process(clk_r)
|
||||||
|
variable p1, p2 : unsigned (addr_width downto 0);
|
||||||
|
begin
|
||||||
|
if rising_edge(clk_r) then
|
||||||
|
bcnt2_aw <= p2;
|
||||||
|
p2 := p1;
|
||||||
|
p1 := bcnt_w;
|
||||||
|
end if;
|
||||||
|
end process;
|
||||||
|
|
||||||
|
proc_status_almost_full:
|
||||||
|
process(rst, clk_w)
|
||||||
|
variable diff : unsigned (addr_width downto 0);
|
||||||
|
begin
|
||||||
|
-- synthesis translate_off
|
||||||
|
diffw <= signed(diff);
|
||||||
|
-- synthesis translate_on
|
||||||
|
if rst = '1' then
|
||||||
|
fifo_afull <= '0';
|
||||||
|
diff := (others => '0');
|
||||||
|
elsif rising_edge(clk_w) then
|
||||||
|
if diff >= almost_full_thresh-1 then
|
||||||
|
fifo_afull <= '1';
|
||||||
|
else
|
||||||
|
fifo_afull <= '0';
|
||||||
|
end if;
|
||||||
|
diff := unsigned(abs(signed(bnxt_w) - signed(bcnt2_ar)));
|
||||||
|
end if;
|
||||||
|
end process;
|
||||||
|
|
||||||
|
proc_status_almost_empty:
|
||||||
|
process(rst, clk_r)
|
||||||
|
variable diff : unsigned (addr_width downto 0);
|
||||||
|
begin
|
||||||
|
-- synthesis translate_off
|
||||||
|
diffr <= signed(diff);
|
||||||
|
-- synthesis translate_on
|
||||||
|
if rst = '1' then
|
||||||
|
fifo_aempty <= '1';
|
||||||
|
diff := (others => '0');
|
||||||
|
elsif rising_edge(clk_r) then
|
||||||
|
if diff <= almost_empty_thresh+1 then
|
||||||
|
fifo_aempty <= '1';
|
||||||
|
else
|
||||||
|
fifo_aempty <= '0';
|
||||||
|
end if;
|
||||||
|
diff := unsigned(abs(signed(bcnt2_aw) - signed(bnxt_r)));
|
||||||
|
end if;
|
||||||
|
end process;
|
||||||
|
|
||||||
|
inst_gray_counter_w : entity work.gray_counter
|
||||||
|
generic map (
|
||||||
|
width => addr_width+1,
|
||||||
|
init_value => 0
|
||||||
|
)
|
||||||
|
port map (
|
||||||
|
rst => rst,
|
||||||
|
clk => clk_w,
|
||||||
|
ce => winc,
|
||||||
|
bcnt => bcnt_w,
|
||||||
|
bnxt => bnxt_w,
|
||||||
|
gcnt => gcnt_w,
|
||||||
|
gnxt => gnxt_w
|
||||||
|
);
|
||||||
|
|
||||||
|
inst_gray_counter_r : entity work.gray_counter
|
||||||
|
generic map (
|
||||||
|
width => addr_width+1,
|
||||||
|
init_value => 0
|
||||||
|
)
|
||||||
|
port map (
|
||||||
|
rst => rst,
|
||||||
|
clk => clk_r,
|
||||||
|
ce => rinc,
|
||||||
|
bcnt => bcnt_r,
|
||||||
|
bnxt => bnxt_r,
|
||||||
|
gcnt => gcnt_r,
|
||||||
|
gnxt => gnxt_r
|
||||||
|
);
|
||||||
|
|
||||||
|
end Behavioral;
|
||||||
|
|
||||||
@@ -0,0 +1,79 @@
|
|||||||
|
-------------------------------------------------------------------------
|
||||||
|
-- Project: JCPU, a portable 8-bit RISC CPU written in VHDL
|
||||||
|
-- This file: Dual-ported register file with asynchrous read
|
||||||
|
|
||||||
|
-- Copyright (C) 2007 J. Ahrensfeld
|
||||||
|
|
||||||
|
-- This library 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 2.1 of the License, or (at your option) any later version.
|
||||||
|
|
||||||
|
-- This library 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 this library; if not, write to the Free Software
|
||||||
|
-- Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
|
||||||
|
|
||||||
|
-- For questions and ideas, please contact the author at jens@jayfield.org
|
||||||
|
|
||||||
|
-----------------------------------------------------------------------
|
||||||
|
-- $Header: /tmp/cvsroot/VHDL/lib/FIFO/src/dpram.vhd,v 1.1 2008-08-23 08:20:28 Jens Exp $
|
||||||
|
-----------------------------------------------------------------------
|
||||||
|
|
||||||
|
LIBRARY IEEE;
|
||||||
|
USE IEEE.STD_LOGIC_1164.ALL;
|
||||||
|
USE IEEE.NUMERIC_STD.ALL;
|
||||||
|
|
||||||
|
entity dpram is
|
||||||
|
Generic (
|
||||||
|
addr_width : integer := 3;
|
||||||
|
data_width : integer := 8
|
||||||
|
);
|
||||||
|
Port (
|
||||||
|
clka : in STD_LOGIC;
|
||||||
|
clkb : in STD_LOGIC;
|
||||||
|
en_a : in STD_LOGIC;
|
||||||
|
en_b : in STD_LOGIC;
|
||||||
|
we_a : in STD_LOGIC;
|
||||||
|
addr_a : in unsigned (addr_width-1 downto 0);
|
||||||
|
addr_b : in unsigned (addr_width-1 downto 0);
|
||||||
|
din_a : in unsigned (data_width-1 downto 0);
|
||||||
|
dout_b : out unsigned (data_width-1 downto 0)
|
||||||
|
);
|
||||||
|
end dpram;
|
||||||
|
|
||||||
|
architecture Behavioral of dpram is
|
||||||
|
|
||||||
|
constant depth : integer := 2**addr_width;
|
||||||
|
type RAMtype is array (0 to depth-1) of unsigned (data_width-1 downto 0);
|
||||||
|
signal RAM : RAMtype;
|
||||||
|
|
||||||
|
begin
|
||||||
|
|
||||||
|
process (clka)
|
||||||
|
begin
|
||||||
|
if clka'event and clka = '1' then
|
||||||
|
if en_a = '1' then
|
||||||
|
if we_a = '1' then
|
||||||
|
RAM(to_integer(addr_a)) <= din_a;
|
||||||
|
end if;
|
||||||
|
end if;
|
||||||
|
end if;
|
||||||
|
end process;
|
||||||
|
|
||||||
|
process (clkb)
|
||||||
|
begin
|
||||||
|
if clkb'event and clkb = '1' then
|
||||||
|
if en_b = '1' then
|
||||||
|
dout_b <= RAM(to_integer(addr_b));
|
||||||
|
end if;
|
||||||
|
end if;
|
||||||
|
end process;
|
||||||
|
|
||||||
|
|
||||||
|
end Behavioral;
|
||||||
|
|
||||||
@@ -0,0 +1,113 @@
|
|||||||
|
-------------------------------------------------------------------------
|
||||||
|
-- Project: JCPU, a portable 8-bit RISC CPU written in VHDL
|
||||||
|
-- This file: Dual-ported register file with asynchrous read
|
||||||
|
|
||||||
|
-- Copyright (C) 2007 J. Ahrensfeld
|
||||||
|
|
||||||
|
-- This library 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 2.1 of the License, or (at your option) any later version.
|
||||||
|
|
||||||
|
-- This library 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 this library; if not, write to the Free Software
|
||||||
|
-- Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
|
||||||
|
|
||||||
|
-- For questions and ideas, please contact the author at jens@jayfield.org
|
||||||
|
|
||||||
|
-----------------------------------------------------------------------
|
||||||
|
|
||||||
|
LIBRARY IEEE;
|
||||||
|
USE IEEE.STD_LOGIC_1164.ALL;
|
||||||
|
USE IEEE.NUMERIC_STD.ALL;
|
||||||
|
|
||||||
|
entity fifo_async is
|
||||||
|
Generic
|
||||||
|
(
|
||||||
|
addr_width : natural := 4;
|
||||||
|
data_width : natural := 8;
|
||||||
|
almost_full_thresh : integer := 12;
|
||||||
|
almost_empty_thresh : integer := 4
|
||||||
|
);
|
||||||
|
Port
|
||||||
|
(
|
||||||
|
rst : in STD_LOGIC;
|
||||||
|
clk_w : in STD_LOGIC;
|
||||||
|
clk_r : in STD_LOGIC;
|
||||||
|
we_w : in STD_LOGIC;
|
||||||
|
re_r : in STD_LOGIC;
|
||||||
|
fifo_full : out STD_LOGIC;
|
||||||
|
fifo_empty : out STD_LOGIC;
|
||||||
|
fifo_afull : out STD_LOGIC;
|
||||||
|
fifo_aempty : out STD_LOGIC;
|
||||||
|
data_w : in unsigned (data_width-1 downto 0);
|
||||||
|
data_r : out unsigned (data_width-1 downto 0)
|
||||||
|
);
|
||||||
|
end fifo_async;
|
||||||
|
|
||||||
|
architecture Behavioral of fifo_async is
|
||||||
|
|
||||||
|
signal buf_we_w : STD_LOGIC;
|
||||||
|
signal ptr_w : unsigned (addr_width-1 downto 0);
|
||||||
|
signal ptr_r : unsigned (addr_width-1 downto 0);
|
||||||
|
signal full : STD_LOGIC;
|
||||||
|
signal empty : STD_LOGIC;
|
||||||
|
signal almost_full : STD_LOGIC;
|
||||||
|
signal almost_empty : STD_LOGIC;
|
||||||
|
|
||||||
|
begin
|
||||||
|
|
||||||
|
buf_we_w <= we_w;
|
||||||
|
fifo_full <= full;
|
||||||
|
fifo_empty <= empty;
|
||||||
|
fifo_afull <= almost_full;
|
||||||
|
fifo_aempty <= almost_empty;
|
||||||
|
|
||||||
|
inst_fifo_ctrl: entity work.async_fifo_ctrl
|
||||||
|
GENERIC MAP
|
||||||
|
(
|
||||||
|
addr_width => ADDR_WIDTH,
|
||||||
|
almost_full_thresh => almost_full_thresh,
|
||||||
|
almost_empty_thresh => almost_empty_thresh
|
||||||
|
)
|
||||||
|
PORT MAP
|
||||||
|
(
|
||||||
|
rst => rst,
|
||||||
|
clk_w => clk_w,
|
||||||
|
clk_r => clk_r,
|
||||||
|
we => we_w,
|
||||||
|
re => re_r,
|
||||||
|
ptr_w => ptr_w,
|
||||||
|
ptr_r => ptr_r,
|
||||||
|
fifo_full => full,
|
||||||
|
fifo_empty => empty,
|
||||||
|
fifo_afull => almost_full,
|
||||||
|
fifo_aempty => almost_empty
|
||||||
|
|
||||||
|
);
|
||||||
|
|
||||||
|
inst_dpram_1w1r: entity work.dpram_1w1r
|
||||||
|
GENERIC MAP
|
||||||
|
(
|
||||||
|
addr_width => addr_width,
|
||||||
|
data_width => data_width
|
||||||
|
)
|
||||||
|
PORT MAP(
|
||||||
|
clka => clk_w,
|
||||||
|
clkb => clk_r,
|
||||||
|
en_a => '1',
|
||||||
|
en_b => '1',
|
||||||
|
we_a => buf_we_w,
|
||||||
|
addr_a => ptr_w,
|
||||||
|
addr_b => ptr_r,
|
||||||
|
din_a => data_w,
|
||||||
|
dout_b => data_r
|
||||||
|
);
|
||||||
|
|
||||||
|
end Behavioral;
|
||||||
|
|
||||||
@@ -0,0 +1,46 @@
|
|||||||
|
-----------------------------------------------------------------------
|
||||||
|
-- $Header: /tmp/cvsroot/VHDL/lib/FIFO/src/fifo_ctrl_pkg.vhd,v 1.1 2008-08-23 08:20:28 Jens Exp $
|
||||||
|
-----------------------------------------------------------------------
|
||||||
|
LIBRARY IEEE;
|
||||||
|
USE IEEE.STD_LOGIC_1164.ALL;
|
||||||
|
USE IEEE.NUMERIC_STD.ALL;
|
||||||
|
|
||||||
|
package fifo_ctrl_pkg is
|
||||||
|
|
||||||
|
-- Constants
|
||||||
|
-- Types
|
||||||
|
|
||||||
|
-- Functions
|
||||||
|
function bin2gray(xb : unsigned) return unsigned;
|
||||||
|
function gray2bin(xg : unsigned) return unsigned;
|
||||||
|
|
||||||
|
end fifo_ctrl_pkg;
|
||||||
|
|
||||||
|
package body fifo_ctrl_pkg is
|
||||||
|
|
||||||
|
function bin2gray(xb : unsigned) return unsigned is
|
||||||
|
variable xg : unsigned(xb'left downto xb'right);
|
||||||
|
begin
|
||||||
|
|
||||||
|
xg(xg'left) := xb(xb'left);
|
||||||
|
for i in 1 to xb'left loop
|
||||||
|
xg(xg'left-i) := xb(xb'left-i+1) xor xb(xb'left-i);
|
||||||
|
end loop;
|
||||||
|
|
||||||
|
return xg;
|
||||||
|
end bin2gray;
|
||||||
|
|
||||||
|
function gray2bin(xg : unsigned) return unsigned is
|
||||||
|
variable xb : unsigned(xg'left downto xg'right);
|
||||||
|
begin
|
||||||
|
|
||||||
|
xb(xb'left) := xg(xg'left);
|
||||||
|
for i in 1 to xg'left loop
|
||||||
|
xb(xb'left-i) := xb(xb'left-i+1) xor xg(xg'left-i);
|
||||||
|
end loop;
|
||||||
|
|
||||||
|
return xb;
|
||||||
|
end gray2bin;
|
||||||
|
|
||||||
|
end fifo_ctrl_pkg;
|
||||||
|
|
||||||
@@ -0,0 +1,119 @@
|
|||||||
|
-------------------------------------------------------------------------
|
||||||
|
-- Project: JCPU, a portable 8-bit RISC CPU written in VHDL
|
||||||
|
-- This file: Dual-ported register file with asynchrous read
|
||||||
|
|
||||||
|
-- Copyright (C) 2007 J. Ahrensfeld
|
||||||
|
|
||||||
|
-- This library 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 2.1 of the License, or (at your option) any later version.
|
||||||
|
|
||||||
|
-- This library 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 this library; if not, write to the Free Software
|
||||||
|
-- Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
|
||||||
|
|
||||||
|
-- For questions and ideas, please contact the author at jens@jayfield.org
|
||||||
|
|
||||||
|
-----------------------------------------------------------------------
|
||||||
|
|
||||||
|
LIBRARY IEEE;
|
||||||
|
USE IEEE.STD_LOGIC_1164.ALL;
|
||||||
|
USE IEEE.NUMERIC_STD.ALL;
|
||||||
|
|
||||||
|
use work.fifo_ctrl_pkg.all;
|
||||||
|
|
||||||
|
entity fifo_sync is
|
||||||
|
Generic
|
||||||
|
(
|
||||||
|
addr_width : natural := 4;
|
||||||
|
data_width : natural := 8;
|
||||||
|
almost_full_thresh : integer := 12;
|
||||||
|
almost_empty_thresh : integer := 4
|
||||||
|
);
|
||||||
|
Port
|
||||||
|
(
|
||||||
|
rst : in STD_LOGIC;
|
||||||
|
clk : in STD_LOGIC;
|
||||||
|
we : in STD_LOGIC;
|
||||||
|
re : in STD_LOGIC;
|
||||||
|
fifo_full : out STD_LOGIC;
|
||||||
|
fifo_empty : out STD_LOGIC;
|
||||||
|
fifo_afull : out STD_LOGIC;
|
||||||
|
fifo_aempty : out STD_LOGIC;
|
||||||
|
data_w : in unsigned (data_width-1 downto 0);
|
||||||
|
data_r : out unsigned (data_width-1 downto 0)
|
||||||
|
);
|
||||||
|
end fifo_sync;
|
||||||
|
|
||||||
|
architecture Behavioral of fifo_sync is
|
||||||
|
|
||||||
|
signal mem_wr_en : STD_LOGIC;
|
||||||
|
signal mem_rd_en : STD_LOGIC;
|
||||||
|
signal ptr_w : unsigned (addr_width-1 downto 0);
|
||||||
|
signal ptr_r : unsigned (addr_width-1 downto 0);
|
||||||
|
signal full : STD_LOGIC;
|
||||||
|
signal empty : STD_LOGIC;
|
||||||
|
signal almost_full : STD_LOGIC;
|
||||||
|
signal almost_empty : STD_LOGIC;
|
||||||
|
signal pre_full : STD_LOGIC;
|
||||||
|
signal pre_empty : STD_LOGIC;
|
||||||
|
|
||||||
|
begin
|
||||||
|
|
||||||
|
mem_wr_en <= not full;
|
||||||
|
mem_rd_en <= not pre_empty;
|
||||||
|
fifo_full <= full;
|
||||||
|
fifo_empty <= empty;
|
||||||
|
fifo_afull <= almost_full;
|
||||||
|
fifo_aempty <= almost_empty;
|
||||||
|
|
||||||
|
inst_sync_fifo_ctrl: entity work.sync_fifo_ctrl
|
||||||
|
GENERIC MAP
|
||||||
|
(
|
||||||
|
addr_width => addr_width,
|
||||||
|
almost_full_thresh => almost_full_thresh,
|
||||||
|
almost_empty_thresh => almost_empty_thresh
|
||||||
|
)
|
||||||
|
PORT MAP
|
||||||
|
(
|
||||||
|
rst => rst,
|
||||||
|
clk => clk,
|
||||||
|
we => we,
|
||||||
|
re => re,
|
||||||
|
ptr_w => ptr_w,
|
||||||
|
ptr_r => ptr_r,
|
||||||
|
fifo_full => full,
|
||||||
|
fifo_empty => empty,
|
||||||
|
fifo_pre_full => pre_full,
|
||||||
|
fifo_pre_empty => pre_empty,
|
||||||
|
fifo_afull => almost_full,
|
||||||
|
fifo_aempty => almost_empty
|
||||||
|
|
||||||
|
);
|
||||||
|
|
||||||
|
inst_dpram_1w1r: entity work.dpram_1w1r
|
||||||
|
GENERIC MAP
|
||||||
|
(
|
||||||
|
addr_width => addr_width,
|
||||||
|
data_width => data_width
|
||||||
|
)
|
||||||
|
PORT MAP(
|
||||||
|
clka => clk,
|
||||||
|
clkb => clk,
|
||||||
|
en_a => mem_wr_en,
|
||||||
|
en_b => mem_rd_en,
|
||||||
|
we_a => we,
|
||||||
|
addr_a => ptr_w,
|
||||||
|
addr_b => ptr_r,
|
||||||
|
din_a => data_w,
|
||||||
|
dout_b => data_r
|
||||||
|
);
|
||||||
|
|
||||||
|
end Behavioral;
|
||||||
|
|
||||||
@@ -0,0 +1,117 @@
|
|||||||
|
-------------------------------------------------------------------------
|
||||||
|
-- Project: JCPU, a portable 8-bit RISC CPU written in VHDL
|
||||||
|
-- This file: Dual-ported register file with asynchrous read
|
||||||
|
|
||||||
|
-- Copyright (C) 2007 J. Ahrensfeld
|
||||||
|
|
||||||
|
-- This library 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 2.1 of the License, or (at your option) any later version.
|
||||||
|
|
||||||
|
-- This library 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 this library; if not, write to the Free Software
|
||||||
|
-- Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
|
||||||
|
|
||||||
|
-- For questions and ideas, please contact the author at jens@jayfield.org
|
||||||
|
|
||||||
|
-----------------------------------------------------------------------
|
||||||
|
|
||||||
|
LIBRARY IEEE;
|
||||||
|
USE IEEE.STD_LOGIC_1164.ALL;
|
||||||
|
USE IEEE.NUMERIC_STD.ALL;
|
||||||
|
|
||||||
|
use work.fifo_ctrl_pkg.all;
|
||||||
|
|
||||||
|
entity fifo_sync_dist is
|
||||||
|
Generic (
|
||||||
|
addr_width : natural := 4;
|
||||||
|
data_width : natural := 8;
|
||||||
|
almost_full_thresh : integer := 12;
|
||||||
|
almost_empty_thresh : integer := 4
|
||||||
|
);
|
||||||
|
Port
|
||||||
|
(
|
||||||
|
rst : in STD_LOGIC;
|
||||||
|
clk : in STD_LOGIC;
|
||||||
|
we : in STD_LOGIC;
|
||||||
|
re : in STD_LOGIC;
|
||||||
|
fifo_full : out STD_LOGIC;
|
||||||
|
fifo_empty : out STD_LOGIC;
|
||||||
|
fifo_afull : out STD_LOGIC;
|
||||||
|
fifo_aempty : out STD_LOGIC;
|
||||||
|
data_w : in unsigned (data_width-1 downto 0);
|
||||||
|
data_r : out unsigned (data_width-1 downto 0)
|
||||||
|
);
|
||||||
|
end fifo_sync_dist;
|
||||||
|
|
||||||
|
architecture Behavioral of fifo_sync_dist is
|
||||||
|
|
||||||
|
signal mem_wr_en : STD_LOGIC;
|
||||||
|
signal mem_rd_en : STD_LOGIC;
|
||||||
|
signal ptr_w : unsigned (addr_width-1 downto 0);
|
||||||
|
signal ptr_r : unsigned (addr_width-1 downto 0);
|
||||||
|
signal full : STD_LOGIC;
|
||||||
|
signal empty : STD_LOGIC;
|
||||||
|
signal almost_full : STD_LOGIC;
|
||||||
|
signal almost_empty : STD_LOGIC;
|
||||||
|
signal pre_full : STD_LOGIC;
|
||||||
|
signal pre_empty : STD_LOGIC;
|
||||||
|
|
||||||
|
begin
|
||||||
|
|
||||||
|
mem_wr_en <= not full;
|
||||||
|
mem_rd_en <= not pre_empty;
|
||||||
|
fifo_full <= full;
|
||||||
|
fifo_empty <= empty;
|
||||||
|
fifo_afull <= almost_full;
|
||||||
|
fifo_aempty <= almost_empty;
|
||||||
|
|
||||||
|
inst_sync_fifo_ctrl: entity work.sync_fifo_ctrl
|
||||||
|
GENERIC MAP
|
||||||
|
(
|
||||||
|
addr_width => addr_width,
|
||||||
|
almost_full_thresh => almost_full_thresh,
|
||||||
|
almost_empty_thresh => almost_empty_thresh
|
||||||
|
)
|
||||||
|
PORT MAP
|
||||||
|
(
|
||||||
|
rst => rst,
|
||||||
|
clk => clk,
|
||||||
|
we => we,
|
||||||
|
re => re,
|
||||||
|
ptr_w => ptr_w,
|
||||||
|
ptr_r => ptr_r,
|
||||||
|
fifo_full => full,
|
||||||
|
fifo_empty => empty,
|
||||||
|
fifo_pre_full => pre_full,
|
||||||
|
fifo_pre_empty => pre_empty,
|
||||||
|
fifo_afull => almost_full,
|
||||||
|
fifo_aempty => almost_empty
|
||||||
|
|
||||||
|
);
|
||||||
|
|
||||||
|
inst_dpram_1w1r: entity work.dpram_1w1r_dist
|
||||||
|
GENERIC MAP (
|
||||||
|
addr_width => addr_width,
|
||||||
|
data_width => data_width
|
||||||
|
)
|
||||||
|
PORT MAP(
|
||||||
|
clka => clk,
|
||||||
|
clkb => clk,
|
||||||
|
en_a => mem_wr_en,
|
||||||
|
en_b => mem_rd_en,
|
||||||
|
we_a => we,
|
||||||
|
addr_a => ptr_w,
|
||||||
|
addr_b => ptr_r,
|
||||||
|
din_a => data_w,
|
||||||
|
dout_b => data_r
|
||||||
|
);
|
||||||
|
|
||||||
|
end Behavioral;
|
||||||
|
|
||||||
@@ -0,0 +1,88 @@
|
|||||||
|
-------------------------------------------------------------------------
|
||||||
|
-- Project: JCPU, a portable 8-bit RISC CPU written in VHDL
|
||||||
|
-- This file: The call/return/data stack
|
||||||
|
|
||||||
|
-- Copyright (C) 2007 J. Ahrensfeld
|
||||||
|
|
||||||
|
-- This library 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 2.1 of the License, or (at your option) any later version.
|
||||||
|
|
||||||
|
-- This library 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 this library; if not, write to the Free Software
|
||||||
|
-- Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
|
||||||
|
|
||||||
|
-- For questions and ideas, please contact the author at jens@jayfield.org
|
||||||
|
|
||||||
|
-----------------------------------------------------------------------
|
||||||
|
-- $Header: /tmp/cvsroot/VHDL/lib/FIFO/src/gray_counter.vhd,v 1.1 2008-08-23 08:20:28 Jens Exp $
|
||||||
|
-----------------------------------------------------------------------
|
||||||
|
|
||||||
|
library IEEE;
|
||||||
|
use IEEE.STD_LOGIC_1164.ALL;
|
||||||
|
use IEEE.numeric_std.ALL;
|
||||||
|
|
||||||
|
LIBRARY WORK;
|
||||||
|
USE WORK.FIFO_CTRL_PKG.ALL;
|
||||||
|
|
||||||
|
entity gray_counter is
|
||||||
|
Generic (
|
||||||
|
width : natural := 3;
|
||||||
|
init_value : natural := 0
|
||||||
|
);
|
||||||
|
Port
|
||||||
|
(
|
||||||
|
rst : in STD_LOGIC;
|
||||||
|
clk : in STD_LOGIC;
|
||||||
|
ce : in STD_LOGIC;
|
||||||
|
bcnt : out unsigned (width-1 downto 0);
|
||||||
|
bnxt : out unsigned (width-1 downto 0);
|
||||||
|
gcnt : out unsigned (width-1 downto 0);
|
||||||
|
gnxt : out unsigned (width-1 downto 0)
|
||||||
|
);
|
||||||
|
end gray_counter;
|
||||||
|
|
||||||
|
architecture Behavioral of gray_counter is
|
||||||
|
|
||||||
|
signal cntb : unsigned (width-1 downto 0);
|
||||||
|
signal nxtb : unsigned (width-1 downto 0);
|
||||||
|
signal cntg : unsigned (width-1 downto 0);
|
||||||
|
signal nxtg : unsigned (width-1 downto 0);
|
||||||
|
|
||||||
|
begin
|
||||||
|
|
||||||
|
bnxt <= nxtb;
|
||||||
|
gnxt <= nxtg;
|
||||||
|
|
||||||
|
process(rst, clk, ce, cntb, nxtb)
|
||||||
|
begin
|
||||||
|
if rst = '1' then
|
||||||
|
cntb <= to_unsigned(init_value, width);
|
||||||
|
nxtb <= to_unsigned(init_value, width);
|
||||||
|
cntg <= to_unsigned(init_value, width);
|
||||||
|
nxtg <= to_unsigned(init_value, width);
|
||||||
|
bcnt <= to_unsigned(init_value, width);
|
||||||
|
gcnt <= to_unsigned(init_value, width);
|
||||||
|
else
|
||||||
|
if rising_edge(clk) then
|
||||||
|
bcnt <= nxtb;
|
||||||
|
gcnt <= nxtg;
|
||||||
|
cntb <= nxtb;
|
||||||
|
cntg <= nxtg;
|
||||||
|
end if;
|
||||||
|
nxtg <= bin2gray(nxtb);
|
||||||
|
nxtb <= cntb;
|
||||||
|
if ce = '1' then
|
||||||
|
nxtb <= cntb + 1;
|
||||||
|
end if;
|
||||||
|
end if;
|
||||||
|
end process;
|
||||||
|
|
||||||
|
end Behavioral;
|
||||||
|
|
||||||
@@ -0,0 +1,203 @@
|
|||||||
|
-------------------------------------------------------------------------
|
||||||
|
-- Project: JCPU, a portable 8-bit RISC CPU written in VHDL
|
||||||
|
-- This file: The call/return/data stack
|
||||||
|
|
||||||
|
-- Copyright (C) 2007 J. Ahrensfeld
|
||||||
|
|
||||||
|
-- This library 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 2.1 of the License, or (at your option) any later version.
|
||||||
|
|
||||||
|
-- This library 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 this library; if not, write to the Free Software
|
||||||
|
-- Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
|
||||||
|
|
||||||
|
-- For questions and ideas, please contact the author at jens@jayfield.org
|
||||||
|
|
||||||
|
-----------------------------------------------------------------------
|
||||||
|
-- $Header: /tmp/cvsroot/VHDL/lib/FIFO/src/sync_fifo_ctrl.vhd,v 1.2 2008-10-12 18:04:36 Jens Exp $
|
||||||
|
-----------------------------------------------------------------------
|
||||||
|
|
||||||
|
library IEEE;
|
||||||
|
use IEEE.STD_LOGIC_1164.ALL;
|
||||||
|
use IEEE.numeric_std.ALL;
|
||||||
|
|
||||||
|
entity sync_fifo_ctrl is
|
||||||
|
Generic (
|
||||||
|
addr_width : integer := 3;
|
||||||
|
almost_full_thresh : integer := 6;
|
||||||
|
almost_empty_thresh : integer := 2
|
||||||
|
);
|
||||||
|
Port
|
||||||
|
(
|
||||||
|
rst : in STD_LOGIC;
|
||||||
|
clk : in STD_LOGIC;
|
||||||
|
we : in STD_LOGIC;
|
||||||
|
re : in STD_LOGIC;
|
||||||
|
ptr_w : out unsigned (addr_width-1 downto 0);
|
||||||
|
ptr_r : out unsigned (addr_width-1 downto 0);
|
||||||
|
fifo_pre_full : out STD_LOGIC;
|
||||||
|
fifo_pre_empty : out STD_LOGIC;
|
||||||
|
fifo_full : out STD_LOGIC;
|
||||||
|
fifo_empty : out STD_LOGIC;
|
||||||
|
fifo_afull : out STD_LOGIC;
|
||||||
|
fifo_aempty : out STD_LOGIC
|
||||||
|
);
|
||||||
|
end sync_fifo_ctrl;
|
||||||
|
|
||||||
|
architecture Behavioral of sync_fifo_ctrl is
|
||||||
|
|
||||||
|
signal pW, pW_cnt, pW_next : unsigned (addr_width-1 downto 0);
|
||||||
|
signal pR, pR_cnt, pR_next : unsigned (addr_width-1 downto 0);
|
||||||
|
signal empty, full : std_logic;
|
||||||
|
signal pre_empty, pre_full : std_logic;
|
||||||
|
signal was_write : std_logic;
|
||||||
|
signal write, read : std_logic;
|
||||||
|
signal diff : unsigned (addr_width downto 0);
|
||||||
|
|
||||||
|
begin
|
||||||
|
|
||||||
|
read <= re and not empty;
|
||||||
|
write <= we and not full;
|
||||||
|
|
||||||
|
fifo_full <= full;
|
||||||
|
fifo_empty <= empty;
|
||||||
|
fifo_pre_full <= pre_full;
|
||||||
|
fifo_pre_empty <= pre_empty;
|
||||||
|
|
||||||
|
|
||||||
|
proc_diff_gen:
|
||||||
|
process(rst, clk)
|
||||||
|
begin
|
||||||
|
if rst = '1' then
|
||||||
|
diff <= (others => '0');
|
||||||
|
elsif rising_edge(clk) then
|
||||||
|
if write = '1' and read = '0' then
|
||||||
|
diff <= diff + 1;
|
||||||
|
elsif write = '0' and read = '1' then
|
||||||
|
diff <= diff - 1;
|
||||||
|
end if;
|
||||||
|
end if;
|
||||||
|
end process;
|
||||||
|
|
||||||
|
proc_status_almost_full:
|
||||||
|
process(rst, clk)
|
||||||
|
begin
|
||||||
|
if rst = '1' then
|
||||||
|
fifo_afull <= '0';
|
||||||
|
elsif rising_edge(clk) then
|
||||||
|
if diff >= almost_full_thresh-1 then
|
||||||
|
fifo_afull <= '1';
|
||||||
|
else
|
||||||
|
fifo_afull <= '0';
|
||||||
|
end if;
|
||||||
|
end if;
|
||||||
|
end process;
|
||||||
|
|
||||||
|
proc_status_almost_empty:
|
||||||
|
process(rst, clk)
|
||||||
|
begin
|
||||||
|
if rst = '1' then
|
||||||
|
fifo_aempty <= '1';
|
||||||
|
elsif rising_edge(clk) then
|
||||||
|
if diff <= almost_empty_thresh+1 then
|
||||||
|
fifo_aempty <= '1';
|
||||||
|
else
|
||||||
|
fifo_aempty <= '0';
|
||||||
|
end if;
|
||||||
|
end if;
|
||||||
|
end process;
|
||||||
|
|
||||||
|
proc_full_reg:
|
||||||
|
process(rst, clk)
|
||||||
|
begin
|
||||||
|
if rst = '1' then
|
||||||
|
full <= '0';
|
||||||
|
elsif rising_edge(clk) then
|
||||||
|
full <= pre_full;
|
||||||
|
end if;
|
||||||
|
end process;
|
||||||
|
|
||||||
|
proc_empty_reg:
|
||||||
|
process(rst, clk)
|
||||||
|
begin
|
||||||
|
if rst = '1' then
|
||||||
|
empty <= '1';
|
||||||
|
elsif rising_edge(clk) then
|
||||||
|
empty <= pre_empty;
|
||||||
|
end if;
|
||||||
|
end process;
|
||||||
|
|
||||||
|
proc_status_w:
|
||||||
|
process(was_write, pW_next, pR_next, pW, pR, write, read)
|
||||||
|
begin
|
||||||
|
if (pW_next = pR) and (write = '1' or was_write = '1') then
|
||||||
|
pre_full <= '1';
|
||||||
|
else
|
||||||
|
pre_full <= '0';
|
||||||
|
end if;
|
||||||
|
if (pR_next = pW) and (read = '1' or was_write = '0') then
|
||||||
|
pre_empty <= '1';
|
||||||
|
else
|
||||||
|
pre_empty <= '0';
|
||||||
|
end if;
|
||||||
|
end process;
|
||||||
|
|
||||||
|
proc_flag_write:
|
||||||
|
process(rst, clk)
|
||||||
|
begin
|
||||||
|
if rst = '1' then
|
||||||
|
was_write <= '0';
|
||||||
|
elsif rising_edge(clk) then
|
||||||
|
if write = '1' then
|
||||||
|
was_write <= '1';
|
||||||
|
elsif read = '1' then
|
||||||
|
was_write <= '0';
|
||||||
|
end if;
|
||||||
|
end if;
|
||||||
|
end process;
|
||||||
|
|
||||||
|
proc_ptr_w:
|
||||||
|
process(rst, clk, pW, write, full)
|
||||||
|
begin
|
||||||
|
if rst = '1' then
|
||||||
|
pW <= to_unsigned(0, addr_width);
|
||||||
|
pW_next <= to_unsigned(0, addr_width);
|
||||||
|
elsif rising_edge(clk) then
|
||||||
|
if write = '1' then
|
||||||
|
pW <= pW_next;
|
||||||
|
end if;
|
||||||
|
end if;
|
||||||
|
pW_next <= pW;
|
||||||
|
if write = '1' then
|
||||||
|
pW_next <= pW + 1;
|
||||||
|
end if;
|
||||||
|
ptr_w <= pW;
|
||||||
|
end process;
|
||||||
|
|
||||||
|
proc_ptr_r:
|
||||||
|
process(rst, clk, pR_next, pR, read, empty)
|
||||||
|
begin
|
||||||
|
if rst = '1' then
|
||||||
|
pR <= to_unsigned(0, addr_width);
|
||||||
|
pR_next <= to_unsigned(0, addr_width);
|
||||||
|
elsif rising_edge(clk) then
|
||||||
|
if read = '1' then
|
||||||
|
pR <= pR_next;
|
||||||
|
end if;
|
||||||
|
end if;
|
||||||
|
pR_next <= pR;
|
||||||
|
if read = '1' then
|
||||||
|
pR_next <= pR + 1;
|
||||||
|
end if;
|
||||||
|
ptr_r <= pR_next;
|
||||||
|
end process;
|
||||||
|
|
||||||
|
end Behavioral;
|
||||||
|
|
||||||
@@ -0,0 +1,176 @@
|
|||||||
|
--------------------------------------------------------------------------------
|
||||||
|
-- Company:
|
||||||
|
-- Engineer:
|
||||||
|
--
|
||||||
|
-- Create Date: 17:16:42 13.05.2007
|
||||||
|
-- Design Name: tb_nco
|
||||||
|
-- Module Name: tb_nco.vhd
|
||||||
|
-- Project Name: nco
|
||||||
|
-- Target Device:
|
||||||
|
-- Tool versions:
|
||||||
|
-- Description:
|
||||||
|
--
|
||||||
|
-----------------------------------------------------------------------
|
||||||
|
-- $Header: /tmp/cvsroot/VHDL/lib/FIFO/src/tb_async_fifo_ctrl.vhd,v 1.1 2008-08-23 08:20:28 Jens Exp $
|
||||||
|
-----------------------------------------------------------------------
|
||||||
|
LIBRARY IEEE;
|
||||||
|
USE IEEE.STD_LOGIC_1164.ALL;
|
||||||
|
USE IEEE.MATH_REAL.ALL;
|
||||||
|
USE IEEE.NUMERIC_STD.ALL;
|
||||||
|
USE STD.TEXTIO.ALL;
|
||||||
|
|
||||||
|
-- LIBRARY WORK;
|
||||||
|
-- USE.YOURLIB.WHATELSE
|
||||||
|
|
||||||
|
ENTITY tb_async_fifo_ctrl IS
|
||||||
|
END tb_async_fifo_ctrl;
|
||||||
|
|
||||||
|
ARCHITECTURE behavior OF tb_async_fifo_ctrl IS
|
||||||
|
|
||||||
|
--Constants
|
||||||
|
constant PERIOD_W : time := 10 ns;
|
||||||
|
constant PERIOD_R : time := 20 ns;
|
||||||
|
constant ADDR_WIDTH : integer := 3;
|
||||||
|
|
||||||
|
--Inputs
|
||||||
|
signal rst : STD_LOGIC := '1';
|
||||||
|
signal clk_w : STD_LOGIC := '0';
|
||||||
|
signal clk_r : STD_LOGIC := '0';
|
||||||
|
signal we : STD_LOGIC := '0';
|
||||||
|
signal re : STD_LOGIC := '0';
|
||||||
|
signal din : unsigned (7 downto 0);
|
||||||
|
--Outputs
|
||||||
|
|
||||||
|
signal ptr_w : unsigned (ADDR_WIDTH-1 downto 0);
|
||||||
|
signal ptr_r : unsigned (ADDR_WIDTH-1 downto 0);
|
||||||
|
signal dout : unsigned (7 downto 0);
|
||||||
|
signal fifo_full : STD_LOGIC;
|
||||||
|
signal fifo_empty : STD_LOGIC;
|
||||||
|
signal fifo_almost_full : STD_LOGIC;
|
||||||
|
signal fifo_almost_empty : STD_LOGIC;
|
||||||
|
signal mem_we : STD_LOGIC;
|
||||||
|
|
||||||
|
signal write_en : STD_LOGIC := '0';
|
||||||
|
signal read_en : STD_LOGIC := '0';
|
||||||
|
|
||||||
|
signal wdata : unsigned (7 downto 0) := (others => '0');
|
||||||
|
signal rdata : unsigned (7 downto 0) := (others => '0');
|
||||||
|
signal rdata2 : unsigned (7 downto 0) := (others => '0');
|
||||||
|
|
||||||
|
BEGIN
|
||||||
|
|
||||||
|
din <= wdata;
|
||||||
|
|
||||||
|
-- Instantiate the Unit Under Test (UUT)
|
||||||
|
uut: entity work.async_fifo_ctrl
|
||||||
|
GENERIC MAP
|
||||||
|
(
|
||||||
|
addr_width => ADDR_WIDTH,
|
||||||
|
almost_full_thresh => 6,
|
||||||
|
almost_empty_thresh => 2
|
||||||
|
)
|
||||||
|
PORT MAP
|
||||||
|
(
|
||||||
|
rst => rst,
|
||||||
|
clk_w => clk_w,
|
||||||
|
clk_r => clk_r,
|
||||||
|
we => we,
|
||||||
|
re => re,
|
||||||
|
ptr_w => ptr_w,
|
||||||
|
ptr_r => ptr_r,
|
||||||
|
fifo_full => fifo_full,
|
||||||
|
fifo_empty => fifo_empty,
|
||||||
|
fifo_afull => fifo_almost_full,
|
||||||
|
fifo_aempty => fifo_almost_empty
|
||||||
|
|
||||||
|
);
|
||||||
|
|
||||||
|
inst_dpram: entity work.dpram
|
||||||
|
GENERIC MAP (
|
||||||
|
addr_width => ADDR_WIDTH,
|
||||||
|
data_width => 8
|
||||||
|
)
|
||||||
|
PORT MAP(
|
||||||
|
clka => clk_w,
|
||||||
|
clkb => clk_r,
|
||||||
|
en_a => '1',
|
||||||
|
en_b => '1',
|
||||||
|
we_a => mem_we,
|
||||||
|
addr_a => ptr_w,
|
||||||
|
addr_b => ptr_r,
|
||||||
|
din_a => din,
|
||||||
|
dout_b => dout
|
||||||
|
);
|
||||||
|
|
||||||
|
tb_clk_w : PROCESS
|
||||||
|
BEGIN
|
||||||
|
clk_w <= not clk_w;
|
||||||
|
wait for PERIOD_W/2;
|
||||||
|
END PROCESS;
|
||||||
|
|
||||||
|
tb_clk_r : PROCESS
|
||||||
|
BEGIN
|
||||||
|
clk_r <= not clk_r;
|
||||||
|
wait for PERIOD_R/2;
|
||||||
|
END PROCESS;
|
||||||
|
|
||||||
|
tb_write : PROCESS
|
||||||
|
BEGIN
|
||||||
|
|
||||||
|
-- Wait 100 ns for global reset to finish
|
||||||
|
wait for 5*PERIOD_W;
|
||||||
|
rst <= '0';
|
||||||
|
wait for 5*PERIOD_W;
|
||||||
|
write_en <= '1';
|
||||||
|
wait for 15*PERIOD_W;
|
||||||
|
write_en <= '0';
|
||||||
|
|
||||||
|
wait;
|
||||||
|
|
||||||
|
END PROCESS;
|
||||||
|
|
||||||
|
tb_read : PROCESS
|
||||||
|
BEGIN
|
||||||
|
|
||||||
|
-- Wait 100 ns for global reset to finish
|
||||||
|
wait for 15*PERIOD_R;
|
||||||
|
read_en <= '1';
|
||||||
|
|
||||||
|
wait;
|
||||||
|
|
||||||
|
END PROCESS;
|
||||||
|
|
||||||
|
we <= write_en and not fifo_full;
|
||||||
|
mem_we <= we;
|
||||||
|
|
||||||
|
tb_w : PROCESS(rst, clk_w)
|
||||||
|
BEGIN
|
||||||
|
|
||||||
|
if rst = '1' then
|
||||||
|
wdata <= (others => '0');
|
||||||
|
elsif rising_edge(clk_w) then
|
||||||
|
if we = '1' then
|
||||||
|
wdata <= wdata + 1;
|
||||||
|
end if;
|
||||||
|
end if;
|
||||||
|
|
||||||
|
END PROCESS;
|
||||||
|
|
||||||
|
re <= read_en and not fifo_empty;
|
||||||
|
|
||||||
|
tb_r : PROCESS(rst, clk_r)
|
||||||
|
BEGIN
|
||||||
|
|
||||||
|
if rst = '1' then
|
||||||
|
rdata <= (others => '0');
|
||||||
|
elsif rising_edge(clk_r) then
|
||||||
|
rdata2 <= rdata;
|
||||||
|
if re = '1' then
|
||||||
|
assert rdata2 = dout report "FIFO read error!" severity failure;
|
||||||
|
rdata <= rdata + 1;
|
||||||
|
end if;
|
||||||
|
end if;
|
||||||
|
|
||||||
|
END PROCESS;
|
||||||
|
|
||||||
|
END behavior;
|
||||||
@@ -0,0 +1,83 @@
|
|||||||
|
--------------------------------------------------------------------------------
|
||||||
|
-- Company:
|
||||||
|
-- Engineer:
|
||||||
|
--
|
||||||
|
-- Create Date: 17:16:42 13.05.2007
|
||||||
|
-- Design Name: tb_gray_counter
|
||||||
|
-- Module Name: tb_gray_counter.vhd
|
||||||
|
-- Project Name: gray_counter package
|
||||||
|
-- Target Device:
|
||||||
|
-- Tool versions:
|
||||||
|
-- Description:
|
||||||
|
--
|
||||||
|
-----------------------------------------------------------------------
|
||||||
|
-- $Header: /tmp/cvsroot/VHDL/lib/FIFO/src/tb_gray_counter.vhd,v 1.1 2008-08-23 08:20:28 Jens Exp $
|
||||||
|
-----------------------------------------------------------------------
|
||||||
|
LIBRARY IEEE;
|
||||||
|
USE IEEE.STD_LOGIC_1164.ALL;
|
||||||
|
USE IEEE.MATH_REAL.ALL;
|
||||||
|
USE IEEE.NUMERIC_STD.ALL;
|
||||||
|
USE STD.TEXTIO.ALL;
|
||||||
|
|
||||||
|
LIBRARY WORK;
|
||||||
|
USE WORK.FIFO_CTRL_PKG.ALL;
|
||||||
|
|
||||||
|
ENTITY tb_gray_counter IS
|
||||||
|
END tb_gray_counter;
|
||||||
|
|
||||||
|
ARCHITECTURE behavior OF tb_gray_counter IS
|
||||||
|
|
||||||
|
constant PERIOD : time := 10 ns;
|
||||||
|
constant WIDTH : integer := 3;
|
||||||
|
|
||||||
|
--Signals
|
||||||
|
signal gcnt : unsigned (WIDTH-1 downto 0) := to_unsigned(0, WIDTH);
|
||||||
|
signal bcnt : unsigned (WIDTH-1 downto 0) := to_unsigned(0, WIDTH);
|
||||||
|
signal gnxt : unsigned (WIDTH-1 downto 0) := to_unsigned(0, WIDTH);
|
||||||
|
signal bnxt : unsigned (WIDTH-1 downto 0) := to_unsigned(0, WIDTH);
|
||||||
|
signal rst : STD_LOGIC := '1';
|
||||||
|
signal clk : STD_LOGIC := '0';
|
||||||
|
signal ce : STD_LOGIC := '0';
|
||||||
|
|
||||||
|
BEGIN
|
||||||
|
|
||||||
|
inst_gray_counter : entity work.gray_counter
|
||||||
|
generic map (width => WIDTH)
|
||||||
|
port map (
|
||||||
|
rst => rst,
|
||||||
|
clk => clk,
|
||||||
|
ce => ce,
|
||||||
|
bcnt => bcnt,
|
||||||
|
bnxt => bnxt,
|
||||||
|
gcnt => gcnt,
|
||||||
|
gnxt => gnxt
|
||||||
|
);
|
||||||
|
|
||||||
|
tb_clk : PROCESS
|
||||||
|
BEGIN
|
||||||
|
clk <= not clk;
|
||||||
|
wait for PERIOD/2;
|
||||||
|
END PROCESS;
|
||||||
|
|
||||||
|
tb_counter : PROCESS
|
||||||
|
|
||||||
|
BEGIN
|
||||||
|
|
||||||
|
wait for 4*PERIOD;
|
||||||
|
rst <= '0';
|
||||||
|
wait for 1*PERIOD;
|
||||||
|
ce <= '1';
|
||||||
|
wait for 3*PERIOD;
|
||||||
|
ce <= '0';
|
||||||
|
wait for 4*PERIOD;
|
||||||
|
ce <= '1';
|
||||||
|
wait for 1*PERIOD;
|
||||||
|
ce <= '0';
|
||||||
|
wait for 1*PERIOD;
|
||||||
|
ce <= '1';
|
||||||
|
|
||||||
|
wait;
|
||||||
|
|
||||||
|
END PROCESS;
|
||||||
|
|
||||||
|
END behavior;
|
||||||
@@ -0,0 +1,221 @@
|
|||||||
|
--------------------------------------------------------------------------------
|
||||||
|
-- Company:
|
||||||
|
-- Engineer:
|
||||||
|
--
|
||||||
|
-- Create Date: 17:16:42 13.05.2007
|
||||||
|
-- Design Name: tb_nco
|
||||||
|
-- Module Name: tb_nco.vhd
|
||||||
|
-- Project Name: nco
|
||||||
|
-- Target Device:
|
||||||
|
-- Tool versions:
|
||||||
|
-- Description:
|
||||||
|
--
|
||||||
|
-----------------------------------------------------------------------
|
||||||
|
-- $Header: /tmp/cvsroot/VHDL/lib/FIFO/src/tb_sync_fifo_ctrl.vhd,v 1.1 2008-08-23 08:20:28 Jens Exp $
|
||||||
|
-----------------------------------------------------------------------
|
||||||
|
LIBRARY IEEE;
|
||||||
|
USE IEEE.STD_LOGIC_1164.ALL;
|
||||||
|
USE IEEE.MATH_REAL.ALL;
|
||||||
|
USE IEEE.NUMERIC_STD.ALL;
|
||||||
|
USE STD.TEXTIO.ALL;
|
||||||
|
|
||||||
|
-- LIBRARY WORK;
|
||||||
|
-- USE.YOURLIB.WHATELSE
|
||||||
|
|
||||||
|
ENTITY tb_sync_fifo_ctrl IS
|
||||||
|
END tb_sync_fifo_ctrl;
|
||||||
|
|
||||||
|
ARCHITECTURE behavior OF tb_sync_fifo_ctrl IS
|
||||||
|
|
||||||
|
--Constants
|
||||||
|
constant PERIOD : time := 10 ns;
|
||||||
|
constant ADDR_WIDTH : integer := 3;
|
||||||
|
|
||||||
|
--Inputs
|
||||||
|
signal rst : STD_LOGIC := '1';
|
||||||
|
signal clk : STD_LOGIC := '0';
|
||||||
|
signal we : STD_LOGIC := '0';
|
||||||
|
signal re : STD_LOGIC := '0';
|
||||||
|
signal din : unsigned (7 downto 0);
|
||||||
|
--Outputs
|
||||||
|
|
||||||
|
signal ptr_w : unsigned (ADDR_WIDTH-1 downto 0);
|
||||||
|
signal ptr_r : unsigned (ADDR_WIDTH-1 downto 0);
|
||||||
|
signal dout : unsigned (7 downto 0);
|
||||||
|
signal fifo_full : STD_LOGIC;
|
||||||
|
signal fifo_empty : STD_LOGIC;
|
||||||
|
signal fifo_almost_full : STD_LOGIC;
|
||||||
|
signal fifo_almost_empty : STD_LOGIC;
|
||||||
|
signal mem_we : STD_LOGIC;
|
||||||
|
|
||||||
|
signal write_en : STD_LOGIC := '0';
|
||||||
|
signal read_en : STD_LOGIC := '0';
|
||||||
|
|
||||||
|
signal wdata : unsigned (7 downto 0) := (others => '0');
|
||||||
|
signal rdata : unsigned (7 downto 0) := (others => '0');
|
||||||
|
signal rdata2 : unsigned (7 downto 0) := (others => '0');
|
||||||
|
|
||||||
|
BEGIN
|
||||||
|
|
||||||
|
din <= wdata;
|
||||||
|
|
||||||
|
-- Instantiate the Unit Under Test (UUT)
|
||||||
|
uut: entity work.sync_fifo_ctrl
|
||||||
|
GENERIC MAP
|
||||||
|
(
|
||||||
|
addr_width => ADDR_WIDTH,
|
||||||
|
almost_full_thresh => 6,
|
||||||
|
almost_empty_thresh => 2
|
||||||
|
)
|
||||||
|
PORT MAP
|
||||||
|
(
|
||||||
|
rst => rst,
|
||||||
|
clk => clk,
|
||||||
|
we => we,
|
||||||
|
re => re,
|
||||||
|
ptr_w => ptr_w,
|
||||||
|
ptr_r => ptr_r,
|
||||||
|
fifo_full => fifo_full,
|
||||||
|
fifo_empty => fifo_empty,
|
||||||
|
fifo_afull => fifo_almost_full,
|
||||||
|
fifo_aempty => fifo_almost_empty
|
||||||
|
|
||||||
|
);
|
||||||
|
|
||||||
|
inst_dpram: entity work.dpram
|
||||||
|
GENERIC MAP (
|
||||||
|
addr_width => ADDR_WIDTH,
|
||||||
|
data_width => 8
|
||||||
|
)
|
||||||
|
PORT MAP(
|
||||||
|
clka => clk,
|
||||||
|
clkb => clk,
|
||||||
|
en_a => '1',
|
||||||
|
en_b => '1',
|
||||||
|
we_a => mem_we,
|
||||||
|
addr_a => ptr_w,
|
||||||
|
addr_b => ptr_r,
|
||||||
|
din_a => din,
|
||||||
|
dout_b => dout
|
||||||
|
);
|
||||||
|
|
||||||
|
tb_clk : PROCESS
|
||||||
|
BEGIN
|
||||||
|
clk <= not clk;
|
||||||
|
wait for PERIOD/2;
|
||||||
|
END PROCESS;
|
||||||
|
|
||||||
|
tb_write : PROCESS
|
||||||
|
BEGIN
|
||||||
|
|
||||||
|
-- Wait 100 ns for global reset to finish
|
||||||
|
wait for 5*PERIOD;
|
||||||
|
rst <= '0';
|
||||||
|
wait for 7*PERIOD;
|
||||||
|
write_en <= '1';
|
||||||
|
wait for 25*PERIOD;
|
||||||
|
write_en <= '0';
|
||||||
|
wait for 7*PERIOD;
|
||||||
|
write_en <= '1';
|
||||||
|
wait for 25*PERIOD;
|
||||||
|
write_en <= '0';
|
||||||
|
wait for 7*PERIOD;
|
||||||
|
write_en <= '1';
|
||||||
|
wait for 1*PERIOD;
|
||||||
|
write_en <= '0';
|
||||||
|
wait for 1*PERIOD;
|
||||||
|
write_en <= '1';
|
||||||
|
wait for 1*PERIOD;
|
||||||
|
write_en <= '0';
|
||||||
|
wait for 3*PERIOD;
|
||||||
|
write_en <= '1';
|
||||||
|
wait for 4*PERIOD;
|
||||||
|
write_en <= '0';
|
||||||
|
wait for 17*PERIOD;
|
||||||
|
write_en <= '1';
|
||||||
|
wait for 25*PERIOD;
|
||||||
|
write_en <= '0';
|
||||||
|
|
||||||
|
wait;
|
||||||
|
|
||||||
|
END PROCESS;
|
||||||
|
|
||||||
|
tb_read : PROCESS
|
||||||
|
BEGIN
|
||||||
|
|
||||||
|
-- Wait 100 ns for global reset to finish
|
||||||
|
wait for 25*PERIOD;
|
||||||
|
read_en <= '1';
|
||||||
|
wait for 25*PERIOD;
|
||||||
|
read_en <= '0';
|
||||||
|
wait for 25*PERIOD;
|
||||||
|
read_en <= '1';
|
||||||
|
wait for 1*PERIOD;
|
||||||
|
read_en <= '0';
|
||||||
|
wait for 5*PERIOD;
|
||||||
|
read_en <= '1';
|
||||||
|
wait for 1*PERIOD;
|
||||||
|
read_en <= '0';
|
||||||
|
wait for 5*PERIOD;
|
||||||
|
read_en <= '1';
|
||||||
|
wait for 1*PERIOD;
|
||||||
|
read_en <= '0';
|
||||||
|
wait for 5*PERIOD;
|
||||||
|
read_en <= '1';
|
||||||
|
wait for 1*PERIOD;
|
||||||
|
read_en <= '0';
|
||||||
|
wait for 5*PERIOD;
|
||||||
|
read_en <= '1';
|
||||||
|
wait for 1*PERIOD;
|
||||||
|
read_en <= '0';
|
||||||
|
wait for 5*PERIOD;
|
||||||
|
read_en <= '1';
|
||||||
|
wait for 1*PERIOD;
|
||||||
|
read_en <= '0';
|
||||||
|
wait for 5*PERIOD;
|
||||||
|
read_en <= '1';
|
||||||
|
wait for 1*PERIOD;
|
||||||
|
read_en <= '0';
|
||||||
|
wait for 7*PERIOD;
|
||||||
|
read_en <= '1';
|
||||||
|
wait for 15*PERIOD;
|
||||||
|
read_en <= '0';
|
||||||
|
|
||||||
|
wait;
|
||||||
|
|
||||||
|
END PROCESS;
|
||||||
|
|
||||||
|
we <= write_en and not fifo_full;
|
||||||
|
mem_we <= we;
|
||||||
|
|
||||||
|
tb_w : PROCESS(rst, clk)
|
||||||
|
BEGIN
|
||||||
|
|
||||||
|
if rst = '1' then
|
||||||
|
wdata <= (others => '0');
|
||||||
|
elsif rising_edge(clk) then
|
||||||
|
if we = '1' then
|
||||||
|
wdata <= wdata + 1;
|
||||||
|
end if;
|
||||||
|
end if;
|
||||||
|
|
||||||
|
END PROCESS;
|
||||||
|
|
||||||
|
re <= read_en and not fifo_empty;
|
||||||
|
|
||||||
|
tb_r : PROCESS(rst, clk)
|
||||||
|
BEGIN
|
||||||
|
|
||||||
|
if rst = '1' then
|
||||||
|
rdata <= (others => '0');
|
||||||
|
elsif rising_edge(clk) then
|
||||||
|
rdata2 <= rdata;
|
||||||
|
if re = '1' then
|
||||||
|
assert rdata = dout report "FIFO read error!" severity failure;
|
||||||
|
rdata <= rdata + 1;
|
||||||
|
end if;
|
||||||
|
end if;
|
||||||
|
|
||||||
|
END PROCESS;
|
||||||
|
|
||||||
|
END behavior;
|
||||||
@@ -0,0 +1,297 @@
|
|||||||
|
<!doctype html public "-//w3c//dtd html 4.0 transitional//en">
|
||||||
|
<html>
|
||||||
|
<head>
|
||||||
|
<meta http-equiv="Content-Type" content="text/html; charset=iso-8859-1">
|
||||||
|
<meta name="GENERATOR" content="Mozilla/4.5 [en] (X11; I; SunOS 5.7 sun4u) [Netscape]">
|
||||||
|
<title>VHDL package for formatted file output</title>
|
||||||
|
<!-- $Id: PCK_FIO.html,v 1.1 2008-08-23 08:20:28 Jens Exp $ -->
|
||||||
|
</head>
|
||||||
|
<body text="#000000" bgcolor="#FFFFFF" link="#0000EE" vlink="#551A8B" alink="#FF0000">
|
||||||
|
|
||||||
|
<hr SIZE=1 NOSHADE WIDTH="100%">
|
||||||
|
<h1>
|
||||||
|
<a NAME="PCK_FIO_name_0"></a>Name</h1>
|
||||||
|
<b>PCK_FIO</b> - VHDL package for formatted file output
|
||||||
|
<p>
|
||||||
|
<hr SIZE=1 NOSHADE WIDTH="100%">
|
||||||
|
<h1>
|
||||||
|
Contents</h1>
|
||||||
|
<a href="#PCK_FIO_usage_0">Usage</a>
|
||||||
|
<br><a href="#PCK_FIO_file_0">The file output function 'fo'</a>
|
||||||
|
<br><a href="#PCK_FIO_format_0">Format specifiers</a>
|
||||||
|
<br><a href="#PCK_FIO_special_0">Special characters</a>
|
||||||
|
<br><a href="#PCK_FIO_things_0">Things to watch out for</a>
|
||||||
|
<br><a href="#PCK_FIO_methodology_0">Methodology notes</a>
|
||||||
|
<br><a href="#PCK_FIO_parametrization_0">Parametrization</a>
|
||||||
|
<br><a href="#PCK_FIO_test_0">Test bench</a>
|
||||||
|
<br><a href="#PCK_FIO_limitations_0">Known limitations and problems</a>
|
||||||
|
<br><a href="#PCK_FIO_author_0">Author</a>
|
||||||
|
<p>
|
||||||
|
<hr SIZE=1 NOSHADE WIDTH="100%">
|
||||||
|
<h1>
|
||||||
|
<a NAME="PCK_FIO_usage_0"></a>Usage</h1>
|
||||||
|
PCK_FIO is a VHDL package that defines <tt>fprint, </tt>a function
|
||||||
|
for formatted file output.
|
||||||
|
<p>After installing the package you can call <tt>fprint</tt> as follows:
|
||||||
|
<pre> fprint(F, L, Format, fo(Expr_1), fo(Expr_2), ... fo(Expr_n));</pre>
|
||||||
|
where F is the filehandle and L is the line variable.
|
||||||
|
<p>The argument Format is the format string, which consists of ``normal''
|
||||||
|
substrings which are copied verbatim, and format specifiers, starting with
|
||||||
|
<tt>'%'</tt>.
|
||||||
|
A typical format string looks as follows:
|
||||||
|
<pre> "Arg1 = %6r, Arg2 = %10d, Arg3 = %-5r\n"</pre>
|
||||||
|
The remaining arguments are the expressions whose results you want to write
|
||||||
|
to the file, embedded in <tt>fo</tt> function calls. There can be 0 to
|
||||||
|
32 of such arguments. The expressions can be of any type for which an <tt>fo</tt>
|
||||||
|
function exists. String expressions can also be called directly.
|
||||||
|
<p>
|
||||||
|
<hr SIZE=1 NOSHADE WIDTH="100%">
|
||||||
|
<h1>
|
||||||
|
<a NAME="PCK_FIO_file_0"></a>The file output function <tt>'fo'</tt></h1>
|
||||||
|
The <tt>fo</tt> (<u>f</u>ile <u>o</u>utput) functions do the trick. They
|
||||||
|
return a tagged string representation that is meaningful to format specifiers.
|
||||||
|
Here are some examples:
|
||||||
|
<pre> fo (signed'("1100")) returns "S:1100"
|
||||||
|
fo (unsigned'("1100")) returns "U:1100"
|
||||||
|
fo (TRUE) returns "L:T"
|
||||||
|
fo (127) returns "I:127"</pre>
|
||||||
|
The internal behavior of <tt>fo</tt> is irrelevant to the typical user.
|
||||||
|
<p>The <tt>fo</tt> function is currently overloaded as follows:
|
||||||
|
<pre> function fo (Arg: unsigned) return string;
|
||||||
|
function fo (Arg: signed) return string;
|
||||||
|
function fo (Arg: std_logic_vector) return string;
|
||||||
|
function fo (Arg: std_ulogic_vector) return string;
|
||||||
|
function fo (Arg: bit_vector) return string;
|
||||||
|
function fo (Arg: integer) return string;
|
||||||
|
function fo (Arg: std_ulogic) return string;
|
||||||
|
function fo (Arg: bit) return string;
|
||||||
|
function fo (Arg: boolean) return string;
|
||||||
|
function fo (Arg: character) return string;
|
||||||
|
function fo (Arg: string) return string;
|
||||||
|
function fo (Arg: time) return string;</pre>
|
||||||
|
|
||||||
|
<pre>
|
||||||
|
<hr SIZE=1 NOSHADE WIDTH="100%"></pre>
|
||||||
|
|
||||||
|
<h1>
|
||||||
|
<a NAME="PCK_FIO_format_0"></a>Format specifiers</h1>
|
||||||
|
The general format of a format specifier is:
|
||||||
|
<pre> %[-][n]c</pre>
|
||||||
|
The optional <b>-</b> sign specifies left justified output; default is
|
||||||
|
right justified.
|
||||||
|
<p>The optional number <b>n</b> specifies a field-width. If it is not specified,
|
||||||
|
<tt>fprint</tt>
|
||||||
|
does something reasonable.
|
||||||
|
<p><b>c</b> is the conversion specifier. Currently the following conversion
|
||||||
|
specifiers are supported:
|
||||||
|
<dl COMPACT>
|
||||||
|
<dt>
|
||||||
|
<a NAME="PCK_FIO_r_0"></a><b>r</b></dt>
|
||||||
|
|
||||||
|
<dd>
|
||||||
|
reasonable output format (inspired by Synopsys VSS)</dd>
|
||||||
|
|
||||||
|
<dl COMPACT>Prints the ``most reasonable'' representation e.g. hex for
|
||||||
|
unsigned, signed and other bit-like vectors (not preferred for integers)</dl>
|
||||||
|
|
||||||
|
<dt>
|
||||||
|
<a NAME="PCK_FIO_b_0"></a><b>b</b></dt>
|
||||||
|
|
||||||
|
<dd>
|
||||||
|
bit-oriented output</dd>
|
||||||
|
|
||||||
|
<dt>
|
||||||
|
<a NAME="PCK_FIO_d_0"></a><b>d</b></dt>
|
||||||
|
|
||||||
|
<dd>
|
||||||
|
decimal output</dd>
|
||||||
|
|
||||||
|
<dt>
|
||||||
|
<a NAME="PCK_FIO_s_0"></a><b>s</b></dt>
|
||||||
|
|
||||||
|
<dd>
|
||||||
|
string output (e.g. in combination with 'IMAGE for enum types)</dd>
|
||||||
|
|
||||||
|
<dt>
|
||||||
|
<a NAME="PCK_FIO_q_0"></a><b>q</b></dt>
|
||||||
|
|
||||||
|
<dd>
|
||||||
|
``qualified'' string output (shows internal representation from <tt>fo</tt>)</dd>
|
||||||
|
|
||||||
|
<dt>
|
||||||
|
<a NAME="PCK_FIO__0"></a><b>{}</b></dt>
|
||||||
|
|
||||||
|
<dd>
|
||||||
|
Iteration operator, used as follows:</dd>
|
||||||
|
|
||||||
|
<dd>
|
||||||
|
<tt>%n{<format-string>}</tt></dd>
|
||||||
|
|
||||||
|
<br>In this case, <b>n</b> is the iteration count and is mandatory. Iteration
|
||||||
|
can be nested.</dl>
|
||||||
|
|
||||||
|
<hr SIZE=1 NOSHADE WIDTH="100%">
|
||||||
|
<h1>
|
||||||
|
<a NAME="PCK_FIO_special_0"></a>Special characters</h1>
|
||||||
|
To print a double-quote, use <tt>'""'</tt> in the format string (VHDL
|
||||||
|
convention). To print the special characters, <tt>'\'</tt>, and <tt>'%'</tt>,
|
||||||
|
escape them with <tt>'\'</tt>. To prevent <tt>'{'</tt> and <tt>'}'</tt>
|
||||||
|
from being interpreted as opening and closing brackets in iteration strings,
|
||||||
|
escape them with <tt>'\'</tt>.
|
||||||
|
<p>A newline is specified in the format string by <tt>'\n'</tt>.
|
||||||
|
<p>
|
||||||
|
<hr SIZE=1 NOSHADE WIDTH="100%">
|
||||||
|
<h1>
|
||||||
|
<a NAME="PCK_FIO_things_0"></a>Things to notice</h1>
|
||||||
|
The fprint function expands into VHDL <tt>write</tt> and <tt>writeline</tt>
|
||||||
|
commands. As in plain VHDL, nothing will be written to the output file
|
||||||
|
until a <tt>writeline</tt> is given. Therefore, don't forget to include
|
||||||
|
<tt>'\n'</tt>
|
||||||
|
commands in the format string, or it ``will not work''.
|
||||||
|
<p>The preferred format specifier for integers is, naturally, <b>%d</b>.
|
||||||
|
This calls the VHDL <tt>write</tt> for integers. If you specify a field
|
||||||
|
width that is too small, the field will automatically be expanded. If you
|
||||||
|
use <b>%r</b> for integers, the field is not expanded automatically, which
|
||||||
|
means that some digits are simply thrown away. This may sometimes be useful
|
||||||
|
but it is also dangerous. Look at the test bench output for differences
|
||||||
|
between <b>%d</b> and <b>%r</b> output.
|
||||||
|
<p>When using the <b>%d</b> format specifier, the VHDL constraints for
|
||||||
|
the allowed integer range apply.
|
||||||
|
<p>In VHDL, signed/unsigned types have been standardized only relatively
|
||||||
|
recently, in the package <tt>IEEE.numeric_std</tt>. The lack of a standard
|
||||||
|
has caused (and is causing) portability issues. The most popular non-standard
|
||||||
|
package that defines signed/unsigned is <tt>IEEE.std_logic_arith</tt> from
|
||||||
|
Synopsys. PCK_FIO has been developed with this latter package, and still
|
||||||
|
refers to this package by default. However, PCK_FIO works with
|
||||||
|
<tt>IEEE.numeric_std</tt>
|
||||||
|
as well. To use <tt>IEEE.numeric_std</tt>, replace the reference to <tt>IEEE.std_logic_arith</tt>
|
||||||
|
in the source code. This needs to be done consistently in a design
|
||||||
|
database (e.g. in the PCK_FIO test bench as well).
|
||||||
|
<p>
|
||||||
|
<hr SIZE=1 NOSHADE WIDTH="100%">
|
||||||
|
<h1>
|
||||||
|
<a NAME="PCK_FIO_methodology_0"></a>Methodology notes</h1>
|
||||||
|
The obvious application for <tt>fprint</tt> is in test benches, to produce
|
||||||
|
output files that trace the simulation behavior.
|
||||||
|
<p>Another interesting application for <tt>fprint</tt> is to produce info,
|
||||||
|
warning and error messages in your models. As it can take arguments, <tt>fprint</tt>
|
||||||
|
is much better suited for this task than VHDL's <tt>assert</tt> or <tt>report</tt>
|
||||||
|
statements. Actually <tt>fprint</tt> produces its own (few) warning messages.
|
||||||
|
<p>An advanced usage is the generation of test vectors in a specific format.
|
||||||
|
Instead of using the <tt>fo </tt>functions, you can write your own set
|
||||||
|
of functions that return the symbols of a specific test format in a way
|
||||||
|
that is understandable to the <tt>fprint</tt> format specifiers. As an
|
||||||
|
example, when a high output value should be represented using the symbol
|
||||||
|
'H' it suffices to write a conversion function that returns "B:H" and call
|
||||||
|
it in combination with the <b>%b</b> format specifier.
|
||||||
|
<p>
|
||||||
|
<hr SIZE=1 NOSHADE WIDTH="100%">
|
||||||
|
<h1>
|
||||||
|
<a NAME="PCK_FIO_parametrization_0"></a>Parametrization</h1>
|
||||||
|
Prefix and postfix strings for bit-oriented and hex-oriented output are
|
||||||
|
parameterizable in the packages to accommodate different output styles.
|
||||||
|
The settings in the distribution are such that hex output is indicated
|
||||||
|
by the prefix '0x', while bit output prefix and postfix are empty
|
||||||
|
strings.
|
||||||
|
<p>You can adapt the output style by modifying the following constants
|
||||||
|
in the package header:
|
||||||
|
<p> <tt> -- prefix string for hex output</tt>
|
||||||
|
<br><tt> -- VHDL style: "X"""</tt>
|
||||||
|
<br><tt> -- Verilog style: "h'"</tt>
|
||||||
|
<br><tt> -- C style: "0x"</tt>
|
||||||
|
<br><tt> constant FIO_h_PRE: string := "0x";</tt>
|
||||||
|
<p><tt> -- postfix string for hex output</tt>
|
||||||
|
<br><tt> -- VHDL style: """"</tt>
|
||||||
|
<br><tt> constant FIO_h_POST: string := "";</tt>
|
||||||
|
<p><tt> -- prefix string for bit vector output</tt>
|
||||||
|
<br><tt> -- VHDL style: "B"""</tt>
|
||||||
|
<br><tt> -- Verilog style: "b'"</tt>
|
||||||
|
<br><tt> constant FIO_bv_PRE: string := "";</tt>
|
||||||
|
<p><tt> -- postfix string for bit vector output</tt>
|
||||||
|
<br><tt> -- VHDL style: """"</tt>
|
||||||
|
<br><tt> constant FIO_bv_POST: string := "";</tt>
|
||||||
|
<p><tt> -- prefix string for bit output</tt>
|
||||||
|
<br><tt> -- VHDL style: "'"</tt>
|
||||||
|
<br><tt> -- Verilog style: "b'"</tt>
|
||||||
|
<br><tt> constant FIO_b_PRE: string := "";</tt>
|
||||||
|
<p><tt> -- postfix string for bit output</tt>
|
||||||
|
<br><tt> -- VHDL style: "'"</tt>
|
||||||
|
<br><tt> constant FIO_b_POST: string := "";</tt>
|
||||||
|
<p>
|
||||||
|
<hr SIZE=1 NOSHADE WIDTH="100%">
|
||||||
|
<h1>
|
||||||
|
<a NAME="PCK_FIO_test_0"></a>Test bench</h1>
|
||||||
|
Included in the distribution is a file <tt>TB_PCK_FIO.vhd</tt> with a test
|
||||||
|
bench for the PCK_FIO package. The file <tt>PCK_FIO.out.gold </tt>contains
|
||||||
|
the expected output. If you run the test bench it should produce the file
|
||||||
|
<tt>PCK_FIO.out</tt>
|
||||||
|
that should be identical to <tt>PCK_FIO.out.gold</tt>. The source files
|
||||||
|
should be analyzed in a VHDL library <tt>EASICS_PACKAGES</tt>.
|
||||||
|
<p>A good way to understand <tt>fprint</tt> is to inspect the test bench
|
||||||
|
and what it produces.
|
||||||
|
<p>
|
||||||
|
<hr SIZE=1 NOSHADE WIDTH="100%">
|
||||||
|
<h1>
|
||||||
|
<a NAME="PCK_FIO_limitations_0"></a>Known limitations and problems</h1>
|
||||||
|
This VHDL package is an implementation of a flexible concept. It is likely
|
||||||
|
to be extended and modified in the future. Backward compatibility is not
|
||||||
|
guaranteed. Therefore, it is not recommended to give this package the status
|
||||||
|
of a company-wide standard package (or even worse, a VHDL standard package).
|
||||||
|
Rather, it should be linked with a particular project (and it can be regarded
|
||||||
|
as a standard package within that project).
|
||||||
|
<p>PCK_FIO is written in standard VHDL Std1076-1987. Nevertheless, some
|
||||||
|
simulators/versions have problems with the package. The following is an
|
||||||
|
overview of currently known issues:
|
||||||
|
<br>
|
||||||
|
<center><table BORDER COLS=2 WIDTH="80%" >
|
||||||
|
<tr>
|
||||||
|
<th>Simulator</th>
|
||||||
|
|
||||||
|
<th>PCK_FIO handling</th>
|
||||||
|
</tr>
|
||||||
|
|
||||||
|
<tr>
|
||||||
|
<td>Synopsys VSS 3.5 and earlier</td>
|
||||||
|
|
||||||
|
<td>Incorrect (all zero) output in compiled mode</td>
|
||||||
|
</tr>
|
||||||
|
|
||||||
|
<tr>
|
||||||
|
<td>Synopsys VSS 97.01</td>
|
||||||
|
|
||||||
|
<td>OK</td>
|
||||||
|
</tr>
|
||||||
|
|
||||||
|
<tr>
|
||||||
|
<td>Mentor quickhdl</td>
|
||||||
|
|
||||||
|
<td>OK</td>
|
||||||
|
</tr>
|
||||||
|
|
||||||
|
<tr>
|
||||||
|
<td>Modeltech modelsim</td>
|
||||||
|
|
||||||
|
<td>OK</td>
|
||||||
|
</tr>
|
||||||
|
|
||||||
|
<tr>
|
||||||
|
<td>Cadence Leapfrog</td>
|
||||||
|
|
||||||
|
<td>Should work with 4.4.1
|
||||||
|
<br>Mysterious problems have been reported - please run the test bench
|
||||||
|
and report problems</td>
|
||||||
|
</tr>
|
||||||
|
|
||||||
|
<caption ALIGN=BOTTOM>PCK_FIO and various simulators/versions</caption>
|
||||||
|
</table></center>
|
||||||
|
|
||||||
|
<p>Although the package name suggests file IO, it only does file output.
|
||||||
|
<p>
|
||||||
|
<hr SIZE=1 NOSHADE WIDTH="100%">
|
||||||
|
<h1>
|
||||||
|
<a NAME="PCK_FIO_author_0"></a>Author</h1>
|
||||||
|
<a href="mailto:jand@easics.be">Jan Decaluwe</a>
|
||||||
|
<p>
|
||||||
|
<hr SIZE=1 NOSHADE WIDTH="100%">
|
||||||
|
</body>
|
||||||
|
</html>
|
||||||
@@ -0,0 +1,206 @@
|
|||||||
|
PCK_FIO.out: TESTBENCH OUTPUT FOR PCK_FIO
|
||||||
|
-----------------------------------------
|
||||||
|
|
||||||
|
This is the result of running the PCK_FIO testbench.
|
||||||
|
This file should be compared with PCK_FIO.out.gold, which is
|
||||||
|
the reference output. Any difference indicates a portability
|
||||||
|
issue or a simulator non-compliance or bug.
|
||||||
|
|
||||||
|
|
||||||
|
--------------------
|
||||||
|
-- Basic features --
|
||||||
|
--------------------
|
||||||
|
|
||||||
|
-- First some auxiliary declarations
|
||||||
|
> file RESULT: text is out "PCK_FIO.out";
|
||||||
|
> variable L: line;
|
||||||
|
> variable BoolTrue: boolean := TRUE;
|
||||||
|
> variable BoolFalse: boolean := FALSE;
|
||||||
|
> variable IntPos: integer := 5678;
|
||||||
|
> variable BigIntPos: integer := 12345678;
|
||||||
|
> variable IntNeg: integer := -8765;
|
||||||
|
> variable BigIntNeg: integer := -87654321;
|
||||||
|
> variable Uns: unsigned(6 downto 0) := unsigned'("1010010");
|
||||||
|
> variable Unk: unsigned(6 downto 0) := unsigned'("1X10Z10");
|
||||||
|
> variable Std: std_logic_vector(6 downto 0) := std_logic_vector'("0010010");
|
||||||
|
> variable SigPos: signed(6 downto 0) := signed'("0010010");
|
||||||
|
> variable SigNeg: signed(6 downto 0) := signed'("1010010");
|
||||||
|
> variable BitX: std_logic := 'X';
|
||||||
|
> variable Bit1: std_logic := '1';
|
||||||
|
> variable Bit0: std_logic := '0';
|
||||||
|
|
||||||
|
|
||||||
|
-- fprint call with no arguments
|
||||||
|
> fprint(RESULT, L, "No arguments.\n);"
|
||||||
|
No arguments.
|
||||||
|
|
||||||
|
-- Special characters need to be escaped
|
||||||
|
> fprint(RESULT, L, "Special characters: \% \\ " \n");
|
||||||
|
Special characters: % \ "
|
||||||
|
|
||||||
|
-- Various format specifiers interprete the same object differently
|
||||||
|
> fprint(RESULT, L, "Format specifiers: %r %d %b %q\n);"
|
||||||
|
> fo(Uns), fo(Uns), fo(Uns), fo(Uns)
|
||||||
|
> );
|
||||||
|
Format specifiers: 0x52 82 1010010 U:1010010
|
||||||
|
|
||||||
|
-- Format string can be shortened by using the iteration specifier
|
||||||
|
> fprint(RESULT, L, "Iteration specifier: %4{%r }\n);"
|
||||||
|
> fo(Uns), fo(SigPos), fo(SigNeg), fo(Std)
|
||||||
|
> );
|
||||||
|
Iteration specifier: 0x52 0x12 0x52 0x12
|
||||||
|
|
||||||
|
------------------------------------
|
||||||
|
-- Support for bit-oriented types --
|
||||||
|
------------------------------------
|
||||||
|
|
||||||
|
-- Reasonable format
|
||||||
|
> fprint(RESULT, L, "Reasonable format: %9{%r }\n",
|
||||||
|
> fo(Std), fo(Uns), fo(SigPos), fo(SigNeg), fo(Unk),
|
||||||
|
> fo(Bit1), fo(BitX), fo(BoolTrue), fo(BoolFalse)
|
||||||
|
> );
|
||||||
|
Reasonable format: 0x12 0x52 0x12 0x52 0x?? 1 X T F
|
||||||
|
|
||||||
|
-- Decimal format
|
||||||
|
> fprint(RESULT, L, "Decimal format: %7{%d }\n",
|
||||||
|
> fo(Std), fo(Uns), fo(SigPos), fo(SigNeg), fo(Unk),
|
||||||
|
> fo(Bit1), fo(BitX), fo(BoolTrue), fo(BoolFalse)
|
||||||
|
> );
|
||||||
|
Decimal format: 18 82 18 -46 -1 1 -1 1 0
|
||||||
|
|
||||||
|
-- Bit format
|
||||||
|
> fprint(RESULT, L, "Bit format: %7{%b }\n",
|
||||||
|
> fo(Std), fo(Uns), fo(SigPos), fo(SigNeg), fo(Unk),
|
||||||
|
> fo(Bit1), fo(BitX), fo(BoolTrue), fo(BoolFalse)
|
||||||
|
> );
|
||||||
|
Bit format: 0010010 1010010 0010010 1010010 1X10Z10 1 X 1 0
|
||||||
|
|
||||||
|
|
||||||
|
-- Alignment
|
||||||
|
-- Template of the call: (<fs> stands for the format specifier)
|
||||||
|
|
||||||
|
> fprint(RESULT, L, "Bitvectors with <fs>: %4{<fs>|}\n",
|
||||||
|
> fo(Std), fo(Uns), fo(SigPos), fo(SigNeg)
|
||||||
|
> );
|
||||||
|
|
||||||
|
-- Results of the call with various format specifiers
|
||||||
|
|
||||||
|
Bitvectors with %1r: 0x52|0x12|0x12|0x52|
|
||||||
|
Bitvectors with %2r: 0x52|0x12|0x12|0x52|
|
||||||
|
Bitvectors with %3r: 0x52|0x12|0x12|0x52|
|
||||||
|
Bitvectors with %4r: 0x52|0x12|0x12|0x52|
|
||||||
|
Bitvectors with %5r: 0x52| 0x12| 0x12| 0x52|
|
||||||
|
Bitvectors with %6r: 0x52| 0x12| 0x12| 0x52|
|
||||||
|
Bitvectors with %7r: 0x52| 0x12| 0x12| 0x52|
|
||||||
|
Bitvectors with %8r: 0x52| 0x12| 0x12| 0x52|
|
||||||
|
Bitvectors with %9r: 0x52| 0x12| 0x12| 0x52|
|
||||||
|
|
||||||
|
Bitvectors with %-1r: 0x52|0x12|0x12|0x52|
|
||||||
|
Bitvectors with %-2r: 0x52|0x12|0x12|0x52|
|
||||||
|
Bitvectors with %-3r: 0x52|0x12|0x12|0x52|
|
||||||
|
Bitvectors with %-4r: 0x52|0x12|0x12|0x52|
|
||||||
|
Bitvectors with %-5r: 0x52 |0x12 |0x12 |0x52 |
|
||||||
|
Bitvectors with %-6r: 0x52 |0x12 |0x12 |0x52 |
|
||||||
|
Bitvectors with %-7r: 0x52 |0x12 |0x12 |0x52 |
|
||||||
|
Bitvectors with %-8r: 0x52 |0x12 |0x12 |0x52 |
|
||||||
|
Bitvectors with %-9r: 0x52 |0x12 |0x12 |0x52 |
|
||||||
|
|
||||||
|
Bitvectors with %1d: 82|18|18|-46|
|
||||||
|
Bitvectors with %2d: 82|18|18|-46|
|
||||||
|
Bitvectors with %3d: 82| 18| 18|-46|
|
||||||
|
Bitvectors with %4d: 82| 18| 18| -46|
|
||||||
|
Bitvectors with %5d: 82| 18| 18| -46|
|
||||||
|
Bitvectors with %6d: 82| 18| 18| -46|
|
||||||
|
Bitvectors with %7d: 82| 18| 18| -46|
|
||||||
|
Bitvectors with %8d: 82| 18| 18| -46|
|
||||||
|
Bitvectors with %9d: 82| 18| 18| -46|
|
||||||
|
|
||||||
|
Bitvectors with %-1d: 82|18|18|-46|
|
||||||
|
Bitvectors with %-2d: 82|18|18|-46|
|
||||||
|
Bitvectors with %-3d: 82 |18 |18 |-46|
|
||||||
|
Bitvectors with %-4d: 82 |18 |18 |-46 |
|
||||||
|
Bitvectors with %-5d: 82 |18 |18 |-46 |
|
||||||
|
Bitvectors with %-6d: 82 |18 |18 |-46 |
|
||||||
|
Bitvectors with %-7d: 82 |18 |18 |-46 |
|
||||||
|
Bitvectors with %-8d: 82 |18 |18 |-46 |
|
||||||
|
Bitvectors with %-9d: 82 |18 |18 |-46 |
|
||||||
|
|
||||||
|
|
||||||
|
-------------------------------
|
||||||
|
-- Support for integer types --
|
||||||
|
-------------------------------
|
||||||
|
|
||||||
|
|
||||||
|
-- Template of the call: (<fs> stands for the format specifier)
|
||||||
|
|
||||||
|
> fprint(RESULT, L, "Integers with <fs>: %4{<fs>|}\n",
|
||||||
|
> fo(IntPos), fo(IntNeg), fo(BigIntPos), fo(BigIntNeg)
|
||||||
|
> );
|
||||||
|
|
||||||
|
-- Results of the call with various format specifiers
|
||||||
|
|
||||||
|
Integers with %5d: 5678|-8765|12345678|-87654321|
|
||||||
|
Integers with %6d: 5678| -8765|12345678|-87654321|
|
||||||
|
Integers with %7d: 5678| -8765|12345678|-87654321|
|
||||||
|
Integers with %8d: 5678| -8765|12345678|-87654321|
|
||||||
|
Integers with %9d: 5678| -8765| 12345678|-87654321|
|
||||||
|
Integers with %10d: 5678| -8765| 12345678| -87654321|
|
||||||
|
|
||||||
|
Integers with %-5d: 5678 |-8765|12345678|-87654321|
|
||||||
|
Integers with %-6d: 5678 |-8765 |12345678|-87654321|
|
||||||
|
Integers with %-7d: 5678 |-8765 |12345678|-87654321|
|
||||||
|
Integers with %-8d: 5678 |-8765 |12345678|-87654321|
|
||||||
|
Integers with %-9d: 5678 |-8765 |12345678 |-87654321|
|
||||||
|
Integers with %-10d: 5678 |-8765 |12345678 |-87654321 |
|
||||||
|
|
||||||
|
Integers with %5r: 5678|-8765| 5678|-4321|
|
||||||
|
Integers with %6r: 5678|- 8765| 45678|-54321|
|
||||||
|
Integers with %7r: 5678|- 8765| 345678|-654321|
|
||||||
|
Integers with %8r: 5678|- 8765| 2345678|-7654321|
|
||||||
|
Integers with %9r: 5678|- 8765| 12345678|-87654321|
|
||||||
|
Integers with %10r: 5678|- 8765| 12345678|- 87654321|
|
||||||
|
|
||||||
|
Integers with %-5r: 5678|-8765| 1234|-8765|
|
||||||
|
Integers with %-6r: 5678 |-8765 | 12345|-87654|
|
||||||
|
Integers with %-7r: 5678 |-8765 | 123456|-876543|
|
||||||
|
Integers with %-8r: 5678 |-8765 | 1234567|-8765432|
|
||||||
|
Integers with %-9r: 5678 |-8765 | 12345678|-87654321|
|
||||||
|
Integers with %-10r: 5678 |-8765 | 12345678 |-87654321 |
|
||||||
|
|
||||||
|
|
||||||
|
----------------------
|
||||||
|
-- Support for time --
|
||||||
|
----------------------
|
||||||
|
-- For portability reasons, time is converted
|
||||||
|
-- into an integer value (of nanoseconds)
|
||||||
|
> wait for 648 ns
|
||||||
|
> fprint (RESULT, L, "The time is now %d ns\n", fo(now));
|
||||||
|
The time is now 648 ns
|
||||||
|
|
||||||
|
----------------------------------------
|
||||||
|
-- Erroneous calls and error messages --
|
||||||
|
----------------------------------------
|
||||||
|
|
||||||
|
-- Less arguments than formats specifiers
|
||||||
|
> fprint(RESULT, L, "%d %d %d %d \n", fo(Uns), fo(Std));
|
||||||
|
82 18
|
||||||
|
** Warning: FIO_PrintLastValue: Format specifier beyond last argument
|
||||||
|
** in format string: "%d %d %d %d \n"
|
||||||
|
** ------^
|
||||||
|
|
||||||
|
-- Unsupported format specifier
|
||||||
|
> fprint(RESULT, L, "%r %v %r %r\n", fo(Uns), fo(Std), fo(Uns), fo(Std));
|
||||||
|
0x52
|
||||||
|
** Warning: FIO_PrintArg: Unexpected format specifier 'v'
|
||||||
|
** in format string: "%r %v %r %r\n"
|
||||||
|
** ----^
|
||||||
|
** Assuming 'q' to proceed: V:0010010 0x52 0x12
|
||||||
|
|
||||||
|
|
||||||
|
----------------------------------------
|
||||||
|
-- Things you wouldn't expect to work --
|
||||||
|
----------------------------------------
|
||||||
|
|
||||||
|
-- Nested iteration
|
||||||
|
> fprint(RESULT, L, "%3{<<%3{_END_}>>}\n");
|
||||||
|
<<_END__END__END_>><<_END__END__END_>><<_END__END__END_>>
|
||||||
@@ -0,0 +1,916 @@
|
|||||||
|
---- File: PCK_FIO.vhd
|
||||||
|
----
|
||||||
|
---- PCK_FIO: a VHDL package for C-style formatted file output
|
||||||
|
---- Copyright (C) 1995, 1999 Easics NV
|
||||||
|
----
|
||||||
|
---- This program is free software; you can redistribute it and/or modify
|
||||||
|
---- it under the terms of the GNU General Public License as published by
|
||||||
|
---- the Free Software Foundation; either version 1, or (at your option)
|
||||||
|
---- any later version.
|
||||||
|
----
|
||||||
|
---- This program 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 General Public License for more details.
|
||||||
|
----
|
||||||
|
---- You should have received a copy of the GNU General Public License
|
||||||
|
---- along with this program; if not, write to the Free Software
|
||||||
|
---- Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
|
||||||
|
----
|
||||||
|
---- For suggestions, bug reports, enhancement requests, and info about
|
||||||
|
---- our design services, you can contact us at the following address:
|
||||||
|
---- Easics NV, Interleuvenlaan 86, B-3001 Leuven, Belgium
|
||||||
|
---- tel.: +32 16 395 600 fax : +32 16 395 619
|
||||||
|
---- e-mail: jand@easics.be (Jan Decaluwe)
|
||||||
|
----
|
||||||
|
----
|
||||||
|
---- Revision history:
|
||||||
|
----
|
||||||
|
---- $Source: /tmp/cvsroot/VHDL/lib/PCK_FIO-1.16/PCK_FIO.vhd,v $
|
||||||
|
---- $Revision: 1.1 $
|
||||||
|
---- $Log: not supported by cvs2svn $
|
||||||
|
---- Revision 1.16 1999/04/21 08:28:46 jand
|
||||||
|
---- Tested with IEEE.numeric_std
|
||||||
|
---- Small patch for Leapfrog
|
||||||
|
----
|
||||||
|
---- Revision 1.14 1997/07/14 10:16:04 jand
|
||||||
|
---- prefix/postfix for bits/bitvectors set to empty strings by default
|
||||||
|
----
|
||||||
|
---- Revision 1.13 1997/07/11 17:42:57 jand
|
||||||
|
---- Corrected Easics address
|
||||||
|
----
|
||||||
|
---- Revision 1.12 1997/07/11 17:38:49 jand
|
||||||
|
---- Improved prefix/postfix support
|
||||||
|
----
|
||||||
|
---- Revision 1.11 1995/11/15 13:46:02 jand
|
||||||
|
---- Catched integer'low value in fo for integers
|
||||||
|
----
|
||||||
|
---- Revision 1.10 1995/08/11 16:42:26 jand
|
||||||
|
---- Reimplemented FIO_FormatExpand as a procedure in an attempt to
|
||||||
|
---- avoid memory leakage problems in VSS
|
||||||
|
----
|
||||||
|
---- Revision 1.9 1995/08/09 13:47:51 jand
|
||||||
|
---- Removed array of line trick in fprint for less memory, less
|
||||||
|
---- CPU time, and more conservatism in general
|
||||||
|
---- Rearranged FIO_PrintValue call so that fprint remains concise
|
||||||
|
----
|
||||||
|
---- Revision 1.8 1995/08/09 10:32:27 jand
|
||||||
|
---- Removed fprint_flat to have a single call level
|
||||||
|
---- Added explicit deallocators of line variables (has strong influence
|
||||||
|
---- on memory usage in VSS - and possibly CPU time)
|
||||||
|
---- Redefined 'fo' for type time to make it more portable
|
||||||
|
----
|
||||||
|
---- Revision 1.7 1995/08/07 08:56:04 jand
|
||||||
|
---- Improved conciseness of fprint argument handling through array of line type
|
||||||
|
----
|
||||||
|
---- Revision 1.6 1995/08/04 18:19:13 jand
|
||||||
|
---- Increase # arguments from 16 to 32
|
||||||
|
---- Corrected bug within fprint 's call to Arg16
|
||||||
|
---- Added support for bit format specifier 'b'
|
||||||
|
----
|
||||||
|
---- Revision 1.5 1995/08/02 10:22:37 jand
|
||||||
|
---- Release 1.1 under GNU
|
||||||
|
----
|
||||||
|
---- Revision 1.4 1995/08/01 11:15:52 jand
|
||||||
|
---- Added escaping during iteration string read
|
||||||
|
----
|
||||||
|
---- Revision 1.3 1995/08/01 08:23:47 jand
|
||||||
|
---- Many improvements in robustness, conciseness and coding style
|
||||||
|
----
|
||||||
|
---- Revision 1.2 1995/07/30 16:15:43 jand
|
||||||
|
---- Improved robustness for release to the world
|
||||||
|
----
|
||||||
|
---- Revision 1.1 1995/07/30 14:21:30 jand
|
||||||
|
---- Initial revision
|
||||||
|
----
|
||||||
|
|
||||||
|
use STD.TEXTIO.all;
|
||||||
|
|
||||||
|
library IEEE;
|
||||||
|
use IEEE.std_logic_1164.all;
|
||||||
|
-- signed/unsigned definition: use either std_logic_arith or numeric_std
|
||||||
|
use IEEE.std_logic_arith.all; -- the Synopsys one
|
||||||
|
-- use IEEE.numeric_std.all;
|
||||||
|
|
||||||
|
package PCK_FIO is
|
||||||
|
|
||||||
|
-- prefix string for hex output
|
||||||
|
-- VHDL style: "X"""
|
||||||
|
-- Verilog style: "h'"
|
||||||
|
-- C style: "0x"
|
||||||
|
constant FIO_h_PRE: string := "0x";
|
||||||
|
|
||||||
|
-- postfix string for hex output
|
||||||
|
-- VHDL style: """"
|
||||||
|
constant FIO_h_POST: string := "";
|
||||||
|
|
||||||
|
-- prefix string for bit vector output
|
||||||
|
-- VHDL style: "B"""
|
||||||
|
-- Verilog style: "b'"
|
||||||
|
constant FIO_bv_PRE: string := "";
|
||||||
|
|
||||||
|
-- postfix string for bit vector output
|
||||||
|
-- VHDL style: """"
|
||||||
|
constant FIO_bv_POST: string := "";
|
||||||
|
|
||||||
|
-- prefix string for bit output
|
||||||
|
-- VHDL style: "'"
|
||||||
|
-- Verilog style: "b'"
|
||||||
|
constant FIO_b_PRE: string := "";
|
||||||
|
|
||||||
|
-- postfix string for bit output
|
||||||
|
-- VHDL style: "'"
|
||||||
|
constant FIO_b_POST: string := "";
|
||||||
|
|
||||||
|
-- digit width for the string representation of integers
|
||||||
|
constant FIO_d_WIDTH: integer := 10;
|
||||||
|
|
||||||
|
-- bit width for the string representation of integers
|
||||||
|
constant FIO_b_WIDTH: integer := 32;
|
||||||
|
|
||||||
|
-- definition of the NIL string (default value for fprint arguments)
|
||||||
|
-- fprint stops consuming arguments at the first NIL argument
|
||||||
|
constant FIO_NIL: string := "\";
|
||||||
|
|
||||||
|
procedure fprint
|
||||||
|
(F: out text;
|
||||||
|
L: inout line;
|
||||||
|
Format: in string;
|
||||||
|
A1 , A2 , A3 , A4 , A5 , A6 , A7 , A8 : in string := FIO_NIL;
|
||||||
|
A9 , A10, A11, A12, A13, A14, A15, A16: in string := FIO_NIL;
|
||||||
|
A17, A18, A19, A20, A21, A22, A23, A24: in string := FIO_NIL;
|
||||||
|
A25, A26, A27, A28, A29, A30, A31, A32: in string := FIO_NIL
|
||||||
|
);
|
||||||
|
|
||||||
|
function fo (Arg: unsigned) return string;
|
||||||
|
function fo (Arg: signed) return string;
|
||||||
|
function fo (Arg: std_logic_vector) return string;
|
||||||
|
function fo (Arg: std_ulogic_vector) return string;
|
||||||
|
function fo (Arg: bit_vector) return string;
|
||||||
|
function fo (Arg: integer) return string;
|
||||||
|
function fo (Arg: std_ulogic) return string;
|
||||||
|
function fo (Arg: bit) return string;
|
||||||
|
function fo (Arg: boolean) return string;
|
||||||
|
function fo (Arg: character) return string;
|
||||||
|
function fo (Arg: string) return string;
|
||||||
|
function fo (Arg: time) return string;
|
||||||
|
|
||||||
|
procedure FIO_FormatExpand (FMT: inout line;
|
||||||
|
Format: in string;
|
||||||
|
StartPointer: in positive);
|
||||||
|
|
||||||
|
end PCK_FIO;
|
||||||
|
|
||||||
|
|
||||||
|
package body PCK_FIO is
|
||||||
|
|
||||||
|
|
||||||
|
--------------------------
|
||||||
|
-- FIO Warnings support --
|
||||||
|
--------------------------
|
||||||
|
|
||||||
|
procedure FIO_Warning_Fsbla (F: out text;
|
||||||
|
L: inout line;
|
||||||
|
Format: in string;
|
||||||
|
Pointer: in positive) is
|
||||||
|
begin
|
||||||
|
fprint (F, L, "\n** Warning: FIO_PrintLastValue: " &
|
||||||
|
"Format specifier beyond last argument\n");
|
||||||
|
fprint (F, L, "** in format string: ""%s""\n", Format);
|
||||||
|
fprint (F, L, "** ");
|
||||||
|
for i in 1 to Pointer-1 loop
|
||||||
|
fprint (F, L, "-");
|
||||||
|
end loop;
|
||||||
|
fprint (F, L, "^\n");
|
||||||
|
end FIO_Warning_Fsbla;
|
||||||
|
|
||||||
|
procedure FIO_Warning_Ufs (F: out text;
|
||||||
|
L: inout line;
|
||||||
|
Format: in string;
|
||||||
|
Pointer: in positive;
|
||||||
|
Char: in character) is
|
||||||
|
begin
|
||||||
|
fprint (F, L, "\n** Warning: FIO_PrintArg: " &
|
||||||
|
"Unexpected format specifier '%r'\n",
|
||||||
|
fo(Char));
|
||||||
|
fprint (F, L, "** in format string: ""%s""\n", Format) ;
|
||||||
|
fprint (F, L, "** ");
|
||||||
|
for i in 1 to Pointer-1 loop
|
||||||
|
fprint (F, L, "-");
|
||||||
|
end loop;
|
||||||
|
fprint (F, L, "^\n** Assuming 'q' to proceed: ");
|
||||||
|
end FIO_Warning_Ufs;
|
||||||
|
|
||||||
|
|
||||||
|
----------------------------------
|
||||||
|
-- bit conversion support --
|
||||||
|
----------------------------------
|
||||||
|
|
||||||
|
type T_bit_map is array(bit) of character;
|
||||||
|
|
||||||
|
constant C_BIT_MAP: T_bit_map
|
||||||
|
:= ('0', '1');
|
||||||
|
|
||||||
|
----------------------------------
|
||||||
|
-- std_logic conversion support --
|
||||||
|
----------------------------------
|
||||||
|
|
||||||
|
type T_std_logic_map is array(std_ulogic) of character;
|
||||||
|
|
||||||
|
constant C_STD_LOGIC_MAP: T_std_logic_map
|
||||||
|
:= ('U', 'X', '0', '1', 'Z', 'W', 'L', 'H', '-');
|
||||||
|
|
||||||
|
------------------------------
|
||||||
|
-- Digit conversion support --
|
||||||
|
------------------------------
|
||||||
|
|
||||||
|
-- types & constants
|
||||||
|
|
||||||
|
subtype S_digit_chars is character range '0' to '9';
|
||||||
|
subtype S_digits is integer range 0 to 9 ;
|
||||||
|
|
||||||
|
type T_digit_chars_map is array(S_digit_chars) of S_digits;
|
||||||
|
|
||||||
|
constant C_DIGIT_CHARS_MAP: T_digit_chars_map
|
||||||
|
:= (0, 1, 2, 3, 4, 5, 6, 7, 8, 9);
|
||||||
|
|
||||||
|
type T_digits_map is array(S_digits) of S_digit_chars;
|
||||||
|
|
||||||
|
constant C_DIGITS_MAP: T_digits_map
|
||||||
|
:= ('0', '1', '2', '3', '4', '5', '6', '7', '8', '9');
|
||||||
|
|
||||||
|
|
||||||
|
--------------------------------
|
||||||
|
-- Decimal conversion support --
|
||||||
|
--------------------------------
|
||||||
|
|
||||||
|
function U_To_d (Arg: string) return integer is
|
||||||
|
constant Argument: string(Arg'length downto 1) := Arg;
|
||||||
|
variable Result: integer := 0;
|
||||||
|
begin
|
||||||
|
for i in Argument'range loop
|
||||||
|
case Argument(i) is when '1' => Result := 2**(i-1) + Result;
|
||||||
|
when '0' => null;
|
||||||
|
when others => return(-1);
|
||||||
|
end case;
|
||||||
|
end loop;
|
||||||
|
return (Result);
|
||||||
|
end U_To_d;
|
||||||
|
|
||||||
|
function S_To_d (Arg: string) return integer is
|
||||||
|
constant Argument: string(Arg'length downto 1) := Arg;
|
||||||
|
variable Result: integer := 0;
|
||||||
|
begin
|
||||||
|
case Argument(Argument'left) is
|
||||||
|
when '1' => Result := - 2**(Argument'left-1);
|
||||||
|
when '0' => Result := 0;
|
||||||
|
when others => return (integer'low);
|
||||||
|
end case;
|
||||||
|
for i in Argument'left-1 downto 1 loop
|
||||||
|
case Argument(i) is when '1' => Result := 2**(i-1) + Result;
|
||||||
|
when '0' => null;
|
||||||
|
when others => return(integer'low);
|
||||||
|
end case;
|
||||||
|
end loop;
|
||||||
|
return (Result);
|
||||||
|
end S_To_d;
|
||||||
|
|
||||||
|
function I_To_d (Arg: string(1 to FIO_d_WIDTH+1)) return integer is
|
||||||
|
constant Sign: character := Arg(1);
|
||||||
|
constant Value: string(Arg'length-1 downto 1) := Arg(2 to Arg'length);
|
||||||
|
variable Char: character;
|
||||||
|
variable Result: integer := 0;
|
||||||
|
begin
|
||||||
|
Result := 0;
|
||||||
|
for i in Value'range loop
|
||||||
|
Result := Result * 10;
|
||||||
|
Char := Value(i);
|
||||||
|
if (Char /= ' ') then
|
||||||
|
Result := Result + C_DIGIT_CHARS_MAP(Char);
|
||||||
|
end if;
|
||||||
|
end loop;
|
||||||
|
case Sign is when '-' => return(-Result);
|
||||||
|
when others => return(Result);
|
||||||
|
end case;
|
||||||
|
end I_To_d;
|
||||||
|
|
||||||
|
function B_To_d (Arg: string(1 to 1)) return integer is
|
||||||
|
begin
|
||||||
|
case Arg is when "1" => return(1);
|
||||||
|
when "0" => return(0);
|
||||||
|
when others => return(-1);
|
||||||
|
end case;
|
||||||
|
end B_To_d;
|
||||||
|
|
||||||
|
function L_To_d (Arg: string(1 to 1)) return integer is
|
||||||
|
begin
|
||||||
|
case Arg is when "T" => return(1);
|
||||||
|
when others => return(0);
|
||||||
|
end case;
|
||||||
|
end L_To_d;
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
----------------------------
|
||||||
|
-- Hex conversion support --
|
||||||
|
----------------------------
|
||||||
|
|
||||||
|
-- Constants & types
|
||||||
|
|
||||||
|
constant C_HEX_CHARS: string(1 to 17) := "0123456789ABCDEF?";
|
||||||
|
|
||||||
|
-- Function to return Hex index of a nibble
|
||||||
|
|
||||||
|
function U_To_h_Index(Arg: string(4 downto 1)) return integer is
|
||||||
|
variable Index: integer := 0;
|
||||||
|
begin
|
||||||
|
for i in Arg'range loop
|
||||||
|
case Arg(i) is when '1' => Index := 2**(i-1) + Index;
|
||||||
|
when '0' => null;
|
||||||
|
when others => return (17);
|
||||||
|
end case;
|
||||||
|
end loop;
|
||||||
|
return (Index+1);
|
||||||
|
end U_To_h_Index;
|
||||||
|
|
||||||
|
-- Hex conversion
|
||||||
|
|
||||||
|
function U_To_h (Arg: string) return string is
|
||||||
|
variable Result: string((Arg'length-1)/4 +1 downto 1);
|
||||||
|
variable ExtArg: string(Result'length*4 downto 1) := (others => '0');
|
||||||
|
begin
|
||||||
|
ExtArg(Arg'length downto 1) := Arg;
|
||||||
|
for i in Result'range loop
|
||||||
|
Result(i) := C_HEX_CHARS(U_To_h_Index( ExtArg(i*4 downto i*4 -3) ));
|
||||||
|
end loop;
|
||||||
|
return (FIO_h_PRE & Result & FIO_h_POST);
|
||||||
|
end U_To_h;
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
----------------------------
|
||||||
|
-- Bit conversion support --
|
||||||
|
----------------------------
|
||||||
|
|
||||||
|
function L_To_b (Arg: string(1 to 1)) return string is
|
||||||
|
variable Result: string(1 to 1);
|
||||||
|
begin
|
||||||
|
case Arg is when "T" => Result := "1";
|
||||||
|
when others => Result := "0";
|
||||||
|
end case;
|
||||||
|
return(FIO_b_PRE & Result & FIO_b_POST);
|
||||||
|
end L_To_b;
|
||||||
|
|
||||||
|
|
||||||
|
function I_To_b (Arg: string(1 to FIO_d_WIDTH+1);
|
||||||
|
Justified: side;
|
||||||
|
Width: integer) return string is
|
||||||
|
|
||||||
|
variable IntValue: integer := I_To_d(Arg);
|
||||||
|
variable BitValue: string(1 to FIO_b_WIDTH) := (others => ' ');
|
||||||
|
variable Sign: character := ' ';
|
||||||
|
constant Blanks: string(1 to FIO_b_WIDTH) := (others => ' ');
|
||||||
|
variable BitWidth: integer range 0 to FIO_b_WIDTH;
|
||||||
|
variable MsPos: integer range 1 to BitValue'length;
|
||||||
|
variable BitValueExtended: string(1 to 2*FIO_b_WIDTH);
|
||||||
|
|
||||||
|
begin
|
||||||
|
|
||||||
|
if (IntValue < 0) then
|
||||||
|
Sign := '-';
|
||||||
|
IntValue := -IntValue;
|
||||||
|
end if;
|
||||||
|
|
||||||
|
for i in BitValue'reverse_range loop
|
||||||
|
BitValue(i) := C_DIGITS_MAP(IntValue mod 2);
|
||||||
|
IntValue := IntValue / 2;
|
||||||
|
exit when (IntValue = 0);
|
||||||
|
end loop;
|
||||||
|
|
||||||
|
BitValueExtended := BitValue & Blanks;
|
||||||
|
|
||||||
|
if (Width = 0) or (Width > FIO_b_WIDTH+1) then
|
||||||
|
BitWidth := FIO_b_WIDTH;
|
||||||
|
else
|
||||||
|
BitWidth := Width-1;
|
||||||
|
end if;
|
||||||
|
|
||||||
|
if (Justified = RIGHT) then
|
||||||
|
return (FIO_bv_PRE &
|
||||||
|
Sign & BitValue(BitValue'length-BitWidth+1 to BitValue'length) &
|
||||||
|
FIO_bv_POST);
|
||||||
|
else
|
||||||
|
for i in BitValue'range loop
|
||||||
|
if BitValue(i) /= ' ' then
|
||||||
|
MSPos := i;
|
||||||
|
exit;
|
||||||
|
end if;
|
||||||
|
end loop;
|
||||||
|
return (FIO_bv_PRE &
|
||||||
|
Sign & BitValueExtended(MSPos to MSPos+BitWidth-1) &
|
||||||
|
FIO_bv_POST);
|
||||||
|
end if;
|
||||||
|
|
||||||
|
end I_To_b;
|
||||||
|
|
||||||
|
|
||||||
|
-----------------------------------
|
||||||
|
-- Reasonable conversion support --
|
||||||
|
-----------------------------------
|
||||||
|
|
||||||
|
function I_To_r (Arg: string(1 to FIO_d_WIDTH+1);
|
||||||
|
Justified: side;
|
||||||
|
Width: integer) return string is
|
||||||
|
constant Value: string(1 to FIO_d_WIDTH) := Arg(2 to FIO_d_WIDTH+1);
|
||||||
|
constant Sign: character := Arg(1);
|
||||||
|
constant Blanks: string(1 to FIO_d_WIDTH) := (others => ' ');
|
||||||
|
variable IntWidth: integer range 0 to FIO_d_WIDTH;
|
||||||
|
variable MsPos: integer range 1 to Value'length;
|
||||||
|
variable ValueExtended: string(1 to 2*FIO_d_WIDTH) := Value & Blanks;
|
||||||
|
begin
|
||||||
|
if (Width = 0) or (Width > FIO_d_WIDTH+1) then
|
||||||
|
IntWidth := FIO_d_WIDTH;
|
||||||
|
else
|
||||||
|
IntWidth := Width-1;
|
||||||
|
end if;
|
||||||
|
if (Justified = RIGHT) then
|
||||||
|
return (Sign & Value(Value'length-IntWidth+1 to Value'length));
|
||||||
|
else
|
||||||
|
for i in Value'range loop
|
||||||
|
if Value(i) /= ' ' then
|
||||||
|
MSPos := i;
|
||||||
|
exit;
|
||||||
|
end if;
|
||||||
|
end loop;
|
||||||
|
return (Sign & ValueExtended(MSPos to MSPos+IntWidth-1));
|
||||||
|
end if;
|
||||||
|
end I_To_r;
|
||||||
|
|
||||||
|
|
||||||
|
-------------------------------------------
|
||||||
|
-- Reasonable output conversion function --
|
||||||
|
-------------------------------------------
|
||||||
|
|
||||||
|
function ReasonableOutput (Arg: string;
|
||||||
|
Justified: side;
|
||||||
|
Width: integer) return string is
|
||||||
|
constant Argument: string(1 to Arg'length) := Arg;
|
||||||
|
constant TypeSpec: string (1 to 2) := Argument(1 to 2);
|
||||||
|
constant Value: string(1 to Arg'length-2) := Argument(3 to Arg'length);
|
||||||
|
begin
|
||||||
|
case TypeSpec is
|
||||||
|
when "U:" | "S:" | "V:" =>
|
||||||
|
return U_To_h(Value);
|
||||||
|
when "I:" =>
|
||||||
|
return I_To_r(Value, Justified, Width);
|
||||||
|
when "B:" | "L:" | "C:" =>
|
||||||
|
return Value;
|
||||||
|
when others =>
|
||||||
|
return Argument;
|
||||||
|
end case;
|
||||||
|
|
||||||
|
end ReasonableOutput;
|
||||||
|
|
||||||
|
|
||||||
|
------------------------------------
|
||||||
|
-- Bit output conversion function --
|
||||||
|
------------------------------------
|
||||||
|
|
||||||
|
function BitOutput (Arg: string;
|
||||||
|
Justified: side;
|
||||||
|
Width: integer) return string is
|
||||||
|
constant Argument: string(1 to Arg'length) := Arg;
|
||||||
|
constant TypeSpec: string (1 to 2) := Argument(1 to 2);
|
||||||
|
constant Value: string(1 to Arg'length-2) := Argument(3 to Arg'length);
|
||||||
|
begin
|
||||||
|
case TypeSpec is
|
||||||
|
when "U:" | "S:" | "V:" =>
|
||||||
|
return (FIO_bv_PRE & Value & FIO_bv_POST);
|
||||||
|
when "B:" =>
|
||||||
|
-- Value(1 to 1) instead of Value for LeapFrog
|
||||||
|
return (FIO_b_PRE & Value(1 to 1) & FIO_b_POST);
|
||||||
|
when "I:" =>
|
||||||
|
return I_To_b(Value, Justified, Width);
|
||||||
|
when "L:" =>
|
||||||
|
-- Value(1 to 1) instead of Value for LeapFrog
|
||||||
|
return L_To_b(Value(1 to 1));
|
||||||
|
when others =>
|
||||||
|
return Argument;
|
||||||
|
end case;
|
||||||
|
|
||||||
|
end BitOutput;
|
||||||
|
|
||||||
|
|
||||||
|
-------------------------------------------
|
||||||
|
-- Decimal output conversion function --
|
||||||
|
-------------------------------------------
|
||||||
|
|
||||||
|
function DecimalOutput (Arg: string) return integer is
|
||||||
|
constant Argument: string(1 to Arg'length) := Arg;
|
||||||
|
constant TypeSpec: string (1 to 2) := Argument(1 to 2);
|
||||||
|
constant Value: string(1 to Arg'length-2) := Argument(3 to Arg'length);
|
||||||
|
begin
|
||||||
|
case TypeSpec is
|
||||||
|
when "U:"| "V:" =>
|
||||||
|
return U_To_d(Value);
|
||||||
|
when "S:" =>
|
||||||
|
return S_To_d(Value);
|
||||||
|
when "I:" =>
|
||||||
|
return I_To_d(Value);
|
||||||
|
when "B:" =>
|
||||||
|
return B_To_d(Value);
|
||||||
|
when "L:" =>
|
||||||
|
return L_To_d(Value);
|
||||||
|
when others =>
|
||||||
|
return integer'low;
|
||||||
|
end case;
|
||||||
|
|
||||||
|
end DecimalOutput;
|
||||||
|
|
||||||
|
|
||||||
|
----------------------------
|
||||||
|
-- Atomic print functions --
|
||||||
|
----------------------------
|
||||||
|
|
||||||
|
function FIO_EOS (Format: in string;
|
||||||
|
Pointer: in integer)
|
||||||
|
return boolean is
|
||||||
|
begin
|
||||||
|
return (Pointer > Format'length);
|
||||||
|
end FIO_EOS;
|
||||||
|
|
||||||
|
|
||||||
|
-- Atomic value print function
|
||||||
|
|
||||||
|
procedure FIO_PrintValue (F: out text;
|
||||||
|
L: inout line;
|
||||||
|
Format: in string;
|
||||||
|
Pointer: inout integer;
|
||||||
|
Last: in boolean := FALSE) is
|
||||||
|
variable Char: character;
|
||||||
|
begin
|
||||||
|
while (not FIO_EOS(Format, Pointer)) loop
|
||||||
|
Char := Format(Pointer);
|
||||||
|
case Char is
|
||||||
|
when '\' =>
|
||||||
|
Pointer := Pointer + 1;
|
||||||
|
exit when (FIO_EOS(Format, Pointer));
|
||||||
|
Char := Format(Pointer);
|
||||||
|
case Char is when 'n' => writeline(F, L);
|
||||||
|
when others => write(L, Char);
|
||||||
|
end case;
|
||||||
|
when '%' =>
|
||||||
|
if Last then
|
||||||
|
FIO_Warning_Fsbla(F, L, Format, Pointer);
|
||||||
|
end if;
|
||||||
|
Pointer := Pointer + 1;
|
||||||
|
exit;
|
||||||
|
when others =>
|
||||||
|
write(L, char);
|
||||||
|
end case;
|
||||||
|
Pointer := Pointer + 1;
|
||||||
|
end loop;
|
||||||
|
end FIO_PrintValue;
|
||||||
|
|
||||||
|
|
||||||
|
---- Atomic argument print function
|
||||||
|
|
||||||
|
procedure FIO_PrintArg (F: out text;
|
||||||
|
L: inout line;
|
||||||
|
Format: in string;
|
||||||
|
Pointer: inout integer;
|
||||||
|
Arg: in string) is
|
||||||
|
variable Char: character;
|
||||||
|
variable Justified: side;
|
||||||
|
variable Width: integer;
|
||||||
|
begin
|
||||||
|
|
||||||
|
FIO_PrintValue(F, L, Format, Pointer);
|
||||||
|
|
||||||
|
Justified := RIGHT;
|
||||||
|
Width := 0;
|
||||||
|
while (not FIO_EOS(Format, Pointer)) loop
|
||||||
|
Char := Format(Pointer);
|
||||||
|
case Char is
|
||||||
|
when '-' =>
|
||||||
|
Justified := LEFT;
|
||||||
|
Pointer := Pointer + 1;
|
||||||
|
when '0' to '9' =>
|
||||||
|
Width := Width*10 + C_DIGIT_CHARS_MAP(Char);
|
||||||
|
Pointer := Pointer + 1;
|
||||||
|
when 'r' =>
|
||||||
|
write(L, ReasonableOutput(Arg, Justified, Width), Justified, Width);
|
||||||
|
Pointer := Pointer + 1;
|
||||||
|
exit;
|
||||||
|
when 'b' =>
|
||||||
|
write(L, BitOutput(Arg, Justified, Width), Justified, Width);
|
||||||
|
Pointer := Pointer + 1;
|
||||||
|
exit;
|
||||||
|
when 'd' =>
|
||||||
|
write(L, DecimalOutput(Arg), Justified, Width);
|
||||||
|
Pointer := Pointer + 1;
|
||||||
|
exit;
|
||||||
|
when 'q' | 's' =>
|
||||||
|
write(L, Arg, Justified, Width);
|
||||||
|
Pointer := Pointer + 1;
|
||||||
|
exit;
|
||||||
|
when others =>
|
||||||
|
FIO_Warning_Ufs(F, L, Format, Pointer, Char);
|
||||||
|
write(L, Arg, Justified, Width);
|
||||||
|
Pointer := Pointer + 1;
|
||||||
|
exit;
|
||||||
|
end case;
|
||||||
|
end loop;
|
||||||
|
end FIO_PrintArg;
|
||||||
|
|
||||||
|
|
||||||
|
-----------------------------------------------------
|
||||||
|
-- The format string iteration expansion procedure --
|
||||||
|
-----------------------------------------------------
|
||||||
|
|
||||||
|
procedure FIO_FormatExpand (FMT: inout line;
|
||||||
|
Format: in string;
|
||||||
|
StartPointer: in positive) is
|
||||||
|
|
||||||
|
variable Pointer: positive := StartPointer;
|
||||||
|
variable TokenStart: positive;
|
||||||
|
variable IterStringStart: positive;
|
||||||
|
variable IterStringEnd: positive;
|
||||||
|
variable IterCount: natural;
|
||||||
|
variable OpenBrackets: natural;
|
||||||
|
variable L: line;
|
||||||
|
|
||||||
|
begin
|
||||||
|
|
||||||
|
FORMAT_SEARCH: while not FIO_EOS(Format, Pointer) loop
|
||||||
|
|
||||||
|
case Format(Pointer) is
|
||||||
|
|
||||||
|
-- look for format specifier
|
||||||
|
when '%' =>
|
||||||
|
|
||||||
|
-- initialize iteration token search
|
||||||
|
TokenStart := Pointer;
|
||||||
|
IterCount := 0;
|
||||||
|
Pointer := Pointer + 1;
|
||||||
|
|
||||||
|
-- start iteration token search
|
||||||
|
TOKEN_READ: while not FIO_EOS(Format, Pointer) loop
|
||||||
|
|
||||||
|
case Format(Pointer) is
|
||||||
|
|
||||||
|
-- read iteration counter
|
||||||
|
when '0' to '9' =>
|
||||||
|
IterCount := IterCount*10 + C_DIGIT_CHARS_MAP(Format(Pointer));
|
||||||
|
Pointer := Pointer + 1;
|
||||||
|
|
||||||
|
-- expect open bracket
|
||||||
|
when '{' =>
|
||||||
|
|
||||||
|
-- initialize iteration string read
|
||||||
|
OpenBrackets := 1;
|
||||||
|
IterStringStart := Pointer + 1;
|
||||||
|
Pointer := Pointer + 1;
|
||||||
|
-- quit prematurely when iteration count is 0
|
||||||
|
next FORMAT_SEARCH when (IterCount = 0);
|
||||||
|
|
||||||
|
-- start iteration string read
|
||||||
|
ITER_STRING_READ: while not FIO_EOS(Format, Pointer) loop
|
||||||
|
|
||||||
|
case Format(Pointer) is
|
||||||
|
-- keep track of open brackets
|
||||||
|
when '{' =>
|
||||||
|
OpenBrackets := OpenBrackets + 1;
|
||||||
|
Pointer := Pointer + 1;
|
||||||
|
-- when closing bracket is found, process iteration string
|
||||||
|
when '}' =>
|
||||||
|
OpenBrackets := OpenBrackets - 1;
|
||||||
|
if (OpenBrackets = 0) then
|
||||||
|
IterStringEnd := Pointer-1;
|
||||||
|
if (TokenStart /= 1) then
|
||||||
|
write(L, Format(1 to TokenStart-1));
|
||||||
|
end if;
|
||||||
|
for i in 1 to IterCount loop
|
||||||
|
write(L, Format(IterStringStart to IterStringEnd));
|
||||||
|
end loop;
|
||||||
|
if (IterStringEnd /= Format'length) then
|
||||||
|
write(L, Format(IterStringEnd+2 to Format'length));
|
||||||
|
end if;
|
||||||
|
-- call expansion procedure recursively on expanded format
|
||||||
|
FIO_FormatExpand(FMT, L.all, TokenStart);
|
||||||
|
deallocate(L);
|
||||||
|
return;
|
||||||
|
end if;
|
||||||
|
Pointer := Pointer + 1;
|
||||||
|
-- skip escaped characters
|
||||||
|
when '\' =>
|
||||||
|
Pointer := Pointer + 2;
|
||||||
|
-- read iteration string
|
||||||
|
when others =>
|
||||||
|
Pointer := Pointer + 1;
|
||||||
|
|
||||||
|
end case;
|
||||||
|
|
||||||
|
end loop ITER_STRING_READ;
|
||||||
|
|
||||||
|
-- stop iteration token search when no opening bracket found
|
||||||
|
when others =>
|
||||||
|
Pointer := Pointer + 1;
|
||||||
|
next FORMAT_SEARCH;
|
||||||
|
|
||||||
|
end case;
|
||||||
|
|
||||||
|
end loop TOKEN_READ;
|
||||||
|
|
||||||
|
-- skip escaped characters
|
||||||
|
when '\' =>
|
||||||
|
Pointer := Pointer + 2;
|
||||||
|
|
||||||
|
-- read other characters
|
||||||
|
when others =>
|
||||||
|
Pointer := Pointer + 1;
|
||||||
|
|
||||||
|
end case;
|
||||||
|
|
||||||
|
end loop FORMAT_SEARCH;
|
||||||
|
|
||||||
|
write(FMT, Format);
|
||||||
|
deallocate(L);
|
||||||
|
|
||||||
|
end FIO_FormatExpand;
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
--------------------------
|
||||||
|
-- The fprint procedure --
|
||||||
|
--------------------------
|
||||||
|
|
||||||
|
procedure fprint
|
||||||
|
(F: out text;
|
||||||
|
L: inout line;
|
||||||
|
Format: in string;
|
||||||
|
A1 , A2 , A3 , A4 , A5 , A6 , A7 , A8 : in string := FIO_NIL;
|
||||||
|
A9 , A10, A11, A12, A13, A14, A15, A16: in string := FIO_NIL;
|
||||||
|
A17, A18, A19, A20, A21, A22, A23, A24: in string := FIO_NIL;
|
||||||
|
A25, A26, A27, A28, A29, A30, A31, A32: in string := FIO_NIL
|
||||||
|
) is
|
||||||
|
|
||||||
|
variable Pointer: integer;
|
||||||
|
variable FMT: line;
|
||||||
|
|
||||||
|
begin
|
||||||
|
|
||||||
|
Pointer := 1;
|
||||||
|
|
||||||
|
FIO_FormatExpand (FMT, Format, Format'low);
|
||||||
|
|
||||||
|
if (A1 /= FIO_NIL) then FIO_PrintArg(F, L, FMT.all, Pointer, A1 );
|
||||||
|
if (A2 /= FIO_NIL) then FIO_PrintArg(F, L, FMT.all, Pointer, A2 );
|
||||||
|
if (A3 /= FIO_NIL) then FIO_PrintArg(F, L, FMT.all, Pointer, A3 );
|
||||||
|
if (A4 /= FIO_NIL) then FIO_PrintArg(F, L, FMT.all, Pointer, A4 );
|
||||||
|
if (A5 /= FIO_NIL) then FIO_PrintArg(F, L, FMT.all, Pointer, A5 );
|
||||||
|
if (A6 /= FIO_NIL) then FIO_PrintArg(F, L, FMT.all, Pointer, A6 );
|
||||||
|
if (A7 /= FIO_NIL) then FIO_PrintArg(F, L, FMT.all, Pointer, A7 );
|
||||||
|
if (A8 /= FIO_NIL) then FIO_PrintArg(F, L, FMT.all, Pointer, A8 );
|
||||||
|
if (A9 /= FIO_NIL) then FIO_PrintArg(F, L, FMT.all, Pointer, A9 );
|
||||||
|
if (A10 /= FIO_NIL) then FIO_PrintArg(F, L, FMT.all, Pointer, A10);
|
||||||
|
if (A11 /= FIO_NIL) then FIO_PrintArg(F, L, FMT.all, Pointer, A11);
|
||||||
|
if (A12 /= FIO_NIL) then FIO_PrintArg(F, L, FMT.all, Pointer, A12);
|
||||||
|
if (A13 /= FIO_NIL) then FIO_PrintArg(F, L, FMT.all, Pointer, A13);
|
||||||
|
if (A14 /= FIO_NIL) then FIO_PrintArg(F, L, FMT.all, Pointer, A14);
|
||||||
|
if (A15 /= FIO_NIL) then FIO_PrintArg(F, L, FMT.all, Pointer, A15);
|
||||||
|
if (A16 /= FIO_NIL) then FIO_PrintArg(F, L, FMT.all, Pointer, A16);
|
||||||
|
if (A17 /= FIO_NIL) then FIO_PrintArg(F, L, FMT.all, Pointer, A17);
|
||||||
|
if (A18 /= FIO_NIL) then FIO_PrintArg(F, L, FMT.all, Pointer, A18);
|
||||||
|
if (A19 /= FIO_NIL) then FIO_PrintArg(F, L, FMT.all, Pointer, A19);
|
||||||
|
if (A20 /= FIO_NIL) then FIO_PrintArg(F, L, FMT.all, Pointer, A20);
|
||||||
|
if (A21 /= FIO_NIL) then FIO_PrintArg(F, L, FMT.all, Pointer, A21);
|
||||||
|
if (A22 /= FIO_NIL) then FIO_PrintArg(F, L, FMT.all, Pointer, A22);
|
||||||
|
if (A23 /= FIO_NIL) then FIO_PrintArg(F, L, FMT.all, Pointer, A23);
|
||||||
|
if (A24 /= FIO_NIL) then FIO_PrintArg(F, L, FMT.all, Pointer, A24);
|
||||||
|
if (A25 /= FIO_NIL) then FIO_PrintArg(F, L, FMT.all, Pointer, A25);
|
||||||
|
if (A26 /= FIO_NIL) then FIO_PrintArg(F, L, FMT.all, Pointer, A26);
|
||||||
|
if (A27 /= FIO_NIL) then FIO_PrintArg(F, L, FMT.all, Pointer, A27);
|
||||||
|
if (A28 /= FIO_NIL) then FIO_PrintArg(F, L, FMT.all, Pointer, A28);
|
||||||
|
if (A29 /= FIO_NIL) then FIO_PrintArg(F, L, FMT.all, Pointer, A29);
|
||||||
|
if (A30 /= FIO_NIL) then FIO_PrintArg(F, L, FMT.all, Pointer, A30);
|
||||||
|
if (A31 /= FIO_NIL) then FIO_PrintArg(F, L, FMT.all, Pointer, A31);
|
||||||
|
if (A32 /= FIO_NIL) then FIO_PrintArg(F, L, FMT.all, Pointer, A32);
|
||||||
|
end if; end if; end if; end if; end if; end if; end if; end if;
|
||||||
|
end if; end if; end if; end if; end if; end if; end if; end if;
|
||||||
|
end if; end if; end if; end if; end if; end if; end if; end if;
|
||||||
|
end if; end if; end if; end if; end if; end if; end if; end if;
|
||||||
|
|
||||||
|
FIO_PrintValue(F, L, FMT.all, Pointer, Last => TRUE);
|
||||||
|
|
||||||
|
deallocate(FMT);
|
||||||
|
|
||||||
|
end fprint;
|
||||||
|
|
||||||
|
|
||||||
|
-------------------------------------------
|
||||||
|
-- Formatted output conversion functions --
|
||||||
|
-------------------------------------------
|
||||||
|
|
||||||
|
function fo (Arg: unsigned) return string is
|
||||||
|
constant Argument: unsigned(1 to Arg'length) := Arg;
|
||||||
|
variable Result: string(1 to Arg'length);
|
||||||
|
begin
|
||||||
|
for i in Argument'range loop
|
||||||
|
Result(i) := C_STD_LOGIC_MAP(Argument(i));
|
||||||
|
end loop;
|
||||||
|
return ("U:" & Result);
|
||||||
|
end fo;
|
||||||
|
|
||||||
|
function fo (Arg: signed) return string is
|
||||||
|
constant Argument: signed(1 to Arg'length) := Arg;
|
||||||
|
variable Result: string(1 to Arg'length);
|
||||||
|
begin
|
||||||
|
for i in Argument'range loop
|
||||||
|
Result(i) := C_STD_LOGIC_MAP(Argument(i));
|
||||||
|
end loop;
|
||||||
|
return ("S:" & Result);
|
||||||
|
end fo;
|
||||||
|
|
||||||
|
function fo (Arg: std_logic_vector) return string is
|
||||||
|
constant Argument: std_logic_vector(1 to Arg'length) := Arg;
|
||||||
|
variable Result: string(1 to Arg'length);
|
||||||
|
begin
|
||||||
|
for i in Argument'range loop
|
||||||
|
Result(i) := C_STD_LOGIC_MAP(Argument(i));
|
||||||
|
end loop;
|
||||||
|
return ("V:" & Result);
|
||||||
|
end fo;
|
||||||
|
|
||||||
|
function fo (Arg: std_ulogic_vector) return string is
|
||||||
|
constant Argument: std_ulogic_vector(1 to Arg'length) := Arg;
|
||||||
|
variable Result: string(1 to Arg'length);
|
||||||
|
begin
|
||||||
|
for i in Argument'range loop
|
||||||
|
Result(i) := C_STD_LOGIC_MAP(Argument(i));
|
||||||
|
end loop;
|
||||||
|
return ("V:" & Result);
|
||||||
|
end fo;
|
||||||
|
|
||||||
|
function fo (Arg: bit_vector) return string is
|
||||||
|
constant Argument: bit_vector(1 to Arg'length) := Arg;
|
||||||
|
variable Result: string(1 to Arg'length);
|
||||||
|
begin
|
||||||
|
for i in Argument'range loop
|
||||||
|
Result(i) := C_BIT_MAP(Argument(i));
|
||||||
|
end loop;
|
||||||
|
return ("V:" & Result);
|
||||||
|
end fo;
|
||||||
|
|
||||||
|
function fo (Arg: integer) return string is
|
||||||
|
variable Argument: integer := Arg;
|
||||||
|
variable Result: string(1 to FIO_d_WIDTH) := (others => ' ');
|
||||||
|
variable Sign: character := ' ';
|
||||||
|
begin
|
||||||
|
if (Argument < 0) and (Argument /= integer'low) then
|
||||||
|
Sign := '-';
|
||||||
|
Argument := -Argument;
|
||||||
|
end if;
|
||||||
|
for i in Result'reverse_range loop
|
||||||
|
Result(i) := C_DIGITS_MAP(Argument mod 10);
|
||||||
|
Argument := Argument / 10;
|
||||||
|
exit when (Argument = 0);
|
||||||
|
end loop;
|
||||||
|
return ("I:" & Sign & Result);
|
||||||
|
end fo;
|
||||||
|
|
||||||
|
function fo (Arg: std_ulogic) return string is
|
||||||
|
begin
|
||||||
|
return ("B:" & C_STD_LOGIC_MAP(Arg));
|
||||||
|
end fo;
|
||||||
|
|
||||||
|
function fo (Arg: bit) return string is
|
||||||
|
begin
|
||||||
|
return ("B:" & C_BIT_MAP(Arg));
|
||||||
|
end fo;
|
||||||
|
|
||||||
|
function fo (Arg: boolean) return string is
|
||||||
|
begin
|
||||||
|
if (ARG = TRUE) then
|
||||||
|
return ("L:T");
|
||||||
|
else
|
||||||
|
return ("L:F");
|
||||||
|
end if;
|
||||||
|
end fo;
|
||||||
|
|
||||||
|
function fo (Arg: character) return string is
|
||||||
|
begin
|
||||||
|
return ("C:" & Arg);
|
||||||
|
end fo;
|
||||||
|
|
||||||
|
function fo (Arg: string) return string is
|
||||||
|
begin
|
||||||
|
return Arg;
|
||||||
|
end fo;
|
||||||
|
|
||||||
|
function fo (Arg: time) return string is
|
||||||
|
begin
|
||||||
|
return fo (integer (Arg / 1 ns));
|
||||||
|
end fo;
|
||||||
|
|
||||||
|
end PCK_FIO;
|
||||||
@@ -0,0 +1,72 @@
|
|||||||
|
# $Id: README,v 1.1 2008-08-23 08:20:28 Jens Exp $
|
||||||
|
# $Log: not supported by cvs2svn $
|
||||||
|
# Revision 1.3 1999/04/21 08:08:35 jand
|
||||||
|
# Tested with IEEE.numeric_std
|
||||||
|
# Small patch for Leapfrog
|
||||||
|
#
|
||||||
|
#
|
||||||
|
|
||||||
|
PCK_FIO, Version 1.16
|
||||||
|
Copyright (C) 1995, 1999 Easics NV
|
||||||
|
|
||||||
|
---- PCK_FIO: a VHDL package for C-style formatted file output
|
||||||
|
---- Copyright (C) 1995, 1999 Easics NV
|
||||||
|
----
|
||||||
|
---- This program is free software; you can redistribute it and/or modify
|
||||||
|
---- it under the terms of the GNU General Public License as published by
|
||||||
|
---- the Free Software Foundation; either version 1, or (at your option)
|
||||||
|
---- any later version.
|
||||||
|
----
|
||||||
|
---- This program 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 General Public License for more details.
|
||||||
|
----
|
||||||
|
---- You should have received a copy of the GNU General Public License
|
||||||
|
---- along with this program; if not, write to the Free Software
|
||||||
|
---- Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
|
||||||
|
----
|
||||||
|
---- For suggestions, bug reports, enhancement requests, and info about
|
||||||
|
---- our design services, you can contact us at the following address:
|
||||||
|
---- Easics NV, Interleuvenlaan 86, B-3001 Leuven, Belgium
|
||||||
|
---- tel.: +32 16 395 600 fax : +32 16 395 619
|
||||||
|
---- e-mail: jand@easics.be (Jan Decaluwe)
|
||||||
|
----
|
||||||
|
|
||||||
|
Contents
|
||||||
|
--------
|
||||||
|
|
||||||
|
This distribution contains the following files:
|
||||||
|
|
||||||
|
PCK_FIO.vhd: VHDL source of the PCK_FIO package
|
||||||
|
TB_PCK_FIO.vhd: VHDL source of the testbench for package PCK_FIO
|
||||||
|
PCK_FIO.out.gold: Certified test bench output
|
||||||
|
PCK_FIO.html: Manual for PCK_FIO in html format
|
||||||
|
README: This file
|
||||||
|
|
||||||
|
|
||||||
|
Installation
|
||||||
|
------------
|
||||||
|
|
||||||
|
To install PCK_FIO, define a VHDL library called EASICS_PACKAGES, and
|
||||||
|
analyze the VHDL file PCK_FIO.vhd into this library.
|
||||||
|
|
||||||
|
To install the test bench, analyze TB_PCK_FIO.vhd into the same library.
|
||||||
|
|
||||||
|
If you want to use IEEE.numeric_std instead of IEEE.std_logic_arith, you need
|
||||||
|
to edit the source code of the package and the test bench and replace the
|
||||||
|
package use clause. PCK_FIO works with either of these packages.
|
||||||
|
|
||||||
|
To install the documentation, point your web browser to the file PCK_FIO.html
|
||||||
|
and bookmark it.
|
||||||
|
|
||||||
|
|
||||||
|
Installation check
|
||||||
|
------------------
|
||||||
|
|
||||||
|
After installing the test bench, you should run it. The corresponding VHDL
|
||||||
|
design unit is EASICS_PACKAGES.TBE_PCK_FIO(TB).
|
||||||
|
|
||||||
|
Simulating the test bench should create a file called PCK_FIO.out. This file
|
||||||
|
should be identical to PCK_FIO.out.gold. Any difference indicates a portability
|
||||||
|
issue or a simulator non-compliance or bug.
|
||||||
@@ -0,0 +1,504 @@
|
|||||||
|
---- File: TB_PCK_FIO.vhd
|
||||||
|
----
|
||||||
|
---- TBC_PCK_FIO: a test bench for the PCK_FIO package.
|
||||||
|
---- Copyright (C) 1995, 1999 Easics NV
|
||||||
|
----
|
||||||
|
---- This program is free software; you can redistribute it and/or modify
|
||||||
|
---- it under the terms of the GNU General Public License as published by
|
||||||
|
---- the Free Software Foundation; either version 1, or (at your option)
|
||||||
|
---- any later version.
|
||||||
|
----
|
||||||
|
---- This program 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 General Public License for more details.
|
||||||
|
----
|
||||||
|
---- You should have received a copy of the GNU General Public License
|
||||||
|
---- along with this program; if not, write to the Free Software
|
||||||
|
---- Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
|
||||||
|
----
|
||||||
|
---- For suggestions, bug reports, enhancement requests, and info about
|
||||||
|
---- our design services, you can contact us at the following address:
|
||||||
|
---- Easics NV, Interleuvenlaan 86, B-3001 Leuven, Belgium
|
||||||
|
---- tel.: +32 16 395 600 fax : +32 16 396 619
|
||||||
|
---- e-mail: jand@easics.be (Jan Decaluwe)
|
||||||
|
----
|
||||||
|
----
|
||||||
|
---- $Source: /tmp/cvsroot/VHDL/lib/PCK_FIO-1.16/TB_PCK_FIO.vhd,v $
|
||||||
|
---- $Revision: 1.1 $
|
||||||
|
---- $Log: not supported by cvs2svn $
|
||||||
|
---- Revision 1.7 1999/04/21 08:23:53 jand
|
||||||
|
---- Tested with IEEE.numeric_std
|
||||||
|
---- Small patch for Leapfrog
|
||||||
|
----
|
||||||
|
---- Revision 1.3 1998/09/29 10:09:44 vhdl
|
||||||
|
---- to EASICS_PACKAGES
|
||||||
|
----
|
||||||
|
---- Revision 1.2 1998/09/29 09:17:51 vhdl
|
||||||
|
---- library EASICS_PACKAGES;
|
||||||
|
----
|
||||||
|
---- Revision 1.1 1998/09/29 09:15:44 vhdl
|
||||||
|
---- Initial revision
|
||||||
|
----
|
||||||
|
|
||||||
|
|
||||||
|
library IEEE;
|
||||||
|
use IEEE.std_logic_1164.all;
|
||||||
|
-- signed/unsigned definition: use either std_logic_arith or numeric_std
|
||||||
|
use IEEE.std_logic_arith.all; -- the Synopsys one
|
||||||
|
-- use IEEE.numeric_std.all;
|
||||||
|
|
||||||
|
use STD.TEXTIO.all;
|
||||||
|
|
||||||
|
library EASICS_PACKAGES;
|
||||||
|
use EASICS_PACKAGES.PCK_FIO.all;
|
||||||
|
|
||||||
|
entity TBE_PCK_FIO is
|
||||||
|
|
||||||
|
end TBE_PCK_FIO;
|
||||||
|
|
||||||
|
architecture TB of TBE_PCK_FIO is
|
||||||
|
|
||||||
|
begin
|
||||||
|
|
||||||
|
USAGE: process
|
||||||
|
|
||||||
|
file RESULT: text is out "PCK_FIO.out";
|
||||||
|
variable L: line;
|
||||||
|
variable Pointer: integer;
|
||||||
|
variable BoolTrue: boolean := TRUE;
|
||||||
|
variable BoolFalse: boolean := FALSE;
|
||||||
|
variable IntPos: integer := 5678;
|
||||||
|
variable BigIntPos: integer := 12345678;
|
||||||
|
variable IntNeg: integer := -8765;
|
||||||
|
variable BigIntNeg: integer := -87654321;
|
||||||
|
variable Uns: unsigned(6 downto 0) := unsigned'("1010010");
|
||||||
|
variable Unk: unsigned(6 downto 0) := unsigned'("1X10Z10");
|
||||||
|
variable Std: std_logic_vector(6 downto 0) := std_logic_vector'("0010010");
|
||||||
|
variable SigPos: signed(6 downto 0) := signed'("0010010");
|
||||||
|
variable SigNeg: signed(6 downto 0) := signed'("1010010");
|
||||||
|
variable BitX: std_logic := 'X';
|
||||||
|
variable Bit1: std_logic := '1';
|
||||||
|
variable Bit0: std_logic := '0';
|
||||||
|
|
||||||
|
variable parameter_1: integer := 1234;
|
||||||
|
variable parameter_2: integer := 2345;
|
||||||
|
variable parameter_3: integer := 4567;
|
||||||
|
|
||||||
|
|
||||||
|
begin
|
||||||
|
|
||||||
|
fprint(RESULT, L,
|
||||||
|
"PCK_FIO.out: TESTBENCH OUTPUT FOR PCK_FIO\n" &
|
||||||
|
"-----------------------------------------\n\n" &
|
||||||
|
"This is the result of running the PCK_FIO testbench.\n" &
|
||||||
|
"This file should be compared with PCK_FIO.out.gold, which is\n" &
|
||||||
|
"the reference output. Any difference indicates a portability\n" &
|
||||||
|
"issue or a simulator non-compliance or bug.\n\n"
|
||||||
|
);
|
||||||
|
|
||||||
|
|
||||||
|
fprint(RESULT, L,
|
||||||
|
"\n--------------------\n" &
|
||||||
|
"-- Basic features --\n" &
|
||||||
|
"--------------------\n\n"
|
||||||
|
);
|
||||||
|
|
||||||
|
fprint(RESULT, L,
|
||||||
|
"-- First some auxiliary declarations\n"
|
||||||
|
);
|
||||||
|
|
||||||
|
fprint(RESULT, L,
|
||||||
|
"> file RESULT: text is out ""PCK_FIO.out"";\n" &
|
||||||
|
"> variable L: line;\n" &
|
||||||
|
"> variable BoolTrue: boolean := TRUE;\n" &
|
||||||
|
"> variable BoolFalse: boolean := FALSE;\n" &
|
||||||
|
"> variable IntPos: integer := 5678;\n" &
|
||||||
|
"> variable BigIntPos: integer := 12345678;\n" &
|
||||||
|
"> variable IntNeg: integer := -8765;\n" &
|
||||||
|
"> variable BigIntNeg: integer := -87654321;\n" &
|
||||||
|
"> variable Uns: unsigned(6 downto 0) := unsigned'(""1010010"");\n" &
|
||||||
|
"> variable Unk: unsigned(6 downto 0) := unsigned'(""1X10Z10"");\n" &
|
||||||
|
"> variable Std: std_logic_vector(6 downto 0) := std_logic_vector'(""0010010"");\n" &
|
||||||
|
"> variable SigPos: signed(6 downto 0) := signed'(""0010010"");\n" &
|
||||||
|
"> variable SigNeg: signed(6 downto 0) := signed'(""1010010"");\n" &
|
||||||
|
"> variable BitX: std_logic := 'X';\n" &
|
||||||
|
"> variable Bit1: std_logic := '1';\n" &
|
||||||
|
"> variable Bit0: std_logic := '0';\n"
|
||||||
|
);
|
||||||
|
|
||||||
|
|
||||||
|
fprint(RESULT, L,
|
||||||
|
"\n\n-- fprint call with no arguments\n" &
|
||||||
|
"> fprint(RESULT, L, ""No arguments.\\n);""\n"
|
||||||
|
);
|
||||||
|
fprint(RESULT, L, "No arguments.\n");
|
||||||
|
|
||||||
|
|
||||||
|
fprint(RESULT, L,
|
||||||
|
"\n-- Special characters need to be escaped\n" &
|
||||||
|
"> fprint(RESULT, L, ""Special characters: \\\% \\\\ "" \\n"");\n"
|
||||||
|
);
|
||||||
|
|
||||||
|
fprint(RESULT, L, "Special characters: \% \\ "" \n");
|
||||||
|
|
||||||
|
|
||||||
|
fprint(RESULT, L,
|
||||||
|
"\n-- Various format specifiers interprete the same object differently\n" &
|
||||||
|
"> fprint(RESULT, L, ""Format specifiers: \%r \%d \%b \%q\\n);""\n" &
|
||||||
|
"> fo(Uns), fo(Uns), fo(Uns), fo(Uns)\n" &
|
||||||
|
"> );\n"
|
||||||
|
);
|
||||||
|
|
||||||
|
fprint(RESULT, L, "Format specifiers: %r %d %b %q\n",
|
||||||
|
fo(Uns), fo(Uns), fo(Uns), fo(Uns)
|
||||||
|
);
|
||||||
|
|
||||||
|
fprint(RESULT, L,
|
||||||
|
"\n-- Format string can be shortened by using the iteration specifier\n" &
|
||||||
|
"> fprint(RESULT, L, ""Iteration specifier: \%4{\%r }\\n);""\n" &
|
||||||
|
"> fo(Uns), fo(SigPos), fo(SigNeg), fo(Std)\n" &
|
||||||
|
"> );\n"
|
||||||
|
);
|
||||||
|
|
||||||
|
fprint(RESULT, L, "Iteration specifier: %4{%r }\n",
|
||||||
|
fo(Uns), fo(SigPos), fo(SigNeg), fo(Std)
|
||||||
|
);
|
||||||
|
|
||||||
|
|
||||||
|
fprint(RESULT, L,
|
||||||
|
"\n------------------------------------\n" &
|
||||||
|
"-- Support for bit-oriented types --\n" &
|
||||||
|
"------------------------------------\n"
|
||||||
|
);
|
||||||
|
|
||||||
|
fprint (RESULT, L, "\n-- Reasonable format\n" &
|
||||||
|
"> fprint(RESULT, L, ""Reasonable format: \%9{\%r }\\n"",\n" &
|
||||||
|
"> fo(Std), fo(Uns), fo(SigPos), fo(SigNeg), fo(Unk),\n" &
|
||||||
|
"> fo(Bit1), fo(BitX), fo(BoolTrue), fo(BoolFalse) \n" &
|
||||||
|
"> );\n"
|
||||||
|
);
|
||||||
|
|
||||||
|
|
||||||
|
fprint(RESULT, L, "Reasonable format: %9{%r }\n",
|
||||||
|
fo(Std), fo(Uns), fo(SigPos), fo(SigNeg), fo(Unk),
|
||||||
|
fo(Bit1), fo(BitX), fo(BoolTrue), fo(BoolFalse)
|
||||||
|
);
|
||||||
|
|
||||||
|
fprint (RESULT, L, "\n-- Decimal format\n" &
|
||||||
|
"> fprint(RESULT, L, ""Decimal format: \%7{\%d }\\n"",\n" &
|
||||||
|
"> fo(Std), fo(Uns), fo(SigPos), fo(SigNeg), fo(Unk),\n" &
|
||||||
|
"> fo(Bit1), fo(BitX), fo(BoolTrue), fo(BoolFalse) \n" &
|
||||||
|
"> );\n"
|
||||||
|
);
|
||||||
|
|
||||||
|
|
||||||
|
fprint(RESULT, L, "Decimal format: %9{%d }\n",
|
||||||
|
fo(Std), fo(Uns), fo(SigPos), fo(SigNeg), fo(Unk),
|
||||||
|
fo(Bit1), fo(BitX), fo(BoolTrue), fo(BoolFalse)
|
||||||
|
);
|
||||||
|
|
||||||
|
fprint (RESULT, L, "\n-- Bit format\n" &
|
||||||
|
"> fprint(RESULT, L, ""Bit format: \%7{\%b }\\n"",\n" &
|
||||||
|
"> fo(Std), fo(Uns), fo(SigPos), fo(SigNeg), fo(Unk),\n" &
|
||||||
|
"> fo(Bit1), fo(BitX), fo(BoolTrue), fo(BoolFalse) \n" &
|
||||||
|
"> );\n"
|
||||||
|
);
|
||||||
|
|
||||||
|
|
||||||
|
fprint(RESULT, L, "Bit format: %9{%b }\n",
|
||||||
|
fo(Std), fo(Uns), fo(SigPos), fo(SigNeg), fo(Unk),
|
||||||
|
fo(Bit1), fo(BitX), fo(BoolTrue), fo(BoolFalse)
|
||||||
|
);
|
||||||
|
|
||||||
|
fprint(RESULT, L,
|
||||||
|
"\n\n" &
|
||||||
|
"-- Alignment\n-- Template of the call: (<fs> stands for the format specifier)\n"
|
||||||
|
);
|
||||||
|
|
||||||
|
|
||||||
|
fprint(RESULT, L, "\n" &
|
||||||
|
"> fprint(RESULT, L, ""Bitvectors with <fs>: \%4{<fs>|}\\n"",\n" &
|
||||||
|
"> fo(Std), fo(Uns), fo(SigPos), fo(SigNeg)\n" &
|
||||||
|
|
||||||
|
"> );\n"
|
||||||
|
);
|
||||||
|
|
||||||
|
fprint(RESULT, L,
|
||||||
|
"\n" &
|
||||||
|
"-- Results of the call with various format specifiers\n\n"
|
||||||
|
);
|
||||||
|
|
||||||
|
fprint(RESULT, L, "Bitvectors with \%1r: %4{%1r|} \n",
|
||||||
|
fo(Uns), fo(Std), fo(SigPos), fo(SigNeg)
|
||||||
|
);
|
||||||
|
fprint(RESULT, L, "Bitvectors with \%2r: %4{%2r|} \n",
|
||||||
|
fo(Uns), fo(Std), fo(SigPos), fo(SigNeg)
|
||||||
|
);
|
||||||
|
fprint(RESULT, L, "Bitvectors with \%3r: %4{%3r|} \n",
|
||||||
|
fo(Uns), fo(Std), fo(SigPos), fo(SigNeg)
|
||||||
|
);
|
||||||
|
fprint(RESULT, L, "Bitvectors with \%4r: %4{%4r|} \n",
|
||||||
|
fo(Uns), fo(Std), fo(SigPos), fo(SigNeg)
|
||||||
|
);
|
||||||
|
fprint(RESULT, L, "Bitvectors with \%5r: %4{%5r|} \n",
|
||||||
|
fo(Uns), fo(Std), fo(SigPos), fo(SigNeg)
|
||||||
|
);
|
||||||
|
fprint(RESULT, L, "Bitvectors with \%6r: %4{%6r|} \n",
|
||||||
|
fo(Uns), fo(Std), fo(SigPos), fo(SigNeg)
|
||||||
|
);
|
||||||
|
fprint(RESULT, L, "Bitvectors with \%7r: %4{%7r|} \n",
|
||||||
|
fo(Uns), fo(Std), fo(SigPos), fo(SigNeg)
|
||||||
|
);
|
||||||
|
fprint(RESULT, L, "Bitvectors with \%8r: %4{%8r|} \n",
|
||||||
|
fo(Uns), fo(Std), fo(SigPos), fo(SigNeg)
|
||||||
|
);
|
||||||
|
fprint(RESULT, L, "Bitvectors with \%9r: %4{%9r|} \n",
|
||||||
|
fo(Uns), fo(Std), fo(SigPos), fo(SigNeg)
|
||||||
|
);
|
||||||
|
fprint(RESULT, L, "\n");
|
||||||
|
fprint(RESULT, L, "Bitvectors with \%-1r: %4{%-1r|} \n",
|
||||||
|
fo(Uns), fo(Std), fo(SigPos), fo(SigNeg)
|
||||||
|
);
|
||||||
|
fprint(RESULT, L, "Bitvectors with \%-2r: %4{%-2r|} \n",
|
||||||
|
fo(Uns), fo(Std), fo(SigPos), fo(SigNeg)
|
||||||
|
);
|
||||||
|
fprint(RESULT, L, "Bitvectors with \%-3r: %4{%-3r|} \n",
|
||||||
|
fo(Uns), fo(Std), fo(SigPos), fo(SigNeg)
|
||||||
|
);
|
||||||
|
fprint(RESULT, L, "Bitvectors with \%-4r: %4{%-4r|} \n",
|
||||||
|
fo(Uns), fo(Std), fo(SigPos), fo(SigNeg)
|
||||||
|
);
|
||||||
|
fprint(RESULT, L, "Bitvectors with \%-5r: %4{%-5r|} \n",
|
||||||
|
fo(Uns), fo(Std), fo(SigPos), fo(SigNeg)
|
||||||
|
);
|
||||||
|
fprint(RESULT, L, "Bitvectors with \%-6r: %4{%-6r|} \n",
|
||||||
|
fo(Uns), fo(Std), fo(SigPos), fo(SigNeg)
|
||||||
|
);
|
||||||
|
fprint(RESULT, L, "Bitvectors with \%-7r: %4{%-7r|} \n",
|
||||||
|
fo(Uns), fo(Std), fo(SigPos), fo(SigNeg)
|
||||||
|
);
|
||||||
|
fprint(RESULT, L, "Bitvectors with \%-8r: %4{%-8r|} \n",
|
||||||
|
fo(Uns), fo(Std), fo(SigPos), fo(SigNeg)
|
||||||
|
);
|
||||||
|
fprint(RESULT, L, "Bitvectors with \%-9r: %4{%-9r|} \n",
|
||||||
|
fo(Uns), fo(Std), fo(SigPos), fo(SigNeg)
|
||||||
|
);
|
||||||
|
fprint(RESULT, L, "\n");
|
||||||
|
fprint(RESULT, L, "Bitvectors with \%1d: %4{%1d|} \n",
|
||||||
|
fo(Uns), fo(Std), fo(SigPos), fo(SigNeg)
|
||||||
|
);
|
||||||
|
fprint(RESULT, L, "Bitvectors with \%2d: %4{%2d|} \n",
|
||||||
|
fo(Uns), fo(Std), fo(SigPos), fo(SigNeg)
|
||||||
|
);
|
||||||
|
fprint(RESULT, L, "Bitvectors with \%3d: %4{%3d|} \n",
|
||||||
|
fo(Uns), fo(Std), fo(SigPos), fo(SigNeg)
|
||||||
|
);
|
||||||
|
fprint(RESULT, L, "Bitvectors with \%4d: %4{%4d|} \n",
|
||||||
|
fo(Uns), fo(Std), fo(SigPos), fo(SigNeg)
|
||||||
|
);
|
||||||
|
fprint(RESULT, L, "Bitvectors with \%5d: %4{%5d|} \n",
|
||||||
|
fo(Uns), fo(Std), fo(SigPos), fo(SigNeg)
|
||||||
|
);
|
||||||
|
fprint(RESULT, L, "Bitvectors with \%6d: %4{%6d|} \n",
|
||||||
|
fo(Uns), fo(Std), fo(SigPos), fo(SigNeg)
|
||||||
|
);
|
||||||
|
fprint(RESULT, L, "Bitvectors with \%7d: %4{%7d|} \n",
|
||||||
|
fo(Uns), fo(Std), fo(SigPos), fo(SigNeg)
|
||||||
|
);
|
||||||
|
fprint(RESULT, L, "Bitvectors with \%8d: %4{%8d|} \n",
|
||||||
|
fo(Uns), fo(Std), fo(SigPos), fo(SigNeg)
|
||||||
|
);
|
||||||
|
fprint(RESULT, L, "Bitvectors with \%9d: %4{%9d|} \n",
|
||||||
|
fo(Uns), fo(Std), fo(SigPos), fo(SigNeg)
|
||||||
|
);
|
||||||
|
fprint(RESULT, L, "\n");
|
||||||
|
fprint(RESULT, L, "Bitvectors with \%-1d: %4{%-1d|} \n",
|
||||||
|
fo(Uns), fo(Std), fo(SigPos), fo(SigNeg)
|
||||||
|
);
|
||||||
|
fprint(RESULT, L, "Bitvectors with \%-2d: %4{%-2d|} \n",
|
||||||
|
fo(Uns), fo(Std), fo(SigPos), fo(SigNeg)
|
||||||
|
);
|
||||||
|
fprint(RESULT, L, "Bitvectors with \%-3d: %4{%-3d|} \n",
|
||||||
|
fo(Uns), fo(Std), fo(SigPos), fo(SigNeg)
|
||||||
|
);
|
||||||
|
fprint(RESULT, L, "Bitvectors with \%-4d: %4{%-4d|} \n",
|
||||||
|
fo(Uns), fo(Std), fo(SigPos), fo(SigNeg)
|
||||||
|
);
|
||||||
|
fprint(RESULT, L, "Bitvectors with \%-5d: %4{%-5d|} \n",
|
||||||
|
fo(Uns), fo(Std), fo(SigPos), fo(SigNeg)
|
||||||
|
);
|
||||||
|
fprint(RESULT, L, "Bitvectors with \%-6d: %4{%-6d|} \n",
|
||||||
|
fo(Uns), fo(Std), fo(SigPos), fo(SigNeg)
|
||||||
|
);
|
||||||
|
fprint(RESULT, L, "Bitvectors with \%-7d: %4{%-7d|} \n",
|
||||||
|
fo(Uns), fo(Std), fo(SigPos), fo(SigNeg)
|
||||||
|
);
|
||||||
|
fprint(RESULT, L, "Bitvectors with \%-8d: %4{%-8d|} \n",
|
||||||
|
fo(Uns), fo(Std), fo(SigPos), fo(SigNeg)
|
||||||
|
);
|
||||||
|
fprint(RESULT, L, "Bitvectors with \%-9d: %4{%-9d|} \n",
|
||||||
|
fo(Uns), fo(Std), fo(SigPos), fo(SigNeg)
|
||||||
|
);
|
||||||
|
fprint(RESULT, L, "\n");
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
fprint(RESULT, L,
|
||||||
|
"\n-------------------------------\n" &
|
||||||
|
"-- Support for integer types --\n" &
|
||||||
|
"-------------------------------\n"
|
||||||
|
);
|
||||||
|
|
||||||
|
fprint(RESULT, L,
|
||||||
|
"\n\n" &
|
||||||
|
"-- Template of the call: (<fs> stands for the format specifier)\n"
|
||||||
|
);
|
||||||
|
|
||||||
|
|
||||||
|
fprint(RESULT, L, "\n" &
|
||||||
|
"> fprint(RESULT, L, ""Integers with <fs>: \%4{<fs>|}\\n"",\n" &
|
||||||
|
"> fo(IntPos), fo(IntNeg), fo(BigIntPos), fo(BigIntNeg)\n" &
|
||||||
|
|
||||||
|
"> );\n"
|
||||||
|
);
|
||||||
|
|
||||||
|
fprint(RESULT, L,
|
||||||
|
"\n" &
|
||||||
|
"-- Results of the call with various format specifiers\n\n"
|
||||||
|
);
|
||||||
|
|
||||||
|
|
||||||
|
fprint(RESULT, L, "Integers with \%5d: %4{%5d|} \n",
|
||||||
|
fo(IntPos), fo(IntNeg), fo(BigIntPos), fo(BigIntNeg)
|
||||||
|
);
|
||||||
|
fprint(RESULT, L, "Integers with \%6d: %4{%6d|} \n",
|
||||||
|
fo(IntPos), fo(IntNeg), fo(BigIntPos), fo(BigIntNeg)
|
||||||
|
);
|
||||||
|
fprint(RESULT, L, "Integers with \%7d: %4{%7d|} \n",
|
||||||
|
fo(IntPos), fo(IntNeg), fo(BigIntPos), fo(BigIntNeg)
|
||||||
|
);
|
||||||
|
fprint(RESULT, L, "Integers with \%8d: %4{%8d|} \n",
|
||||||
|
fo(IntPos), fo(IntNeg), fo(BigIntPos), fo(BigIntNeg)
|
||||||
|
);
|
||||||
|
fprint(RESULT, L, "Integers with \%9d: %4{%9d|} \n",
|
||||||
|
fo(IntPos), fo(IntNeg), fo(BigIntPos), fo(BigIntNeg)
|
||||||
|
);
|
||||||
|
fprint(RESULT, L, "Integers with \%10d: %4{%10d|} \n",
|
||||||
|
fo(IntPos), fo(IntNeg), fo(BigIntPos), fo(BigIntNeg)
|
||||||
|
);
|
||||||
|
fprint(RESULT, L, "\n");
|
||||||
|
fprint(RESULT, L, "Integers with \%-5d: %4{%-5d|} \n",
|
||||||
|
fo(IntPos), fo(IntNeg), fo(BigIntPos), fo(BigIntNeg)
|
||||||
|
);
|
||||||
|
fprint(RESULT, L, "Integers with \%-6d: %4{%-6d|} \n",
|
||||||
|
fo(IntPos), fo(IntNeg), fo(BigIntPos), fo(BigIntNeg)
|
||||||
|
);
|
||||||
|
fprint(RESULT, L, "Integers with \%-7d: %4{%-7d|} \n",
|
||||||
|
fo(IntPos), fo(IntNeg), fo(BigIntPos), fo(BigIntNeg)
|
||||||
|
);
|
||||||
|
fprint(RESULT, L, "Integers with \%-8d: %4{%-8d|} \n",
|
||||||
|
fo(IntPos), fo(IntNeg), fo(BigIntPos), fo(BigIntNeg)
|
||||||
|
);
|
||||||
|
fprint(RESULT, L, "Integers with \%-9d: %4{%-9d|} \n",
|
||||||
|
fo(IntPos), fo(IntNeg), fo(BigIntPos), fo(BigIntNeg)
|
||||||
|
);
|
||||||
|
fprint(RESULT, L, "Integers with \%-10d: %4{%-10d|} \n",
|
||||||
|
fo(IntPos), fo(IntNeg), fo(BigIntPos), fo(BigIntNeg)
|
||||||
|
);
|
||||||
|
fprint(RESULT, L, "\n");
|
||||||
|
fprint(RESULT, L, "Integers with \%5r: %4{%5r|} \n",
|
||||||
|
fo(IntPos), fo(IntNeg), fo(BigIntPos), fo(BigIntNeg)
|
||||||
|
);
|
||||||
|
fprint(RESULT, L, "Integers with \%6r: %4{%6r|} \n",
|
||||||
|
fo(IntPos), fo(IntNeg), fo(BigIntPos), fo(BigIntNeg)
|
||||||
|
);
|
||||||
|
fprint(RESULT, L, "Integers with \%7r: %4{%7r|} \n",
|
||||||
|
fo(IntPos), fo(IntNeg), fo(BigIntPos), fo(BigIntNeg)
|
||||||
|
);
|
||||||
|
fprint(RESULT, L, "Integers with \%8r: %4{%8r|} \n",
|
||||||
|
fo(IntPos), fo(IntNeg), fo(BigIntPos), fo(BigIntNeg)
|
||||||
|
);
|
||||||
|
fprint(RESULT, L, "Integers with \%9r: %4{%9r|} \n",
|
||||||
|
fo(IntPos), fo(IntNeg), fo(BigIntPos), fo(BigIntNeg)
|
||||||
|
);
|
||||||
|
fprint(RESULT, L, "Integers with \%10r: %4{%10r|} \n",
|
||||||
|
fo(IntPos), fo(IntNeg), fo(BigIntPos), fo(BigIntNeg)
|
||||||
|
);
|
||||||
|
fprint(RESULT, L, "\n");
|
||||||
|
fprint(RESULT, L, "Integers with \%-5r: %4{%-5r|} \n",
|
||||||
|
fo(IntPos), fo(IntNeg), fo(BigIntPos), fo(BigIntNeg)
|
||||||
|
);
|
||||||
|
fprint(RESULT, L, "Integers with \%-6r: %4{%-6r|} \n",
|
||||||
|
fo(IntPos), fo(IntNeg), fo(BigIntPos), fo(BigIntNeg)
|
||||||
|
);
|
||||||
|
fprint(RESULT, L, "Integers with \%-7r: %4{%-7r|} \n",
|
||||||
|
fo(IntPos), fo(IntNeg), fo(BigIntPos), fo(BigIntNeg)
|
||||||
|
);
|
||||||
|
fprint(RESULT, L, "Integers with \%-8r: %4{%-8r|} \n",
|
||||||
|
fo(IntPos), fo(IntNeg), fo(BigIntPos), fo(BigIntNeg)
|
||||||
|
);
|
||||||
|
fprint(RESULT, L, "Integers with \%-9r: %4{%-9r|} \n",
|
||||||
|
fo(IntPos), fo(IntNeg), fo(BigIntPos), fo(BigIntNeg)
|
||||||
|
);
|
||||||
|
fprint(RESULT, L, "Integers with \%-10r: %4{%-10r|} \n",
|
||||||
|
fo(IntPos), fo(IntNeg), fo(BigIntPos), fo(BigIntNeg)
|
||||||
|
);
|
||||||
|
fprint(RESULT, L, "\n");
|
||||||
|
|
||||||
|
|
||||||
|
fprint(RESULT, L,
|
||||||
|
"\n----------------------\n" &
|
||||||
|
"-- Support for time --\n" &
|
||||||
|
"----------------------\n"
|
||||||
|
);
|
||||||
|
|
||||||
|
fprint (RESULT, L, "-- For portability reasons, time is converted \n" &
|
||||||
|
"-- into an integer value (of nanoseconds)\n"
|
||||||
|
);
|
||||||
|
fprint (RESULT, L, "> wait for 648 ns\n");
|
||||||
|
fprint (RESULT, L, "> fprint (RESULT, L, ""The time is now \%d ns\\n"", fo(now));\n");
|
||||||
|
|
||||||
|
wait for 648 ns;
|
||||||
|
|
||||||
|
fprint (RESULT, L, "The time is now %d ns\n", fo(now));
|
||||||
|
|
||||||
|
|
||||||
|
fprint(RESULT, L,
|
||||||
|
"\n----------------------------------------\n" &
|
||||||
|
"-- Erroneous calls and error messages --\n" &
|
||||||
|
"----------------------------------------\n"
|
||||||
|
);
|
||||||
|
|
||||||
|
fprint(RESULT, L, "\n-- Less arguments than formats specifiers\n" &
|
||||||
|
"> fprint(RESULT, L, ""\%d \%d \%d \%d \\n"", fo(Uns), fo(Std));\n"
|
||||||
|
);
|
||||||
|
|
||||||
|
fprint(RESULT, L, "%d %d %d %d \n", fo(Uns), fo(Std));
|
||||||
|
|
||||||
|
fprint(RESULT, L, "\n");
|
||||||
|
|
||||||
|
fprint(RESULT, L, "-- Unsupported format specifier\n" &
|
||||||
|
"> fprint(RESULT, L, ""\%r \%v \%r \%r\\n"", " &
|
||||||
|
"fo(Uns), fo(Std), fo(Uns), fo(Std));\n"
|
||||||
|
);
|
||||||
|
|
||||||
|
fprint(RESULT, L, "%r %v %r %r\n", fo(Uns), fo(Std), fo(Uns), fo(Std));
|
||||||
|
|
||||||
|
fprint(RESULT, L, "\n");
|
||||||
|
|
||||||
|
fprint(RESULT, L,
|
||||||
|
"\n----------------------------------------\n" &
|
||||||
|
"-- Things you wouldn't expect to work --\n" &
|
||||||
|
"----------------------------------------\n"
|
||||||
|
);
|
||||||
|
|
||||||
|
fprint(RESULT, L, "\n-- Nested iteration\n");
|
||||||
|
fprint(RESULT, L, "> fprint(RESULT, L, ""\%3{<<\%3{_END_}>>}\\n"");\n");
|
||||||
|
fprint(RESULT, L, "%3{<<%3{_END_}>>}\n");
|
||||||
|
|
||||||
|
wait;
|
||||||
|
|
||||||
|
end process USAGE;
|
||||||
|
|
||||||
|
end TB;
|
||||||
@@ -0,0 +1,86 @@
|
|||||||
|
---- $Id: CHANGES,v 1.1 2008-08-23 08:20:28 Jens Exp $
|
||||||
|
----
|
||||||
|
---- PCK_FIO: a VHDL package for C-style formatted file output
|
||||||
|
---- Copyright (C) 1995, 2001 Easics NV
|
||||||
|
----
|
||||||
|
---- This library 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 2.1 of the License, or (at your option) any later version.
|
||||||
|
----
|
||||||
|
---- This library 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 this library; if not, write to the Free Software
|
||||||
|
---- Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
|
||||||
|
----
|
||||||
|
---- For suggestions, bug reports, enhancement requests, and info about
|
||||||
|
---- our design services, you can contact us at the following address:
|
||||||
|
---- http://www.easics.com
|
||||||
|
---- Easics NV, Interleuvenlaan 86, B-3001 Leuven, Belgium
|
||||||
|
---- tel.: +32 16 395 600 fax : +32 16 395 619
|
||||||
|
---- e-mail: jand@easics.be (Jan Decaluwe)
|
||||||
|
----
|
||||||
|
|
||||||
|
|
||||||
|
Changes from version 1.16 to version 2002.07
|
||||||
|
============================================
|
||||||
|
|
||||||
|
PCK_FIO is now distributed under the GNU Lesser General Public Licencse
|
||||||
|
instead of the ordinary GPL, to better reflect intended usage.
|
||||||
|
|
||||||
|
Cosmetic changes in source code to correct some typos in the testbench output.
|
||||||
|
A new testbench is also supplied.
|
||||||
|
|
||||||
|
The package now uses IEEE.numeric_std as default.
|
||||||
|
|
||||||
|
URL http://www.easics.com has been made part of address.
|
||||||
|
|
||||||
|
Changed syntax in the PCK_FIO package and its testbench to support VHDL-1993.
|
||||||
|
Because of backwards-incompatibility, it has been necessary to supply
|
||||||
|
different sets of files for 1987 and 1993.
|
||||||
|
|
||||||
|
Split the packages into a separate file for the header and a
|
||||||
|
separate file for the body (in compliance with Easics' guidelines).
|
||||||
|
|
||||||
|
These changes resulted in the files:
|
||||||
|
|
||||||
|
Files for VHDL-1993:
|
||||||
|
--------------------
|
||||||
|
PCK_FIO_1993.vhd : the source code of the header file for the package
|
||||||
|
PCK_FIO_1993_BODY.vhd: the source code of the body of the package
|
||||||
|
TB_PCK_FIO_1993.vhd: the testbench for the package
|
||||||
|
|
||||||
|
Files for VHDL-1987:
|
||||||
|
--------------------
|
||||||
|
PCK_FIO_1987.vhd: the source code of the header file for the package
|
||||||
|
PCK_FIO_1987_BODY.vhd: the source code of the body of the package
|
||||||
|
TB_PCK_FIO_1987.vhd: the testbench for the package
|
||||||
|
|
||||||
|
Updated README and PCK_FIO.html to support these changes.
|
||||||
|
|
||||||
|
Adapted package files to support NUL termination of strings.
|
||||||
|
fo(Arg: string) now prints the string until the first NUL.
|
||||||
|
Several examples of its use are demonstrated in the supplied testbenches.
|
||||||
|
|
||||||
|
Made cosmetic changes to code to improve readability.
|
||||||
|
|
||||||
|
Acknowledgment
|
||||||
|
--------------
|
||||||
|
These changes have been implemented by Peter Geens.
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
@@ -0,0 +1,339 @@
|
|||||||
|
<!doctype html public "-//w3c//dtd html 4.0 transitional//en">
|
||||||
|
<html>
|
||||||
|
<head>
|
||||||
|
<meta http-equiv="Content-Type" content="text/html; charset=iso-8859-1">
|
||||||
|
<meta name="GENERATOR" content="Mozilla/4.76 [en] (X11; U; Linux 2.4.13 i686) [Netscape]">
|
||||||
|
<title>VHDL package for formatted file output</title>
|
||||||
|
<!-- $Id: PCK_FIO.html,v 1.1 2008-08-23 08:20:28 Jens Exp $ -->
|
||||||
|
</head>
|
||||||
|
<body text="#000000" bgcolor="#FFFFFF" link="#0000EE" vlink="#551A8B" alink="#FF0000">
|
||||||
|
|
||||||
|
<hr SIZE=1 NOSHADE WIDTH="100%">
|
||||||
|
<h1>
|
||||||
|
<a NAME="PCK_FIO_name_0"></a>Name</h1>
|
||||||
|
<b>PCK_FIO</b> - VHDL package for formatted file output
|
||||||
|
<p>
|
||||||
|
<hr SIZE=1 NOSHADE WIDTH="100%">
|
||||||
|
<h1>
|
||||||
|
Contents</h1>
|
||||||
|
<a href="#PCK_FIO_usage_0">Usage</a>
|
||||||
|
<br><a href="#PCK_FIO_file_0">The file output function 'fo'</a>
|
||||||
|
<br><a href="#PCK_FIO_format_0">Format specifiers</a>
|
||||||
|
<br><a href="#PCK_FIO_special_0">Special characters</a>
|
||||||
|
<br><a href="#PCK_FIO_things_0">Things to watch out for</a>
|
||||||
|
<br><a href="#PCK_FIO_methodology_0">Methodology notes</a>
|
||||||
|
<br><a href="#PCK_FIO_parametrization_0">Parametrization</a>
|
||||||
|
<br><a href="#PCK_FIO_test_0">Test bench</a>
|
||||||
|
<br><a href="#PCK_FIO_limitations_0">Known limitations and problems</a>
|
||||||
|
<br><a href="#PCK_FIO_author_0">Author</a>
|
||||||
|
<p>
|
||||||
|
<hr SIZE=1 NOSHADE WIDTH="100%">
|
||||||
|
<h1>
|
||||||
|
<a NAME="PCK_FIO_usage_0"></a>Usage</h1>
|
||||||
|
PCK_FIO is a VHDL package that defines <tt>fprint, </tt>a function
|
||||||
|
for formatted file output.
|
||||||
|
<p>After installing the package you can call <tt>fprint</tt> as follows:
|
||||||
|
<pre> fprint(F, L, Format, fo(Expr_1), fo(Expr_2), ... fo(Expr_n));</pre>
|
||||||
|
where F is the filehandle and L is the line variable.
|
||||||
|
<p>The argument Format is the format string, which consists of ``normal''
|
||||||
|
substrings which are copied verbatim, and format specifiers, starting with
|
||||||
|
<tt>'%'</tt>.
|
||||||
|
A typical format string looks as follows:
|
||||||
|
<pre> "Arg1 = %6r, Arg2 = %10d, Arg3 = %-5r\n"</pre>
|
||||||
|
The remaining arguments are the expressions whose results you want to write
|
||||||
|
to the file, embedded in <tt>fo</tt> function calls. There can be 0 to
|
||||||
|
32 of such arguments. The expressions can be of any type for which an <tt>fo</tt>
|
||||||
|
function exists. String expressions can also be called directly.
|
||||||
|
<p>
|
||||||
|
<hr SIZE=1 NOSHADE WIDTH="100%">
|
||||||
|
<h1>
|
||||||
|
<a NAME="PCK_FIO_file_0"></a>The file output function <tt>'fo'</tt></h1>
|
||||||
|
The <tt>fo</tt> (<u>f</u>ile <u>o</u>utput) functions do the trick. They
|
||||||
|
return a tagged string representation that is meaningful to format specifiers.
|
||||||
|
Here are some examples:
|
||||||
|
<pre> fo (signed'("1100")) returns "S:1100"
|
||||||
|
fo (unsigned'("1100")) returns "U:1100"
|
||||||
|
fo (TRUE) returns "L:T"
|
||||||
|
fo (127) returns "I:127"</pre>
|
||||||
|
The internal behavior of <tt>fo</tt> is irrelevant to the typical user.
|
||||||
|
<br>
|
||||||
|
<pre>The <tt>fo</tt> function is currently overloaded as follows:</pre>
|
||||||
|
|
||||||
|
<pre> function fo (Arg: unsigned) return string;
|
||||||
|
function fo (Arg: signed) return string;
|
||||||
|
function fo (Arg: std_logic_vector) return string;
|
||||||
|
function fo (Arg: std_ulogic_vector) return string;
|
||||||
|
function fo (Arg: bit_vector) return string;
|
||||||
|
function fo (Arg: integer) return string;
|
||||||
|
function fo (Arg: std_ulogic) return string;
|
||||||
|
function fo (Arg: bit) return string;
|
||||||
|
function fo (Arg: boolean) return string;
|
||||||
|
function fo (Arg: character) return string;
|
||||||
|
function fo (Arg: string) return string;
|
||||||
|
function fo (Arg: time) return string;</pre>
|
||||||
|
|
||||||
|
<p><br>To support null-terminated strings, the function <tt>fo</tt>(Arg:
|
||||||
|
string) processes <tt>Arg</tt> up to the first <tt>NUL</tt> character,
|
||||||
|
if any. If you want the whole string to be outputted you can just enter
|
||||||
|
the string as a direct argument in <tt>fprint</tt>. See also the
|
||||||
|
examples in the testbench.
|
||||||
|
<pre>
|
||||||
|
<hr SIZE=1 NOSHADE WIDTH="100%"></pre>
|
||||||
|
|
||||||
|
<h1>
|
||||||
|
<a NAME="PCK_FIO_format_0"></a>Format specifiers</h1>
|
||||||
|
The general format of a format specifier is:
|
||||||
|
<pre> %[-][n]c</pre>
|
||||||
|
The optional <b>-</b> sign specifies left justified output; default is
|
||||||
|
right justified.
|
||||||
|
<p>The optional number <b>n</b> specifies a field-width. If it is not specified,
|
||||||
|
<tt>fprint</tt>
|
||||||
|
does something reasonable.
|
||||||
|
<p><b>c</b> is the conversion specifier. Currently the following conversion
|
||||||
|
specifiers are supported:
|
||||||
|
<dl COMPACT>
|
||||||
|
<dt>
|
||||||
|
<a NAME="PCK_FIO_r_0"></a><b>r</b></dt>
|
||||||
|
|
||||||
|
<dd>
|
||||||
|
reasonable output format (inspired by Synopsys VSS)</dd>
|
||||||
|
|
||||||
|
<dl COMPACT>Prints the ``most reasonable'' representation e.g. hex for
|
||||||
|
unsigned, signed and other bit-like vectors (not preferred for integers)</dl>
|
||||||
|
|
||||||
|
<dt>
|
||||||
|
<a NAME="PCK_FIO_b_0"></a><b>b</b></dt>
|
||||||
|
|
||||||
|
<dd>
|
||||||
|
bit-oriented output</dd>
|
||||||
|
|
||||||
|
<dt>
|
||||||
|
<a NAME="PCK_FIO_d_0"></a><b>d</b></dt>
|
||||||
|
|
||||||
|
<dd>
|
||||||
|
decimal output</dd>
|
||||||
|
|
||||||
|
<dt>
|
||||||
|
<a NAME="PCK_FIO_s_0"></a><b>s</b></dt>
|
||||||
|
|
||||||
|
<dd>
|
||||||
|
string output (e.g. in combination with 'IMAGE for enum types)</dd>
|
||||||
|
|
||||||
|
<dt>
|
||||||
|
<a NAME="PCK_FIO_q_0"></a><b>q</b></dt>
|
||||||
|
|
||||||
|
<dd>
|
||||||
|
``qualified'' string output (shows internal representation from <tt>fo</tt>)</dd>
|
||||||
|
|
||||||
|
<dt>
|
||||||
|
<a NAME="PCK_FIO__0"></a><b>{}</b></dt>
|
||||||
|
|
||||||
|
<dd>
|
||||||
|
Iteration operator, used as follows:</dd>
|
||||||
|
|
||||||
|
<dd>
|
||||||
|
<tt>%n{<format-string>}</tt></dd>
|
||||||
|
|
||||||
|
<br>In this case, <b>n</b> is the iteration count and is mandatory. Iteration
|
||||||
|
can be nested.</dl>
|
||||||
|
|
||||||
|
<hr SIZE=1 NOSHADE WIDTH="100%">
|
||||||
|
<h1>
|
||||||
|
<a NAME="PCK_FIO_special_0"></a>Special characters</h1>
|
||||||
|
To print a double quote, use <tt>'""'</tt> in the format string (VHDL
|
||||||
|
convention). To print the special characters, <tt>'\'</tt>, and <tt>'%'</tt>,
|
||||||
|
escape them with <tt>'\'</tt>. To prevent <tt>'{'</tt> and <tt>'}'</tt>
|
||||||
|
from being interpreted as opening and closing brackets in iteration strings,
|
||||||
|
escape them with <tt>'\'</tt>.
|
||||||
|
<p>A newline is specified in the format string by <tt>'\n'</tt>.
|
||||||
|
<p>
|
||||||
|
<hr SIZE=1 NOSHADE WIDTH="100%">
|
||||||
|
<h1>
|
||||||
|
<a NAME="PCK_FIO_things_0"></a>Things to notice</h1>
|
||||||
|
The fprint function expands into VHDL <tt>write</tt> and <tt>writeline</tt>
|
||||||
|
commands. As in plain VHDL, nothing will be written to the output file
|
||||||
|
until a <tt>writeline</tt> is given. Therefore, don't forget to include
|
||||||
|
<tt>'\n'</tt>
|
||||||
|
commands in the format string, or it ``will not work''.
|
||||||
|
<p>The preferred format specifier for integers is, naturally, <b>%d</b>.
|
||||||
|
This calls the VHDL <tt>write</tt> for integers. If you specify a field
|
||||||
|
width that is too small, the field will automatically be expanded. If you
|
||||||
|
use <b>%r</b> for integers, the field is not expanded automatically, which
|
||||||
|
means that some digits are simply thrown away. This may sometimes be useful
|
||||||
|
but it is also dangerous. Look at the test bench output for differences
|
||||||
|
between <b>%d</b> and <b>%r</b> output.
|
||||||
|
<p>When using the <b>%d</b> format specifier, the VHDL constraints for
|
||||||
|
the allowed integer range apply.
|
||||||
|
<p>In VHDL, signed/unsigned types have been standardized only relatively
|
||||||
|
recently, in the package <tt>IEEE.numeric_std</tt>. The lack of a standard
|
||||||
|
has caused (and is causing) portability issues. The most popular non-standard
|
||||||
|
package that defines signed/unsigned is <tt>IEEE.std_logic_arith</tt> from
|
||||||
|
Synopsys. PCK_FIO works with both packages, but refers to the standard
|
||||||
|
package <tt>IEEE.numeric_std</tt> by default. To use <tt>IEEE.std_logic_arith</tt>
|
||||||
|
instead, replace the reference to <tt>IEEE.numeric_std</tt> in the source
|
||||||
|
code. This needs to be done consistently in a design database (e.g.
|
||||||
|
in the PCK_FIO test bench as well).
|
||||||
|
<p>
|
||||||
|
<hr SIZE=1 NOSHADE WIDTH="100%">
|
||||||
|
<h1>
|
||||||
|
<a NAME="PCK_FIO_methodology_0"></a>Methodology notes</h1>
|
||||||
|
The obvious application for <tt>fprint</tt> is in test benches, to produce
|
||||||
|
output files that trace the simulation behavior.
|
||||||
|
<p>Another interesting application for <tt>fprint</tt> is to produce info,
|
||||||
|
warning and error messages in your models. As it can take arguments, <tt>fprint</tt>
|
||||||
|
is much better suited for this task than VHDL's <tt>assert</tt> or <tt>report</tt>
|
||||||
|
statements. Actually <tt>fprint</tt> produces its own (few) warning messages.
|
||||||
|
<p>An advanced usage is the generation of test vectors in a specific format.
|
||||||
|
Instead of using the <tt>fo </tt>functions, you can write your own set
|
||||||
|
of functions that return the symbols of a specific test format in a way
|
||||||
|
that is understandable to the <tt>fprint</tt> format specifiers. As an
|
||||||
|
example, when a high output value should be represented using the symbol
|
||||||
|
'H' it suffices to write a conversion function that returns "B:H" and call
|
||||||
|
it in combination with the <b>%b</b> format specifier.
|
||||||
|
<p>
|
||||||
|
<hr SIZE=1 NOSHADE WIDTH="100%">
|
||||||
|
<h1>
|
||||||
|
<a NAME="PCK_FIO_parametrization_0"></a>Parametrization</h1>
|
||||||
|
Prefix and postfix strings for bit-oriented and hex-oriented output are
|
||||||
|
parameterizable in the packages to accommodate different output styles.
|
||||||
|
The settings in the distribution are such that hex output is indicated
|
||||||
|
by the prefix '0x', while bit output prefix and postfix are empty
|
||||||
|
strings.
|
||||||
|
<p>You can adapt the output style by modifying the following constants
|
||||||
|
in the package header:
|
||||||
|
<p> <tt> -- prefix string for hex output</tt>
|
||||||
|
<br><tt> -- VHDL style: "X"""</tt>
|
||||||
|
<br><tt> -- Verilog style: "h'"</tt>
|
||||||
|
<br><tt> -- C style: "0x"</tt>
|
||||||
|
<br><tt> constant FIO_h_PRE: string := "0x";</tt>
|
||||||
|
<p><tt> -- postfix string for hex output</tt>
|
||||||
|
<br><tt> -- VHDL style: """"</tt>
|
||||||
|
<br><tt> constant FIO_h_POST: string := "";</tt>
|
||||||
|
<p><tt> -- prefix string for bit vector output</tt>
|
||||||
|
<br><tt> -- VHDL style: "B"""</tt>
|
||||||
|
<br><tt> -- Verilog style: "b'"</tt>
|
||||||
|
<br><tt> constant FIO_bv_PRE: string := "";</tt>
|
||||||
|
<p><tt> -- postfix string for bit vector output</tt>
|
||||||
|
<br><tt> -- VHDL style: """"</tt>
|
||||||
|
<br><tt> constant FIO_bv_POST: string := "";</tt>
|
||||||
|
<p><tt> -- prefix string for bit output</tt>
|
||||||
|
<br><tt> -- VHDL style: "'"</tt>
|
||||||
|
<br><tt> -- Verilog style: "b'"</tt>
|
||||||
|
<br><tt> constant FIO_b_PRE: string := "";</tt>
|
||||||
|
<p><tt> -- postfix string for bit output</tt>
|
||||||
|
<br><tt> -- VHDL style: "'"</tt>
|
||||||
|
<br><tt> constant FIO_b_POST: string := "";</tt>
|
||||||
|
<p>
|
||||||
|
<hr SIZE=1 NOSHADE WIDTH="100%">
|
||||||
|
<h1>
|
||||||
|
<a NAME="PCK_FIO_test_0"></a>Test bench</h1>
|
||||||
|
Included in the distribution are the files <tt>TB_PCK_FIO_1987.vhd and
|
||||||
|
TB_PCK_FIO_1993</tt> with a test bench,depending on the standard you're
|
||||||
|
running, for the PCK_FIO package. The file <tt>PCK_FIO.out.gold </tt>contains
|
||||||
|
the expected output. If you run the test bench it should produce the file
|
||||||
|
<tt>PCK_FIO.out</tt>
|
||||||
|
that should be identical to <tt>PCK_FIO.out.gold</tt>. The source files
|
||||||
|
should be analyzed in a VHDL library <tt>EASICS_PACKAGES</tt>.
|
||||||
|
<p>A good way to understand <tt>fprint</tt> is to inspect the test bench
|
||||||
|
and what it produces.
|
||||||
|
<p>
|
||||||
|
<hr SIZE=1 NOSHADE WIDTH="100%">
|
||||||
|
<h1>
|
||||||
|
<a NAME="PCK_FIO_limitations_0"></a>Known limitations and problems</h1>
|
||||||
|
This VHDL package is an implementation of a flexible concept. It is likely
|
||||||
|
to be extended and modified in the future. Backward compatibility is not
|
||||||
|
guaranteed. Therefore, it is not recommended to give this package the status
|
||||||
|
of a company wide standard package (or even worse, a VHDL standard package).
|
||||||
|
Rather, it should be linked with a particular project (and it can be regarded
|
||||||
|
as a standard package within that project).
|
||||||
|
<p>PCK_FIO is available in either standard VHDL Std1076-1987 or standard
|
||||||
|
VHDL Std1076-1993. Nevertheless, some simulators/versions have problems
|
||||||
|
with the package. The following is an overview of currently known issues:
|
||||||
|
<br>
|
||||||
|
<center><table BORDER COLS=2 WIDTH="80%" NOSAVE >
|
||||||
|
<caption>PCK_FIO_1987 and various simulators/versions</caption>
|
||||||
|
|
||||||
|
<tr>
|
||||||
|
<th>Simulator</th>
|
||||||
|
|
||||||
|
<th>PCK_FIO_1987</th>
|
||||||
|
</tr>
|
||||||
|
|
||||||
|
<tr>
|
||||||
|
<td>Synopsys VSS 3.5 and earlier</td>
|
||||||
|
|
||||||
|
<td>Incorrect (all zero) output in compiled mode</td>
|
||||||
|
</tr>
|
||||||
|
|
||||||
|
<tr>
|
||||||
|
<td>Synopsys VSS 97.01</td>
|
||||||
|
|
||||||
|
<td>OK</td>
|
||||||
|
</tr>
|
||||||
|
|
||||||
|
<tr>
|
||||||
|
<td>Synopsys VSS/Scirocco 2000.02</td>
|
||||||
|
|
||||||
|
<td>Incorrect output in compiled mode, interpreted mode works</td>
|
||||||
|
</tr>
|
||||||
|
|
||||||
|
<tr>
|
||||||
|
<td>Mentor quickhdl</td>
|
||||||
|
|
||||||
|
<td>OK</td>
|
||||||
|
</tr>
|
||||||
|
|
||||||
|
<tr NOSAVE>
|
||||||
|
<td NOSAVE>Modeltech modelsim</td>
|
||||||
|
|
||||||
|
<td>OK</td>
|
||||||
|
</tr>
|
||||||
|
|
||||||
|
<tr>
|
||||||
|
<td>Cadence Leapfrog</td>
|
||||||
|
|
||||||
|
<td>Should work with 4.4.1
|
||||||
|
<br>Mysterious problems have been reported - please run the test bench
|
||||||
|
and report problems</td>
|
||||||
|
</tr>
|
||||||
|
</table></center>
|
||||||
|
|
||||||
|
<br>
|
||||||
|
<center><table BORDER COLS=2 WIDTH="80%" NOSAVE >
|
||||||
|
<caption>PCK_FIO_1993 and various simulators/versions</caption>
|
||||||
|
|
||||||
|
<tr NOSAVE>
|
||||||
|
<th NOSAVE>Simulator</th>
|
||||||
|
|
||||||
|
<th NOSAVE>PCK_FIO_1993</th>
|
||||||
|
</tr>
|
||||||
|
|
||||||
|
<tr>
|
||||||
|
<td>Synopsys VSS/Scirocco 2000.02</td>
|
||||||
|
|
||||||
|
<td>Compile errors due to improper handling of files by Synopsys</td>
|
||||||
|
</tr>
|
||||||
|
|
||||||
|
<tr>
|
||||||
|
<td>Synopsys VSS/Scirocco 2000.06</td>
|
||||||
|
|
||||||
|
<td>works fine</td>
|
||||||
|
</tr>
|
||||||
|
|
||||||
|
<tr>
|
||||||
|
<td>Modeltech modelsim 5.4c and higher</td>
|
||||||
|
|
||||||
|
<td>OK</td>
|
||||||
|
</tr>
|
||||||
|
</table></center>
|
||||||
|
|
||||||
|
<p>Although the package name suggests file IO, it only does file output.
|
||||||
|
<p>
|
||||||
|
<hr SIZE=1 NOSHADE WIDTH="100%">
|
||||||
|
<h1>
|
||||||
|
<a NAME="PCK_FIO_author_0"></a>Author</h1>
|
||||||
|
<a href="mailto:jand@easics.be">Jan Decaluwe</a>
|
||||||
|
<p>
|
||||||
|
<hr SIZE=1 NOSHADE WIDTH="100%">
|
||||||
|
</body>
|
||||||
|
</html>
|
||||||
Binary file not shown.
@@ -0,0 +1,105 @@
|
|||||||
|
---- $Id: PCK_FIO_1987.vhd,v 1.1 2008-08-23 08:20:28 Jens Exp $
|
||||||
|
----
|
||||||
|
---- PCK_FIO: a VHDL package for C-style formatted file output
|
||||||
|
---- Copyright (C) 1995, 2001 Easics NV
|
||||||
|
----
|
||||||
|
---- This library 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 2.1 of the License, or (at your option) any later version.
|
||||||
|
----
|
||||||
|
---- This library 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 this library; if not, write to the Free Software
|
||||||
|
---- Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
|
||||||
|
----
|
||||||
|
---- For suggestions, bug reports, enhancement requests, and info about
|
||||||
|
---- our design services, you can contact us at the following address:
|
||||||
|
---- http://www.easics.com
|
||||||
|
---- Easics NV, Interleuvenlaan 86, B-3001 Leuven, Belgium
|
||||||
|
---- tel.: +32 16 395 600 fax : +32 16 395 619
|
||||||
|
---- e-mail: jand@easics.be (Jan Decaluwe)
|
||||||
|
----
|
||||||
|
|
||||||
|
use STD.TEXTIO.all;
|
||||||
|
|
||||||
|
library IEEE;
|
||||||
|
use IEEE.std_logic_1164.all;
|
||||||
|
-- signed/unsigned definition: use either std_logic_arith or numeric_std
|
||||||
|
-- use IEEE.std_logic_arith.all; -- the Synopsys one
|
||||||
|
use IEEE.numeric_std.all;
|
||||||
|
|
||||||
|
package PCK_FIO is
|
||||||
|
|
||||||
|
-- prefix string for hex output
|
||||||
|
-- VHDL style: "X"""
|
||||||
|
-- Verilog style: "h'"
|
||||||
|
-- C style: "0x"
|
||||||
|
constant FIO_h_PRE: string := "0x";
|
||||||
|
|
||||||
|
-- postfix string for hex output
|
||||||
|
-- VHDL style: """"
|
||||||
|
constant FIO_h_POST: string := "";
|
||||||
|
|
||||||
|
-- prefix string for bit vector output
|
||||||
|
-- VHDL style: "B"""
|
||||||
|
-- Verilog style: "b'"
|
||||||
|
constant FIO_bv_PRE: string := "";
|
||||||
|
|
||||||
|
-- postfix string for bit vector output
|
||||||
|
-- VHDL style: """"
|
||||||
|
constant FIO_bv_POST: string := "";
|
||||||
|
|
||||||
|
-- prefix string for bit output
|
||||||
|
-- VHDL style: "'"
|
||||||
|
-- Verilog style: "b'"
|
||||||
|
constant FIO_b_PRE: string := "";
|
||||||
|
|
||||||
|
-- postfix string for bit output
|
||||||
|
-- VHDL style: "'"
|
||||||
|
constant FIO_b_POST: string := "";
|
||||||
|
|
||||||
|
-- digit width for the string representation of integers
|
||||||
|
constant FIO_d_WIDTH: integer := 10;
|
||||||
|
|
||||||
|
-- bit width for the string representation of integers
|
||||||
|
constant FIO_b_WIDTH: integer := 32;
|
||||||
|
|
||||||
|
-- definition of the NIL string (default value for fprint arguments)
|
||||||
|
-- fprint stops consuming arguments at the first NIL argument
|
||||||
|
constant FIO_NIL: string := "\";
|
||||||
|
|
||||||
|
|
||||||
|
procedure fprint
|
||||||
|
(F: out text;
|
||||||
|
L: inout line;
|
||||||
|
Format: in string;
|
||||||
|
A1 , A2 , A3 , A4 , A5 , A6 , A7 , A8 : in string := FIO_NIL;
|
||||||
|
A9 , A10, A11, A12, A13, A14, A15, A16: in string := FIO_NIL;
|
||||||
|
A17, A18, A19, A20, A21, A22, A23, A24: in string := FIO_NIL;
|
||||||
|
A25, A26, A27, A28, A29, A30, A31, A32: in string := FIO_NIL
|
||||||
|
);
|
||||||
|
|
||||||
|
function fo (Arg: unsigned) return string;
|
||||||
|
function fo (Arg: signed) return string;
|
||||||
|
function fo (Arg: std_logic_vector) return string;
|
||||||
|
function fo (Arg: std_ulogic_vector) return string;
|
||||||
|
function fo (Arg: bit_vector) return string;
|
||||||
|
function fo (Arg: integer) return string;
|
||||||
|
function fo (Arg: std_ulogic) return string;
|
||||||
|
function fo (Arg: bit) return string;
|
||||||
|
function fo (Arg: boolean) return string;
|
||||||
|
function fo (Arg: character) return string;
|
||||||
|
function fo (Arg: string) return string;
|
||||||
|
function fo (Arg: time) return string;
|
||||||
|
|
||||||
|
procedure FIO_FormatExpand (FMT: inout line;
|
||||||
|
Format: in string;
|
||||||
|
StartPointer: in positive);
|
||||||
|
|
||||||
|
end PCK_FIO;
|
||||||
|
|
||||||
@@ -0,0 +1,821 @@
|
|||||||
|
---- $Id: PCK_FIO_1987_BODY.vhd,v 1.1 2008-08-23 08:20:28 Jens Exp $
|
||||||
|
----
|
||||||
|
---- PCK_FIO: a VHDL package for C-style formatted file output
|
||||||
|
---- Copyright (C) 1995, 2001 Easics NV
|
||||||
|
----
|
||||||
|
---- This library 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 2.1 of the License, or (at your option) any later version.
|
||||||
|
----
|
||||||
|
---- This library 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 this library; if not, write to the Free Software
|
||||||
|
---- Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
|
||||||
|
----
|
||||||
|
---- For suggestions, bug reports, enhancement requests, and info about
|
||||||
|
---- our design services, you can contact us at the following address:
|
||||||
|
---- http://www.easics.com
|
||||||
|
---- Easics NV, Interleuvenlaan 86, B-3001 Leuven, Belgium
|
||||||
|
---- tel.: +32 16 395 600 fax : +32 16 395 619
|
||||||
|
---- e-mail: jand@easics.be (Jan Decaluwe)
|
||||||
|
----
|
||||||
|
|
||||||
|
|
||||||
|
package body PCK_FIO is
|
||||||
|
|
||||||
|
--------------------------
|
||||||
|
-- FIO Warnings support --
|
||||||
|
--------------------------
|
||||||
|
|
||||||
|
procedure FIO_Warning_Fsbla (F: out text;
|
||||||
|
L: inout line;
|
||||||
|
Format: in string;
|
||||||
|
Pointer: in positive) is
|
||||||
|
begin
|
||||||
|
fprint (F, L, "\n** Warning: FIO_PrintLastValue: " &
|
||||||
|
"Format specifier beyond last argument\n");
|
||||||
|
fprint (F, L, "** in format string: ""%s""\n", Format);
|
||||||
|
fprint (F, L, "** ");
|
||||||
|
for i in 1 to Pointer-1 loop
|
||||||
|
fprint (F, L, "-");
|
||||||
|
end loop;
|
||||||
|
fprint (F, L, "^\n");
|
||||||
|
end FIO_Warning_Fsbla;
|
||||||
|
|
||||||
|
procedure FIO_Warning_Ufs (F: out text;
|
||||||
|
L: inout line;
|
||||||
|
Format: in string;
|
||||||
|
Pointer: in positive;
|
||||||
|
Char: in character) is
|
||||||
|
begin
|
||||||
|
fprint (F, L, "\n** Warning: FIO_PrintArg: " &
|
||||||
|
"Unexpected format specifier '%r'\n",
|
||||||
|
fo(Char));
|
||||||
|
fprint (F, L, "** in format string: ""%s""\n", Format) ;
|
||||||
|
fprint (F, L, "** ");
|
||||||
|
for i in 1 to Pointer-1 loop
|
||||||
|
fprint (F, L, "-");
|
||||||
|
end loop;
|
||||||
|
fprint (F, L, "^\n** Assuming 'q' to proceed: ");
|
||||||
|
end FIO_Warning_Ufs;
|
||||||
|
|
||||||
|
|
||||||
|
----------------------------------
|
||||||
|
-- bit conversion support --
|
||||||
|
----------------------------------
|
||||||
|
|
||||||
|
type T_bit_map is array(bit) of character;
|
||||||
|
|
||||||
|
constant C_BIT_MAP: T_bit_map
|
||||||
|
:= ('0', '1');
|
||||||
|
|
||||||
|
----------------------------------
|
||||||
|
-- std_logic conversion support --
|
||||||
|
----------------------------------
|
||||||
|
|
||||||
|
type T_std_logic_map is array(std_ulogic) of character;
|
||||||
|
|
||||||
|
constant C_STD_LOGIC_MAP: T_std_logic_map
|
||||||
|
:= ('U', 'X', '0', '1', 'Z', 'W', 'L', 'H', '-');
|
||||||
|
|
||||||
|
------------------------------
|
||||||
|
-- Digit conversion support --
|
||||||
|
------------------------------
|
||||||
|
|
||||||
|
-- types & constants
|
||||||
|
|
||||||
|
subtype S_digit_chars is character range '0' to '9';
|
||||||
|
subtype S_digits is integer range 0 to 9 ;
|
||||||
|
|
||||||
|
type T_digit_chars_map is array(S_digit_chars) of S_digits;
|
||||||
|
|
||||||
|
constant C_DIGIT_CHARS_MAP: T_digit_chars_map
|
||||||
|
:= (0, 1, 2, 3, 4, 5, 6, 7, 8, 9);
|
||||||
|
|
||||||
|
type T_digits_map is array(S_digits) of S_digit_chars;
|
||||||
|
|
||||||
|
constant C_DIGITS_MAP: T_digits_map
|
||||||
|
:= ('0', '1', '2', '3', '4', '5', '6', '7', '8', '9');
|
||||||
|
|
||||||
|
|
||||||
|
--------------------------------
|
||||||
|
-- Decimal conversion support --
|
||||||
|
--------------------------------
|
||||||
|
|
||||||
|
-- unsigned to decimal
|
||||||
|
|
||||||
|
function U_To_d (Arg: string) return integer is
|
||||||
|
constant Argument: string(Arg'length downto 1) := Arg;
|
||||||
|
variable Result: integer := 0;
|
||||||
|
begin
|
||||||
|
for i in Argument'range loop
|
||||||
|
case Argument(i) is when '1' => Result := 2**(i-1) + Result;
|
||||||
|
when '0' => null;
|
||||||
|
when others => return(-1);
|
||||||
|
end case;
|
||||||
|
end loop;
|
||||||
|
return (Result);
|
||||||
|
end U_To_d;
|
||||||
|
|
||||||
|
-- signed to decimal
|
||||||
|
|
||||||
|
function S_To_d (Arg: string) return integer is
|
||||||
|
constant Argument: string(Arg'length downto 1) := Arg;
|
||||||
|
variable Result: integer := 0;
|
||||||
|
begin
|
||||||
|
case Argument(Argument'left) is
|
||||||
|
when '1' => Result := - 2**(Argument'left-1);
|
||||||
|
when '0' => Result := 0;
|
||||||
|
when others => return (integer'low);
|
||||||
|
end case;
|
||||||
|
for i in Argument'left-1 downto 1 loop
|
||||||
|
case Argument(i) is when '1' => Result := 2**(i-1) + Result;
|
||||||
|
when '0' => null;
|
||||||
|
when others => return(integer'low);
|
||||||
|
end case;
|
||||||
|
end loop;
|
||||||
|
return (Result);
|
||||||
|
end S_To_d;
|
||||||
|
|
||||||
|
-- string to decimal
|
||||||
|
|
||||||
|
function I_To_d (Arg: string(1 to FIO_d_WIDTH+1)) return integer is
|
||||||
|
constant Sign: character := Arg(1);
|
||||||
|
constant Value: string(Arg'length-1 downto 1) := Arg(2 to Arg'length);
|
||||||
|
variable Char: character;
|
||||||
|
variable Result: integer := 0;
|
||||||
|
begin
|
||||||
|
Result := 0;
|
||||||
|
for i in Value'range loop
|
||||||
|
Result := Result * 10;
|
||||||
|
Char := Value(i);
|
||||||
|
if (Char /= ' ') then
|
||||||
|
Result := Result + C_DIGIT_CHARS_MAP(Char);
|
||||||
|
end if;
|
||||||
|
end loop;
|
||||||
|
case Sign is when '-' => return(-Result);
|
||||||
|
when others => return(Result);
|
||||||
|
end case;
|
||||||
|
end I_To_d;
|
||||||
|
|
||||||
|
-- boolean (0,1) to decimal
|
||||||
|
|
||||||
|
function B_To_d (Arg: string(1 to 1)) return integer is
|
||||||
|
begin
|
||||||
|
case Arg is when "1" => return(1);
|
||||||
|
when "0" => return(0);
|
||||||
|
when others => return(-1);
|
||||||
|
end case;
|
||||||
|
end B_To_d;
|
||||||
|
|
||||||
|
-- boolean (T,F) to decimal
|
||||||
|
|
||||||
|
function L_To_d (Arg: string(1 to 1)) return integer is
|
||||||
|
begin
|
||||||
|
case Arg is when "T" => return(1);
|
||||||
|
when others => return(0);
|
||||||
|
end case;
|
||||||
|
end L_To_d;
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
----------------------------
|
||||||
|
-- Hex conversion support --
|
||||||
|
----------------------------
|
||||||
|
|
||||||
|
-- Constants & types
|
||||||
|
|
||||||
|
constant C_HEX_CHARS: string(1 to 17) := "0123456789ABCDEF?";
|
||||||
|
|
||||||
|
-- Function to return Hex index of a nibble
|
||||||
|
|
||||||
|
function U_To_h_Index(Arg: string(4 downto 1)) return integer is
|
||||||
|
variable Index: integer := 0;
|
||||||
|
begin
|
||||||
|
for i in Arg'range loop
|
||||||
|
case Arg(i) is when '1' => Index := 2**(i-1) + Index;
|
||||||
|
when '0' => null;
|
||||||
|
when others => return (17);
|
||||||
|
end case;
|
||||||
|
end loop;
|
||||||
|
return (Index+1);
|
||||||
|
end U_To_h_Index;
|
||||||
|
|
||||||
|
-- Hex conversion
|
||||||
|
|
||||||
|
function U_To_h (Arg: string) return string is
|
||||||
|
variable Result: string((Arg'length-1)/4 +1 downto 1);
|
||||||
|
variable ExtArg: string(Result'length*4 downto 1) := (others => '0');
|
||||||
|
begin
|
||||||
|
ExtArg(Arg'length downto 1) := Arg;
|
||||||
|
for i in Result'range loop
|
||||||
|
Result(i) := C_HEX_CHARS(U_To_h_Index( ExtArg(i*4 downto i*4 -3) ));
|
||||||
|
end loop;
|
||||||
|
return (FIO_h_PRE & Result & FIO_h_POST);
|
||||||
|
end U_To_h;
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
----------------------------
|
||||||
|
-- Bit conversion support --
|
||||||
|
----------------------------
|
||||||
|
|
||||||
|
function L_To_b (Arg: string(1 to 1)) return string is
|
||||||
|
variable Result: string(1 to 1);
|
||||||
|
begin
|
||||||
|
case Arg is when "T" => Result := "1";
|
||||||
|
when others => Result := "0";
|
||||||
|
end case;
|
||||||
|
return(FIO_b_PRE & Result & FIO_b_POST);
|
||||||
|
end L_To_b;
|
||||||
|
|
||||||
|
|
||||||
|
function I_To_b (Arg: string(1 to FIO_d_WIDTH+1);
|
||||||
|
Justified: side;
|
||||||
|
Width: integer) return string is
|
||||||
|
|
||||||
|
variable IntValue: integer := I_To_d(Arg);
|
||||||
|
variable BitValue: string(1 to FIO_b_WIDTH) := (others => ' ');
|
||||||
|
variable Sign: character := ' ';
|
||||||
|
constant Blanks: string(1 to FIO_b_WIDTH) := (others => ' ');
|
||||||
|
variable BitWidth: integer range 0 to FIO_b_WIDTH;
|
||||||
|
variable MsPos: integer range 1 to BitValue'length;
|
||||||
|
variable BitValueExtended: string(1 to 2*FIO_b_WIDTH);
|
||||||
|
|
||||||
|
begin
|
||||||
|
|
||||||
|
if (IntValue < 0) then
|
||||||
|
Sign := '-';
|
||||||
|
IntValue := -IntValue;
|
||||||
|
end if;
|
||||||
|
|
||||||
|
for i in BitValue'reverse_range loop
|
||||||
|
BitValue(i) := C_DIGITS_MAP(IntValue mod 2);
|
||||||
|
IntValue := IntValue / 2;
|
||||||
|
exit when (IntValue = 0);
|
||||||
|
end loop;
|
||||||
|
|
||||||
|
BitValueExtended := BitValue & Blanks;
|
||||||
|
|
||||||
|
if (Width = 0) or (Width > FIO_b_WIDTH+1) then
|
||||||
|
BitWidth := FIO_b_WIDTH;
|
||||||
|
else
|
||||||
|
BitWidth := Width-1;
|
||||||
|
end if;
|
||||||
|
|
||||||
|
if (Justified = RIGHT) then
|
||||||
|
return (FIO_bv_PRE &
|
||||||
|
Sign & BitValue(BitValue'length-BitWidth+1 to BitValue'length) &
|
||||||
|
FIO_bv_POST);
|
||||||
|
else
|
||||||
|
for i in BitValue'range loop
|
||||||
|
if BitValue(i) /= ' ' then
|
||||||
|
MSPos := i;
|
||||||
|
exit;
|
||||||
|
end if;
|
||||||
|
end loop;
|
||||||
|
return (FIO_bv_PRE &
|
||||||
|
Sign & BitValueExtended(MSPos to MSPos+BitWidth-1) &
|
||||||
|
FIO_bv_POST);
|
||||||
|
end if;
|
||||||
|
|
||||||
|
end I_To_b;
|
||||||
|
|
||||||
|
|
||||||
|
-----------------------------------
|
||||||
|
-- Reasonable conversion support --
|
||||||
|
-----------------------------------
|
||||||
|
|
||||||
|
function I_To_r (Arg: string(1 to FIO_d_WIDTH+1);
|
||||||
|
Justified: side;
|
||||||
|
Width: integer) return string is
|
||||||
|
constant Value: string(1 to FIO_d_WIDTH) := Arg(2 to FIO_d_WIDTH+1);
|
||||||
|
constant Sign: character := Arg(1);
|
||||||
|
constant Blanks: string(1 to FIO_d_WIDTH) := (others => ' ');
|
||||||
|
variable IntWidth: integer range 0 to FIO_d_WIDTH;
|
||||||
|
variable MsPos: integer range 1 to Value'length;
|
||||||
|
variable ValueExtended: string(1 to 2*FIO_d_WIDTH) := Value & Blanks;
|
||||||
|
begin
|
||||||
|
if (Width = 0) or (Width > FIO_d_WIDTH+1) then
|
||||||
|
IntWidth := FIO_d_WIDTH;
|
||||||
|
else
|
||||||
|
IntWidth := Width-1;
|
||||||
|
end if;
|
||||||
|
if (Justified = RIGHT) then
|
||||||
|
return (Sign & Value(Value'length-IntWidth+1 to Value'length));
|
||||||
|
else
|
||||||
|
for i in Value'range loop
|
||||||
|
if Value(i) /= ' ' then
|
||||||
|
MSPos := i;
|
||||||
|
exit;
|
||||||
|
end if;
|
||||||
|
end loop;
|
||||||
|
return (Sign & ValueExtended(MSPos to MSPos+IntWidth-1));
|
||||||
|
end if;
|
||||||
|
end I_To_r;
|
||||||
|
|
||||||
|
|
||||||
|
-------------------------------------------
|
||||||
|
-- Reasonable output conversion function --
|
||||||
|
-------------------------------------------
|
||||||
|
|
||||||
|
function ReasonableOutput (Arg: string;
|
||||||
|
Justified: side;
|
||||||
|
Width: integer) return string is
|
||||||
|
constant Argument: string(1 to Arg'length) := Arg;
|
||||||
|
constant TypeSpec: string (1 to 2) := Argument(1 to 2);
|
||||||
|
constant Value: string(1 to Arg'length-2) := Argument(3 to Arg'length);
|
||||||
|
begin
|
||||||
|
case TypeSpec is
|
||||||
|
when "U:" | "S:" | "V:" =>
|
||||||
|
return U_To_h(Value);
|
||||||
|
when "I:" =>
|
||||||
|
return I_To_r(Value, Justified, Width);
|
||||||
|
when "B:" | "L:" | "C:" =>
|
||||||
|
return Value;
|
||||||
|
when others =>
|
||||||
|
return Argument;
|
||||||
|
end case;
|
||||||
|
|
||||||
|
end ReasonableOutput;
|
||||||
|
|
||||||
|
|
||||||
|
------------------------------------
|
||||||
|
-- Bit output conversion function --
|
||||||
|
------------------------------------
|
||||||
|
|
||||||
|
function BitOutput (Arg: string;
|
||||||
|
Justified: side;
|
||||||
|
Width: integer) return string is
|
||||||
|
constant Argument: string(1 to Arg'length) := Arg;
|
||||||
|
constant TypeSpec: string (1 to 2) := Argument(1 to 2);
|
||||||
|
constant Value: string(1 to Arg'length-2) := Argument(3 to Arg'length);
|
||||||
|
begin
|
||||||
|
case TypeSpec is
|
||||||
|
when "U:" | "S:" | "V:" =>
|
||||||
|
return (FIO_bv_PRE & Value & FIO_bv_POST);
|
||||||
|
when "B:" =>
|
||||||
|
-- Value(1 to 1) instead of Value for LeapFrog
|
||||||
|
return (FIO_b_PRE & Value(1 to 1) & FIO_b_POST);
|
||||||
|
when "I:" =>
|
||||||
|
return I_To_b(Value, Justified, Width);
|
||||||
|
when "L:" =>
|
||||||
|
-- Value(1 to 1) instead of Value for LeapFrog
|
||||||
|
return L_To_b(Value(1 to 1));
|
||||||
|
when others =>
|
||||||
|
return Argument;
|
||||||
|
end case;
|
||||||
|
|
||||||
|
end BitOutput;
|
||||||
|
|
||||||
|
|
||||||
|
-------------------------------------------
|
||||||
|
-- Decimal output conversion function --
|
||||||
|
-------------------------------------------
|
||||||
|
|
||||||
|
function DecimalOutput (Arg: string) return integer is
|
||||||
|
constant Argument: string(1 to Arg'length) := Arg;
|
||||||
|
constant TypeSpec: string (1 to 2) := Argument(1 to 2);
|
||||||
|
constant Value: string(1 to Arg'length-2) := Argument(3 to Arg'length);
|
||||||
|
begin
|
||||||
|
case TypeSpec is
|
||||||
|
when "U:"| "V:" =>
|
||||||
|
return U_To_d(Value);
|
||||||
|
when "S:" =>
|
||||||
|
return S_To_d(Value);
|
||||||
|
when "I:" =>
|
||||||
|
return I_To_d(Value);
|
||||||
|
when "B:" =>
|
||||||
|
return B_To_d(Value);
|
||||||
|
when "L:" =>
|
||||||
|
return L_To_d(Value);
|
||||||
|
when others =>
|
||||||
|
return integer'low;
|
||||||
|
end case;
|
||||||
|
|
||||||
|
end DecimalOutput;
|
||||||
|
|
||||||
|
|
||||||
|
----------------------------
|
||||||
|
-- Atomic print functions --
|
||||||
|
----------------------------
|
||||||
|
|
||||||
|
-- test for end of format string
|
||||||
|
|
||||||
|
function FIO_EOS (Format: in string;
|
||||||
|
Pointer: in integer)
|
||||||
|
return boolean is
|
||||||
|
begin
|
||||||
|
return (Pointer > Format'length);
|
||||||
|
end FIO_EOS;
|
||||||
|
|
||||||
|
|
||||||
|
-- Atomic value print function
|
||||||
|
|
||||||
|
procedure FIO_PrintValue (F: out text;
|
||||||
|
L: inout line;
|
||||||
|
Format: in string;
|
||||||
|
Pointer: inout integer;
|
||||||
|
Last: in boolean := FALSE) is
|
||||||
|
variable Char: character;
|
||||||
|
begin
|
||||||
|
while (not FIO_EOS(Format, Pointer)) loop
|
||||||
|
Char := Format(Pointer);
|
||||||
|
case Char is
|
||||||
|
when '\' =>
|
||||||
|
Pointer := Pointer + 1;
|
||||||
|
exit when (FIO_EOS(Format, Pointer));
|
||||||
|
Char := Format(Pointer);
|
||||||
|
case Char is when 'n' => writeline(F, L);
|
||||||
|
when others => write(L, Char);
|
||||||
|
end case;
|
||||||
|
when '%' =>
|
||||||
|
if Last then
|
||||||
|
FIO_Warning_Fsbla(F, L, Format, Pointer);
|
||||||
|
end if;
|
||||||
|
Pointer := Pointer + 1;
|
||||||
|
exit;
|
||||||
|
when others =>
|
||||||
|
write(L, char);
|
||||||
|
end case;
|
||||||
|
Pointer := Pointer + 1;
|
||||||
|
end loop;
|
||||||
|
end FIO_PrintValue;
|
||||||
|
|
||||||
|
|
||||||
|
---- Atomic argument print function
|
||||||
|
|
||||||
|
procedure FIO_PrintArg (F: out text;
|
||||||
|
L: inout line;
|
||||||
|
Format: in string;
|
||||||
|
Pointer: inout integer;
|
||||||
|
Arg: in string) is
|
||||||
|
variable Char: character;
|
||||||
|
variable Justified: side;
|
||||||
|
variable Width: integer;
|
||||||
|
begin
|
||||||
|
|
||||||
|
FIO_PrintValue(F, L, Format, Pointer);
|
||||||
|
|
||||||
|
Justified := RIGHT;
|
||||||
|
Width := 0;
|
||||||
|
while (not FIO_EOS(Format, Pointer)) loop
|
||||||
|
Char := Format(Pointer);
|
||||||
|
case Char is
|
||||||
|
when '-' =>
|
||||||
|
Justified := LEFT;
|
||||||
|
Pointer := Pointer + 1;
|
||||||
|
when '0' to '9' =>
|
||||||
|
Width := Width*10 + C_DIGIT_CHARS_MAP(Char);
|
||||||
|
Pointer := Pointer + 1;
|
||||||
|
when 'r' =>
|
||||||
|
write(L, ReasonableOutput(Arg, Justified, Width), Justified, Width);
|
||||||
|
Pointer := Pointer + 1;
|
||||||
|
exit;
|
||||||
|
when 'b' =>
|
||||||
|
write(L, BitOutput(Arg, Justified, Width), Justified, Width);
|
||||||
|
Pointer := Pointer + 1;
|
||||||
|
exit;
|
||||||
|
when 'd' =>
|
||||||
|
write(L, DecimalOutput(Arg), Justified, Width);
|
||||||
|
Pointer := Pointer + 1;
|
||||||
|
exit;
|
||||||
|
when 'q' | 's' =>
|
||||||
|
write(L, Arg, Justified, Width);
|
||||||
|
Pointer := Pointer + 1;
|
||||||
|
exit;
|
||||||
|
when others =>
|
||||||
|
FIO_Warning_Ufs(F, L, Format, Pointer, Char);
|
||||||
|
write(L, Arg, Justified, Width);
|
||||||
|
Pointer := Pointer + 1;
|
||||||
|
exit;
|
||||||
|
end case;
|
||||||
|
end loop;
|
||||||
|
end FIO_PrintArg;
|
||||||
|
|
||||||
|
|
||||||
|
-----------------------------------------------------
|
||||||
|
-- The format string iteration expansion procedure --
|
||||||
|
-----------------------------------------------------
|
||||||
|
|
||||||
|
procedure FIO_FormatExpand (FMT: inout line;
|
||||||
|
Format: in string;
|
||||||
|
StartPointer: in positive) is
|
||||||
|
|
||||||
|
variable Pointer: positive := StartPointer;
|
||||||
|
variable TokenStart: positive;
|
||||||
|
variable IterStringStart: positive;
|
||||||
|
variable IterStringEnd: positive;
|
||||||
|
variable IterCount: natural;
|
||||||
|
variable OpenBrackets: natural;
|
||||||
|
variable L: line;
|
||||||
|
|
||||||
|
begin
|
||||||
|
|
||||||
|
FORMAT_SEARCH: while not FIO_EOS(Format, Pointer) loop
|
||||||
|
|
||||||
|
case Format(Pointer) is
|
||||||
|
|
||||||
|
-- look for format specifier
|
||||||
|
when '%' =>
|
||||||
|
|
||||||
|
-- initialize iteration token search
|
||||||
|
TokenStart := Pointer;
|
||||||
|
IterCount := 0;
|
||||||
|
Pointer := Pointer + 1;
|
||||||
|
|
||||||
|
-- start iteration token search
|
||||||
|
TOKEN_READ: while not FIO_EOS(Format, Pointer) loop
|
||||||
|
|
||||||
|
case Format(Pointer) is
|
||||||
|
|
||||||
|
-- read iteration counter
|
||||||
|
when '0' to '9' =>
|
||||||
|
IterCount := IterCount*10 + C_DIGIT_CHARS_MAP(Format(Pointer));
|
||||||
|
Pointer := Pointer + 1;
|
||||||
|
|
||||||
|
-- expect open bracket
|
||||||
|
when '{' =>
|
||||||
|
|
||||||
|
-- initialize iteration string read
|
||||||
|
OpenBrackets := 1;
|
||||||
|
IterStringStart := Pointer + 1;
|
||||||
|
Pointer := Pointer + 1;
|
||||||
|
-- quit prematurely when iteration count is 0
|
||||||
|
next FORMAT_SEARCH when (IterCount = 0);
|
||||||
|
|
||||||
|
-- start iteration string read
|
||||||
|
ITER_STRING_READ: while not FIO_EOS(Format, Pointer) loop
|
||||||
|
|
||||||
|
case Format(Pointer) is
|
||||||
|
-- keep track of open brackets
|
||||||
|
when '{' =>
|
||||||
|
OpenBrackets := OpenBrackets + 1;
|
||||||
|
Pointer := Pointer + 1;
|
||||||
|
-- when closing bracket is found, process iteration string
|
||||||
|
when '}' =>
|
||||||
|
OpenBrackets := OpenBrackets - 1;
|
||||||
|
if (OpenBrackets = 0) then
|
||||||
|
IterStringEnd := Pointer-1;
|
||||||
|
if (TokenStart /= 1) then
|
||||||
|
write(L, Format(1 to TokenStart-1));
|
||||||
|
end if;
|
||||||
|
for i in 1 to IterCount loop
|
||||||
|
write(L, Format(IterStringStart to IterStringEnd));
|
||||||
|
end loop;
|
||||||
|
if (IterStringEnd /= Format'length) then
|
||||||
|
write(L, Format(IterStringEnd+2 to Format'length));
|
||||||
|
end if;
|
||||||
|
-- call expansion procedure recursively on expanded format
|
||||||
|
FIO_FormatExpand(FMT, L.all, TokenStart);
|
||||||
|
deallocate(L);
|
||||||
|
return;
|
||||||
|
end if;
|
||||||
|
Pointer := Pointer + 1;
|
||||||
|
-- skip escaped characters
|
||||||
|
when '\' =>
|
||||||
|
Pointer := Pointer + 2;
|
||||||
|
-- read iteration string
|
||||||
|
when others =>
|
||||||
|
Pointer := Pointer + 1;
|
||||||
|
|
||||||
|
end case;
|
||||||
|
|
||||||
|
end loop ITER_STRING_READ;
|
||||||
|
|
||||||
|
-- stop iteration token search when no opening bracket found
|
||||||
|
when others =>
|
||||||
|
Pointer := Pointer + 1;
|
||||||
|
next FORMAT_SEARCH;
|
||||||
|
|
||||||
|
end case;
|
||||||
|
|
||||||
|
end loop TOKEN_READ;
|
||||||
|
|
||||||
|
-- skip escaped characters
|
||||||
|
when '\' =>
|
||||||
|
Pointer := Pointer + 2;
|
||||||
|
|
||||||
|
-- read other characters
|
||||||
|
when others =>
|
||||||
|
Pointer := Pointer + 1;
|
||||||
|
|
||||||
|
end case;
|
||||||
|
|
||||||
|
end loop FORMAT_SEARCH;
|
||||||
|
|
||||||
|
write(FMT, Format);
|
||||||
|
deallocate(L);
|
||||||
|
|
||||||
|
end FIO_FormatExpand;
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
--------------------------
|
||||||
|
-- The fprint procedure --
|
||||||
|
--------------------------
|
||||||
|
|
||||||
|
procedure fprint
|
||||||
|
(F: out text;
|
||||||
|
L: inout line;
|
||||||
|
Format: in string;
|
||||||
|
A1 , A2 , A3 , A4 , A5 , A6 , A7 , A8 : in string := FIO_NIL;
|
||||||
|
A9 , A10, A11, A12, A13, A14, A15, A16: in string := FIO_NIL;
|
||||||
|
A17, A18, A19, A20, A21, A22, A23, A24: in string := FIO_NIL;
|
||||||
|
A25, A26, A27, A28, A29, A30, A31, A32: in string := FIO_NIL
|
||||||
|
) is
|
||||||
|
|
||||||
|
variable Pointer: integer;
|
||||||
|
variable FMT: line;
|
||||||
|
|
||||||
|
begin
|
||||||
|
|
||||||
|
Pointer := 1;
|
||||||
|
|
||||||
|
FIO_FormatExpand (FMT, Format, Format'low);
|
||||||
|
|
||||||
|
if (A1 /= FIO_NIL) then FIO_PrintArg(F, L, FMT.all, Pointer, A1 );
|
||||||
|
if (A2 /= FIO_NIL) then FIO_PrintArg(F, L, FMT.all, Pointer, A2 );
|
||||||
|
if (A3 /= FIO_NIL) then FIO_PrintArg(F, L, FMT.all, Pointer, A3 );
|
||||||
|
if (A4 /= FIO_NIL) then FIO_PrintArg(F, L, FMT.all, Pointer, A4 );
|
||||||
|
if (A5 /= FIO_NIL) then FIO_PrintArg(F, L, FMT.all, Pointer, A5 );
|
||||||
|
if (A6 /= FIO_NIL) then FIO_PrintArg(F, L, FMT.all, Pointer, A6 );
|
||||||
|
if (A7 /= FIO_NIL) then FIO_PrintArg(F, L, FMT.all, Pointer, A7 );
|
||||||
|
if (A8 /= FIO_NIL) then FIO_PrintArg(F, L, FMT.all, Pointer, A8 );
|
||||||
|
if (A9 /= FIO_NIL) then FIO_PrintArg(F, L, FMT.all, Pointer, A9 );
|
||||||
|
if (A10 /= FIO_NIL) then FIO_PrintArg(F, L, FMT.all, Pointer, A10);
|
||||||
|
if (A11 /= FIO_NIL) then FIO_PrintArg(F, L, FMT.all, Pointer, A11);
|
||||||
|
if (A12 /= FIO_NIL) then FIO_PrintArg(F, L, FMT.all, Pointer, A12);
|
||||||
|
if (A13 /= FIO_NIL) then FIO_PrintArg(F, L, FMT.all, Pointer, A13);
|
||||||
|
if (A14 /= FIO_NIL) then FIO_PrintArg(F, L, FMT.all, Pointer, A14);
|
||||||
|
if (A15 /= FIO_NIL) then FIO_PrintArg(F, L, FMT.all, Pointer, A15);
|
||||||
|
if (A16 /= FIO_NIL) then FIO_PrintArg(F, L, FMT.all, Pointer, A16);
|
||||||
|
if (A17 /= FIO_NIL) then FIO_PrintArg(F, L, FMT.all, Pointer, A17);
|
||||||
|
if (A18 /= FIO_NIL) then FIO_PrintArg(F, L, FMT.all, Pointer, A18);
|
||||||
|
if (A19 /= FIO_NIL) then FIO_PrintArg(F, L, FMT.all, Pointer, A19);
|
||||||
|
if (A20 /= FIO_NIL) then FIO_PrintArg(F, L, FMT.all, Pointer, A20);
|
||||||
|
if (A21 /= FIO_NIL) then FIO_PrintArg(F, L, FMT.all, Pointer, A21);
|
||||||
|
if (A22 /= FIO_NIL) then FIO_PrintArg(F, L, FMT.all, Pointer, A22);
|
||||||
|
if (A23 /= FIO_NIL) then FIO_PrintArg(F, L, FMT.all, Pointer, A23);
|
||||||
|
if (A24 /= FIO_NIL) then FIO_PrintArg(F, L, FMT.all, Pointer, A24);
|
||||||
|
if (A25 /= FIO_NIL) then FIO_PrintArg(F, L, FMT.all, Pointer, A25);
|
||||||
|
if (A26 /= FIO_NIL) then FIO_PrintArg(F, L, FMT.all, Pointer, A26);
|
||||||
|
if (A27 /= FIO_NIL) then FIO_PrintArg(F, L, FMT.all, Pointer, A27);
|
||||||
|
if (A28 /= FIO_NIL) then FIO_PrintArg(F, L, FMT.all, Pointer, A28);
|
||||||
|
if (A29 /= FIO_NIL) then FIO_PrintArg(F, L, FMT.all, Pointer, A29);
|
||||||
|
if (A30 /= FIO_NIL) then FIO_PrintArg(F, L, FMT.all, Pointer, A30);
|
||||||
|
if (A31 /= FIO_NIL) then FIO_PrintArg(F, L, FMT.all, Pointer, A31);
|
||||||
|
if (A32 /= FIO_NIL) then FIO_PrintArg(F, L, FMT.all, Pointer, A32);
|
||||||
|
end if; end if; end if; end if; end if; end if; end if; end if;
|
||||||
|
end if; end if; end if; end if; end if; end if; end if; end if;
|
||||||
|
end if; end if; end if; end if; end if; end if; end if; end if;
|
||||||
|
end if; end if; end if; end if; end if; end if; end if; end if;
|
||||||
|
|
||||||
|
FIO_PrintValue(F, L, FMT.all, Pointer, Last => TRUE);
|
||||||
|
|
||||||
|
deallocate(FMT);
|
||||||
|
|
||||||
|
end fprint;
|
||||||
|
|
||||||
|
|
||||||
|
-------------------------------------------
|
||||||
|
-- Formatted output conversion functions --
|
||||||
|
-------------------------------------------
|
||||||
|
|
||||||
|
function fo (Arg: unsigned) return string is
|
||||||
|
constant Argument: unsigned(1 to Arg'length) := Arg;
|
||||||
|
variable Result: string(1 to Arg'length);
|
||||||
|
begin
|
||||||
|
for i in Argument'range loop
|
||||||
|
Result(i) := C_STD_LOGIC_MAP(Argument(i));
|
||||||
|
end loop;
|
||||||
|
return ("U:" & Result);
|
||||||
|
end fo;
|
||||||
|
|
||||||
|
function fo (Arg: signed) return string is
|
||||||
|
constant Argument: signed(1 to Arg'length) := Arg;
|
||||||
|
variable Result: string(1 to Arg'length);
|
||||||
|
begin
|
||||||
|
for i in Argument'range loop
|
||||||
|
Result(i) := C_STD_LOGIC_MAP(Argument(i));
|
||||||
|
end loop;
|
||||||
|
return ("S:" & Result);
|
||||||
|
end fo;
|
||||||
|
|
||||||
|
function fo (Arg: std_logic_vector) return string is
|
||||||
|
constant Argument: std_logic_vector(1 to Arg'length) := Arg;
|
||||||
|
variable Result: string(1 to Arg'length);
|
||||||
|
begin
|
||||||
|
for i in Argument'range loop
|
||||||
|
Result(i) := C_STD_LOGIC_MAP(Argument(i));
|
||||||
|
end loop;
|
||||||
|
return ("V:" & Result);
|
||||||
|
end fo;
|
||||||
|
|
||||||
|
function fo (Arg: std_ulogic_vector) return string is
|
||||||
|
constant Argument: std_ulogic_vector(1 to Arg'length) := Arg;
|
||||||
|
variable Result: string(1 to Arg'length);
|
||||||
|
begin
|
||||||
|
for i in Argument'range loop
|
||||||
|
Result(i) := C_STD_LOGIC_MAP(Argument(i));
|
||||||
|
end loop;
|
||||||
|
return ("V:" & Result);
|
||||||
|
end fo;
|
||||||
|
|
||||||
|
function fo (Arg: bit_vector) return string is
|
||||||
|
constant Argument: bit_vector(1 to Arg'length) := Arg;
|
||||||
|
variable Result: string(1 to Arg'length);
|
||||||
|
begin
|
||||||
|
for i in Argument'range loop
|
||||||
|
Result(i) := C_BIT_MAP(Argument(i));
|
||||||
|
end loop;
|
||||||
|
return ("V:" & Result);
|
||||||
|
end fo;
|
||||||
|
|
||||||
|
function fo (Arg: integer) return string is
|
||||||
|
variable Argument: integer := Arg;
|
||||||
|
variable Result: string(1 to FIO_d_WIDTH) := (others => ' ');
|
||||||
|
variable Sign: character := ' ';
|
||||||
|
begin
|
||||||
|
if (Argument < 0) and (Argument /= integer'low) then
|
||||||
|
Sign := '-';
|
||||||
|
Argument := -Argument;
|
||||||
|
end if;
|
||||||
|
for i in Result'reverse_range loop
|
||||||
|
Result(i) := C_DIGITS_MAP(Argument mod 10);
|
||||||
|
Argument := Argument / 10;
|
||||||
|
exit when (Argument = 0);
|
||||||
|
end loop;
|
||||||
|
return ("I:" & Sign & Result);
|
||||||
|
end fo;
|
||||||
|
|
||||||
|
function fo (Arg: std_ulogic) return string is
|
||||||
|
begin
|
||||||
|
return ("B:" & C_STD_LOGIC_MAP(Arg));
|
||||||
|
end fo;
|
||||||
|
|
||||||
|
function fo (Arg: bit) return string is
|
||||||
|
begin
|
||||||
|
return ("B:" & C_BIT_MAP(Arg));
|
||||||
|
end fo;
|
||||||
|
|
||||||
|
function fo (Arg: boolean) return string is
|
||||||
|
begin
|
||||||
|
if (ARG = TRUE) then
|
||||||
|
return ("L:T");
|
||||||
|
else
|
||||||
|
return ("L:F");
|
||||||
|
end if;
|
||||||
|
end fo;
|
||||||
|
|
||||||
|
function fo (Arg: character) return string is
|
||||||
|
begin
|
||||||
|
return ("C:" & Arg);
|
||||||
|
end fo;
|
||||||
|
|
||||||
|
-- auxilary function fgets(Arg: string)
|
||||||
|
-- gives index until first NUL
|
||||||
|
-- reads string from 1 to Arg'length
|
||||||
|
function fgets (Arg: string) return integer is
|
||||||
|
variable index: integer := Arg'length;
|
||||||
|
begin
|
||||||
|
for i in 1 to Arg'length loop
|
||||||
|
if Arg(i) = NUL then
|
||||||
|
index := i - 1;
|
||||||
|
exit;
|
||||||
|
else
|
||||||
|
null;
|
||||||
|
end if;
|
||||||
|
end loop;
|
||||||
|
return index;
|
||||||
|
end fgets;
|
||||||
|
|
||||||
|
function fo (Arg: string) return string is
|
||||||
|
begin
|
||||||
|
return Arg(1 to fgets(Arg));
|
||||||
|
end fo;
|
||||||
|
|
||||||
|
function fo (Arg: time) return string is
|
||||||
|
begin
|
||||||
|
return fo (integer (Arg / 1 ns));
|
||||||
|
end fo;
|
||||||
|
|
||||||
|
end PCK_FIO;
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
@@ -0,0 +1,108 @@
|
|||||||
|
---- $Id: PCK_FIO_1993.vhd,v 1.1 2008-08-23 08:20:28 Jens Exp $
|
||||||
|
----
|
||||||
|
---- PCK_FIO: a VHDL package for C-style formatted file output
|
||||||
|
---- Copyright (C) 1995, 2001 Easics NV
|
||||||
|
----
|
||||||
|
---- This library 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 2.1 of the License, or (at your option) any later version.
|
||||||
|
----
|
||||||
|
---- This library 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 this library; if not, write to the Free Software
|
||||||
|
---- Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
|
||||||
|
----
|
||||||
|
---- For suggestions, bug reports, enhancement requests, and info about
|
||||||
|
---- our design services, you can contact us at the following address:
|
||||||
|
---- http://www.easics.com
|
||||||
|
---- Easics NV, Interleuvenlaan 86, B-3001 Leuven, Belgium
|
||||||
|
---- tel.: +32 16 395 600 fax : +32 16 395 619
|
||||||
|
---- e-mail: jand@easics.be (Jan Decaluwe)
|
||||||
|
----
|
||||||
|
|
||||||
|
|
||||||
|
use STD.TEXTIO.all;
|
||||||
|
|
||||||
|
library IEEE;
|
||||||
|
use IEEE.std_logic_1164.all;
|
||||||
|
-- signed/unsigned definition: use either std_logic_arith or numeric_std
|
||||||
|
-- use IEEE.std_logic_arith.all; -- the Synopsys one
|
||||||
|
use IEEE.numeric_std.all;
|
||||||
|
|
||||||
|
package PCK_FIO is
|
||||||
|
|
||||||
|
|
||||||
|
-- prefix string for hex output
|
||||||
|
-- VHDL style: "X"""
|
||||||
|
-- Verilog style: "h'"
|
||||||
|
-- C style: "0x"
|
||||||
|
constant FIO_h_PRE: string := "0x";
|
||||||
|
|
||||||
|
-- postfix string for hex output
|
||||||
|
-- VHDL style: """"
|
||||||
|
constant FIO_h_POST: string := "";
|
||||||
|
|
||||||
|
-- prefix string for bit vector output
|
||||||
|
-- VHDL style: "B"""
|
||||||
|
-- Verilog style: "b'"
|
||||||
|
constant FIO_bv_PRE: string := "";
|
||||||
|
|
||||||
|
-- postfix string for bit vector output
|
||||||
|
-- VHDL style: """"
|
||||||
|
constant FIO_bv_POST: string := "";
|
||||||
|
|
||||||
|
-- prefix string for bit output
|
||||||
|
-- VHDL style: "'"
|
||||||
|
-- Verilog style: "b'"
|
||||||
|
constant FIO_b_PRE: string := "";
|
||||||
|
|
||||||
|
-- postfix string for bit output
|
||||||
|
-- VHDL style: "'"
|
||||||
|
constant FIO_b_POST: string := "";
|
||||||
|
|
||||||
|
-- digit width for the string representation of integers
|
||||||
|
constant FIO_d_WIDTH: integer := 10;
|
||||||
|
|
||||||
|
-- bit width for the string representation of integers
|
||||||
|
constant FIO_b_WIDTH: integer := 32;
|
||||||
|
|
||||||
|
-- definition of the NIL string (default value for fprint arguments)
|
||||||
|
-- fprint stops consuming arguments at the first NIL argument
|
||||||
|
constant FIO_NIL: string := "\";
|
||||||
|
|
||||||
|
procedure fprint
|
||||||
|
(file F: text;
|
||||||
|
L: inout line;
|
||||||
|
Format: in string;
|
||||||
|
A1 , A2 , A3 , A4 , A5 , A6 , A7 , A8 : in string := FIO_NIL;
|
||||||
|
A9 , A10, A11, A12, A13, A14, A15, A16: in string := FIO_NIL;
|
||||||
|
A17, A18, A19, A20, A21, A22, A23, A24: in string := FIO_NIL;
|
||||||
|
A25, A26, A27, A28, A29, A30, A31, A32: in string := FIO_NIL
|
||||||
|
);
|
||||||
|
|
||||||
|
function fo (Arg: unsigned) return string;
|
||||||
|
function fo (Arg: signed) return string;
|
||||||
|
function fo (Arg: std_logic_vector) return string;
|
||||||
|
function fo (Arg: std_ulogic_vector) return string;
|
||||||
|
function fo (Arg: bit_vector) return string;
|
||||||
|
function fo (Arg: integer) return string;
|
||||||
|
function fo (Arg: std_ulogic) return string;
|
||||||
|
function fo (Arg: bit) return string;
|
||||||
|
function fo (Arg: boolean) return string;
|
||||||
|
function fo (Arg: character) return string;
|
||||||
|
function fo (Arg: string) return string;
|
||||||
|
function fo (Arg: time) return string;
|
||||||
|
|
||||||
|
procedure FIO_FormatExpand (FMT: inout line;
|
||||||
|
Format: in string;
|
||||||
|
StartPointer: in positive);
|
||||||
|
|
||||||
|
end PCK_FIO;
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
@@ -0,0 +1,814 @@
|
|||||||
|
---- $Id: PCK_FIO_1993_BODY.vhd,v 1.1 2008-08-23 08:20:28 Jens Exp $
|
||||||
|
----
|
||||||
|
---- PCK_FIO: a VHDL package for C-style formatted file output
|
||||||
|
---- Copyright (C) 1995, 2001 Easics NV
|
||||||
|
----
|
||||||
|
---- This library 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 2.1 of the License, or (at your option) any later version.
|
||||||
|
----
|
||||||
|
---- This library 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 this library; if not, write to the Free Software
|
||||||
|
---- Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
|
||||||
|
----
|
||||||
|
---- For suggestions, bug reports, enhancement requests, and info about
|
||||||
|
---- our design services, you can contact us at the following address:
|
||||||
|
---- http://www.easics.com
|
||||||
|
---- Easics NV, Interleuvenlaan 86, B-3001 Leuven, Belgium
|
||||||
|
---- tel.: +32 16 395 600 fax : +32 16 395 619
|
||||||
|
---- e-mail: jand@easics.be (Jan Decaluwe)
|
||||||
|
----
|
||||||
|
|
||||||
|
|
||||||
|
package body PCK_FIO is
|
||||||
|
|
||||||
|
--------------------------
|
||||||
|
-- FIO Warnings support --
|
||||||
|
--------------------------
|
||||||
|
|
||||||
|
procedure FIO_Warning_Fsbla (file F: text;
|
||||||
|
L: inout line;
|
||||||
|
Format: in string;
|
||||||
|
Pointer: in positive) is
|
||||||
|
begin
|
||||||
|
fprint (F, L, "\n** Warning: FIO_PrintLastValue: " &
|
||||||
|
"Format specifier beyond last argument\n");
|
||||||
|
fprint (F, L, "** in format string: ""%s""\n", Format);
|
||||||
|
fprint (F, L, "** ");
|
||||||
|
for i in 1 to Pointer-1 loop
|
||||||
|
fprint (F, L, "-");
|
||||||
|
end loop;
|
||||||
|
fprint (F, L, "^\n");
|
||||||
|
end FIO_Warning_Fsbla;
|
||||||
|
|
||||||
|
procedure FIO_Warning_Ufs (file F: text;
|
||||||
|
L: inout line;
|
||||||
|
Format: in string;
|
||||||
|
Pointer: in positive;
|
||||||
|
Char: in character) is
|
||||||
|
begin
|
||||||
|
fprint (F, L, "\n** Warning: FIO_PrintArg: " &
|
||||||
|
"Unexpected format specifier '%r'\n",
|
||||||
|
fo(Char));
|
||||||
|
fprint (F, L, "** in format string: ""%s""\n", Format) ;
|
||||||
|
fprint (F, L, "** ");
|
||||||
|
for i in 1 to Pointer-1 loop
|
||||||
|
fprint (F, L, "-");
|
||||||
|
end loop;
|
||||||
|
fprint (F, L, "^\n** Assuming 'q' to proceed: ");
|
||||||
|
end FIO_Warning_Ufs;
|
||||||
|
|
||||||
|
|
||||||
|
----------------------------------
|
||||||
|
-- bit conversion support --
|
||||||
|
----------------------------------
|
||||||
|
|
||||||
|
type T_bit_map is array(bit) of character;
|
||||||
|
|
||||||
|
constant C_BIT_MAP: T_bit_map
|
||||||
|
:= ('0', '1');
|
||||||
|
|
||||||
|
----------------------------------
|
||||||
|
-- std_logic conversion support --
|
||||||
|
----------------------------------
|
||||||
|
|
||||||
|
type T_std_logic_map is array(std_ulogic) of character;
|
||||||
|
|
||||||
|
constant C_STD_LOGIC_MAP: T_std_logic_map
|
||||||
|
:= ('U', 'X', '0', '1', 'Z', 'W', 'L', 'H', '-');
|
||||||
|
|
||||||
|
------------------------------
|
||||||
|
-- Digit conversion support --
|
||||||
|
------------------------------
|
||||||
|
|
||||||
|
-- types & constants
|
||||||
|
|
||||||
|
subtype S_digit_chars is character range '0' to '9';
|
||||||
|
subtype S_digits is integer range 0 to 9 ;
|
||||||
|
|
||||||
|
type T_digit_chars_map is array(S_digit_chars) of S_digits;
|
||||||
|
|
||||||
|
constant C_DIGIT_CHARS_MAP: T_digit_chars_map
|
||||||
|
:= (0, 1, 2, 3, 4, 5, 6, 7, 8, 9);
|
||||||
|
|
||||||
|
type T_digits_map is array(S_digits) of S_digit_chars;
|
||||||
|
|
||||||
|
constant C_DIGITS_MAP: T_digits_map
|
||||||
|
:= ('0', '1', '2', '3', '4', '5', '6', '7', '8', '9');
|
||||||
|
|
||||||
|
|
||||||
|
--------------------------------
|
||||||
|
-- Decimal conversion support --
|
||||||
|
--------------------------------
|
||||||
|
|
||||||
|
-- unsigned to decimal
|
||||||
|
|
||||||
|
function U_To_d (Arg: string) return integer is
|
||||||
|
constant Argument: string(Arg'length downto 1) := Arg;
|
||||||
|
variable Result: integer := 0;
|
||||||
|
begin
|
||||||
|
for i in Argument'range loop
|
||||||
|
case Argument(i) is when '1' => Result := 2**(i-1) + Result;
|
||||||
|
when '0' => null;
|
||||||
|
when others => return(-1);
|
||||||
|
end case;
|
||||||
|
end loop;
|
||||||
|
return (Result);
|
||||||
|
end U_To_d;
|
||||||
|
|
||||||
|
-- signed to decimal
|
||||||
|
|
||||||
|
function S_To_d (Arg: string) return integer is
|
||||||
|
constant Argument: string(Arg'length downto 1) := Arg;
|
||||||
|
variable Result: integer := 0;
|
||||||
|
begin
|
||||||
|
case Argument(Argument'left) is
|
||||||
|
when '1' => Result := - 2**(Argument'left-1);
|
||||||
|
when '0' => Result := 0;
|
||||||
|
when others => return (integer'low);
|
||||||
|
end case;
|
||||||
|
for i in Argument'left-1 downto 1 loop
|
||||||
|
case Argument(i) is when '1' => Result := 2**(i-1) + Result;
|
||||||
|
when '0' => null;
|
||||||
|
when others => return(integer'low);
|
||||||
|
end case;
|
||||||
|
end loop;
|
||||||
|
return (Result);
|
||||||
|
end S_To_d;
|
||||||
|
|
||||||
|
-- string to decimal
|
||||||
|
|
||||||
|
function I_To_d (Arg: string(1 to FIO_d_WIDTH+1)) return integer is
|
||||||
|
constant Sign: character := Arg(1);
|
||||||
|
constant Value: string(Arg'length-1 downto 1) := Arg(2 to Arg'length);
|
||||||
|
variable Char: character;
|
||||||
|
variable Result: integer := 0;
|
||||||
|
begin
|
||||||
|
Result := 0;
|
||||||
|
for i in Value'range loop
|
||||||
|
Result := Result * 10;
|
||||||
|
Char := Value(i);
|
||||||
|
if (Char /= ' ') then
|
||||||
|
Result := Result + C_DIGIT_CHARS_MAP(Char);
|
||||||
|
end if;
|
||||||
|
end loop;
|
||||||
|
case Sign is when '-' => return(-Result);
|
||||||
|
when others => return(Result);
|
||||||
|
end case;
|
||||||
|
end I_To_d;
|
||||||
|
|
||||||
|
-- boolean (0,1) to decimal
|
||||||
|
|
||||||
|
function B_To_d (Arg: string(1 to 1)) return integer is
|
||||||
|
begin
|
||||||
|
case Arg is when "1" => return(1);
|
||||||
|
when "0" => return(0);
|
||||||
|
when others => return(-1);
|
||||||
|
end case;
|
||||||
|
end B_To_d;
|
||||||
|
|
||||||
|
-- boolean (T,F) to decimal
|
||||||
|
|
||||||
|
function L_To_d (Arg: string(1 to 1)) return integer is
|
||||||
|
begin
|
||||||
|
case Arg is when "T" => return(1);
|
||||||
|
when others => return(0);
|
||||||
|
end case;
|
||||||
|
end L_To_d;
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
----------------------------
|
||||||
|
-- Hex conversion support --
|
||||||
|
----------------------------
|
||||||
|
|
||||||
|
-- Constants & types
|
||||||
|
|
||||||
|
constant C_HEX_CHARS: string(1 to 17) := "0123456789ABCDEF?";
|
||||||
|
|
||||||
|
-- Function to return Hex index of a nibble
|
||||||
|
|
||||||
|
function U_To_h_Index(Arg: string(4 downto 1)) return integer is
|
||||||
|
variable Index: integer := 0;
|
||||||
|
begin
|
||||||
|
for i in Arg'range loop
|
||||||
|
case Arg(i) is when '1' => Index := 2**(i-1) + Index;
|
||||||
|
when '0' => null;
|
||||||
|
when others => return (17);
|
||||||
|
end case;
|
||||||
|
end loop;
|
||||||
|
return (Index+1);
|
||||||
|
end U_To_h_Index;
|
||||||
|
|
||||||
|
-- Hex conversion
|
||||||
|
|
||||||
|
function U_To_h (Arg: string) return string is
|
||||||
|
variable Result: string((Arg'length-1)/4 +1 downto 1);
|
||||||
|
variable ExtArg: string(Result'length*4 downto 1) := (others => '0');
|
||||||
|
begin
|
||||||
|
ExtArg(Arg'length downto 1) := Arg;
|
||||||
|
for i in Result'range loop
|
||||||
|
Result(i) := C_HEX_CHARS(U_To_h_Index( ExtArg(i*4 downto i*4 -3) ));
|
||||||
|
end loop;
|
||||||
|
return (FIO_h_PRE & Result & FIO_h_POST);
|
||||||
|
end U_To_h;
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
----------------------------
|
||||||
|
-- Bit conversion support --
|
||||||
|
----------------------------
|
||||||
|
|
||||||
|
function L_To_b (Arg: string(1 to 1)) return string is
|
||||||
|
variable Result: string(1 to 1);
|
||||||
|
begin
|
||||||
|
case Arg is when "T" => Result := "1";
|
||||||
|
when others => Result := "0";
|
||||||
|
end case;
|
||||||
|
return(FIO_b_PRE & Result & FIO_b_POST);
|
||||||
|
end L_To_b;
|
||||||
|
|
||||||
|
|
||||||
|
function I_To_b (Arg: string(1 to FIO_d_WIDTH+1);
|
||||||
|
Justified: side;
|
||||||
|
Width: integer) return string is
|
||||||
|
|
||||||
|
variable IntValue: integer := I_To_d(Arg);
|
||||||
|
variable BitValue: string(1 to FIO_b_WIDTH) := (others => ' ');
|
||||||
|
variable Sign: character := ' ';
|
||||||
|
constant Blanks: string(1 to FIO_b_WIDTH) := (others => ' ');
|
||||||
|
variable BitWidth: integer range 0 to FIO_b_WIDTH;
|
||||||
|
variable MsPos: integer range 1 to BitValue'length;
|
||||||
|
variable BitValueExtended: string(1 to 2*FIO_b_WIDTH);
|
||||||
|
|
||||||
|
begin
|
||||||
|
|
||||||
|
if (IntValue < 0) then
|
||||||
|
Sign := '-';
|
||||||
|
IntValue := -IntValue;
|
||||||
|
end if;
|
||||||
|
|
||||||
|
for i in BitValue'reverse_range loop
|
||||||
|
BitValue(i) := C_DIGITS_MAP(IntValue mod 2);
|
||||||
|
IntValue := IntValue / 2;
|
||||||
|
exit when (IntValue = 0);
|
||||||
|
end loop;
|
||||||
|
|
||||||
|
BitValueExtended := BitValue & Blanks;
|
||||||
|
|
||||||
|
if (Width = 0) or (Width > FIO_b_WIDTH+1) then
|
||||||
|
BitWidth := FIO_b_WIDTH;
|
||||||
|
else
|
||||||
|
BitWidth := Width-1;
|
||||||
|
end if;
|
||||||
|
|
||||||
|
if (Justified = RIGHT) then
|
||||||
|
return (FIO_bv_PRE &
|
||||||
|
Sign & BitValue(BitValue'length-BitWidth+1 to BitValue'length) &
|
||||||
|
FIO_bv_POST);
|
||||||
|
else
|
||||||
|
for i in BitValue'range loop
|
||||||
|
if BitValue(i) /= ' ' then
|
||||||
|
MSPos := i;
|
||||||
|
exit;
|
||||||
|
end if;
|
||||||
|
end loop;
|
||||||
|
return (FIO_bv_PRE &
|
||||||
|
Sign & BitValueExtended(MSPos to MSPos+BitWidth-1) &
|
||||||
|
FIO_bv_POST);
|
||||||
|
end if;
|
||||||
|
|
||||||
|
end I_To_b;
|
||||||
|
|
||||||
|
|
||||||
|
-----------------------------------
|
||||||
|
-- Reasonable conversion support --
|
||||||
|
-----------------------------------
|
||||||
|
|
||||||
|
function I_To_r (Arg: string(1 to FIO_d_WIDTH+1);
|
||||||
|
Justified: side;
|
||||||
|
Width: integer) return string is
|
||||||
|
constant Value: string(1 to FIO_d_WIDTH) := Arg(2 to FIO_d_WIDTH+1);
|
||||||
|
constant Sign: character := Arg(1);
|
||||||
|
constant Blanks: string(1 to FIO_d_WIDTH) := (others => ' ');
|
||||||
|
variable IntWidth: integer range 0 to FIO_d_WIDTH;
|
||||||
|
variable MsPos: integer range 1 to Value'length;
|
||||||
|
variable ValueExtended: string(1 to 2*FIO_d_WIDTH) := Value & Blanks;
|
||||||
|
begin
|
||||||
|
if (Width = 0) or (Width > FIO_d_WIDTH+1) then
|
||||||
|
IntWidth := FIO_d_WIDTH;
|
||||||
|
else
|
||||||
|
IntWidth := Width-1;
|
||||||
|
end if;
|
||||||
|
if (Justified = RIGHT) then
|
||||||
|
return (Sign & Value(Value'length-IntWidth+1 to Value'length));
|
||||||
|
else
|
||||||
|
for i in Value'range loop
|
||||||
|
if Value(i) /= ' ' then
|
||||||
|
MSPos := i;
|
||||||
|
exit;
|
||||||
|
end if;
|
||||||
|
end loop;
|
||||||
|
return (Sign & ValueExtended(MSPos to MSPos+IntWidth-1));
|
||||||
|
end if;
|
||||||
|
end I_To_r;
|
||||||
|
|
||||||
|
|
||||||
|
-------------------------------------------
|
||||||
|
-- Reasonable output conversion function --
|
||||||
|
-------------------------------------------
|
||||||
|
|
||||||
|
function ReasonableOutput (Arg: string;
|
||||||
|
Justified: side;
|
||||||
|
Width: integer) return string is
|
||||||
|
constant Argument: string(1 to Arg'length) := Arg;
|
||||||
|
constant TypeSpec: string (1 to 2) := Argument(1 to 2);
|
||||||
|
constant Value: string(1 to Arg'length-2) := Argument(3 to Arg'length);
|
||||||
|
begin
|
||||||
|
case TypeSpec is
|
||||||
|
when "U:" | "S:" | "V:" =>
|
||||||
|
return U_To_h(Value);
|
||||||
|
when "I:" =>
|
||||||
|
return I_To_r(Value, Justified, Width);
|
||||||
|
when "B:" | "L:" | "C:" =>
|
||||||
|
return Value;
|
||||||
|
when others =>
|
||||||
|
return Argument;
|
||||||
|
end case;
|
||||||
|
|
||||||
|
end ReasonableOutput;
|
||||||
|
|
||||||
|
|
||||||
|
------------------------------------
|
||||||
|
-- Bit output conversion function --
|
||||||
|
------------------------------------
|
||||||
|
|
||||||
|
function BitOutput (Arg: string;
|
||||||
|
Justified: side;
|
||||||
|
Width: integer) return string is
|
||||||
|
constant Argument: string(1 to Arg'length) := Arg;
|
||||||
|
constant TypeSpec: string (1 to 2) := Argument(1 to 2);
|
||||||
|
constant Value: string(1 to Arg'length-2) := Argument(3 to Arg'length);
|
||||||
|
begin
|
||||||
|
case TypeSpec is
|
||||||
|
when "U:" | "S:" | "V:" =>
|
||||||
|
return (FIO_bv_PRE & Value & FIO_bv_POST);
|
||||||
|
when "B:" =>
|
||||||
|
-- Value(1 to 1) instead of Value for LeapFrog
|
||||||
|
return (FIO_b_PRE & Value(1 to 1) & FIO_b_POST);
|
||||||
|
when "I:" =>
|
||||||
|
return I_To_b(Value, Justified, Width);
|
||||||
|
when "L:" =>
|
||||||
|
-- Value(1 to 1) instead of Value for LeapFrog
|
||||||
|
return L_To_b(Value(1 to 1));
|
||||||
|
when others =>
|
||||||
|
return Argument;
|
||||||
|
end case;
|
||||||
|
|
||||||
|
end BitOutput;
|
||||||
|
|
||||||
|
|
||||||
|
-------------------------------------------
|
||||||
|
-- Decimal output conversion function --
|
||||||
|
-------------------------------------------
|
||||||
|
|
||||||
|
function DecimalOutput (Arg: string) return integer is
|
||||||
|
constant Argument: string(1 to Arg'length) := Arg;
|
||||||
|
constant TypeSpec: string (1 to 2) := Argument(1 to 2);
|
||||||
|
constant Value: string(1 to Arg'length-2) := Argument(3 to Arg'length);
|
||||||
|
begin
|
||||||
|
case TypeSpec is
|
||||||
|
when "U:"| "V:" =>
|
||||||
|
return U_To_d(Value);
|
||||||
|
when "S:" =>
|
||||||
|
return S_To_d(Value);
|
||||||
|
when "I:" =>
|
||||||
|
return I_To_d(Value);
|
||||||
|
when "B:" =>
|
||||||
|
return B_To_d(Value);
|
||||||
|
when "L:" =>
|
||||||
|
return L_To_d(Value);
|
||||||
|
when others =>
|
||||||
|
return integer'low;
|
||||||
|
end case;
|
||||||
|
|
||||||
|
end DecimalOutput;
|
||||||
|
|
||||||
|
|
||||||
|
----------------------------
|
||||||
|
-- Atomic print functions --
|
||||||
|
----------------------------
|
||||||
|
|
||||||
|
-- test for end of format string
|
||||||
|
|
||||||
|
function FIO_EOS (Format: in string;
|
||||||
|
Pointer: in integer)
|
||||||
|
return boolean is
|
||||||
|
begin
|
||||||
|
return (Pointer > Format'length);
|
||||||
|
end FIO_EOS;
|
||||||
|
|
||||||
|
|
||||||
|
-- Atomic value print function
|
||||||
|
|
||||||
|
procedure FIO_PrintValue (file F: text;
|
||||||
|
L: inout line;
|
||||||
|
Format: in string;
|
||||||
|
Pointer: inout integer;
|
||||||
|
Last: in boolean := FALSE) is
|
||||||
|
variable Char: character;
|
||||||
|
begin
|
||||||
|
while (not FIO_EOS(Format, Pointer)) loop
|
||||||
|
Char := Format(Pointer);
|
||||||
|
case Char is
|
||||||
|
when '\' =>
|
||||||
|
Pointer := Pointer + 1;
|
||||||
|
exit when (FIO_EOS(Format, Pointer));
|
||||||
|
Char := Format(Pointer);
|
||||||
|
case Char is when 'n' => writeline(F, L);
|
||||||
|
when others => write(L, Char);
|
||||||
|
end case;
|
||||||
|
when '%' =>
|
||||||
|
if Last then
|
||||||
|
FIO_Warning_Fsbla(F, L, Format, Pointer);
|
||||||
|
end if;
|
||||||
|
Pointer := Pointer + 1;
|
||||||
|
exit;
|
||||||
|
when others =>
|
||||||
|
write(L, char);
|
||||||
|
end case;
|
||||||
|
Pointer := Pointer + 1;
|
||||||
|
end loop;
|
||||||
|
end FIO_PrintValue;
|
||||||
|
|
||||||
|
|
||||||
|
---- Atomic argument print function
|
||||||
|
|
||||||
|
procedure FIO_PrintArg (file F: text;
|
||||||
|
L: inout line;
|
||||||
|
Format: in string;
|
||||||
|
Pointer: inout integer;
|
||||||
|
Arg: in string) is
|
||||||
|
variable Char: character;
|
||||||
|
variable Justified: side;
|
||||||
|
variable Width: integer;
|
||||||
|
|
||||||
|
begin
|
||||||
|
|
||||||
|
FIO_PrintValue(F, L, Format, Pointer);
|
||||||
|
|
||||||
|
Justified := RIGHT;
|
||||||
|
Width := 0;
|
||||||
|
while (not FIO_EOS(Format, Pointer)) loop
|
||||||
|
Char := Format(Pointer);
|
||||||
|
case Char is
|
||||||
|
when '-' =>
|
||||||
|
Justified := LEFT;
|
||||||
|
Pointer := Pointer + 1;
|
||||||
|
when '0' to '9' =>
|
||||||
|
Width := Width*10 + C_DIGIT_CHARS_MAP(Char);
|
||||||
|
Pointer := Pointer + 1;
|
||||||
|
when 'r' =>
|
||||||
|
write(L, ReasonableOutput(Arg, Justified, Width), Justified, Width);
|
||||||
|
Pointer := Pointer + 1;
|
||||||
|
exit;
|
||||||
|
when 'b' =>
|
||||||
|
write(L, BitOutput(Arg, Justified, Width), Justified, Width);
|
||||||
|
Pointer := Pointer + 1;
|
||||||
|
exit;
|
||||||
|
when 'd' =>
|
||||||
|
write(L, DecimalOutput(Arg), Justified, Width);
|
||||||
|
Pointer := Pointer + 1;
|
||||||
|
exit;
|
||||||
|
when 'q' | 's' =>
|
||||||
|
write(L, Arg, Justified, Width);
|
||||||
|
Pointer := Pointer + 1;
|
||||||
|
exit;
|
||||||
|
when others =>
|
||||||
|
FIO_Warning_Ufs(F, L, Format, Pointer, Char);
|
||||||
|
write(L, Arg, Justified, Width);
|
||||||
|
Pointer := Pointer + 1;
|
||||||
|
exit;
|
||||||
|
end case;
|
||||||
|
end loop;
|
||||||
|
end FIO_PrintArg;
|
||||||
|
|
||||||
|
|
||||||
|
-----------------------------------------------------
|
||||||
|
-- The format string iteration expansion procedure --
|
||||||
|
-----------------------------------------------------
|
||||||
|
|
||||||
|
procedure FIO_FormatExpand (FMT: inout line;
|
||||||
|
Format: in string;
|
||||||
|
StartPointer: in positive) is
|
||||||
|
|
||||||
|
variable Pointer: positive := StartPointer;
|
||||||
|
variable TokenStart: positive;
|
||||||
|
variable IterStringStart: positive;
|
||||||
|
variable IterStringEnd: positive;
|
||||||
|
variable IterCount: natural;
|
||||||
|
variable OpenBrackets: natural;
|
||||||
|
variable L: line;
|
||||||
|
|
||||||
|
begin
|
||||||
|
|
||||||
|
FORMAT_SEARCH: while not FIO_EOS(Format, Pointer) loop
|
||||||
|
|
||||||
|
case Format(Pointer) is
|
||||||
|
|
||||||
|
-- look for format specifier
|
||||||
|
when '%' =>
|
||||||
|
|
||||||
|
-- initialize iteration token search
|
||||||
|
TokenStart := Pointer;
|
||||||
|
IterCount := 0;
|
||||||
|
Pointer := Pointer + 1;
|
||||||
|
|
||||||
|
-- start iteration token search
|
||||||
|
TOKEN_READ: while not FIO_EOS(Format, Pointer) loop
|
||||||
|
|
||||||
|
case Format(Pointer) is
|
||||||
|
|
||||||
|
-- read iteration counter
|
||||||
|
when '0' to '9' =>
|
||||||
|
IterCount := IterCount*10 + C_DIGIT_CHARS_MAP(Format(Pointer));
|
||||||
|
Pointer := Pointer + 1;
|
||||||
|
|
||||||
|
-- expect open bracket
|
||||||
|
when '{' =>
|
||||||
|
|
||||||
|
-- initialize iteration string read
|
||||||
|
OpenBrackets := 1;
|
||||||
|
IterStringStart := Pointer + 1;
|
||||||
|
Pointer := Pointer + 1;
|
||||||
|
-- quit prematurely when iteration count is 0
|
||||||
|
next FORMAT_SEARCH when (IterCount = 0);
|
||||||
|
|
||||||
|
-- start iteration string read
|
||||||
|
ITER_STRING_READ: while not FIO_EOS(Format, Pointer) loop
|
||||||
|
|
||||||
|
case Format(Pointer) is
|
||||||
|
-- keep track of open brackets
|
||||||
|
when '{' =>
|
||||||
|
OpenBrackets := OpenBrackets + 1;
|
||||||
|
Pointer := Pointer + 1;
|
||||||
|
-- when closing bracket is found, process iteration string
|
||||||
|
when '}' =>
|
||||||
|
OpenBrackets := OpenBrackets - 1;
|
||||||
|
if (OpenBrackets = 0) then
|
||||||
|
IterStringEnd := Pointer-1;
|
||||||
|
if (TokenStart /= 1) then
|
||||||
|
write(L, Format(1 to TokenStart-1));
|
||||||
|
end if;
|
||||||
|
for i in 1 to IterCount loop
|
||||||
|
write(L, Format(IterStringStart to IterStringEnd));
|
||||||
|
end loop;
|
||||||
|
if (IterStringEnd /= Format'length) then
|
||||||
|
write(L, Format(IterStringEnd+2 to Format'length));
|
||||||
|
end if;
|
||||||
|
-- call expansion procedure recursively on expanded format
|
||||||
|
FIO_FormatExpand(FMT, L.all, TokenStart);
|
||||||
|
deallocate(L);
|
||||||
|
return;
|
||||||
|
end if;
|
||||||
|
Pointer := Pointer + 1;
|
||||||
|
-- skip escaped characters
|
||||||
|
when '\' =>
|
||||||
|
Pointer := Pointer + 2;
|
||||||
|
-- read iteration string
|
||||||
|
when others =>
|
||||||
|
Pointer := Pointer + 1;
|
||||||
|
|
||||||
|
end case;
|
||||||
|
|
||||||
|
end loop ITER_STRING_READ;
|
||||||
|
|
||||||
|
-- stop iteration token search when no opening bracket found
|
||||||
|
when others =>
|
||||||
|
Pointer := Pointer + 1;
|
||||||
|
next FORMAT_SEARCH;
|
||||||
|
|
||||||
|
end case;
|
||||||
|
|
||||||
|
end loop TOKEN_READ;
|
||||||
|
|
||||||
|
-- skip escaped characters
|
||||||
|
when '\' =>
|
||||||
|
Pointer := Pointer + 2;
|
||||||
|
|
||||||
|
-- read other characters
|
||||||
|
when others =>
|
||||||
|
Pointer := Pointer + 1;
|
||||||
|
|
||||||
|
end case;
|
||||||
|
|
||||||
|
end loop FORMAT_SEARCH;
|
||||||
|
|
||||||
|
write(FMT, Format);
|
||||||
|
deallocate(L);
|
||||||
|
|
||||||
|
end FIO_FormatExpand;
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
--------------------------
|
||||||
|
-- The fprint procedure --
|
||||||
|
--------------------------
|
||||||
|
|
||||||
|
procedure fprint
|
||||||
|
(file F: text;
|
||||||
|
L: inout line;
|
||||||
|
Format: in string;
|
||||||
|
A1 , A2 , A3 , A4 , A5 , A6 , A7 , A8 : in string := FIO_NIL;
|
||||||
|
A9 , A10, A11, A12, A13, A14, A15, A16: in string := FIO_NIL;
|
||||||
|
A17, A18, A19, A20, A21, A22, A23, A24: in string := FIO_NIL;
|
||||||
|
A25, A26, A27, A28, A29, A30, A31, A32: in string := FIO_NIL
|
||||||
|
) is
|
||||||
|
|
||||||
|
variable Pointer: integer;
|
||||||
|
variable FMT: line;
|
||||||
|
|
||||||
|
begin
|
||||||
|
|
||||||
|
Pointer := 1;
|
||||||
|
|
||||||
|
FIO_FormatExpand (FMT, Format, Format'low);
|
||||||
|
|
||||||
|
if (A1 /= FIO_NIL) then FIO_PrintArg(F, L, FMT.all, Pointer, A1 );
|
||||||
|
if (A2 /= FIO_NIL) then FIO_PrintArg(F, L, FMT.all, Pointer, A2 );
|
||||||
|
if (A3 /= FIO_NIL) then FIO_PrintArg(F, L, FMT.all, Pointer, A3 );
|
||||||
|
if (A4 /= FIO_NIL) then FIO_PrintArg(F, L, FMT.all, Pointer, A4 );
|
||||||
|
if (A5 /= FIO_NIL) then FIO_PrintArg(F, L, FMT.all, Pointer, A5 );
|
||||||
|
if (A6 /= FIO_NIL) then FIO_PrintArg(F, L, FMT.all, Pointer, A6 );
|
||||||
|
if (A7 /= FIO_NIL) then FIO_PrintArg(F, L, FMT.all, Pointer, A7 );
|
||||||
|
if (A8 /= FIO_NIL) then FIO_PrintArg(F, L, FMT.all, Pointer, A8 );
|
||||||
|
if (A9 /= FIO_NIL) then FIO_PrintArg(F, L, FMT.all, Pointer, A9 );
|
||||||
|
if (A10 /= FIO_NIL) then FIO_PrintArg(F, L, FMT.all, Pointer, A10);
|
||||||
|
if (A11 /= FIO_NIL) then FIO_PrintArg(F, L, FMT.all, Pointer, A11);
|
||||||
|
if (A12 /= FIO_NIL) then FIO_PrintArg(F, L, FMT.all, Pointer, A12);
|
||||||
|
if (A13 /= FIO_NIL) then FIO_PrintArg(F, L, FMT.all, Pointer, A13);
|
||||||
|
if (A14 /= FIO_NIL) then FIO_PrintArg(F, L, FMT.all, Pointer, A14);
|
||||||
|
if (A15 /= FIO_NIL) then FIO_PrintArg(F, L, FMT.all, Pointer, A15);
|
||||||
|
if (A16 /= FIO_NIL) then FIO_PrintArg(F, L, FMT.all, Pointer, A16);
|
||||||
|
if (A17 /= FIO_NIL) then FIO_PrintArg(F, L, FMT.all, Pointer, A17);
|
||||||
|
if (A18 /= FIO_NIL) then FIO_PrintArg(F, L, FMT.all, Pointer, A18);
|
||||||
|
if (A19 /= FIO_NIL) then FIO_PrintArg(F, L, FMT.all, Pointer, A19);
|
||||||
|
if (A20 /= FIO_NIL) then FIO_PrintArg(F, L, FMT.all, Pointer, A20);
|
||||||
|
if (A21 /= FIO_NIL) then FIO_PrintArg(F, L, FMT.all, Pointer, A21);
|
||||||
|
if (A22 /= FIO_NIL) then FIO_PrintArg(F, L, FMT.all, Pointer, A22);
|
||||||
|
if (A23 /= FIO_NIL) then FIO_PrintArg(F, L, FMT.all, Pointer, A23);
|
||||||
|
if (A24 /= FIO_NIL) then FIO_PrintArg(F, L, FMT.all, Pointer, A24);
|
||||||
|
if (A25 /= FIO_NIL) then FIO_PrintArg(F, L, FMT.all, Pointer, A25);
|
||||||
|
if (A26 /= FIO_NIL) then FIO_PrintArg(F, L, FMT.all, Pointer, A26);
|
||||||
|
if (A27 /= FIO_NIL) then FIO_PrintArg(F, L, FMT.all, Pointer, A27);
|
||||||
|
if (A28 /= FIO_NIL) then FIO_PrintArg(F, L, FMT.all, Pointer, A28);
|
||||||
|
if (A29 /= FIO_NIL) then FIO_PrintArg(F, L, FMT.all, Pointer, A29);
|
||||||
|
if (A30 /= FIO_NIL) then FIO_PrintArg(F, L, FMT.all, Pointer, A30);
|
||||||
|
if (A31 /= FIO_NIL) then FIO_PrintArg(F, L, FMT.all, Pointer, A31);
|
||||||
|
if (A32 /= FIO_NIL) then FIO_PrintArg(F, L, FMT.all, Pointer, A32);
|
||||||
|
end if; end if; end if; end if; end if; end if; end if; end if;
|
||||||
|
end if; end if; end if; end if; end if; end if; end if; end if;
|
||||||
|
end if; end if; end if; end if; end if; end if; end if; end if;
|
||||||
|
end if; end if; end if; end if; end if; end if; end if; end if;
|
||||||
|
|
||||||
|
FIO_PrintValue(F, L, FMT.all, Pointer, Last => TRUE);
|
||||||
|
|
||||||
|
deallocate(FMT);
|
||||||
|
|
||||||
|
end fprint;
|
||||||
|
|
||||||
|
|
||||||
|
-------------------------------------------
|
||||||
|
-- Formatted output conversion functions --
|
||||||
|
-------------------------------------------
|
||||||
|
|
||||||
|
function fo (Arg: unsigned) return string is
|
||||||
|
constant Argument: unsigned(1 to Arg'length) := Arg;
|
||||||
|
variable Result: string(1 to Arg'length);
|
||||||
|
begin
|
||||||
|
for i in Argument'range loop
|
||||||
|
Result(i) := C_STD_LOGIC_MAP(Argument(i));
|
||||||
|
end loop;
|
||||||
|
return ("U:" & Result);
|
||||||
|
end fo;
|
||||||
|
|
||||||
|
function fo (Arg: signed) return string is
|
||||||
|
constant Argument: signed(1 to Arg'length) := Arg;
|
||||||
|
variable Result: string(1 to Arg'length);
|
||||||
|
begin
|
||||||
|
for i in Argument'range loop
|
||||||
|
Result(i) := C_STD_LOGIC_MAP(Argument(i));
|
||||||
|
end loop;
|
||||||
|
return ("S:" & Result);
|
||||||
|
end fo;
|
||||||
|
|
||||||
|
function fo (Arg: std_logic_vector) return string is
|
||||||
|
constant Argument: std_logic_vector(1 to Arg'length) := Arg;
|
||||||
|
variable Result: string(1 to Arg'length);
|
||||||
|
begin
|
||||||
|
for i in Argument'range loop
|
||||||
|
Result(i) := C_STD_LOGIC_MAP(Argument(i));
|
||||||
|
end loop;
|
||||||
|
return ("V:" & Result);
|
||||||
|
end fo;
|
||||||
|
|
||||||
|
function fo (Arg: std_ulogic_vector) return string is
|
||||||
|
constant Argument: std_ulogic_vector(1 to Arg'length) := Arg;
|
||||||
|
variable Result: string(1 to Arg'length);
|
||||||
|
begin
|
||||||
|
for i in Argument'range loop
|
||||||
|
Result(i) := C_STD_LOGIC_MAP(Argument(i));
|
||||||
|
end loop;
|
||||||
|
return ("V:" & Result);
|
||||||
|
end fo;
|
||||||
|
|
||||||
|
function fo (Arg: bit_vector) return string is
|
||||||
|
constant Argument: bit_vector(1 to Arg'length) := Arg;
|
||||||
|
variable Result: string(1 to Arg'length);
|
||||||
|
begin
|
||||||
|
for i in Argument'range loop
|
||||||
|
Result(i) := C_BIT_MAP(Argument(i));
|
||||||
|
end loop;
|
||||||
|
return ("V:" & Result);
|
||||||
|
end fo;
|
||||||
|
|
||||||
|
function fo (Arg: integer) return string is
|
||||||
|
variable Argument: integer := Arg;
|
||||||
|
variable Result: string(1 to FIO_d_WIDTH) := (others => ' ');
|
||||||
|
variable Sign: character := ' ';
|
||||||
|
begin
|
||||||
|
if (Argument < 0) and (Argument /= integer'low) then
|
||||||
|
Sign := '-';
|
||||||
|
Argument := -Argument;
|
||||||
|
end if;
|
||||||
|
for i in Result'reverse_range loop
|
||||||
|
Result(i) := C_DIGITS_MAP(Argument mod 10);
|
||||||
|
Argument := Argument / 10;
|
||||||
|
exit when (Argument = 0);
|
||||||
|
end loop;
|
||||||
|
return ("I:" & Sign & Result);
|
||||||
|
end fo;
|
||||||
|
|
||||||
|
function fo (Arg: std_ulogic) return string is
|
||||||
|
begin
|
||||||
|
return ("B:" & C_STD_LOGIC_MAP(Arg));
|
||||||
|
end fo;
|
||||||
|
|
||||||
|
function fo (Arg: bit) return string is
|
||||||
|
begin
|
||||||
|
return ("B:" & C_BIT_MAP(Arg));
|
||||||
|
end fo;
|
||||||
|
|
||||||
|
function fo (Arg: boolean) return string is
|
||||||
|
begin
|
||||||
|
if (ARG = TRUE) then
|
||||||
|
return ("L:T");
|
||||||
|
else
|
||||||
|
return ("L:F");
|
||||||
|
end if;
|
||||||
|
end fo;
|
||||||
|
|
||||||
|
function fo (Arg: character) return string is
|
||||||
|
begin
|
||||||
|
return ("C:" & Arg);
|
||||||
|
end fo;
|
||||||
|
|
||||||
|
-- auxilary function fgets(Arg :string)
|
||||||
|
-- returns index of first NUL in Arg or if no NUL is present just Arg'length
|
||||||
|
-- goes through Arg from 1 to Arg'length
|
||||||
|
function fgets (Arg: string) return integer is
|
||||||
|
variable index: integer := Arg'length;
|
||||||
|
begin
|
||||||
|
for i in 1 to Arg'length loop
|
||||||
|
if Arg(i) = NUL then
|
||||||
|
index := i - 1;
|
||||||
|
exit;
|
||||||
|
else
|
||||||
|
null;
|
||||||
|
end if;
|
||||||
|
end loop;
|
||||||
|
return index;
|
||||||
|
end fgets;
|
||||||
|
|
||||||
|
-- returns the Arg string until the first NUL was encountered
|
||||||
|
-- if fo is used on a string with NUL in it it will stop reading the rest
|
||||||
|
-- of the string, even if a larger field width has been supplied. fo will
|
||||||
|
-- then just pad the remaining characters with blanco's
|
||||||
|
function fo (Arg: string) return string is
|
||||||
|
begin
|
||||||
|
return Arg(1 to fgets(Arg));
|
||||||
|
end fo;
|
||||||
|
|
||||||
|
function fo (Arg: time) return string is
|
||||||
|
begin
|
||||||
|
return fo (integer (Arg / 1 ns));
|
||||||
|
end fo;
|
||||||
|
|
||||||
|
end PCK_FIO;
|
||||||
|
|
||||||
@@ -0,0 +1,88 @@
|
|||||||
|
---- $Id: README,v 1.1 2008-08-23 08:20:28 Jens Exp $
|
||||||
|
----
|
||||||
|
---- PCK_FIO: a VHDL package for C-style formatted file output
|
||||||
|
---- Copyright (C) 1995, 2001 Easics NV
|
||||||
|
----
|
||||||
|
---- This library 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 2.1 of the License, or (at your option) any later version.
|
||||||
|
----
|
||||||
|
---- This library 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 this library; if not, write to the Free Software
|
||||||
|
---- Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
|
||||||
|
----
|
||||||
|
---- For suggestions, bug reports, enhancement requests, and info about
|
||||||
|
---- our design services, you can contact us at the following address:
|
||||||
|
---- http://www.easics.com
|
||||||
|
---- Easics NV, Interleuvenlaan 86, B-3001 Leuven, Belgium
|
||||||
|
---- tel.: +32 16 395 600 fax : +32 16 395 619
|
||||||
|
---- e-mail: jand@easics.be (Jan Decaluwe)
|
||||||
|
----
|
||||||
|
|
||||||
|
Version 2002.07
|
||||||
|
===============
|
||||||
|
|
||||||
|
Contents
|
||||||
|
========
|
||||||
|
|
||||||
|
This distribution contains the following files:
|
||||||
|
|
||||||
|
PCK_FIO_1987.vhd: VHDL-87 source of the header of the PCK_FIO package
|
||||||
|
PCK_FIO_1987_BODY.vhd: VHDL-87 source of the body of the PCK_FIO package
|
||||||
|
PCK_FIO_1993.vhd: VHDL-93 source of the header of the PCK_FIO package
|
||||||
|
PCK_FIO_1993_BODY.vhd: VHDL-93 source of the body of the PCK_FIO package
|
||||||
|
TB_PCK_FIO_1987.vhd: VHDL-87 source of the testbench for package PCK_FIO
|
||||||
|
TB_PCK_FIO_1993.vhd: VHDL-93 source of the testbench for package PCK_FIO
|
||||||
|
PCK_FIO.out.gold: Certified test bench output
|
||||||
|
PCK_FIO.html: Manual for PCK_FIO in html format
|
||||||
|
README: This file
|
||||||
|
|
||||||
|
|
||||||
|
Installation
|
||||||
|
============
|
||||||
|
|
||||||
|
VHDL-1987
|
||||||
|
---------
|
||||||
|
To install PCK_FIO, define a VHDL library called EASICS_PACKAGES, and
|
||||||
|
analyze the VHDL file PCK_FIO_1987.vhd and PCK_FIO_1987_BODY.vhd into this library.
|
||||||
|
|
||||||
|
To install the test bench, analyze TB_PCK_FIO_1987.vhd into the same library.
|
||||||
|
|
||||||
|
VHDL-1993
|
||||||
|
---------
|
||||||
|
To install PCK_FIO, define a VHDL library called EASICS_PACKAGES, and
|
||||||
|
analyze the VHDL file PCK_FIO_1993.vhd and PCK_FIO_1993_BODY.vhd into this library.
|
||||||
|
|
||||||
|
To install the test bench, analyze TB_PCK_FIO_1993.vhd into the same library.
|
||||||
|
|
||||||
|
Numeric packages
|
||||||
|
----------------
|
||||||
|
If you want to use IEEE.std_logic_arith instead of IEEE.numeric_std, you need
|
||||||
|
to edit the source code of the package, both header and body, and the test bench
|
||||||
|
and replace the package use clause. PCK_FIO works with either of these packages.
|
||||||
|
|
||||||
|
Documentation
|
||||||
|
-------------
|
||||||
|
To install the documentation, put the file point PCK_FIO.html in a path of
|
||||||
|
your choosing, point your web browser to it, and bookmark it.
|
||||||
|
|
||||||
|
|
||||||
|
Installation check
|
||||||
|
==================
|
||||||
|
|
||||||
|
After installing the test bench, you should run it. The corresponding VHDL
|
||||||
|
design unit is EASICS_PACKAGES.TBE_PCK_FIO(TB).
|
||||||
|
|
||||||
|
Simulating the test bench should create a file called PCK_FIO.out. This file
|
||||||
|
should be identical to PCK_FIO.out.gold. Any difference indicates a portability
|
||||||
|
issue or a simulator non-compliance or bug.
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
@@ -0,0 +1,531 @@
|
|||||||
|
---- $Id: TB_PCK_FIO_1987.vhd,v 1.1 2008-08-23 08:20:28 Jens Exp $
|
||||||
|
----
|
||||||
|
---- PCK_FIO: a VHDL package for C-style formatted file output
|
||||||
|
---- Copyright (C) 1995, 2001 Easics NV
|
||||||
|
----
|
||||||
|
---- This library 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 2.1 of the License, or (at your option) any later version.
|
||||||
|
----
|
||||||
|
---- This library 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 this library; if not, write to the Free Software
|
||||||
|
---- Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
|
||||||
|
----
|
||||||
|
---- For suggestions, bug reports, enhancement requests, and info about
|
||||||
|
---- our design services, you can contact us at the following address:
|
||||||
|
---- http://www.easics.com
|
||||||
|
---- Easics NV, Interleuvenlaan 86, B-3001 Leuven, Belgium
|
||||||
|
---- tel.: +32 16 395 600 fax : +32 16 395 619
|
||||||
|
---- e-mail: jand@easics.be (Jan Decaluwe)
|
||||||
|
----
|
||||||
|
|
||||||
|
|
||||||
|
library IEEE;
|
||||||
|
use IEEE.std_logic_1164.all;
|
||||||
|
-- signed/unsigned definition: use either std_logic_arith or numeric_std
|
||||||
|
-- use IEEE.std_logic_arith.all; -- the Synopsys one
|
||||||
|
use IEEE.numeric_std.all;
|
||||||
|
|
||||||
|
use STD.TEXTIO.all;
|
||||||
|
|
||||||
|
library EASICS_PACKAGES;
|
||||||
|
use EASICS_PACKAGES.PCK_FIO.all;
|
||||||
|
|
||||||
|
entity TBE_PCK_FIO is
|
||||||
|
|
||||||
|
end TBE_PCK_FIO;
|
||||||
|
|
||||||
|
architecture TB of TBE_PCK_FIO is
|
||||||
|
|
||||||
|
begin
|
||||||
|
|
||||||
|
USAGE: process
|
||||||
|
|
||||||
|
file RESULT: text is out "PCK_FIO.out";
|
||||||
|
variable L: line;
|
||||||
|
variable Pointer: integer;
|
||||||
|
variable BoolTrue: boolean := TRUE;
|
||||||
|
variable BoolFalse: boolean := FALSE;
|
||||||
|
variable IntPos: integer := 5678;
|
||||||
|
variable BigIntPos: integer := 12345678;
|
||||||
|
variable IntNeg: integer := -8765;
|
||||||
|
variable BigIntNeg: integer := -87654321;
|
||||||
|
variable Uns: unsigned(6 downto 0) := unsigned'("1010010");
|
||||||
|
variable Unk: unsigned(6 downto 0) := unsigned'("1X10Z10");
|
||||||
|
variable Std: std_logic_vector(6 downto 0) := std_logic_vector'("0010010");
|
||||||
|
variable SigPos: signed(6 downto 0) := signed'("0010010");
|
||||||
|
variable SigNeg: signed(6 downto 0) := signed'("1010010");
|
||||||
|
variable BitX: std_logic := 'X';
|
||||||
|
variable Bit1: std_logic := '1';
|
||||||
|
variable Bit0: std_logic := '0';
|
||||||
|
|
||||||
|
variable parameter_1: integer := 1234;
|
||||||
|
variable parameter_2: integer := 2345;
|
||||||
|
variable parameter_3: integer := 4567;
|
||||||
|
|
||||||
|
constant TempString: string :="ABC" & NUL & "DEF";
|
||||||
|
begin
|
||||||
|
|
||||||
|
fprint(RESULT, L,
|
||||||
|
"PCK_FIO.out: TESTBENCH OUTPUT FOR PCK_FIO\n" &
|
||||||
|
"-----------------------------------------\n\n" &
|
||||||
|
"This is the result of running the PCK_FIO testbench.\n" &
|
||||||
|
"This file should be compared with PCK_FIO.out.gold, which is\n" &
|
||||||
|
"the reference output. Any difference indicates a portability\n" &
|
||||||
|
"issue or a simulator non-compliance or bug.\n\n"
|
||||||
|
);
|
||||||
|
|
||||||
|
|
||||||
|
fprint(RESULT, L,
|
||||||
|
"\n--------------------\n" &
|
||||||
|
"-- Basic features --\n" &
|
||||||
|
"--------------------\n\n"
|
||||||
|
);
|
||||||
|
|
||||||
|
fprint(RESULT, L,
|
||||||
|
"-- First some auxiliary declarations\n"
|
||||||
|
);
|
||||||
|
|
||||||
|
fprint(RESULT, L,
|
||||||
|
"> file RESULT: text is out ""PCK_FIO.out"";\n" &
|
||||||
|
"> variable L: line;\n" &
|
||||||
|
"> variable BoolTrue: boolean := TRUE;\n" &
|
||||||
|
"> variable BoolFalse: boolean := FALSE;\n" &
|
||||||
|
"> variable IntPos: integer := 5678;\n" &
|
||||||
|
"> variable BigIntPos: integer := 12345678;\n" &
|
||||||
|
"> variable IntNeg: integer := -8765;\n" &
|
||||||
|
"> variable BigIntNeg: integer := -87654321;\n" &
|
||||||
|
"> variable Uns: unsigned(6 downto 0) := unsigned'(""1010010"");\n" &
|
||||||
|
"> variable Unk: unsigned(6 downto 0) := unsigned'(""1X10Z10"");\n" &
|
||||||
|
"> variable Std: std_logic_vector(6 downto 0) := std_logic_vector'(""0010010"");\n" &
|
||||||
|
"> variable SigPos: signed(6 downto 0) := signed'(""0010010"");\n" &
|
||||||
|
"> variable SigNeg: signed(6 downto 0) := signed'(""1010010"");\n" &
|
||||||
|
"> variable BitX: std_logic := 'X';\n" &
|
||||||
|
"> variable Bit1: std_logic := '1';\n" &
|
||||||
|
"> variable Bit0: std_logic := '0';\n" &
|
||||||
|
"> constant TempString: string := ""ABC"" & NUL & ""DEF"";\n"
|
||||||
|
);
|
||||||
|
|
||||||
|
|
||||||
|
fprint(RESULT, L,
|
||||||
|
"\n\n-- fprint call with no arguments\n" &
|
||||||
|
"> fprint(RESULT, L, ""No arguments.\\n"");\n"
|
||||||
|
);
|
||||||
|
fprint(RESULT, L, "No arguments.\n");
|
||||||
|
|
||||||
|
|
||||||
|
fprint(RESULT, L,
|
||||||
|
"\n-- Special characters need to be escaped\n" &
|
||||||
|
"> fprint(RESULT, L, ""Special characters: \\\% \\\\ "" \\n"");\n"
|
||||||
|
);
|
||||||
|
|
||||||
|
fprint(RESULT, L, "Special characters: \% \\ "" \n");
|
||||||
|
|
||||||
|
|
||||||
|
fprint(RESULT, L,
|
||||||
|
"\n-- Various format specifiers interprete the same object differently\n" &
|
||||||
|
"> fprint(RESULT, L, ""Format specifiers: \%r \%d \%b \%q\\n"",\n" &
|
||||||
|
"> fo(Uns), fo(Uns), fo(Uns), fo(Uns)\n" &
|
||||||
|
"> );\n"
|
||||||
|
);
|
||||||
|
|
||||||
|
fprint(RESULT, L, "Format specifiers: %r %d %b %q\n",
|
||||||
|
fo(Uns), fo(Uns), fo(Uns), fo(Uns)
|
||||||
|
);
|
||||||
|
|
||||||
|
fprint(RESULT, L,
|
||||||
|
"\n-- Format string can be shortened by using the iteration specifier\n" &
|
||||||
|
"> fprint(RESULT, L, ""Iteration specifier: \%4{\%r }\\n"",\n" &
|
||||||
|
"> fo(Uns), fo(SigPos), fo(SigNeg), fo(Std)\n" &
|
||||||
|
"> );\n"
|
||||||
|
);
|
||||||
|
|
||||||
|
fprint(RESULT, L, "Iteration specifier: %4{%r }\n",
|
||||||
|
fo(Uns), fo(SigPos), fo(SigNeg), fo(Std)
|
||||||
|
);
|
||||||
|
fprint(RESULT, L,
|
||||||
|
"\n-------------------------------\n"&
|
||||||
|
"--Testing string manipulation--\n"&
|
||||||
|
"-------------------------------\n");
|
||||||
|
fprint(RESULT, L, "--testing done using the string TempString : " & """ABC"""
|
||||||
|
& " & NUL & ""DEF""\n");
|
||||||
|
-- temp_string: string:="ABC"&NUL&"DEF"
|
||||||
|
-- test for detecting NUL in string
|
||||||
|
fprint(RESULT, L, "\n--test for NUL ending in strings\n");
|
||||||
|
fprint(RESULT, L, "> fprint(RESULT, L, fo(TempString));\n");
|
||||||
|
fprint(RESULT, L, fo(TempString));
|
||||||
|
|
||||||
|
-- direct inclusion of string in fprint should give whole string
|
||||||
|
fprint(RESULT, L, "\n--same without fo,so without NUL testing\n");
|
||||||
|
fprint(RESULT, L, "> fprint(RESULT, L, TempString);\n");
|
||||||
|
fprint(RESULT, L, TempString & "\n");
|
||||||
|
|
||||||
|
-- influence of given width
|
||||||
|
|
||||||
|
fprint(RESULT, L, "\n--if there are less characters in the given string then"
|
||||||
|
& " in the width fo will\n"&
|
||||||
|
"-- pad the remaining with blanco's according to the given justification\n");
|
||||||
|
fprint(RESULT, L, "\n--with specified width, justified right,using fo\n");
|
||||||
|
fprint(RESULT, L, "> fprint(RESULT, L, ""\%5s"", fo(TempString));\n");
|
||||||
|
fprint(RESULT, L, "%5s", fo(TempString));
|
||||||
|
fprint(RESULT, L, "\n--with specified width, justified left, using fo\n");
|
||||||
|
fprint(RESULT, L, "> fprint(RESULT, L, ""\%-5s"", fo(TempString));\n");
|
||||||
|
fprint(RESULT, L, "%-5s",fo(TempString));
|
||||||
|
fprint(RESULT, L, "\n--with specified width without fo\n");
|
||||||
|
fprint(RESUlT, L, "> fprint(RESULT, L, ""\%9s"", TempString);\n");
|
||||||
|
fprint(RESULT, L, "%9s", TempString);
|
||||||
|
fprint(RESULT, L, "\n\n-- if the width is smaller then the number" &
|
||||||
|
" of characters in the string fprint\n" &
|
||||||
|
"-- will output the string with the minimum of characters needed\n");
|
||||||
|
fprint(RESULT, L, "\n--with specified width,using fo\n");
|
||||||
|
fprint(RESULT, L, "> fprint(RESULT, L, ""\%2s"", fo(TempString));\n");
|
||||||
|
fprint(RESULT, L, "%2s",fo(TempString));
|
||||||
|
fprint(RESULT, L, "\n--with specified width without fo\n");
|
||||||
|
fprint(RESUlT, L, "> fprint(RESULT, L, ""\%4s"", TempString);\n");
|
||||||
|
fprint(RESULT, L, "%4s", TempString);
|
||||||
|
|
||||||
|
|
||||||
|
fprint(RESULT, L,
|
||||||
|
"\n\n------------------------------------\n" &
|
||||||
|
"-- Support for bit-oriented types --\n" &
|
||||||
|
"------------------------------------\n"
|
||||||
|
);
|
||||||
|
|
||||||
|
fprint (RESULT, L, "\n-- Reasonable format\n" &
|
||||||
|
"> fprint(RESULT, L, ""Reasonable format: \%9{\%r }\\n"",\n" &
|
||||||
|
"> fo(Std), fo(Uns), fo(SigPos), fo(SigNeg), fo(Unk),\n" &
|
||||||
|
"> fo(Bit1), fo(BitX), fo(BoolTrue), fo(BoolFalse) \n" &
|
||||||
|
"> );\n"
|
||||||
|
);
|
||||||
|
|
||||||
|
|
||||||
|
fprint(RESULT, L, "Reasonable format: %9{%r }\n",
|
||||||
|
fo(Std), fo(Uns), fo(SigPos), fo(SigNeg), fo(Unk),
|
||||||
|
fo(Bit1), fo(BitX), fo(BoolTrue), fo(BoolFalse)
|
||||||
|
);
|
||||||
|
|
||||||
|
fprint (RESULT, L, "\n-- Decimal format\n" &
|
||||||
|
"> fprint(RESULT, L, ""Decimal format: \%7{\%d }\\n"",\n" &
|
||||||
|
"> fo(Std), fo(Uns), fo(SigPos), fo(SigNeg), fo(Unk),\n" &
|
||||||
|
"> fo(Bit1), fo(BitX), fo(BoolTrue), fo(BoolFalse) \n" &
|
||||||
|
"> );\n"
|
||||||
|
);
|
||||||
|
|
||||||
|
|
||||||
|
fprint(RESULT, L, "Decimal format: %9{%d }\n",
|
||||||
|
fo(Std), fo(Uns), fo(SigPos), fo(SigNeg), fo(Unk),
|
||||||
|
fo(Bit1), fo(BitX), fo(BoolTrue), fo(BoolFalse)
|
||||||
|
);
|
||||||
|
|
||||||
|
fprint (RESULT, L, "\n-- Bit format\n" &
|
||||||
|
"> fprint(RESULT, L, ""Bit format: \%7{\%b }\\n"",\n" &
|
||||||
|
"> fo(Std), fo(Uns), fo(SigPos), fo(SigNeg), fo(Unk),\n" &
|
||||||
|
"> fo(Bit1), fo(BitX), fo(BoolTrue), fo(BoolFalse) \n" &
|
||||||
|
"> );\n"
|
||||||
|
);
|
||||||
|
|
||||||
|
|
||||||
|
fprint(RESULT, L, "Bit format: %9{%b }\n",
|
||||||
|
fo(Std), fo(Uns), fo(SigPos), fo(SigNeg), fo(Unk),
|
||||||
|
fo(Bit1), fo(BitX), fo(BoolTrue), fo(BoolFalse)
|
||||||
|
);
|
||||||
|
|
||||||
|
fprint(RESULT, L,
|
||||||
|
"\n\n" &
|
||||||
|
"-- Alignment\n-- Template of the call: (<fs> stands for the format specifier)\n"
|
||||||
|
);
|
||||||
|
|
||||||
|
|
||||||
|
fprint(RESULT, L, "\n" &
|
||||||
|
"> fprint(RESULT, L, ""Bitvectors with <fs>: \%4{<fs>|}\\n"",\n" &
|
||||||
|
"> fo(Std), fo(Uns), fo(SigPos), fo(SigNeg)\n" &
|
||||||
|
|
||||||
|
"> );\n"
|
||||||
|
);
|
||||||
|
|
||||||
|
fprint(RESULT, L,
|
||||||
|
"\n" &
|
||||||
|
"-- Results of the call with various format specifiers\n\n"
|
||||||
|
);
|
||||||
|
|
||||||
|
fprint(RESULT, L, "Bitvectors with \%1r: %4{%1r|} \n",
|
||||||
|
fo(Uns), fo(Std), fo(SigPos), fo(SigNeg)
|
||||||
|
);
|
||||||
|
fprint(RESULT, L, "Bitvectors with \%2r: %4{%2r|} \n",
|
||||||
|
fo(Uns), fo(Std), fo(SigPos), fo(SigNeg)
|
||||||
|
);
|
||||||
|
fprint(RESULT, L, "Bitvectors with \%3r: %4{%3r|} \n",
|
||||||
|
fo(Uns), fo(Std), fo(SigPos), fo(SigNeg)
|
||||||
|
);
|
||||||
|
fprint(RESULT, L, "Bitvectors with \%4r: %4{%4r|} \n",
|
||||||
|
fo(Uns), fo(Std), fo(SigPos), fo(SigNeg)
|
||||||
|
);
|
||||||
|
fprint(RESULT, L, "Bitvectors with \%5r: %4{%5r|} \n",
|
||||||
|
fo(Uns), fo(Std), fo(SigPos), fo(SigNeg)
|
||||||
|
);
|
||||||
|
fprint(RESULT, L, "Bitvectors with \%6r: %4{%6r|} \n",
|
||||||
|
fo(Uns), fo(Std), fo(SigPos), fo(SigNeg)
|
||||||
|
);
|
||||||
|
fprint(RESULT, L, "Bitvectors with \%7r: %4{%7r|} \n",
|
||||||
|
fo(Uns), fo(Std), fo(SigPos), fo(SigNeg)
|
||||||
|
);
|
||||||
|
fprint(RESULT, L, "Bitvectors with \%8r: %4{%8r|} \n",
|
||||||
|
fo(Uns), fo(Std), fo(SigPos), fo(SigNeg)
|
||||||
|
);
|
||||||
|
fprint(RESULT, L, "Bitvectors with \%9r: %4{%9r|} \n",
|
||||||
|
fo(Uns), fo(Std), fo(SigPos), fo(SigNeg)
|
||||||
|
);
|
||||||
|
fprint(RESULT, L, "\n");
|
||||||
|
fprint(RESULT, L, "Bitvectors with \%-1r: %4{%-1r|} \n",
|
||||||
|
fo(Uns), fo(Std), fo(SigPos), fo(SigNeg)
|
||||||
|
);
|
||||||
|
fprint(RESULT, L, "Bitvectors with \%-2r: %4{%-2r|} \n",
|
||||||
|
fo(Uns), fo(Std), fo(SigPos), fo(SigNeg)
|
||||||
|
);
|
||||||
|
fprint(RESULT, L, "Bitvectors with \%-3r: %4{%-3r|} \n",
|
||||||
|
fo(Uns), fo(Std), fo(SigPos), fo(SigNeg)
|
||||||
|
);
|
||||||
|
fprint(RESULT, L, "Bitvectors with \%-4r: %4{%-4r|} \n",
|
||||||
|
fo(Uns), fo(Std), fo(SigPos), fo(SigNeg)
|
||||||
|
);
|
||||||
|
fprint(RESULT, L, "Bitvectors with \%-5r: %4{%-5r|} \n",
|
||||||
|
fo(Uns), fo(Std), fo(SigPos), fo(SigNeg)
|
||||||
|
);
|
||||||
|
fprint(RESULT, L, "Bitvectors with \%-6r: %4{%-6r|} \n",
|
||||||
|
fo(Uns), fo(Std), fo(SigPos), fo(SigNeg)
|
||||||
|
);
|
||||||
|
fprint(RESULT, L, "Bitvectors with \%-7r: %4{%-7r|} \n",
|
||||||
|
fo(Uns), fo(Std), fo(SigPos), fo(SigNeg)
|
||||||
|
);
|
||||||
|
fprint(RESULT, L, "Bitvectors with \%-8r: %4{%-8r|} \n",
|
||||||
|
fo(Uns), fo(Std), fo(SigPos), fo(SigNeg)
|
||||||
|
);
|
||||||
|
fprint(RESULT, L, "Bitvectors with \%-9r: %4{%-9r|} \n",
|
||||||
|
fo(Uns), fo(Std), fo(SigPos), fo(SigNeg)
|
||||||
|
);
|
||||||
|
fprint(RESULT, L, "\n");
|
||||||
|
fprint(RESULT, L, "Bitvectors with \%1d: %4{%1d|} \n",
|
||||||
|
fo(Uns), fo(Std), fo(SigPos), fo(SigNeg)
|
||||||
|
);
|
||||||
|
fprint(RESULT, L, "Bitvectors with \%2d: %4{%2d|} \n",
|
||||||
|
fo(Uns), fo(Std), fo(SigPos), fo(SigNeg)
|
||||||
|
);
|
||||||
|
fprint(RESULT, L, "Bitvectors with \%3d: %4{%3d|} \n",
|
||||||
|
fo(Uns), fo(Std), fo(SigPos), fo(SigNeg)
|
||||||
|
);
|
||||||
|
fprint(RESULT, L, "Bitvectors with \%4d: %4{%4d|} \n",
|
||||||
|
fo(Uns), fo(Std), fo(SigPos), fo(SigNeg)
|
||||||
|
);
|
||||||
|
fprint(RESULT, L, "Bitvectors with \%5d: %4{%5d|} \n",
|
||||||
|
fo(Uns), fo(Std), fo(SigPos), fo(SigNeg)
|
||||||
|
);
|
||||||
|
fprint(RESULT, L, "Bitvectors with \%6d: %4{%6d|} \n",
|
||||||
|
fo(Uns), fo(Std), fo(SigPos), fo(SigNeg)
|
||||||
|
);
|
||||||
|
fprint(RESULT, L, "Bitvectors with \%7d: %4{%7d|} \n",
|
||||||
|
fo(Uns), fo(Std), fo(SigPos), fo(SigNeg)
|
||||||
|
);
|
||||||
|
fprint(RESULT, L, "Bitvectors with \%8d: %4{%8d|} \n",
|
||||||
|
fo(Uns), fo(Std), fo(SigPos), fo(SigNeg)
|
||||||
|
);
|
||||||
|
fprint(RESULT, L, "Bitvectors with \%9d: %4{%9d|} \n",
|
||||||
|
fo(Uns), fo(Std), fo(SigPos), fo(SigNeg)
|
||||||
|
);
|
||||||
|
fprint(RESULT, L, "\n");
|
||||||
|
fprint(RESULT, L, "Bitvectors with \%-1d: %4{%-1d|} \n",
|
||||||
|
fo(Uns), fo(Std), fo(SigPos), fo(SigNeg)
|
||||||
|
);
|
||||||
|
fprint(RESULT, L, "Bitvectors with \%-2d: %4{%-2d|} \n",
|
||||||
|
fo(Uns), fo(Std), fo(SigPos), fo(SigNeg)
|
||||||
|
);
|
||||||
|
fprint(RESULT, L, "Bitvectors with \%-3d: %4{%-3d|} \n",
|
||||||
|
fo(Uns), fo(Std), fo(SigPos), fo(SigNeg)
|
||||||
|
);
|
||||||
|
fprint(RESULT, L, "Bitvectors with \%-4d: %4{%-4d|} \n",
|
||||||
|
fo(Uns), fo(Std), fo(SigPos), fo(SigNeg)
|
||||||
|
);
|
||||||
|
fprint(RESULT, L, "Bitvectors with \%-5d: %4{%-5d|} \n",
|
||||||
|
fo(Uns), fo(Std), fo(SigPos), fo(SigNeg)
|
||||||
|
);
|
||||||
|
fprint(RESULT, L, "Bitvectors with \%-6d: %4{%-6d|} \n",
|
||||||
|
fo(Uns), fo(Std), fo(SigPos), fo(SigNeg)
|
||||||
|
);
|
||||||
|
fprint(RESULT, L, "Bitvectors with \%-7d: %4{%-7d|} \n",
|
||||||
|
fo(Uns), fo(Std), fo(SigPos), fo(SigNeg)
|
||||||
|
);
|
||||||
|
fprint(RESULT, L, "Bitvectors with \%-8d: %4{%-8d|} \n",
|
||||||
|
fo(Uns), fo(Std), fo(SigPos), fo(SigNeg)
|
||||||
|
);
|
||||||
|
fprint(RESULT, L, "Bitvectors with \%-9d: %4{%-9d|} \n",
|
||||||
|
fo(Uns), fo(Std), fo(SigPos), fo(SigNeg)
|
||||||
|
);
|
||||||
|
fprint(RESULT, L, "\n");
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
fprint(RESULT, L,
|
||||||
|
"\n-------------------------------\n" &
|
||||||
|
"-- Support for integer types --\n" &
|
||||||
|
"-------------------------------\n"
|
||||||
|
);
|
||||||
|
|
||||||
|
fprint(RESULT, L,
|
||||||
|
"\n\n" &
|
||||||
|
"-- Template of the call: (<fs> stands for the format specifier)\n"
|
||||||
|
);
|
||||||
|
|
||||||
|
|
||||||
|
fprint(RESULT, L, "\n" &
|
||||||
|
"> fprint(RESULT, L, ""Integers with <fs>: \%4{<fs>|}\\n"",\n" &
|
||||||
|
"> fo(IntPos), fo(IntNeg), fo(BigIntPos), fo(BigIntNeg)\n" &
|
||||||
|
|
||||||
|
"> );\n"
|
||||||
|
);
|
||||||
|
|
||||||
|
fprint(RESULT, L,
|
||||||
|
"\n" &
|
||||||
|
"-- Results of the call with various format specifiers\n\n"
|
||||||
|
);
|
||||||
|
|
||||||
|
|
||||||
|
fprint(RESULT, L, "Integers with \%5d: %4{%5d|} \n",
|
||||||
|
fo(IntPos), fo(IntNeg), fo(BigIntPos), fo(BigIntNeg)
|
||||||
|
);
|
||||||
|
fprint(RESULT, L, "Integers with \%6d: %4{%6d|} \n",
|
||||||
|
fo(IntPos), fo(IntNeg), fo(BigIntPos), fo(BigIntNeg)
|
||||||
|
);
|
||||||
|
fprint(RESULT, L, "Integers with \%7d: %4{%7d|} \n",
|
||||||
|
fo(IntPos), fo(IntNeg), fo(BigIntPos), fo(BigIntNeg)
|
||||||
|
);
|
||||||
|
fprint(RESULT, L, "Integers with \%8d: %4{%8d|} \n",
|
||||||
|
fo(IntPos), fo(IntNeg), fo(BigIntPos), fo(BigIntNeg)
|
||||||
|
);
|
||||||
|
fprint(RESULT, L, "Integers with \%9d: %4{%9d|} \n",
|
||||||
|
fo(IntPos), fo(IntNeg), fo(BigIntPos), fo(BigIntNeg)
|
||||||
|
);
|
||||||
|
fprint(RESULT, L, "Integers with \%10d: %4{%10d|} \n",
|
||||||
|
fo(IntPos), fo(IntNeg), fo(BigIntPos), fo(BigIntNeg)
|
||||||
|
);
|
||||||
|
fprint(RESULT, L, "\n");
|
||||||
|
fprint(RESULT, L, "Integers with \%-5d: %4{%-5d|} \n",
|
||||||
|
fo(IntPos), fo(IntNeg), fo(BigIntPos), fo(BigIntNeg)
|
||||||
|
);
|
||||||
|
fprint(RESULT, L, "Integers with \%-6d: %4{%-6d|} \n",
|
||||||
|
fo(IntPos), fo(IntNeg), fo(BigIntPos), fo(BigIntNeg)
|
||||||
|
);
|
||||||
|
fprint(RESULT, L, "Integers with \%-7d: %4{%-7d|} \n",
|
||||||
|
fo(IntPos), fo(IntNeg), fo(BigIntPos), fo(BigIntNeg)
|
||||||
|
);
|
||||||
|
fprint(RESULT, L, "Integers with \%-8d: %4{%-8d|} \n",
|
||||||
|
fo(IntPos), fo(IntNeg), fo(BigIntPos), fo(BigIntNeg)
|
||||||
|
);
|
||||||
|
fprint(RESULT, L, "Integers with \%-9d: %4{%-9d|} \n",
|
||||||
|
fo(IntPos), fo(IntNeg), fo(BigIntPos), fo(BigIntNeg)
|
||||||
|
);
|
||||||
|
fprint(RESULT, L, "Integers with \%-10d: %4{%-10d|} \n",
|
||||||
|
fo(IntPos), fo(IntNeg), fo(BigIntPos), fo(BigIntNeg)
|
||||||
|
);
|
||||||
|
fprint(RESULT, L, "\n");
|
||||||
|
fprint(RESULT, L, "Integers with \%5r: %4{%5r|} \n",
|
||||||
|
fo(IntPos), fo(IntNeg), fo(BigIntPos), fo(BigIntNeg)
|
||||||
|
);
|
||||||
|
fprint(RESULT, L, "Integers with \%6r: %4{%6r|} \n",
|
||||||
|
fo(IntPos), fo(IntNeg), fo(BigIntPos), fo(BigIntNeg)
|
||||||
|
);
|
||||||
|
fprint(RESULT, L, "Integers with \%7r: %4{%7r|} \n",
|
||||||
|
fo(IntPos), fo(IntNeg), fo(BigIntPos), fo(BigIntNeg)
|
||||||
|
);
|
||||||
|
fprint(RESULT, L, "Integers with \%8r: %4{%8r|} \n",
|
||||||
|
fo(IntPos), fo(IntNeg), fo(BigIntPos), fo(BigIntNeg)
|
||||||
|
);
|
||||||
|
fprint(RESULT, L, "Integers with \%9r: %4{%9r|} \n",
|
||||||
|
fo(IntPos), fo(IntNeg), fo(BigIntPos), fo(BigIntNeg)
|
||||||
|
);
|
||||||
|
fprint(RESULT, L, "Integers with \%10r: %4{%10r|} \n",
|
||||||
|
fo(IntPos), fo(IntNeg), fo(BigIntPos), fo(BigIntNeg)
|
||||||
|
);
|
||||||
|
fprint(RESULT, L, "\n");
|
||||||
|
fprint(RESULT, L, "Integers with \%-5r: %4{%-5r|} \n",
|
||||||
|
fo(IntPos), fo(IntNeg), fo(BigIntPos), fo(BigIntNeg)
|
||||||
|
);
|
||||||
|
fprint(RESULT, L, "Integers with \%-6r: %4{%-6r|} \n",
|
||||||
|
fo(IntPos), fo(IntNeg), fo(BigIntPos), fo(BigIntNeg)
|
||||||
|
);
|
||||||
|
fprint(RESULT, L, "Integers with \%-7r: %4{%-7r|} \n",
|
||||||
|
fo(IntPos), fo(IntNeg), fo(BigIntPos), fo(BigIntNeg)
|
||||||
|
);
|
||||||
|
fprint(RESULT, L, "Integers with \%-8r: %4{%-8r|} \n",
|
||||||
|
fo(IntPos), fo(IntNeg), fo(BigIntPos), fo(BigIntNeg)
|
||||||
|
);
|
||||||
|
fprint(RESULT, L, "Integers with \%-9r: %4{%-9r|} \n",
|
||||||
|
fo(IntPos), fo(IntNeg), fo(BigIntPos), fo(BigIntNeg)
|
||||||
|
);
|
||||||
|
fprint(RESULT, L, "Integers with \%-10r: %4{%-10r|} \n",
|
||||||
|
fo(IntPos), fo(IntNeg), fo(BigIntPos), fo(BigIntNeg)
|
||||||
|
);
|
||||||
|
fprint(RESULT, L, "\n");
|
||||||
|
|
||||||
|
|
||||||
|
fprint(RESULT, L,
|
||||||
|
"\n----------------------\n" &
|
||||||
|
"-- Support for time --\n" &
|
||||||
|
"----------------------\n"
|
||||||
|
);
|
||||||
|
|
||||||
|
fprint (RESULT, L, "-- For portability reasons, time is converted \n" &
|
||||||
|
"-- into an integer value (of nanoseconds)\n"
|
||||||
|
);
|
||||||
|
fprint (RESULT, L, "> wait for 648 ns\n");
|
||||||
|
fprint (RESULT, L, "> fprint (RESULT, L, ""The time is now \%d ns\\n"", fo(now));\n");
|
||||||
|
|
||||||
|
wait for 648 ns;
|
||||||
|
|
||||||
|
fprint (RESULT, L, "The time is now %d ns\n", fo(now));
|
||||||
|
|
||||||
|
|
||||||
|
fprint(RESULT, L,
|
||||||
|
"\n----------------------------------------\n" &
|
||||||
|
"-- Erroneous calls and error messages --\n" &
|
||||||
|
"----------------------------------------\n"
|
||||||
|
);
|
||||||
|
|
||||||
|
fprint(RESULT, L, "\n-- Less arguments than formats specifiers\n" &
|
||||||
|
"> fprint(RESULT, L, ""\%d \%d \%d \%d \\n"", fo(Uns), fo(Std));\n"
|
||||||
|
);
|
||||||
|
|
||||||
|
fprint(RESULT, L, "%d %d %d %d \n", fo(Uns), fo(Std));
|
||||||
|
|
||||||
|
fprint(RESULT, L, "\n");
|
||||||
|
|
||||||
|
fprint(RESULT, L, "-- Unsupported format specifier\n" &
|
||||||
|
"> fprint(RESULT, L, ""\%r \%v \%r \%r\\n"", " &
|
||||||
|
"fo(Uns), fo(Std), fo(Uns), fo(Std));\n"
|
||||||
|
);
|
||||||
|
|
||||||
|
fprint(RESULT, L, "%r %v %r %r\n", fo(Uns), fo(Std), fo(Uns), fo(Std));
|
||||||
|
|
||||||
|
fprint(RESULT, L, "\n");
|
||||||
|
|
||||||
|
fprint(RESULT, L,
|
||||||
|
"\n----------------------------------------\n" &
|
||||||
|
"-- Things you wouldn't expect to work --\n" &
|
||||||
|
"----------------------------------------\n"
|
||||||
|
);
|
||||||
|
|
||||||
|
fprint(RESULT, L, "\n-- Nested iteration\n");
|
||||||
|
fprint(RESULT, L, "> fprint(RESULT, L, ""\%3{<<\%3{_END_}>>}\\n"");\n");
|
||||||
|
fprint(RESULT, L, "%3{<<%3{_END_}>>}\n");
|
||||||
|
|
||||||
|
wait;
|
||||||
|
|
||||||
|
end process USAGE;
|
||||||
|
|
||||||
|
end TB;
|
||||||
|
|
||||||
|
|
||||||
@@ -0,0 +1,536 @@
|
|||||||
|
---- $Id: TB_PCK_FIO_1993.vhd,v 1.1 2008-08-23 08:20:28 Jens Exp $
|
||||||
|
----
|
||||||
|
---- PCK_FIO: a VHDL package for C-style formatted file output
|
||||||
|
---- Copyright (C) 1995, 2001 Easics NV
|
||||||
|
----
|
||||||
|
---- This library 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 2.1 of the License, or (at your option) any later version.
|
||||||
|
----
|
||||||
|
---- This library 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 this library; if not, write to the Free Software
|
||||||
|
---- Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
|
||||||
|
----
|
||||||
|
---- For suggestions, bug reports, enhancement requests, and info about
|
||||||
|
---- our design services, you can contact us at the following address:
|
||||||
|
---- http://www.easics.com
|
||||||
|
---- Easics NV, Interleuvenlaan 86, B-3001 Leuven, Belgium
|
||||||
|
---- tel.: +32 16 395 600 fax : +32 16 395 619
|
||||||
|
---- e-mail: jand@easics.be (Jan Decaluwe)
|
||||||
|
----
|
||||||
|
|
||||||
|
|
||||||
|
library IEEE;
|
||||||
|
use IEEE.std_logic_1164.all;
|
||||||
|
-- signed/unsigned definition: use either std_logic_arith or numeric_std
|
||||||
|
-- use IEEE.std_logic_arith.all; -- the Synopsys one
|
||||||
|
use IEEE.numeric_std.all;
|
||||||
|
|
||||||
|
use STD.TEXTIO.all;
|
||||||
|
|
||||||
|
library EASICS_PACKAGES;
|
||||||
|
use EASICS_PACKAGES.PCK_FIO.all;
|
||||||
|
|
||||||
|
entity TBE_PCK_FIO is
|
||||||
|
|
||||||
|
end TBE_PCK_FIO;
|
||||||
|
|
||||||
|
architecture TB of TBE_PCK_FIO is
|
||||||
|
|
||||||
|
begin
|
||||||
|
|
||||||
|
USAGE: process
|
||||||
|
|
||||||
|
file RESULT: text open write_mode is "PCK_FIO.out";
|
||||||
|
variable L: line;
|
||||||
|
variable Pointer: integer;
|
||||||
|
variable BoolTrue: boolean := TRUE;
|
||||||
|
variable BoolFalse: boolean := FALSE;
|
||||||
|
variable IntPos: integer := 5678;
|
||||||
|
variable BigIntPos: integer := 12345678;
|
||||||
|
variable IntNeg: integer := -8765;
|
||||||
|
variable BigIntNeg: integer := -87654321;
|
||||||
|
variable Uns: unsigned(6 downto 0) := unsigned'("1010010");
|
||||||
|
variable Unk: unsigned(6 downto 0) := unsigned'("1X10Z10");
|
||||||
|
variable Std: std_logic_vector(6 downto 0) := std_logic_vector'("0010010");
|
||||||
|
variable SigPos: signed(6 downto 0) := signed'("0010010");
|
||||||
|
variable SigNeg: signed(6 downto 0) := signed'("1010010");
|
||||||
|
variable BitX: std_logic := 'X';
|
||||||
|
variable Bit1: std_logic := '1';
|
||||||
|
variable Bit0: std_logic := '0';
|
||||||
|
|
||||||
|
variable parameter_1: integer := 1234;
|
||||||
|
variable parameter_2: integer := 2345;
|
||||||
|
variable parameter_3: integer := 4567;
|
||||||
|
|
||||||
|
constant TempString: string :="ABC" & NUL & "DEF";
|
||||||
|
begin
|
||||||
|
|
||||||
|
fprint(RESULT, L,
|
||||||
|
"PCK_FIO.out: TESTBENCH OUTPUT FOR PCK_FIO\n" &
|
||||||
|
"-----------------------------------------\n\n" &
|
||||||
|
"This is the result of running the PCK_FIO testbench.\n" &
|
||||||
|
"This file should be compared with PCK_FIO.out.gold, which is\n" &
|
||||||
|
"the reference output. Any difference indicates a portability\n" &
|
||||||
|
"issue or a simulator non-compliance or bug.\n\n"
|
||||||
|
);
|
||||||
|
|
||||||
|
|
||||||
|
fprint(RESULT, L,
|
||||||
|
"\n--------------------\n" &
|
||||||
|
"-- Basic features --\n" &
|
||||||
|
"--------------------\n\n"
|
||||||
|
);
|
||||||
|
|
||||||
|
fprint(RESULT, L,
|
||||||
|
"-- First some auxiliary declarations\n"
|
||||||
|
);
|
||||||
|
|
||||||
|
fprint(RESULT, L,
|
||||||
|
"> file RESULT: text is out ""PCK_FIO.out"";\n" &
|
||||||
|
"> variable L: line;\n" &
|
||||||
|
"> variable BoolTrue: boolean := TRUE;\n" &
|
||||||
|
"> variable BoolFalse: boolean := FALSE;\n" &
|
||||||
|
"> variable IntPos: integer := 5678;\n" &
|
||||||
|
"> variable BigIntPos: integer := 12345678;\n" &
|
||||||
|
"> variable IntNeg: integer := -8765;\n" &
|
||||||
|
"> variable BigIntNeg: integer := -87654321;\n" &
|
||||||
|
"> variable Uns: unsigned(6 downto 0) := unsigned'(""1010010"");\n" &
|
||||||
|
"> variable Unk: unsigned(6 downto 0) := unsigned'(""1X10Z10"");\n" &
|
||||||
|
"> variable Std: std_logic_vector(6 downto 0) := std_logic_vector'(""0010010"");\n" &
|
||||||
|
"> variable SigPos: signed(6 downto 0) := signed'(""0010010"");\n" &
|
||||||
|
"> variable SigNeg: signed(6 downto 0) := signed'(""1010010"");\n" &
|
||||||
|
"> variable BitX: std_logic := 'X';\n" &
|
||||||
|
"> variable Bit1: std_logic := '1';\n" &
|
||||||
|
"> variable Bit0: std_logic := '0';\n" &
|
||||||
|
"> constant TempString: string := ""ABC"" & NUL & ""DEF"";\n"
|
||||||
|
);
|
||||||
|
|
||||||
|
|
||||||
|
fprint(RESULT, L,
|
||||||
|
"\n\n-- fprint call with no arguments\n" &
|
||||||
|
"> fprint(RESULT, L, ""No arguments.\\n"");\n"
|
||||||
|
);
|
||||||
|
fprint(RESULT, L, "No arguments.\n");
|
||||||
|
|
||||||
|
|
||||||
|
fprint(RESULT, L,
|
||||||
|
"\n-- Special characters need to be escaped\n" &
|
||||||
|
"> fprint(RESULT, L, ""Special characters: \\\% \\\\ "" \\n"");\n"
|
||||||
|
);
|
||||||
|
|
||||||
|
fprint(RESULT, L, "Special characters: \% \\ "" \n");
|
||||||
|
|
||||||
|
|
||||||
|
fprint(RESULT, L,
|
||||||
|
"\n-- Various format specifiers interprete the same object differently\n" &
|
||||||
|
"> fprint(RESULT, L, ""Format specifiers: \%r \%d \%b \%q\\n"",\n" &
|
||||||
|
"> fo(Uns), fo(Uns), fo(Uns), fo(Uns)\n" &
|
||||||
|
"> );\n"
|
||||||
|
);
|
||||||
|
|
||||||
|
fprint(RESULT, L, "Format specifiers: %r %d %b %q\n",
|
||||||
|
fo(Uns), fo(Uns), fo(Uns), fo(Uns)
|
||||||
|
);
|
||||||
|
|
||||||
|
fprint(RESULT, L,
|
||||||
|
"\n-- Format string can be shortened by using the iteration specifier\n" &
|
||||||
|
"> fprint(RESULT, L, ""Iteration specifier: \%4{\%r }\\n"",\n" &
|
||||||
|
"> fo(Uns), fo(SigPos), fo(SigNeg), fo(Std)\n" &
|
||||||
|
"> );\n"
|
||||||
|
);
|
||||||
|
|
||||||
|
fprint(RESULT, L, "Iteration specifier: %4{%r }\n",
|
||||||
|
fo(Uns), fo(SigPos), fo(SigNeg), fo(Std)
|
||||||
|
);
|
||||||
|
fprint(RESULT, L,
|
||||||
|
"\n-------------------------------\n"&
|
||||||
|
"--Testing string manipulation--\n"&
|
||||||
|
"-------------------------------\n");
|
||||||
|
fprint(RESULT, L, "--testing done using the string TempString : " & """ABC"""
|
||||||
|
& " & NUL & ""DEF""\n");
|
||||||
|
-- TempString: string:="ABC" & NUL & "DEF"
|
||||||
|
-- test for detecting NUL in string
|
||||||
|
fprint(RESULT, L ,"\n--test for NUL ending in strings\n");
|
||||||
|
fprint(RESULT, L, "> fprint(RESULT, L, fo(TempString));\n");
|
||||||
|
fprint(RESULT, L, fo(TempString));
|
||||||
|
|
||||||
|
-- direct inclusion of string in fprint should give whole string
|
||||||
|
fprint(RESULT, L, "\n--same without fo,so without NUL testing\n");
|
||||||
|
fprint(RESULT, L, "> fprint(RESULT, L, TempString);\n");
|
||||||
|
fprint(RESULT, L, TempString & "\n");
|
||||||
|
|
||||||
|
-- influence of given width
|
||||||
|
|
||||||
|
fprint(RESULT, L, "\n--if there are less characters in the given string then in the width fo will\n"&
|
||||||
|
"-- pad the remaining with blanco's according to the given justification\n");
|
||||||
|
fprint(RESULT, L, "\n--with specified width, justified right,using fo\n");
|
||||||
|
fprint(RESULT, L, "> fprint(RESULT, L, ""\%5s"", fo(TempString));\n");
|
||||||
|
fprint(RESULT, L, "%5s", fo(TempString));
|
||||||
|
fprint(RESULT, L, "\n--with specified width, justified left, using fo\n");
|
||||||
|
fprint(RESULT, L, "> fprint(RESULT, L, ""\%-5s"", fo(TempString));\n");
|
||||||
|
fprint(RESULT, L, "%-5s", fo(TempString));
|
||||||
|
fprint(RESULT, L, "\n--with specified width without fo\n");
|
||||||
|
fprint(RESUlT, L, "> fprint(RESULT, L, ""\%9s"", TempString);\n");
|
||||||
|
fprint(RESULT, L, "%9s", TempString);
|
||||||
|
fprint(RESULT, L, "\n\n-- if the width is smaller then the number of characters in the string fprint\n"&
|
||||||
|
"-- will output the string with the minimum of characters needed\n");
|
||||||
|
fprint(RESULT, L, "\n--with specified width,using fo\n");
|
||||||
|
fprint(RESULT, L, "> fprint(RESULT, L, ""\%2s"", fo(TempString));\n");
|
||||||
|
fprint(RESULT, L, "%2s", fo(TempString));
|
||||||
|
fprint(RESULT, L, "\n--with specified width without fo\n");
|
||||||
|
fprint(RESUlT, L, "> fprint(RESULT, L, ""\%4s"", TempString);\n");
|
||||||
|
fprint(RESULT, L, "%4s", TempString);
|
||||||
|
|
||||||
|
fprint(RESULT, L,
|
||||||
|
"\n\n------------------------------------\n" &
|
||||||
|
"-- Support for bit-oriented types --\n" &
|
||||||
|
"------------------------------------\n"
|
||||||
|
);
|
||||||
|
|
||||||
|
fprint (RESULT, L, "\n-- Reasonable format\n" &
|
||||||
|
"> fprint(RESULT, L, ""Reasonable format: \%9{\%r }\\n"",\n" &
|
||||||
|
"> fo(Std), fo(Uns), fo(SigPos), fo(SigNeg), fo(Unk),\n" &
|
||||||
|
"> fo(Bit1), fo(BitX), fo(BoolTrue), fo(BoolFalse) \n" &
|
||||||
|
"> );\n"
|
||||||
|
);
|
||||||
|
|
||||||
|
|
||||||
|
fprint(RESULT, L, "Reasonable format: %9{%r }\n",
|
||||||
|
fo(Std), fo(Uns), fo(SigPos), fo(SigNeg), fo(Unk),
|
||||||
|
fo(Bit1), fo(BitX), fo(BoolTrue), fo(BoolFalse)
|
||||||
|
);
|
||||||
|
|
||||||
|
fprint (RESULT, L, "\n-- Decimal format\n" &
|
||||||
|
"> fprint(RESULT, L, ""Decimal format: \%7{\%d }\\n"",\n" &
|
||||||
|
"> fo(Std), fo(Uns), fo(SigPos), fo(SigNeg), fo(Unk),\n" &
|
||||||
|
"> fo(Bit1), fo(BitX), fo(BoolTrue), fo(BoolFalse) \n" &
|
||||||
|
"> );\n"
|
||||||
|
);
|
||||||
|
|
||||||
|
|
||||||
|
fprint(RESULT, L, "Decimal format: %9{%d }\n",
|
||||||
|
fo(Std), fo(Uns), fo(SigPos), fo(SigNeg), fo(Unk),
|
||||||
|
fo(Bit1), fo(BitX), fo(BoolTrue), fo(BoolFalse)
|
||||||
|
);
|
||||||
|
|
||||||
|
fprint (RESULT, L, "\n-- Bit format\n" &
|
||||||
|
"> fprint(RESULT, L, ""Bit format: \%7{\%b }\\n"",\n" &
|
||||||
|
"> fo(Std), fo(Uns), fo(SigPos), fo(SigNeg), fo(Unk),\n" &
|
||||||
|
"> fo(Bit1), fo(BitX), fo(BoolTrue), fo(BoolFalse) \n" &
|
||||||
|
"> );\n"
|
||||||
|
);
|
||||||
|
|
||||||
|
|
||||||
|
fprint(RESULT, L, "Bit format: %9{%b }\n",
|
||||||
|
fo(Std), fo(Uns), fo(SigPos), fo(SigNeg), fo(Unk),
|
||||||
|
fo(Bit1), fo(BitX), fo(BoolTrue), fo(BoolFalse)
|
||||||
|
);
|
||||||
|
|
||||||
|
fprint(RESULT, L,
|
||||||
|
"\n\n" &
|
||||||
|
"-- Alignment\n-- Template of the call: (<fs> stands for the format specifier)\n"
|
||||||
|
);
|
||||||
|
|
||||||
|
|
||||||
|
fprint(RESULT, L, "\n" &
|
||||||
|
"> fprint(RESULT, L, ""Bitvectors with <fs>: \%4{<fs>|}\\n"",\n" &
|
||||||
|
"> fo(Std), fo(Uns), fo(SigPos), fo(SigNeg)\n" &
|
||||||
|
"> );\n"
|
||||||
|
);
|
||||||
|
|
||||||
|
fprint(RESULT, L,
|
||||||
|
"\n" &
|
||||||
|
"-- Results of the call with various format specifiers\n\n"
|
||||||
|
);
|
||||||
|
|
||||||
|
fprint(RESULT, L, "Bitvectors with \%1r: %4{%1r|} \n",
|
||||||
|
fo(Uns), fo(Std), fo(SigPos), fo(SigNeg)
|
||||||
|
);
|
||||||
|
fprint(RESULT, L, "Bitvectors with \%2r: %4{%2r|} \n",
|
||||||
|
fo(Uns), fo(Std), fo(SigPos), fo(SigNeg)
|
||||||
|
);
|
||||||
|
fprint(RESULT, L, "Bitvectors with \%3r: %4{%3r|} \n",
|
||||||
|
fo(Uns), fo(Std), fo(SigPos), fo(SigNeg)
|
||||||
|
);
|
||||||
|
fprint(RESULT, L, "Bitvectors with \%4r: %4{%4r|} \n",
|
||||||
|
fo(Uns), fo(Std), fo(SigPos), fo(SigNeg)
|
||||||
|
);
|
||||||
|
fprint(RESULT, L, "Bitvectors with \%5r: %4{%5r|} \n",
|
||||||
|
fo(Uns), fo(Std), fo(SigPos), fo(SigNeg)
|
||||||
|
);
|
||||||
|
fprint(RESULT, L, "Bitvectors with \%6r: %4{%6r|} \n",
|
||||||
|
fo(Uns), fo(Std), fo(SigPos), fo(SigNeg)
|
||||||
|
);
|
||||||
|
fprint(RESULT, L, "Bitvectors with \%7r: %4{%7r|} \n",
|
||||||
|
fo(Uns), fo(Std), fo(SigPos), fo(SigNeg)
|
||||||
|
);
|
||||||
|
fprint(RESULT, L, "Bitvectors with \%8r: %4{%8r|} \n",
|
||||||
|
fo(Uns), fo(Std), fo(SigPos), fo(SigNeg)
|
||||||
|
);
|
||||||
|
fprint(RESULT, L, "Bitvectors with \%9r: %4{%9r|} \n",
|
||||||
|
fo(Uns), fo(Std), fo(SigPos), fo(SigNeg)
|
||||||
|
);
|
||||||
|
fprint(RESULT, L, "\n");
|
||||||
|
fprint(RESULT, L, "Bitvectors with \%-1r: %4{%-1r|} \n",
|
||||||
|
fo(Uns), fo(Std), fo(SigPos), fo(SigNeg)
|
||||||
|
);
|
||||||
|
fprint(RESULT, L, "Bitvectors with \%-2r: %4{%-2r|} \n",
|
||||||
|
fo(Uns), fo(Std), fo(SigPos), fo(SigNeg)
|
||||||
|
);
|
||||||
|
fprint(RESULT, L, "Bitvectors with \%-3r: %4{%-3r|} \n",
|
||||||
|
fo(Uns), fo(Std), fo(SigPos), fo(SigNeg)
|
||||||
|
);
|
||||||
|
fprint(RESULT, L, "Bitvectors with \%-4r: %4{%-4r|} \n",
|
||||||
|
fo(Uns), fo(Std), fo(SigPos), fo(SigNeg)
|
||||||
|
);
|
||||||
|
fprint(RESULT, L, "Bitvectors with \%-5r: %4{%-5r|} \n",
|
||||||
|
fo(Uns), fo(Std), fo(SigPos), fo(SigNeg)
|
||||||
|
);
|
||||||
|
fprint(RESULT, L, "Bitvectors with \%-6r: %4{%-6r|} \n",
|
||||||
|
fo(Uns), fo(Std), fo(SigPos), fo(SigNeg)
|
||||||
|
);
|
||||||
|
fprint(RESULT, L, "Bitvectors with \%-7r: %4{%-7r|} \n",
|
||||||
|
fo(Uns), fo(Std), fo(SigPos), fo(SigNeg)
|
||||||
|
);
|
||||||
|
fprint(RESULT, L, "Bitvectors with \%-8r: %4{%-8r|} \n",
|
||||||
|
fo(Uns), fo(Std), fo(SigPos), fo(SigNeg)
|
||||||
|
);
|
||||||
|
fprint(RESULT, L, "Bitvectors with \%-9r: %4{%-9r|} \n",
|
||||||
|
fo(Uns), fo(Std), fo(SigPos), fo(SigNeg)
|
||||||
|
);
|
||||||
|
fprint(RESULT, L, "\n");
|
||||||
|
fprint(RESULT, L, "Bitvectors with \%1d: %4{%1d|} \n",
|
||||||
|
fo(Uns), fo(Std), fo(SigPos), fo(SigNeg)
|
||||||
|
);
|
||||||
|
fprint(RESULT, L, "Bitvectors with \%2d: %4{%2d|} \n",
|
||||||
|
fo(Uns), fo(Std), fo(SigPos), fo(SigNeg)
|
||||||
|
);
|
||||||
|
fprint(RESULT, L, "Bitvectors with \%3d: %4{%3d|} \n",
|
||||||
|
fo(Uns), fo(Std), fo(SigPos), fo(SigNeg)
|
||||||
|
);
|
||||||
|
fprint(RESULT, L, "Bitvectors with \%4d: %4{%4d|} \n",
|
||||||
|
fo(Uns), fo(Std), fo(SigPos), fo(SigNeg)
|
||||||
|
);
|
||||||
|
fprint(RESULT, L, "Bitvectors with \%5d: %4{%5d|} \n",
|
||||||
|
fo(Uns), fo(Std), fo(SigPos), fo(SigNeg)
|
||||||
|
);
|
||||||
|
fprint(RESULT, L, "Bitvectors with \%6d: %4{%6d|} \n",
|
||||||
|
fo(Uns), fo(Std), fo(SigPos), fo(SigNeg)
|
||||||
|
);
|
||||||
|
fprint(RESULT, L, "Bitvectors with \%7d: %4{%7d|} \n",
|
||||||
|
fo(Uns), fo(Std), fo(SigPos), fo(SigNeg)
|
||||||
|
);
|
||||||
|
fprint(RESULT, L, "Bitvectors with \%8d: %4{%8d|} \n",
|
||||||
|
fo(Uns), fo(Std), fo(SigPos), fo(SigNeg)
|
||||||
|
);
|
||||||
|
fprint(RESULT, L, "Bitvectors with \%9d: %4{%9d|} \n",
|
||||||
|
fo(Uns), fo(Std), fo(SigPos), fo(SigNeg)
|
||||||
|
);
|
||||||
|
fprint(RESULT, L, "\n");
|
||||||
|
fprint(RESULT, L, "Bitvectors with \%-1d: %4{%-1d|} \n",
|
||||||
|
fo(Uns), fo(Std), fo(SigPos), fo(SigNeg)
|
||||||
|
);
|
||||||
|
fprint(RESULT, L, "Bitvectors with \%-2d: %4{%-2d|} \n",
|
||||||
|
fo(Uns), fo(Std), fo(SigPos), fo(SigNeg)
|
||||||
|
);
|
||||||
|
fprint(RESULT, L, "Bitvectors with \%-3d: %4{%-3d|} \n",
|
||||||
|
fo(Uns), fo(Std), fo(SigPos), fo(SigNeg)
|
||||||
|
);
|
||||||
|
fprint(RESULT, L, "Bitvectors with \%-4d: %4{%-4d|} \n",
|
||||||
|
fo(Uns), fo(Std), fo(SigPos), fo(SigNeg)
|
||||||
|
);
|
||||||
|
fprint(RESULT, L, "Bitvectors with \%-5d: %4{%-5d|} \n",
|
||||||
|
fo(Uns), fo(Std), fo(SigPos), fo(SigNeg)
|
||||||
|
);
|
||||||
|
fprint(RESULT, L, "Bitvectors with \%-6d: %4{%-6d|} \n",
|
||||||
|
fo(Uns), fo(Std), fo(SigPos), fo(SigNeg)
|
||||||
|
);
|
||||||
|
fprint(RESULT, L, "Bitvectors with \%-7d: %4{%-7d|} \n",
|
||||||
|
fo(Uns), fo(Std), fo(SigPos), fo(SigNeg)
|
||||||
|
);
|
||||||
|
fprint(RESULT, L, "Bitvectors with \%-8d: %4{%-8d|} \n",
|
||||||
|
fo(Uns), fo(Std), fo(SigPos), fo(SigNeg)
|
||||||
|
);
|
||||||
|
fprint(RESULT, L, "Bitvectors with \%-9d: %4{%-9d|} \n",
|
||||||
|
fo(Uns), fo(Std), fo(SigPos), fo(SigNeg)
|
||||||
|
);
|
||||||
|
fprint(RESULT, L, "\n");
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
fprint(RESULT, L,
|
||||||
|
"\n-------------------------------\n" &
|
||||||
|
"-- Support for integer types --\n" &
|
||||||
|
"-------------------------------\n"
|
||||||
|
);
|
||||||
|
|
||||||
|
fprint(RESULT, L,
|
||||||
|
"\n\n" &
|
||||||
|
"-- Template of the call: (<fs> stands for the format specifier)\n"
|
||||||
|
);
|
||||||
|
|
||||||
|
|
||||||
|
fprint(RESULT, L, "\n" &
|
||||||
|
"> fprint(RESULT, L, ""Integers with <fs>: \%4{<fs>|}\\n"",\n" &
|
||||||
|
"> fo(IntPos), fo(IntNeg), fo(BigIntPos), fo(BigIntNeg)\n" &
|
||||||
|
|
||||||
|
"> );\n"
|
||||||
|
);
|
||||||
|
|
||||||
|
fprint(RESULT, L,
|
||||||
|
"\n" &
|
||||||
|
"-- Results of the call with various format specifiers\n\n"
|
||||||
|
);
|
||||||
|
|
||||||
|
|
||||||
|
fprint(RESULT, L, "Integers with \%5d: %4{%5d|} \n",
|
||||||
|
fo(IntPos), fo(IntNeg), fo(BigIntPos), fo(BigIntNeg)
|
||||||
|
);
|
||||||
|
fprint(RESULT, L, "Integers with \%6d: %4{%6d|} \n",
|
||||||
|
fo(IntPos), fo(IntNeg), fo(BigIntPos), fo(BigIntNeg)
|
||||||
|
);
|
||||||
|
fprint(RESULT, L, "Integers with \%7d: %4{%7d|} \n",
|
||||||
|
fo(IntPos), fo(IntNeg), fo(BigIntPos), fo(BigIntNeg)
|
||||||
|
);
|
||||||
|
fprint(RESULT, L, "Integers with \%8d: %4{%8d|} \n",
|
||||||
|
fo(IntPos), fo(IntNeg), fo(BigIntPos), fo(BigIntNeg)
|
||||||
|
);
|
||||||
|
fprint(RESULT, L, "Integers with \%9d: %4{%9d|} \n",
|
||||||
|
fo(IntPos), fo(IntNeg), fo(BigIntPos), fo(BigIntNeg)
|
||||||
|
);
|
||||||
|
fprint(RESULT, L, "Integers with \%10d: %4{%10d|} \n",
|
||||||
|
fo(IntPos), fo(IntNeg), fo(BigIntPos), fo(BigIntNeg)
|
||||||
|
);
|
||||||
|
fprint(RESULT, L, "\n");
|
||||||
|
fprint(RESULT, L, "Integers with \%-5d: %4{%-5d|} \n",
|
||||||
|
fo(IntPos), fo(IntNeg), fo(BigIntPos), fo(BigIntNeg)
|
||||||
|
);
|
||||||
|
fprint(RESULT, L, "Integers with \%-6d: %4{%-6d|} \n",
|
||||||
|
fo(IntPos), fo(IntNeg), fo(BigIntPos), fo(BigIntNeg)
|
||||||
|
);
|
||||||
|
fprint(RESULT, L, "Integers with \%-7d: %4{%-7d|} \n",
|
||||||
|
fo(IntPos), fo(IntNeg), fo(BigIntPos), fo(BigIntNeg)
|
||||||
|
);
|
||||||
|
fprint(RESULT, L, "Integers with \%-8d: %4{%-8d|} \n",
|
||||||
|
fo(IntPos), fo(IntNeg), fo(BigIntPos), fo(BigIntNeg)
|
||||||
|
);
|
||||||
|
fprint(RESULT, L, "Integers with \%-9d: %4{%-9d|} \n",
|
||||||
|
fo(IntPos), fo(IntNeg), fo(BigIntPos), fo(BigIntNeg)
|
||||||
|
);
|
||||||
|
fprint(RESULT, L, "Integers with \%-10d: %4{%-10d|} \n",
|
||||||
|
fo(IntPos), fo(IntNeg), fo(BigIntPos), fo(BigIntNeg)
|
||||||
|
);
|
||||||
|
fprint(RESULT, L, "\n");
|
||||||
|
fprint(RESULT, L, "Integers with \%5r: %4{%5r|} \n",
|
||||||
|
fo(IntPos), fo(IntNeg), fo(BigIntPos), fo(BigIntNeg)
|
||||||
|
);
|
||||||
|
fprint(RESULT, L, "Integers with \%6r: %4{%6r|} \n",
|
||||||
|
fo(IntPos), fo(IntNeg), fo(BigIntPos), fo(BigIntNeg)
|
||||||
|
);
|
||||||
|
fprint(RESULT, L, "Integers with \%7r: %4{%7r|} \n",
|
||||||
|
fo(IntPos), fo(IntNeg), fo(BigIntPos), fo(BigIntNeg)
|
||||||
|
);
|
||||||
|
fprint(RESULT, L, "Integers with \%8r: %4{%8r|} \n",
|
||||||
|
fo(IntPos), fo(IntNeg), fo(BigIntPos), fo(BigIntNeg)
|
||||||
|
);
|
||||||
|
fprint(RESULT, L, "Integers with \%9r: %4{%9r|} \n",
|
||||||
|
fo(IntPos), fo(IntNeg), fo(BigIntPos), fo(BigIntNeg)
|
||||||
|
);
|
||||||
|
fprint(RESULT, L, "Integers with \%10r: %4{%10r|} \n",
|
||||||
|
fo(IntPos), fo(IntNeg), fo(BigIntPos), fo(BigIntNeg)
|
||||||
|
);
|
||||||
|
fprint(RESULT, L, "\n");
|
||||||
|
fprint(RESULT, L, "Integers with \%-5r: %4{%-5r|} \n",
|
||||||
|
fo(IntPos), fo(IntNeg), fo(BigIntPos), fo(BigIntNeg)
|
||||||
|
);
|
||||||
|
fprint(RESULT, L, "Integers with \%-6r: %4{%-6r|} \n",
|
||||||
|
fo(IntPos), fo(IntNeg), fo(BigIntPos), fo(BigIntNeg)
|
||||||
|
);
|
||||||
|
fprint(RESULT, L, "Integers with \%-7r: %4{%-7r|} \n",
|
||||||
|
fo(IntPos), fo(IntNeg), fo(BigIntPos), fo(BigIntNeg)
|
||||||
|
);
|
||||||
|
fprint(RESULT, L, "Integers with \%-8r: %4{%-8r|} \n",
|
||||||
|
fo(IntPos), fo(IntNeg), fo(BigIntPos), fo(BigIntNeg)
|
||||||
|
);
|
||||||
|
fprint(RESULT, L, "Integers with \%-9r: %4{%-9r|} \n",
|
||||||
|
fo(IntPos), fo(IntNeg), fo(BigIntPos), fo(BigIntNeg)
|
||||||
|
);
|
||||||
|
fprint(RESULT, L, "Integers with \%-10r: %4{%-10r|} \n",
|
||||||
|
fo(IntPos), fo(IntNeg), fo(BigIntPos), fo(BigIntNeg)
|
||||||
|
);
|
||||||
|
fprint(RESULT, L, "\n");
|
||||||
|
|
||||||
|
|
||||||
|
fprint(RESULT, L,
|
||||||
|
"\n----------------------\n" &
|
||||||
|
"-- Support for time --\n" &
|
||||||
|
"----------------------\n"
|
||||||
|
);
|
||||||
|
|
||||||
|
fprint (RESULT, L, "-- For portability reasons, time is converted \n" &
|
||||||
|
"-- into an integer value (of nanoseconds)\n"
|
||||||
|
);
|
||||||
|
fprint (RESULT, L, "> wait for 648 ns\n");
|
||||||
|
fprint (RESULT, L, "> fprint (RESULT, L, ""The time is now \%d ns\\n"", fo(now));\n");
|
||||||
|
|
||||||
|
wait for 648 ns;
|
||||||
|
|
||||||
|
fprint (RESULT, L, "The time is now %d ns\n", fo(now));
|
||||||
|
|
||||||
|
|
||||||
|
fprint(RESULT, L,
|
||||||
|
"\n----------------------------------------\n" &
|
||||||
|
"-- Erroneous calls and error messages --\n" &
|
||||||
|
"----------------------------------------\n"
|
||||||
|
);
|
||||||
|
|
||||||
|
fprint(RESULT, L, "\n-- Less arguments than formats specifiers\n" &
|
||||||
|
"> fprint(RESULT, L, ""\%d \%d \%d \%d \\n"", fo(Uns), fo(Std));\n"
|
||||||
|
);
|
||||||
|
|
||||||
|
fprint(RESULT, L, "%d %d %d %d \n", fo(Uns), fo(Std));
|
||||||
|
|
||||||
|
fprint(RESULT, L, "\n");
|
||||||
|
|
||||||
|
fprint(RESULT, L, "-- Unsupported format specifier\n" &
|
||||||
|
"> fprint(RESULT, L, ""\%r \%v \%r \%r\\n"", " &
|
||||||
|
"fo(Uns), fo(Std), fo(Uns), fo(Std));\n"
|
||||||
|
);
|
||||||
|
|
||||||
|
fprint(RESULT, L, "%r %v %r %r\n", fo(Uns), fo(Std), fo(Uns), fo(Std));
|
||||||
|
|
||||||
|
fprint(RESULT, L, "\n");
|
||||||
|
|
||||||
|
fprint(RESULT, L,
|
||||||
|
"\n----------------------------------------\n" &
|
||||||
|
"-- Things you wouldn't expect to work --\n" &
|
||||||
|
"----------------------------------------\n"
|
||||||
|
);
|
||||||
|
|
||||||
|
fprint(RESULT, L, "\n-- Nested iteration\n");
|
||||||
|
fprint(RESULT, L, "> fprint(RESULT, L, ""\%3{<<\%3{_END_}>>}\\n"");\n");
|
||||||
|
fprint(RESULT, L, "%3{<<%3{_END_}>>}\n");
|
||||||
|
|
||||||
|
wait;
|
||||||
|
|
||||||
|
end process USAGE;
|
||||||
|
|
||||||
|
end TB;
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
@@ -0,0 +1,34 @@
|
|||||||
|
### msMakefile generated by vma on Thu Oct 4 17:33:56 CEST 2001
|
||||||
|
|
||||||
|
ANALYZER = vcom -quiet -nologo
|
||||||
|
ANALYZER_C = vcom -quiet -nologo
|
||||||
|
all : \
|
||||||
|
bin/tbe_pck_fio/tb.dat \
|
||||||
|
bin/tbe_pck_fio/_primary.dat
|
||||||
|
|
||||||
|
# Prerequisites for architecture EASICS_PACKAGES.TBE_PCK_FIO(TB)
|
||||||
|
# Prerequisites for entity EASICS_PACKAGES.TBE_PCK_FIO
|
||||||
|
|
||||||
|
bin/tbe_pck_fio/tb.dat \
|
||||||
|
bin/tbe_pck_fio/_primary.dat : \
|
||||||
|
bin/pck_fio/body.dat \
|
||||||
|
bin/pck_fio/_primary.dat \
|
||||||
|
TB_PCK_FIO_1987.vhd
|
||||||
|
${ANALYZER_C} -work EASICS_PACKAGES TB_PCK_FIO_1987.vhd
|
||||||
|
|
||||||
|
|
||||||
|
# Prerequisites for package body EASICS_PACKAGES.PCK_FIO(<body>)
|
||||||
|
|
||||||
|
bin/pck_fio/body.dat : \
|
||||||
|
bin/pck_fio/_primary.dat \
|
||||||
|
PCK_FIO_1987_BODY.vhd
|
||||||
|
${ANALYZER_C} -work EASICS_PACKAGES PCK_FIO_1987_BODY.vhd
|
||||||
|
|
||||||
|
|
||||||
|
# Prerequisites for package declaration EASICS_PACKAGES.PCK_FIO
|
||||||
|
|
||||||
|
bin/pck_fio/_primary.dat : \
|
||||||
|
PCK_FIO_1987.vhd
|
||||||
|
${ANALYZER} -work EASICS_PACKAGES PCK_FIO_1987.vhd
|
||||||
|
|
||||||
|
|
||||||
@@ -0,0 +1,34 @@
|
|||||||
|
### msMakefile generated by vma on Thu Oct 4 17:32:23 CEST 2001
|
||||||
|
|
||||||
|
ANALYZER = vcom -quiet -nologo -93
|
||||||
|
ANALYZER_C = vcom -quiet -nologo -93
|
||||||
|
all : \
|
||||||
|
bin/tbe_pck_fio/tb.dat \
|
||||||
|
bin/tbe_pck_fio/_primary.dat
|
||||||
|
|
||||||
|
# Prerequisites for architecture EASICS_PACKAGES.TBE_PCK_FIO(TB)
|
||||||
|
# Prerequisites for entity EASICS_PACKAGES.TBE_PCK_FIO
|
||||||
|
|
||||||
|
bin/tbe_pck_fio/tb.dat \
|
||||||
|
bin/tbe_pck_fio/_primary.dat : \
|
||||||
|
bin/pck_fio/body.dat \
|
||||||
|
bin/pck_fio/_primary.dat \
|
||||||
|
TB_PCK_FIO_1993.vhd
|
||||||
|
${ANALYZER_C} -work EASICS_PACKAGES TB_PCK_FIO_1993.vhd
|
||||||
|
|
||||||
|
|
||||||
|
# Prerequisites for package body EASICS_PACKAGES.PCK_FIO(<body>)
|
||||||
|
|
||||||
|
bin/pck_fio/body.dat : \
|
||||||
|
bin/pck_fio/_primary.dat \
|
||||||
|
PCK_FIO_1993_BODY.vhd
|
||||||
|
${ANALYZER_C} -work EASICS_PACKAGES PCK_FIO_1993_BODY.vhd
|
||||||
|
|
||||||
|
|
||||||
|
# Prerequisites for package declaration EASICS_PACKAGES.PCK_FIO
|
||||||
|
|
||||||
|
bin/pck_fio/_primary.dat : \
|
||||||
|
PCK_FIO_1993.vhd
|
||||||
|
${ANALYZER} -work EASICS_PACKAGES PCK_FIO_1993.vhd
|
||||||
|
|
||||||
|
|
||||||
@@ -0,0 +1,13 @@
|
|||||||
|
vhdl work "W:\vhdl\lib\misc\utils_pkg.vhd"
|
||||||
|
vhdl work "W:\vhdl\lib\SDRAM\ddr_sdr_v1_4\src\sdram_config.vhd"
|
||||||
|
vhdl work "W:\vhdl\lib\FIFO\src\fifo_ctrl_pkg.vhd"
|
||||||
|
vhdl work "W:\vhdl\lib\SDRAM\ddr_sdr_v1_4\src\sdram_types.vhd"
|
||||||
|
vhdl work "W:\vhdl\lib\FIFO\src\sync_fifo_ctrl.vhd"
|
||||||
|
vhdl work "W:\vhdl\lib\FIFO\src\dpram.vhd"
|
||||||
|
vhdl work "W:\vhdl\lib\SDRAM\ddr_sdr_v1_4\src\sdram_ctrl.vhd"
|
||||||
|
vhdl work "W:\vhdl\lib\SDRAM\ddr_sdr_v1_4\src\sdram_cmd.vhd"
|
||||||
|
vhdl work "W:\vhdl\lib\SDRAM\ddr_sdr_v1_4\src\reset_virtex4.vhd"
|
||||||
|
vhdl work "W:\vhdl\lib\SDRAM\ddr_sdr_v1_4\src\fifo_sync.vhd"
|
||||||
|
vhdl work "W:\vhdl\lib\SDRAM\ddr_sdr_v1_4\src\ddr_phy_virtex4.vhd"
|
||||||
|
vhdl work "W:\vhdl\lib\SDRAM\ddr_sdr_v1_4\src\clockgen_virtex4.vhd"
|
||||||
|
vhdl work "W:\vhdl\lib\SDRAM\ddr_sdr_v1_4\src\sdram_ctrl_top.vhd"
|
||||||
Some files were not shown because too many files have changed in this diff Show More
Reference in New Issue
Block a user