mirror of
https://github.com/Gehstock/Mist_FPGA.git
synced 2026-01-15 07:53:37 +00:00
add V30 CPU
This commit is contained in:
parent
e61740cda2
commit
104392cbfd
6
common/CPU/v30/V30.qip
Normal file
6
common/CPU/v30/V30.qip
Normal file
@ -0,0 +1,6 @@
|
||||
set_global_assignment -name VHDL_FILE [file join $::quartus(qip_path) cpu.vhd ]
|
||||
set_global_assignment -name VHDL_FILE [file join $::quartus(qip_path) divider.vhd ]
|
||||
set_global_assignment -name VHDL_FILE [file join $::quartus(qip_path) export.vhd ]
|
||||
set_global_assignment -name VHDL_FILE [file join $::quartus(qip_path) registerpackage.vhd ]
|
||||
set_global_assignment -name VHDL_FILE [file join $::quartus(qip_path) bus_savestates.vhd ]
|
||||
set_global_assignment -name VHDL_FILE [file join $::quartus(qip_path) reg_savestates.vhd ]
|
||||
105
common/CPU/v30/bus_savestates.vhd
Normal file
105
common/CPU/v30/bus_savestates.vhd
Normal file
@ -0,0 +1,105 @@
|
||||
-----------------------------------------------------------------
|
||||
--------------- Bus Package --------------------------------
|
||||
-----------------------------------------------------------------
|
||||
|
||||
library IEEE;
|
||||
use IEEE.std_logic_1164.all;
|
||||
use IEEE.numeric_std.all;
|
||||
|
||||
package pBus_savestates is
|
||||
|
||||
constant SSBUS_buswidth : integer := 64;
|
||||
constant SSBUS_busadr : integer := 7;
|
||||
|
||||
type savestate_type is record
|
||||
Adr : integer range 0 to (2**SSBUS_busadr)-1;
|
||||
upper : integer range 0 to SSBUS_buswidth-1;
|
||||
lower : integer range 0 to SSBUS_buswidth-1;
|
||||
size : integer range 0 to (2**SSBUS_busadr)-1;
|
||||
defval : std_logic_vector(SSBUS_buswidth-1 downto 0);
|
||||
end record;
|
||||
|
||||
end package;
|
||||
|
||||
-----------------------------------------------------------------
|
||||
--------------- Reg Interface -----------------------------------
|
||||
-----------------------------------------------------------------
|
||||
|
||||
library IEEE;
|
||||
use IEEE.std_logic_1164.all;
|
||||
use IEEE.numeric_std.all;
|
||||
|
||||
library work;
|
||||
use work.pBus_savestates.all;
|
||||
|
||||
entity eReg_SS is
|
||||
generic
|
||||
(
|
||||
Reg : savestate_type;
|
||||
index : integer := 0
|
||||
);
|
||||
port
|
||||
(
|
||||
clk : in std_logic;
|
||||
BUS_Din : in std_logic_vector(SSBUS_buswidth-1 downto 0);
|
||||
BUS_Adr : in std_logic_vector(SSBUS_busadr-1 downto 0);
|
||||
BUS_wren : in std_logic;
|
||||
BUS_rst : in std_logic;
|
||||
BUS_Dout : out std_logic_vector(SSBUS_buswidth-1 downto 0) := (others => '0');
|
||||
Din : in std_logic_vector(Reg.upper downto Reg.lower);
|
||||
Dout : out std_logic_vector(Reg.upper downto Reg.lower)
|
||||
);
|
||||
end entity;
|
||||
|
||||
architecture arch of eReg_SS is
|
||||
|
||||
signal Dout_buffer : std_logic_vector(Reg.upper downto Reg.lower) := Reg.defval(Reg.upper downto Reg.lower);
|
||||
|
||||
signal AdrI : std_logic_vector(BUS_Adr'left downto 0);
|
||||
|
||||
begin
|
||||
|
||||
AdrI <= std_logic_vector(to_unsigned(Reg.Adr + index, BUS_Adr'length));
|
||||
|
||||
process (clk)
|
||||
begin
|
||||
if rising_edge(clk) then
|
||||
|
||||
if (BUS_rst = '1') then
|
||||
|
||||
Dout_buffer <= Reg.defval(Reg.upper downto Reg.lower);
|
||||
|
||||
else
|
||||
|
||||
if (BUS_Adr = AdrI and BUS_wren = '1') then
|
||||
for i in Reg.lower to Reg.upper loop
|
||||
Dout_buffer(i) <= BUS_Din(i);
|
||||
end loop;
|
||||
end if;
|
||||
|
||||
end if;
|
||||
|
||||
end if;
|
||||
end process;
|
||||
|
||||
Dout <= Dout_buffer;
|
||||
|
||||
goutputbit: for i in Reg.lower to Reg.upper generate
|
||||
BUS_Dout(i) <= Din(i) when BUS_Adr = AdrI else '0';
|
||||
end generate;
|
||||
|
||||
glowzero_required: if Reg.lower > 0 generate
|
||||
glowzero: for i in 0 to Reg.lower - 1 generate
|
||||
BUS_Dout(i) <= '0';
|
||||
end generate;
|
||||
end generate;
|
||||
|
||||
ghighzero_required: if Reg.upper < SSBUS_buswidth-1 generate
|
||||
ghighzero: for i in Reg.upper + 1 to SSBUS_buswidth-1 generate
|
||||
BUS_Dout(i) <= '0';
|
||||
end generate;
|
||||
end generate;
|
||||
|
||||
end architecture;
|
||||
|
||||
|
||||
3073
common/CPU/v30/cpu.vhd
Normal file
3073
common/CPU/v30/cpu.vhd
Normal file
File diff suppressed because it is too large
Load Diff
123
common/CPU/v30/divider.vhd
Normal file
123
common/CPU/v30/divider.vhd
Normal file
@ -0,0 +1,123 @@
|
||||
library IEEE;
|
||||
use IEEE.std_logic_1164.all;
|
||||
use IEEE.numeric_std.all;
|
||||
|
||||
entity divider is
|
||||
port
|
||||
(
|
||||
clk : in std_logic;
|
||||
start : in std_logic;
|
||||
done : out std_logic := '0';
|
||||
busy : out std_logic := '0';
|
||||
dividend : in signed(32 downto 0);
|
||||
divisor : in signed(32 downto 0);
|
||||
quotient : out signed(32 downto 0);
|
||||
remainder : out signed(32 downto 0)
|
||||
);
|
||||
end entity;
|
||||
|
||||
architecture arch of divider is
|
||||
|
||||
constant bits_per_cycle : integer := 1;
|
||||
|
||||
signal dividend_u : unsigned(dividend'length downto 0);
|
||||
signal divisor_u : unsigned(divisor'length downto 0);
|
||||
signal quotient_u : unsigned(quotient'length downto 0);
|
||||
signal Akku : unsigned (divisor'left + 1 downto divisor'right);
|
||||
signal QPointer : integer range quotient_u'range;
|
||||
signal done_buffer : std_logic := '0';
|
||||
|
||||
begin
|
||||
|
||||
process (clk) is
|
||||
variable XPointer : integer range dividend_u'range;
|
||||
variable QPointerNew : integer range quotient_u'range;
|
||||
variable AkkuNew : unsigned (divisor'left + 1 downto divisor'right);
|
||||
variable Rdy_i : std_logic;
|
||||
variable Q_bits : std_logic_vector(bits_per_cycle-1 downto 0);
|
||||
variable Diff : unsigned (AkkuNew'range);
|
||||
begin
|
||||
if rising_edge(clk) then
|
||||
|
||||
done_buffer <= '0';
|
||||
busy <= '0';
|
||||
|
||||
-- == Initialize loop ===============================================
|
||||
if start = '1' then
|
||||
|
||||
busy <= '1';
|
||||
|
||||
dividend_u <= '0' & unsigned(abs(dividend));
|
||||
divisor_u <= '0' & unsigned(abs(divisor));
|
||||
|
||||
QPointerNew := quotient_u'left;
|
||||
XPointer := dividend_u'left;
|
||||
Rdy_i := '0';
|
||||
--AkkuNew := (Akku'left downto 1 => '0') & dividend(XPointer);
|
||||
AkkuNew := (others => '0');
|
||||
-- == Repeat for every Digit in Q ===================================
|
||||
elsif Rdy_i = '0' then
|
||||
busy <= '1';
|
||||
AkkuNew := Akku;
|
||||
QPointerNew := QPointer;
|
||||
|
||||
for i in 1 to bits_per_cycle loop
|
||||
|
||||
-- Calculate output digit and new Akku ---------------------------
|
||||
Diff := AkkuNew - divisor_u;
|
||||
if Diff(Diff'left) = '0' then -- Does Y fit in Akku?
|
||||
Q_bits(bits_per_cycle-i) := '1'; -- YES: Digit is '1'
|
||||
AkkuNew := unsigned(shift_left(Diff,1));-- Diff -> Akku
|
||||
else --
|
||||
Q_bits(bits_per_cycle-i) := '0'; -- NO : Digit is '0'
|
||||
AkkuNew := unsigned(Shift_left(AkkuNew,1));-- Shift Akku
|
||||
end if;
|
||||
-- ---------------------------------------------------------------
|
||||
if XPointer > dividend'right then -- divisor read completely?
|
||||
XPointer := XPointer - 1; -- NO : Put next digit
|
||||
AkkuNew(AkkuNew'right) := dividend_u(XPointer); -- in Akku
|
||||
else
|
||||
AkkuNew(AkkuNew'right) := '0' ; -- YES: Read Zeros (post point)
|
||||
end if;
|
||||
-- ---------------------------------------------------------------
|
||||
if QPointerNew > quotient'right then -- Has this been the last cycle?
|
||||
QPointerNew := QPointerNew - 1; -- NO : Prepare next cycle
|
||||
else --
|
||||
Rdy_i := '1'; -- YES: work done
|
||||
done_buffer <= '1';
|
||||
end if;
|
||||
|
||||
end loop;
|
||||
|
||||
quotient_u(QPointer downto QPointer-(bits_per_cycle-1)) <= unsigned(Q_bits);
|
||||
end if;
|
||||
|
||||
QPointer <= QPointerNew;
|
||||
Akku <= AkkuNew;
|
||||
|
||||
if ((dividend(dividend'left) xor divisor(divisor'left)) = '1') then
|
||||
quotient <= -signed(quotient_u(quotient'left downto 0));
|
||||
else
|
||||
quotient <= signed(quotient_u(quotient'left downto 0));
|
||||
end if;
|
||||
if (dividend(dividend'left) = '1') then
|
||||
remainder <= -signed(AkkuNew(remainder'left + 1 downto remainder'right + 1));
|
||||
else
|
||||
remainder <= signed(AkkuNew(remainder'left + 1 downto remainder'right + 1));
|
||||
end if;
|
||||
|
||||
done <= done_buffer;
|
||||
|
||||
end if;
|
||||
|
||||
|
||||
|
||||
end process;
|
||||
|
||||
|
||||
end architecture;
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
221
common/CPU/v30/export.vhd
Normal file
221
common/CPU/v30/export.vhd
Normal file
@ -0,0 +1,221 @@
|
||||
-----------------------------------------------------------------
|
||||
--------------- Export Package --------------------------------
|
||||
-----------------------------------------------------------------
|
||||
|
||||
library IEEE;
|
||||
use IEEE.std_logic_1164.all;
|
||||
use IEEE.numeric_std.all;
|
||||
|
||||
package pexport is
|
||||
|
||||
type cpu_export_type is record
|
||||
reg_ax : unsigned(15 downto 0);
|
||||
reg_cx : unsigned(15 downto 0);
|
||||
reg_dx : unsigned(15 downto 0);
|
||||
reg_bx : unsigned(15 downto 0);
|
||||
reg_sp : unsigned(15 downto 0);
|
||||
reg_bp : unsigned(15 downto 0);
|
||||
reg_si : unsigned(15 downto 0);
|
||||
reg_di : unsigned(15 downto 0);
|
||||
reg_es : unsigned(15 downto 0);
|
||||
reg_cs : unsigned(15 downto 0);
|
||||
reg_ss : unsigned(15 downto 0);
|
||||
reg_ds : unsigned(15 downto 0);
|
||||
reg_ip : unsigned(15 downto 0);
|
||||
reg_f : unsigned(15 downto 0);
|
||||
opcodebyte_last : std_logic_vector(7 downto 0);
|
||||
end record;
|
||||
|
||||
end package;
|
||||
|
||||
-----------------------------------------------------------------
|
||||
--------------- Export module --------------------------------
|
||||
-----------------------------------------------------------------
|
||||
|
||||
|
||||
library IEEE;
|
||||
use IEEE.std_logic_1164.all;
|
||||
use IEEE.numeric_std.all;
|
||||
use STD.textio.all;
|
||||
|
||||
use work.pexport.all;
|
||||
|
||||
entity export is
|
||||
port
|
||||
(
|
||||
clk : in std_logic;
|
||||
ce : in std_logic;
|
||||
reset : in std_logic;
|
||||
|
||||
new_export : in std_logic;
|
||||
export_cpu : in cpu_export_type;
|
||||
|
||||
export_irq : in std_logic_vector(7 downto 0);
|
||||
|
||||
export_8 : in std_logic_vector(7 downto 0);
|
||||
export_16 : in std_logic_vector(15 downto 0);
|
||||
export_32 : in std_logic_vector(31 downto 0)
|
||||
);
|
||||
end entity;
|
||||
|
||||
architecture arch of export is
|
||||
|
||||
signal totalticks : unsigned(31 downto 0) := (others => '0');
|
||||
signal cyclenr : unsigned(31 downto 0) := x"00000001";
|
||||
|
||||
signal reset_1 : std_logic := '0';
|
||||
signal export_reset : std_logic := '0';
|
||||
signal exportnow : std_logic;
|
||||
|
||||
function to_lower(c: character) return character is
|
||||
variable l: character;
|
||||
begin
|
||||
case c is
|
||||
when 'A' => l := 'a';
|
||||
when 'B' => l := 'b';
|
||||
when 'C' => l := 'c';
|
||||
when 'D' => l := 'd';
|
||||
when 'E' => l := 'e';
|
||||
when 'F' => l := 'f';
|
||||
when 'G' => l := 'g';
|
||||
when 'H' => l := 'h';
|
||||
when 'I' => l := 'i';
|
||||
when 'J' => l := 'j';
|
||||
when 'K' => l := 'k';
|
||||
when 'L' => l := 'l';
|
||||
when 'M' => l := 'm';
|
||||
when 'N' => l := 'n';
|
||||
when 'O' => l := 'o';
|
||||
when 'P' => l := 'p';
|
||||
when 'Q' => l := 'q';
|
||||
when 'R' => l := 'r';
|
||||
when 'S' => l := 's';
|
||||
when 'T' => l := 't';
|
||||
when 'U' => l := 'u';
|
||||
when 'V' => l := 'v';
|
||||
when 'W' => l := 'w';
|
||||
when 'X' => l := 'x';
|
||||
when 'Y' => l := 'y';
|
||||
when 'Z' => l := 'z';
|
||||
when others => l := c;
|
||||
end case;
|
||||
return l;
|
||||
end to_lower;
|
||||
|
||||
function to_lower(s: string) return string is
|
||||
variable lowercase: string (s'range);
|
||||
begin
|
||||
for i in s'range loop
|
||||
lowercase(i):= to_lower(s(i));
|
||||
end loop;
|
||||
return lowercase;
|
||||
end to_lower;
|
||||
|
||||
begin
|
||||
|
||||
-- synthesis translate_off
|
||||
process(clk)
|
||||
begin
|
||||
if rising_edge(clk) then
|
||||
if (reset = '1') then
|
||||
totalticks <= (others => '0');
|
||||
elsif (ce = '1') then
|
||||
totalticks <= totalticks + 1;
|
||||
end if;
|
||||
reset_1 <= reset;
|
||||
end if;
|
||||
end process;
|
||||
|
||||
export_reset <= '1' when (reset = '0' and reset_1 = '1') else '0';
|
||||
|
||||
exportnow <= export_reset or new_export;
|
||||
|
||||
process
|
||||
|
||||
file outfile: text;
|
||||
file outfile_irp: text;
|
||||
variable f_status: FILE_OPEN_STATUS;
|
||||
variable line_out : line;
|
||||
variable recordcount : integer := 0;
|
||||
|
||||
constant filenamebase : string := "R:\\debug_sim";
|
||||
variable filename_current : string(1 to 25);
|
||||
|
||||
begin
|
||||
|
||||
filename_current := filenamebase & "00000000.txt";
|
||||
|
||||
file_open(f_status, outfile, filename_current, write_mode);
|
||||
file_close(outfile);
|
||||
file_open(f_status, outfile, filename_current, append_mode);
|
||||
|
||||
write(line_out, string'("IP F AX BX CX DX SP BP SI DI ES CS SS DS OP TICKS IQ GPU D8 D16 D32"));
|
||||
writeline(outfile, line_out);
|
||||
|
||||
while (true) loop
|
||||
wait until rising_edge(clk);
|
||||
if (reset = '1') then
|
||||
cyclenr <= x"00000001";
|
||||
filename_current := filenamebase & "00000000.txt";
|
||||
file_close(outfile);
|
||||
file_open(f_status, outfile, filename_current, write_mode);
|
||||
file_close(outfile);
|
||||
file_open(f_status, outfile, filename_current, append_mode);
|
||||
write(line_out, string'("IP F AX BX CX DX SP BP SI DI ES CS SS DS OP TICKS IQ GPU D8 D16 D32"));
|
||||
writeline(outfile, line_out);
|
||||
end if;
|
||||
|
||||
if (exportnow = '1') then
|
||||
|
||||
write(line_out, to_lower(to_hstring(export_cpu.reg_ip)) & " ");
|
||||
write(line_out, to_lower(to_hstring(export_cpu.reg_f )) & " ");
|
||||
write(line_out, to_lower(to_hstring(export_cpu.reg_ax)) & " ");
|
||||
write(line_out, to_lower(to_hstring(export_cpu.reg_bx)) & " ");
|
||||
write(line_out, to_lower(to_hstring(export_cpu.reg_cx)) & " ");
|
||||
write(line_out, to_lower(to_hstring(export_cpu.reg_dx)) & " ");
|
||||
write(line_out, to_lower(to_hstring(export_cpu.reg_sp)) & " ");
|
||||
write(line_out, to_lower(to_hstring(export_cpu.reg_bp)) & " ");
|
||||
write(line_out, to_lower(to_hstring(export_cpu.reg_si)) & " ");
|
||||
write(line_out, to_lower(to_hstring(export_cpu.reg_di)) & " ");
|
||||
write(line_out, to_lower(to_hstring(export_cpu.reg_es)) & " ");
|
||||
write(line_out, to_lower(to_hstring(export_cpu.reg_cs)) & " ");
|
||||
write(line_out, to_lower(to_hstring(export_cpu.reg_ss)) & " ");
|
||||
write(line_out, to_lower(to_hstring(export_cpu.reg_ds)) & " ");
|
||||
|
||||
write(line_out, to_lower(to_hstring(export_cpu.opcodebyte_last)) & " ");
|
||||
write(line_out, to_lower(to_hstring(totalticks)) & " ");
|
||||
|
||||
write(line_out, to_lower(to_hstring(export_irq )) & " ");
|
||||
write(line_out, to_lower(to_hstring(to_unsigned(0, 12))) & " "); -- gpu
|
||||
|
||||
write(line_out, to_lower(to_hstring(export_8 )) & " ");
|
||||
write(line_out, to_lower(to_hstring(export_16)) & " ");
|
||||
write(line_out, to_lower(to_hstring(export_32)) & " ");
|
||||
|
||||
writeline(outfile, line_out);
|
||||
|
||||
cyclenr <= cyclenr + 1;
|
||||
|
||||
if (cyclenr mod 10000000 = 0) then
|
||||
filename_current := filenamebase & to_hstring(cyclenr) & ".txt";
|
||||
file_close(outfile);
|
||||
file_open(f_status, outfile, filename_current, write_mode);
|
||||
file_close(outfile);
|
||||
file_open(f_status, outfile, filename_current, append_mode);
|
||||
write(line_out, string'("IP F AX BX CX DX SP BP SI DI ES CS SS DS OP TICKS IQ GPU D8 D16 D32"));
|
||||
writeline(outfile, line_out);
|
||||
end if;
|
||||
|
||||
end if;
|
||||
|
||||
end loop;
|
||||
|
||||
end process;
|
||||
-- synthesis translate_on
|
||||
|
||||
end architecture;
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
37
common/CPU/v30/reg_savestates.vhd
Normal file
37
common/CPU/v30/reg_savestates.vhd
Normal file
@ -0,0 +1,37 @@
|
||||
library IEEE;
|
||||
use IEEE.std_logic_1164.all;
|
||||
use IEEE.numeric_std.all;
|
||||
|
||||
use work.pBus_savestates.all;
|
||||
|
||||
package pReg_savestates is
|
||||
|
||||
-- ( adr upper lower size default)
|
||||
|
||||
-- cpu
|
||||
constant REG_SAVESTATE_CPU1 : savestate_type := ( 0, 63, 0, 1, x"0000000000000000"); -- DX_CX_AX_IP
|
||||
constant REG_SAVESTATE_CPU2 : savestate_type := ( 1, 63, 0, 1, x"0000000020000000"); -- SI_BP_SP_BX
|
||||
constant REG_SAVESTATE_CPU3 : savestate_type := ( 2, 63, 0, 1, x"0000FFFF00000000"); -- SS_CS_ES_DI
|
||||
constant REG_SAVESTATE_CPU4 : savestate_type := ( 3, 31, 0, 1, x"00000000F0020000"); -- F_DS
|
||||
|
||||
constant REG_SAVESTATE_IRQ : savestate_type := ( 5, 7, 0, 1, x"0000000000000000");
|
||||
|
||||
constant REG_SAVESTATE_GPU : savestate_type := ( 7, 15, 0, 1, x"0000000000009EFF");
|
||||
|
||||
constant REG_SAVESTATE_DMA : savestate_type := ( 11, 59, 0, 1, x"0000000000000000");
|
||||
|
||||
constant REG_SAVESTATE_SOUND3 : savestate_type := ( 15, 10, 0, 1, x"0000000000000000");
|
||||
constant REG_SAVESTATE_SOUND4 : savestate_type := ( 16, 19, 0, 1, x"0000000000000000");
|
||||
constant REG_SAVESTATE_SOUNDDMA : savestate_type := ( 17, 59, 0, 1, x"0000000000000000");
|
||||
|
||||
constant REG_SAVESTATE_EEPROMINT : savestate_type := ( 19, 16, 0, 1, x"0000000000000000");
|
||||
constant REG_SAVESTATE_EEPROMEXT : savestate_type := ( 21, 16, 0, 1, x"0000000000000000");
|
||||
|
||||
constant REG_SAVESTATE_MIXED : savestate_type := ( 23, 0, 0, 1, x"0000000000000000");
|
||||
|
||||
constant REG_SAVESTATE_TIMER : savestate_type := ( 27, 35, 0, 1, x"0000000000000000");
|
||||
|
||||
|
||||
|
||||
|
||||
end package;
|
||||
119
common/CPU/v30/registerpackage.vhd
Normal file
119
common/CPU/v30/registerpackage.vhd
Normal file
@ -0,0 +1,119 @@
|
||||
-----------------------------------------------------------------
|
||||
--------------- Bus Package --------------------------------
|
||||
-----------------------------------------------------------------
|
||||
|
||||
library IEEE;
|
||||
use IEEE.std_logic_1164.all;
|
||||
use IEEE.numeric_std.all;
|
||||
|
||||
package pRegisterBus is
|
||||
|
||||
constant BUS_buswidth : integer := 8;
|
||||
constant BUS_busadr : integer := 8;
|
||||
|
||||
type regaccess_type is
|
||||
(
|
||||
readwrite,
|
||||
readonly,
|
||||
writeonly,
|
||||
writeDone -- writeonly, but does send back done, so it is not dead
|
||||
);
|
||||
|
||||
type regmap_type is record
|
||||
Adr : integer range 0 to (2**BUS_busadr)-1;
|
||||
upper : integer range 0 to BUS_buswidth-1;
|
||||
lower : integer range 0 to BUS_buswidth-1;
|
||||
size : integer range 0 to (2**BUS_busadr)-1;
|
||||
defval : integer;
|
||||
acccesstype : regaccess_type;
|
||||
end record;
|
||||
|
||||
end package;
|
||||
|
||||
|
||||
-----------------------------------------------------------------
|
||||
--------------- Reg Interface ----------------------------------
|
||||
-----------------------------------------------------------------
|
||||
|
||||
library IEEE;
|
||||
use IEEE.std_logic_1164.all;
|
||||
use IEEE.numeric_std.all;
|
||||
|
||||
library work;
|
||||
use work.pRegisterBus.all;
|
||||
|
||||
entity eReg is
|
||||
generic
|
||||
(
|
||||
Reg : regmap_type;
|
||||
index : integer := 0
|
||||
);
|
||||
port
|
||||
(
|
||||
clk : in std_logic;
|
||||
BUS_Din : in std_logic_vector(BUS_buswidth-1 downto 0);
|
||||
BUS_Adr : in std_logic_vector(BUS_busadr-1 downto 0);
|
||||
BUS_wren : in std_logic;
|
||||
BUS_rst : in std_logic;
|
||||
BUS_Dout : out std_logic_vector(BUS_buswidth-1 downto 0) := (others => '0');
|
||||
Din : in std_logic_vector(Reg.upper downto Reg.lower);
|
||||
Dout : out std_logic_vector(Reg.upper downto Reg.lower);
|
||||
written : out std_logic := '0'
|
||||
);
|
||||
end entity;
|
||||
|
||||
architecture arch of eReg is
|
||||
|
||||
signal Dout_buffer : std_logic_vector(Reg.upper downto Reg.lower) := std_logic_vector(to_unsigned(Reg.defval,Reg.upper-Reg.lower+1));
|
||||
|
||||
signal AdrI : std_logic_vector(BUS_Adr'left downto 0);
|
||||
|
||||
begin
|
||||
|
||||
AdrI <= std_logic_vector(to_unsigned(Reg.Adr + index, BUS_Adr'length));
|
||||
|
||||
process (clk)
|
||||
begin
|
||||
if rising_edge(clk) then
|
||||
|
||||
if (BUS_rst = '1') then
|
||||
|
||||
Dout_buffer <= std_logic_vector(to_unsigned(Reg.defval,Reg.upper-Reg.lower+1));
|
||||
|
||||
else
|
||||
|
||||
if (BUS_Adr = AdrI and BUS_wren = '1') then
|
||||
for i in Reg.lower to Reg.upper loop
|
||||
Dout_buffer(i) <= BUS_Din(i);
|
||||
end loop;
|
||||
end if;
|
||||
|
||||
end if;
|
||||
|
||||
end if;
|
||||
end process;
|
||||
|
||||
Dout <= Dout_buffer;
|
||||
|
||||
written <= '1' when (BUS_Adr = AdrI and BUS_wren = '1') else '0';
|
||||
|
||||
goutputbit: for i in Reg.lower to Reg.upper generate
|
||||
BUS_Dout(i) <= Din(i) when BUS_Adr = AdrI else '0';
|
||||
end generate;
|
||||
|
||||
glowzero_required: if Reg.lower > 0 generate
|
||||
glowzero: for i in 0 to Reg.lower - 1 generate
|
||||
BUS_Dout(i) <= '0';
|
||||
end generate;
|
||||
end generate;
|
||||
|
||||
ghighzero_required: if Reg.upper < BUS_buswidth-1 generate
|
||||
ghighzero: for i in Reg.upper + 1 to BUS_buswidth-1 generate
|
||||
BUS_Dout(i) <= '0';
|
||||
end generate;
|
||||
end generate;
|
||||
|
||||
end architecture;
|
||||
|
||||
|
||||
|
||||
Loading…
x
Reference in New Issue
Block a user