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

Subversion Repositories open8_urisc

Compare Revisions

  • This comparison shows the changes necessary to convert path
    /open8_urisc/trunk/VHDL
    from Rev 216 to Rev 217
    Reverse comparison

Rev 216 → Rev 217

/o8_alu16.vhd
167,19 → 167,19
 
entity o8_alu16 is
generic(
Reset_Level : std_logic;
Address : ADDRESS_TYPE
Reset_Level : std_logic;
Address : ADDRESS_TYPE
);
port(
Clock : in std_logic;
Reset : in std_logic;
Clock : in std_logic;
Reset : in std_logic;
--
Bus_Address : in ADDRESS_TYPE;
Wr_Enable : in std_logic;
Wr_Data : in DATA_TYPE;
Rd_Enable : in std_logic;
Rd_Data : out DATA_TYPE;
Interrupt : out std_logic
Bus_Address : in ADDRESS_TYPE;
Wr_Enable : in std_logic;
Wr_Data : in DATA_TYPE;
Rd_Enable : in std_logic;
Rd_Data : out DATA_TYPE;
Interrupt : out std_logic
);
end entity;
 
188,236 → 188,264
-------------------------------------------------------------------
-- Opcode Definitions (should match the table above)
-- Register Manipulation
constant OP_T0X : std_logic_vector(4 downto 0) := "00000";
constant OP_TX0 : std_logic_vector(4 downto 0) := "00001";
constant OP_CLR : std_logic_vector(4 downto 0) := "00010";
constant OP_T0X : std_logic_vector(4 downto 0) := "00000";
constant OP_TX0 : std_logic_vector(4 downto 0) := "00001";
constant OP_CLR : std_logic_vector(4 downto 0) := "00010";
 
-- Integer Division
constant OP_IDIV : std_logic_vector(4 downto 0) := "00011";
constant OP_IDIV : std_logic_vector(4 downto 0) := "00011";
 
-- Unsigned Math Operations
constant OP_UMUL : std_logic_vector(4 downto 0) := "00100";
constant OP_UADD : std_logic_vector(4 downto 0) := "00101";
constant OP_UADC : std_logic_vector(4 downto 0) := "00110";
constant OP_USUB : std_logic_vector(4 downto 0) := "00111";
constant OP_USBC : std_logic_vector(4 downto 0) := "01000";
constant OP_UCMP : std_logic_vector(4 downto 0) := "01001";
constant OP_UMUL : std_logic_vector(4 downto 0) := "00100";
constant OP_UADD : std_logic_vector(4 downto 0) := "00101";
constant OP_UADC : std_logic_vector(4 downto 0) := "00110";
constant OP_USUB : std_logic_vector(4 downto 0) := "00111";
constant OP_USBC : std_logic_vector(4 downto 0) := "01000";
constant OP_UCMP : std_logic_vector(4 downto 0) := "01001";
 
-- Signed Math Operations
constant OP_SMUL : std_logic_vector(4 downto 0) := "01010";
constant OP_SADD : std_logic_vector(4 downto 0) := "01011";
constant OP_SSUB : std_logic_vector(4 downto 0) := "01100";
constant OP_SCMP : std_logic_vector(4 downto 0) := "01101";
constant OP_SMAG : std_logic_vector(4 downto 0) := "01110";
constant OP_SNEG : std_logic_vector(4 downto 0) := "01111";
constant OP_SMUL : std_logic_vector(4 downto 0) := "01010";
constant OP_SADD : std_logic_vector(4 downto 0) := "01011";
constant OP_SSUB : std_logic_vector(4 downto 0) := "01100";
constant OP_SCMP : std_logic_vector(4 downto 0) := "01101";
constant OP_SMAG : std_logic_vector(4 downto 0) := "01110";
constant OP_SNEG : std_logic_vector(4 downto 0) := "01111";
 
-- Signed Almost Equal
constant OP_ACMP : std_logic_vector(4 downto 0) := "10000";
constant OP_ACMP : std_logic_vector(4 downto 0) := "10000";
 
-- Carry Flag set/clear
constant OP_SCRY : std_logic_vector(4 downto 0) := "10001";
constant OP_SCRY : std_logic_vector(4 downto 0) := "10001";
 
-- (Un)Signed Decimal Adjust Byte
constant OP_UDAB : std_logic_vector(4 downto 0) := "10010";
constant OP_SDAB : std_logic_vector(4 downto 0) := "10011";
constant OP_UDAB : std_logic_vector(4 downto 0) := "10010";
constant OP_SDAB : std_logic_vector(4 downto 0) := "10011";
 
-- (Un)Signed Decimal Adjust Word
constant OP_UDAW : std_logic_vector(4 downto 0) := "10100";
constant OP_SDAW : std_logic_vector(4 downto 0) := "10101";
constant OP_UDAW : std_logic_vector(4 downto 0) := "10100";
constant OP_SDAW : std_logic_vector(4 downto 0) := "10101";
 
-- Reserved for future use
constant OP_RSVD : std_logic_vector(4 downto 0) := "10110";
constant OP_RSVD : std_logic_vector(4 downto 0) := "10110";
 
-- Byte Swap ( U <> L )
constant OP_BSWP : std_logic_vector(4 downto 0) := "10111";
constant OP_BSWP : std_logic_vector(4 downto 0) := "10111";
 
-- Bitwise Boolean Operations (two operand)
constant OP_BOR : std_logic_vector(4 downto 0) := "11000";
constant OP_BAND : std_logic_vector(4 downto 0) := "11001";
constant OP_BXOR : std_logic_vector(4 downto 0) := "11010";
constant OP_BOR : std_logic_vector(4 downto 0) := "11000";
constant OP_BAND : std_logic_vector(4 downto 0) := "11001";
constant OP_BXOR : std_logic_vector(4 downto 0) := "11010";
 
-- In-place Bitwise Boolean Operations (single operand)
constant OP_BINV : std_logic_vector(4 downto 0) := "11011";
constant OP_BSFL : std_logic_vector(4 downto 0) := "11100";
constant OP_BROL : std_logic_vector(4 downto 0) := "11101";
constant OP_BSFR : std_logic_vector(4 downto 0) := "11110";
constant OP_BROR : std_logic_vector(4 downto 0) := "11111";
constant OP_BINV : std_logic_vector(4 downto 0) := "11011";
constant OP_BSFL : std_logic_vector(4 downto 0) := "11100";
constant OP_BROL : std_logic_vector(4 downto 0) := "11101";
constant OP_BSFR : std_logic_vector(4 downto 0) := "11110";
constant OP_BROR : std_logic_vector(4 downto 0) := "11111";
-------------------------------------------------------------------
 
constant User_Addr : std_logic_vector(15 downto 5):=
Address(15 downto 5);
alias Comp_Addr is Bus_Address(15 downto 5);
signal Reg_Addr : std_logic_vector(4 downto 0) := (others => '0');
constant User_Addr : std_logic_vector(15 downto 5):=
Address(15 downto 5);
alias Comp_Addr is Bus_Address(15 downto 5);
 
signal Addr_Match : std_logic := '0';
signal Wr_En : std_logic := '0';
signal Wr_Data_q : DATA_TYPE := (others => '0');
signal Rd_En : std_logic := '0';
signal Reg_Addr : std_logic_vector(4 downto 0) :=
(others => '0');
 
signal Addr_Match : std_logic := '0';
signal Wr_En : std_logic := '0';
signal Wr_Data_q : DATA_TYPE := (others => '0');
signal Rd_En : std_logic := '0';
 
type REG_ARRAY is array( 0 to 7 ) of std_logic_vector(15 downto 0);
signal regfile : REG_ARRAY := (
x"0000",x"0000",x"0000",x"0000",
x"0000",x"0000",x"0000",x"0000");
signal regfile : REG_ARRAY := (
x"0000",x"0000",x"0000",x"0000",
x"0000",x"0000",x"0000",x"0000");
 
signal Start : std_logic := '0';
signal Opcode : std_logic_vector(4 downto 0) := (others => '0');
signal Operand_Sel : std_logic_vector(2 downto 0) := (others => '0');
signal Start : std_logic := '0';
signal Opcode : std_logic_vector(4 downto 0) :=
(others => '0');
 
signal Tolerance : std_logic_vector(15 downto 0) := (others => '0');
signal High_Tol : signed(16 downto 0) := (others => '0');
signal Low_Tol : signed(16 downto 0) := (others => '0');
signal Almost_Equal : std_logic := '0';
signal Operand_Sel : std_logic_vector(2 downto 0) :=
(others => '0');
 
constant FLAG_Z : integer := 0;
constant FLAG_C : integer := 1;
constant FLAG_N : integer := 2;
constant FLAG_O : integer := 3;
signal Tolerance : std_logic_vector(15 downto 0) :=
(others => '0');
 
signal Flags : std_logic_vector(3 downto 0) := (others => '0');
signal High_Tol : signed(16 downto 0) := (others => '0');
signal Low_Tol : signed(16 downto 0) := (others => '0');
signal Almost_Equal : std_logic := '0';
 
constant FLAG_Z : integer := 0;
constant FLAG_C : integer := 1;
constant FLAG_N : integer := 2;
constant FLAG_O : integer := 3;
 
signal Flags : std_logic_vector(3 downto 0) :=
(others => '0');
 
type ALU_STATES is ( IDLE, LOAD, EXECUTE, IDIV_INIT, IDIV_WAIT,
DAW_INIT, DAB_INIT, DAA_WAIT1, DAA_STEP2,
DAA_WAIT2, DAA_STEP3, DAA_WAIT3, DAA_STEP4,
STORE );
signal alu_ctrl : ALU_STATES := IDLE;
signal alu_ctrl : ALU_STATES := IDLE;
 
signal Busy : std_logic := '0';
signal Busy_q : std_logic := '0';
signal Busy : std_logic := '0';
signal Busy_q : std_logic := '0';
 
signal Operand_1 : std_logic_vector(15 downto 0) := (others => '0');
signal Operand_2 : std_logic_vector(15 downto 0) := (others => '0');
signal Operand_1 : std_logic_vector(15 downto 0) :=
(others => '0');
 
alias Dividend is Operand_1;
alias Divisor is Operand_2;
signal Operand_2 : std_logic_vector(15 downto 0) :=
(others => '0');
 
alias u_Operand_1 is Operand_1;
alias u_Operand_2 is Operand_2;
alias Dividend is Operand_1;
alias Divisor is Operand_2;
 
alias u_Addend_1 is Operand_1;
alias u_Addend_2 is Operand_2;
alias u_Operand_1 is Operand_1;
alias u_Operand_2 is Operand_2;
 
signal s_Operand_1 : signed(16 downto 0) := (others => '0');
signal s_Operand_2 : signed(16 downto 0) := (others => '0');
alias u_Addend_1 is Operand_1;
alias u_Addend_2 is Operand_2;
 
alias s_Addend_1 is S_Operand_1;
alias s_Addend_2 is S_Operand_2;
signal s_Operand_1 : signed(16 downto 0) := (others => '0');
signal s_Operand_2 : signed(16 downto 0) := (others => '0');
 
signal u_accum : std_logic_vector(16 downto 0) := (others => '0');
alias u_data is u_accum(15 downto 0);
alias u_sign is u_accum(15);
alias u_carry is u_accum(16);
alias s_Addend_1 is S_Operand_1;
alias s_Addend_2 is S_Operand_2;
 
signal u_prod : std_logic_vector(31 downto 0) := (others => '0');
signal u_accum : std_logic_vector(16 downto 0) :=
(others => '0');
alias u_data is u_accum(15 downto 0);
alias u_sign is u_accum(15);
alias u_carry is u_accum(16);
 
signal s_accum : signed(16 downto 0) := (others => '0');
alias s_data is s_accum(15 downto 0);
alias s_sign is s_accum(15);
alias s_ovf is s_accum(16);
signal u_prod : std_logic_vector(31 downto 0) :=
(others => '0');
 
signal s_prod : signed(33 downto 0) := (others => '0');
signal s_accum : signed(16 downto 0) := (others => '0');
alias s_data is s_accum(15 downto 0);
alias s_sign is s_accum(15);
alias s_ovf is s_accum(16);
 
signal IDIV_Start : std_logic := '0';
signal IDIV_Busy : std_logic := '0';
signal s_prod : signed(33 downto 0) := (others => '0');
 
constant DIV_WIDTH : integer := 16; -- Width of Operands
signal IDIV_Start : std_logic := '0';
signal IDIV_Busy : std_logic := '0';
 
signal q : std_logic_vector(DIV_WIDTH*2-1 downto 0) :=
(others => '0');
constant DIV_WIDTH : integer := 16; -- Width of Operands
 
signal diff : std_logic_vector(DIV_WIDTH downto 0) :=
(others => '0');
signal q : std_logic_vector(DIV_WIDTH*2-1 downto 0) :=
(others => '0');
 
signal count : integer range 0 to DIV_WIDTH + 1 := 0;
signal diff : std_logic_vector(DIV_WIDTH downto 0) :=
(others => '0');
 
signal Quotient_i : std_logic_vector(15 downto 0) := (others => '0');
signal Quotient : std_logic_vector(15 downto 0) := (others => '0');
signal count : integer range 0 to DIV_WIDTH + 1 := 0;
 
signal Remainder_i : std_logic_vector(15 downto 0) := (others => '0');
signal Remainder : std_logic_vector(15 downto 0) := (others => '0');
signal Quotient_i : std_logic_vector(15 downto 0) :=
(others => '0');
 
signal DAA_intreg : std_logic_vector(15 downto 0) := (others => '0');
signal DAA_mode : std_logic := '0';
signal DAA_sign : std_logic := '0';
signal DAA_p4 : std_logic_vector(3 downto 0) := (others => '0');
signal DAA_p3 : std_logic_vector(3 downto 0) := (others => '0');
signal DAA_p2 : std_logic_vector(3 downto 0) := (others => '0');
alias DAA_p1 is Quotient(3 downto 0);
alias DAA_p0 is Remainder(3 downto 0);
signal DAA_result : std_logic_vector(19 downto 0) := (others => '0');
signal Quotient : std_logic_vector(15 downto 0) :=
(others => '0');
 
signal Remainder_i : std_logic_vector(15 downto 0) :=
(others => '0');
 
signal Remainder : std_logic_vector(15 downto 0) :=
(others => '0');
 
signal DAA_intreg : std_logic_vector(15 downto 0) :=
(others => '0');
 
signal DAA_mode : std_logic := '0';
signal DAA_sign : std_logic := '0';
signal DAA_p4 : std_logic_vector(3 downto 0) :=
(others => '0');
 
signal DAA_p3 : std_logic_vector(3 downto 0) :=
(others => '0');
 
signal DAA_p2 : std_logic_vector(3 downto 0) :=
(others => '0');
 
alias DAA_p1 is Quotient(3 downto 0);
alias DAA_p0 is Remainder(3 downto 0);
signal DAA_result : std_logic_vector(19 downto 0) :=
(others => '0');
 
begin
 
Addr_Match <= '1' when Comp_Addr = User_Addr else '0';
Addr_Match <= '1' when Comp_Addr = User_Addr else '0';
 
-- Sign-extend the base operands to created operands for signed math
S_Operand_1 <= signed(Operand_1(15) & Operand_1);
S_Operand_2 <= signed(Operand_2(15) & Operand_2);
S_Operand_1 <= signed(Operand_1(15) & Operand_1);
S_Operand_2 <= signed(Operand_2(15) & Operand_2);
 
-- Compute the tolerance bounds for the Almost Equal function
High_Tol <= S_Operand_2 + signed('0' & Tolerance);
Low_Tol <= S_Operand_2 - signed('0' & Tolerance);
High_Tol <= S_Operand_2 + signed('0' & Tolerance);
Low_Tol <= S_Operand_2 - signed('0' & Tolerance);
 
-- Combinational logic for the Decimal Adjust logic
DAA_result <= DAA_p4 & DAA_p3 & DAA_p2 & DAA_p1 & DAA_p0;
DAA_result <= DAA_p4 & DAA_p3 & DAA_p2 & DAA_p1 & DAA_p0;
 
-- Combinational logic for the division logic
diff <= ('0' & Q(DIV_WIDTH*2-2 downto DIV_WIDTH-1)) -
('0' & Divisor);
Quotient_i <= q(DIV_WIDTH-1 downto 0);
Remainder_i <= q(DIV_WIDTH*2-1 downto DIV_WIDTH);
diff <= ('0' & Q(DIV_WIDTH*2-2 downto DIV_WIDTH-1)) -
('0' & Divisor);
Quotient_i <= q(DIV_WIDTH-1 downto 0);
Remainder_i <= q(DIV_WIDTH*2-1 downto DIV_WIDTH);
 
ALU_proc: process( Clock, Reset )
variable Reg_Sel : integer;
variable Oper_Sel : integer;
variable Reg_Sel : integer;
variable Oper_Sel : integer;
begin
if( Reset = Reset_Level )then
Wr_En <= '0';
Wr_Data_q <= (others => '0');
Rd_En <= '0';
Rd_Data <= OPEN8_NULLBUS;
Reg_Addr <= (others => '0');
Opcode <= (others => '0');
Operand_Sel <= (others => '0');
Tolerance <= (others => '0');
Start <= '0';
Busy_q <= '0';
Interrupt <= '0';
Wr_En <= '0';
Wr_Data_q <= (others => '0');
Rd_En <= '0';
Rd_Data <= OPEN8_NULLBUS;
Reg_Addr <= (others => '0');
Opcode <= (others => '0');
Operand_Sel <= (others => '0');
Tolerance <= (others => '0');
Start <= '0';
Busy_q <= '0';
Interrupt <= '0';
for i in 0 to 7 loop
regfile(i) <= (others => '0');
regfile(i) <= (others => '0');
end loop;
alu_ctrl <= IDLE;
Operand_1 <= (others => '0');
Operand_2 <= (others => '0');
u_accum <= (others => '0');
u_prod <= (others => '0');
s_accum <= (others => '0');
s_prod <= (others => '0');
Quotient <= (others => '0');
Remainder <= (others => '0');
Flags <= (others => '0');
Almost_Equal <= '0';
Busy <= '0';
DAA_mode <= '0';
DAA_sign <= '0';
DAA_intreg <= (others => '0');
DAA_p4 <= (others => '0');
DAA_p3 <= (others => '0');
DAA_p2 <= (others => '0');
IDIV_Start <= '0';
q <= (others => '0');
count <= DIV_WIDTH;
IDIV_Busy <= '0';
alu_ctrl <= IDLE;
Operand_1 <= (others => '0');
Operand_2 <= (others => '0');
u_accum <= (others => '0');
u_prod <= (others => '0');
s_accum <= (others => '0');
s_prod <= (others => '0');
Quotient <= (others => '0');
Remainder <= (others => '0');
Flags <= (others => '0');
Almost_Equal <= '0';
Busy <= '0';
DAA_mode <= '0';
DAA_sign <= '0';
DAA_intreg <= (others => '0');
DAA_p4 <= (others => '0');
DAA_p3 <= (others => '0');
DAA_p2 <= (others => '0');
IDIV_Start <= '0';
q <= (others => '0');
count <= DIV_WIDTH;
IDIV_Busy <= '0';
elsif( rising_edge(Clock) )then
-- For convenience, convert these to integers and assign them to
-- variables
Reg_Sel := conv_integer(Reg_Addr(3 downto 1));
Oper_Sel := conv_integer(Operand_Sel);
Reg_Sel := conv_integer(Reg_Addr(3 downto 1));
Oper_Sel := conv_integer(Operand_Sel);
 
Wr_En <= Addr_Match and Wr_Enable;
Wr_Data_q <= Wr_Data;
Reg_Addr <= Bus_Address(4 downto 0);
Wr_En <= Addr_Match and Wr_Enable;
Wr_Data_q <= Wr_Data;
Reg_Addr <= Bus_Address(4 downto 0);
 
Start <= '0';
Start <= '0';
if( Wr_En = '1' )then
case( Reg_Addr )is
-- Even addresses go to the lower byte of the register
437,47 → 465,47
Tolerance(15 downto 8) <= Wr_Data_q;
 
when "11110" => -- 0x1E -> Opcode register
Opcode <= Wr_Data_q(7 downto 3);
Operand_Sel <= Wr_Data_q(2 downto 0);
Opcode <= Wr_Data_q(7 downto 3);
Operand_Sel <= Wr_Data_q(2 downto 0);
 
when "11111" => -- 0x1F -> Status/Start register
Start <= '1';
Start <= '1';
 
when others => null;
end case;
end if;
 
Rd_Data <= OPEN8_NULLBUS;
Rd_En <= Addr_Match and Rd_Enable;
Rd_Data <= OPEN8_NULLBUS;
Rd_En <= Addr_Match and Rd_Enable;
 
if( Rd_En = '1' )then
case( Reg_Addr )is
when "00000" | "00010" | "00100" | "00110" |
"01000" | "01010" | "01100" | "01110" =>
Rd_Data <= regfile(Reg_Sel)(7 downto 0);
Rd_Data <= regfile(Reg_Sel)(7 downto 0);
when "00001" | "00011" | "00101" | "00111" |
"01001" | "01011" | "01101" | "01111" =>
Rd_Data <= regfile(Reg_Sel)(15 downto 8);
Rd_Data <= regfile(Reg_Sel)(15 downto 8);
when "11100" => -- 0x1C -> Tolerance.l
Rd_Data <= Tolerance(7 downto 0);
Rd_Data <= Tolerance(7 downto 0);
when "11101" => -- 0x1D -> Tolerance.u
Rd_Data <= Tolerance(15 downto 8);
Rd_Data <= Tolerance(15 downto 8);
when "11110" => -- 0x1E -> Opcode register
Rd_Data <= Opcode & Operand_Sel;
Rd_Data <= Opcode & Operand_Sel;
when "11111" => -- 0x1F -> Flags & Status register
Rd_Data <= Busy & "000" & Flags;
Rd_Data <= Busy & "000" & Flags;
 
when others => null;
end case;
end if;
 
Busy <= '1';
IDIV_Start <= '0';
Busy <= '1';
IDIV_Start <= '0';
case( alu_ctrl )is
when IDLE =>
Busy <= '0';
Busy <= '0';
if( Start = '1' )then
alu_ctrl <= LOAD;
alu_ctrl <= LOAD;
end if;
 
-- Load the operands from the reg file. We also check for specific
484,113 → 512,113
-- opcodes to set the DAA mode (signed vs unsigned). This is the only
-- place where we READ the register file outside of the bus interface
when LOAD =>
Operand_1 <= regfile(0);
Operand_2 <= regfile(Oper_Sel);
DAA_mode <= '0';
Operand_1 <= regfile(0);
Operand_2 <= regfile(Oper_Sel);
DAA_mode <= '0';
if( Opcode = OP_SDAW or Opcode = OP_SDAB )then
DAA_mode <= '1';
DAA_mode <= '1';
end if;
alu_ctrl <= EXECUTE;
alu_ctrl <= EXECUTE;
 
-- Now that the operands are loaded, we can execute the actual math
-- operations. We do it with separate operand registers to pipeline
-- the logic.
when EXECUTE =>
alu_ctrl <= STORE;
alu_ctrl <= STORE;
case( Opcode)is
when OP_T0X =>
u_accum <= '0' & Operand_1;
u_accum <= '0' & Operand_1;
 
when OP_TX0 =>
u_accum <= '0' & Operand_2;
u_accum <= '0' & Operand_2;
 
when OP_CLR | OP_SCRY =>
u_accum <= (others => '0');
u_accum <= (others => '0');
 
when OP_BSWP =>
u_accum <= '0' &
Operand_2(7 downto 0) &
Operand_2(15 downto 8);
u_accum <= '0' &
Operand_2(7 downto 0) &
Operand_2(15 downto 8);
 
when OP_SMAG =>
s_accum <= S_Operand_2;
s_accum <= S_Operand_2;
if( S_Operand_2 < 0)then
s_accum <= -S_Operand_2;
s_accum <= -S_Operand_2;
end if;
 
when OP_SNEG =>
s_accum <= -S_Operand_2;
s_accum <= -S_Operand_2;
 
when OP_SMUL =>
s_prod <= S_Operand_1 * S_Operand_2;
s_prod <= S_Operand_1 * S_Operand_2;
 
when OP_UMUL =>
u_prod <= U_Operand_1 * U_Operand_2;
u_prod <= U_Operand_1 * U_Operand_2;
 
when OP_SADD =>
s_accum <= S_Addend_1 + S_Addend_2;
s_accum <= S_Addend_1 + S_Addend_2;
 
when OP_UADD =>
u_accum <= ('0' & Operand_1) +
('0' & Operand_2);
u_accum <= ('0' & Operand_1) +
('0' & Operand_2);
 
when OP_UADC =>
u_accum <= ('0' & Operand_1) +
('0' & Operand_2) +
Flags(FLAG_C);
u_accum <= ('0' & Operand_1) +
('0' & Operand_2) +
Flags(FLAG_C);
 
when OP_SSUB | OP_SCMP =>
s_accum <= S_Addend_1 - S_Addend_2;
s_accum <= S_Addend_1 - S_Addend_2;
 
when OP_USUB | OP_UCMP =>
u_accum <= ('0' & U_Addend_1) -
('0' & U_Addend_2);
u_accum <= ('0' & U_Addend_1) -
('0' & U_Addend_2);
 
when OP_USBC =>
u_accum <= ('0' & U_Addend_1) -
('0' & U_Addend_2) -
Flags(FLAG_C);
u_accum <= ('0' & U_Addend_1) -
('0' & U_Addend_2) -
Flags(FLAG_C);
 
when OP_ACMP =>
-- Perform the function
-- AE = '1' when (A1 <= A2 + T) and (A1 >= A2 - T) else '0'
Almost_Equal <= '0';
Almost_Equal <= '0';
if( (S_Addend_1 <= High_Tol) and
(S_Addend_1 >= Low_Tol) )then
Almost_Equal <= '1';
Almost_Equal <= '1';
end if;
 
when OP_BINV =>
u_accum <= '0' & (not U_Operand_1);
u_accum <= '0' & (not U_Operand_1);
 
when OP_BSFL =>
u_accum <= U_Operand_1 & '0';
u_accum <= U_Operand_1 & '0';
 
when OP_BROL =>
u_accum <= U_Operand_1 & Flags(FLAG_C);
u_accum <= U_Operand_1 & Flags(FLAG_C);
 
when OP_BSFR =>
u_accum <= "00" & U_Operand_1(15 downto 1);
u_accum <= "00" & U_Operand_1(15 downto 1);
 
when OP_BROR =>
u_accum <= U_Operand_1(0) & Flags(FLAG_C) &
U_Operand_1(15 downto 1);
u_accum <= U_Operand_1(0) & Flags(FLAG_C) &
U_Operand_1(15 downto 1);
 
when OP_BOR =>
u_accum <= '0' & (U_Operand_1 or U_Operand_2);
u_accum <= '0' & (U_Operand_1 or U_Operand_2);
 
when OP_BAND =>
u_accum <= '0' & (U_Operand_1 and U_Operand_2);
u_accum <= '0' & (U_Operand_1 and U_Operand_2);
 
when OP_BXOR =>
u_accum <= '0' & (U_Operand_1 xor U_Operand_2);
u_accum <= '0' & (U_Operand_1 xor U_Operand_2);
 
-- Division unit has a longer latency, so we need to wait for its busy
-- signal to return low before storing results. Trigger the engine,
-- and then jump to the wait state for it to finish
when OP_IDIV =>
IDIV_Start<= '1';
alu_ctrl <= IDIV_INIT;
IDIV_Start <= '1';
alu_ctrl <= IDIV_INIT;
 
-- Decimal Adjust Word initialization
-- Stores the sign bit for later use setting the N flag
597,14 → 625,14
-- Assigns Operand_1 to register as-is
-- If the sign bit is set, do a 2's complement of the register
when OP_UDAW | OP_SDAW =>
IDIV_Start<= '1';
DAA_sign <= Operand_2(15);
Operand_1 <= Operand_2;
IDIV_Start <= '1';
DAA_sign <= Operand_2(15);
Operand_1 <= Operand_2;
if( (Operand_2(15) and DAA_mode) = '1' )then
Operand_1 <= (not Operand_2) + 1;
Operand_1 <= (not Operand_2) + 1;
end if;
Operand_2 <= x"2710";
alu_ctrl <= DAW_INIT;
Operand_2 <= x"2710";
alu_ctrl <= DAW_INIT;
 
-- Decimal Adjust Byte initialization
-- Stores the sign bit for later use setting the N flag
611,16 → 639,16
-- Assigns Operand_1 to the lower byte of the register
-- If the sign bit is set, do a 2's complement of the register
when OP_UDAB | OP_SDAB =>
IDIV_Start<= '1';
DAA_p4 <= (others => '0');
DAA_p3 <= (others => '0');
DAA_sign <= Operand_2(7);
Operand_1 <= x"00" & Operand_2(7 downto 0);
IDIV_Start <= '1';
DAA_p4 <= (others => '0');
DAA_p3 <= (others => '0');
DAA_sign <= Operand_2(7);
Operand_1 <= x"00" & Operand_2(7 downto 0);
if( (Operand_2(7) and DAA_mode) = '1' )then
Operand_1 <= ((not Operand_2) + 1) and x"00FF";
Operand_1 <= ((not Operand_2) + 1) and x"00FF";
end if;
Operand_2 <= x"0064";
alu_ctrl <= DAB_INIT;
Operand_2 <= x"0064";
alu_ctrl <= DAB_INIT;
 
when others => null;
end case;
629,69 → 657,69
-- logic enough to improve performance. Leave them.
when IDIV_INIT =>
if( IDIV_Busy = '1' )then
alu_ctrl <= IDIV_WAIT;
alu_ctrl <= IDIV_WAIT;
end if;
 
when DAW_INIT =>
if( IDIV_Busy = '1' )then
alu_ctrl <= DAA_WAIT1;
alu_ctrl <= DAA_WAIT1;
end if;
 
when DAB_INIT =>
if( IDIV_Busy = '1' )then
alu_ctrl <= DAA_WAIT3;
alu_ctrl <= DAA_WAIT3;
end if;
 
when DAA_WAIT1 =>
if( IDIV_Busy = '0' )then
DAA_p4 <= Quotient_i(3 downto 0);
DAA_intreg <= Remainder_i;
alu_ctrl <= DAA_STEP2;
DAA_p4 <= Quotient_i(3 downto 0);
DAA_intreg <= Remainder_i;
alu_ctrl <= DAA_STEP2;
end if;
 
when DAA_STEP2 =>
Operand_1 <= DAA_intreg;
Operand_2 <= x"03E8";
IDIV_Start <= '1';
Operand_1 <= DAA_intreg;
Operand_2 <= x"03E8";
IDIV_Start <= '1';
if( IDIV_Busy = '1' )then
alu_ctrl <= DAA_WAIT2;
alu_ctrl <= DAA_WAIT2;
end if;
 
when DAA_WAIT2 =>
if( IDIV_Busy = '0' )then
DAA_p3 <= Quotient_i(3 downto 0);
DAA_intreg <= Remainder_i;
alu_ctrl <= DAA_STEP3;
DAA_p3 <= Quotient_i(3 downto 0);
DAA_intreg <= Remainder_i;
alu_ctrl <= DAA_STEP3;
end if;
 
when DAA_STEP3 =>
Operand_1 <= DAA_intreg;
Operand_2 <= x"0064";
IDIV_Start <= '1';
Operand_1 <= DAA_intreg;
Operand_2 <= x"0064";
IDIV_Start <= '1';
if( IDIV_Busy = '1' )then
alu_ctrl <= DAA_WAIT3;
alu_ctrl <= DAA_WAIT3;
end if;
 
when DAA_WAIT3 =>
if( IDIV_Busy = '0' )then
DAA_p2 <= Quotient_i(3 downto 0);
DAA_intreg <= Remainder_i;
alu_ctrl <= DAA_STEP4;
DAA_p2 <= Quotient_i(3 downto 0);
DAA_intreg <= Remainder_i;
alu_ctrl <= DAA_STEP4;
end if;
 
when DAA_STEP4 =>
Operand_1 <= DAA_intreg;
Operand_2 <= x"000A";
IDIV_Start <= '1';
Operand_1 <= DAA_intreg;
Operand_2 <= x"000A";
IDIV_Start <= '1';
if( IDIV_Busy = '1' )then
alu_ctrl <= IDIV_WAIT;
alu_ctrl <= IDIV_WAIT;
end if;
 
when IDIV_WAIT =>
if( IDIV_Busy = '0' )then
Quotient <= Quotient_i;
Remainder <= Remainder_i;
alu_ctrl <= STORE;
Quotient <= Quotient_i;
Remainder <= Remainder_i;
alu_ctrl <= STORE;
end if;
 
-- All ALU writes to the register file go through here. This is also
699,69 → 727,69
-- place where the register file gets WRITTEN outside of the bus
-- interface.
when STORE =>
Flags <= (others => '0');
Flags <= (others => '0');
case( Opcode)is
when OP_T0X | OP_CLR | OP_BSWP =>
regfile(Oper_Sel) <= u_data;
Flags(FLAG_Z) <= nor_reduce(u_data);
Flags(FLAG_N) <= u_sign;
Flags(FLAG_Z) <= nor_reduce(u_data);
Flags(FLAG_N) <= u_sign;
 
when OP_TX0 =>
regfile(0) <= u_data;
Flags(FLAG_Z) <= nor_reduce(u_data);
Flags(FLAG_N) <= u_sign;
regfile(0) <= u_data;
Flags(FLAG_Z) <= nor_reduce(u_data);
Flags(FLAG_N) <= u_sign;
 
when OP_SCRY =>
Flags(FLAG_C) <= '0';
Flags(FLAG_C) <= '0';
if( Oper_Sel > 0 )then
Flags(FLAG_C)<= '1';
end if;
 
when OP_IDIV =>
regfile(0) <= Quotient;
regfile(0) <= Quotient;
regfile(Oper_Sel) <= Remainder;
Flags(FLAG_Z) <= nor_reduce(Quotient);
Flags(FLAG_Z) <= nor_reduce(Quotient);
 
when OP_SMAG | OP_SNEG | OP_SADD | OP_SSUB =>
regfile(0) <= std_logic_vector(s_data);
Flags(FLAG_N) <= s_sign;
Flags(FLAG_Z) <= nor_reduce(std_logic_vector(s_data));
Flags(FLAG_O) <= s_ovf xor s_sign;
regfile(0) <= std_logic_vector(s_data);
Flags(FLAG_N) <= s_sign;
Flags(FLAG_Z) <= nor_reduce(std_logic_vector(s_data));
Flags(FLAG_O) <= s_ovf xor s_sign;
 
when OP_SMUL =>
regfile(0) <= std_logic_vector(s_prod(15 downto 0));
regfile(1) <= std_logic_vector(s_prod(31 downto 16));
Flags(FLAG_N) <= s_prod(33) or s_prod(32);
Flags(FLAG_Z) <= nor_reduce(std_logic_vector(s_prod));
regfile(0) <= std_logic_vector(s_prod(15 downto 0));
regfile(1) <= std_logic_vector(s_prod(31 downto 16));
Flags(FLAG_N) <= s_prod(33) or s_prod(32);
Flags(FLAG_Z) <= nor_reduce(std_logic_vector(s_prod));
 
when OP_UMUL =>
regfile(0) <= u_prod(15 downto 0);
regfile(1) <= u_prod(31 downto 16);
Flags(FLAG_N) <= u_prod(31);
Flags(FLAG_Z) <= nor_reduce(u_prod);
regfile(0) <= u_prod(15 downto 0);
regfile(1) <= u_prod(31 downto 16);
Flags(FLAG_N) <= u_prod(31);
Flags(FLAG_Z) <= nor_reduce(u_prod);
 
when OP_UADD | OP_USUB =>
regfile(0) <= u_data;
Flags(FLAG_Z) <= nor_reduce(u_data);
Flags(FLAG_N) <= u_sign;
Flags(FLAG_C) <= u_carry;
regfile(0) <= u_data;
Flags(FLAG_Z) <= nor_reduce(u_data);
Flags(FLAG_N) <= u_sign;
Flags(FLAG_C) <= u_carry;
 
when OP_SCMP =>
Flags(FLAG_N) <= s_ovf;
Flags(FLAG_Z) <= nor_reduce(std_logic_vector(s_data));
Flags(FLAG_O) <= s_accum(16) xor s_accum(15);
Flags(FLAG_N) <= s_ovf;
Flags(FLAG_Z) <= nor_reduce(std_logic_vector(s_data));
Flags(FLAG_O) <= s_accum(16) xor s_accum(15);
 
when OP_UCMP =>
Flags(FLAG_Z) <= nor_reduce(u_data);
Flags(FLAG_C) <= u_carry;
Flags(FLAG_Z) <= nor_reduce(u_data);
Flags(FLAG_C) <= u_carry;
 
when OP_ACMP =>
Flags(FLAG_Z) <= Almost_Equal;
Flags(FLAG_Z) <= Almost_Equal;
 
when OP_UDAB | OP_SDAB =>
regfile(Oper_Sel) <= DAA_result(15 downto 0);
Flags(FLAG_Z) <= nor_reduce(DAA_result);
Flags(FLAG_N) <= DAA_sign;
Flags(FLAG_Z) <= nor_reduce(DAA_result);
Flags(FLAG_N) <= DAA_sign;
 
when OP_UDAW | OP_SDAW =>
regfile(Oper_Sel) <= DAA_result(15 downto 0);
771,24 → 799,24
end if;
 
when OP_BOR | OP_BAND | OP_BXOR =>
regfile(0) <= u_data;
Flags(FLAG_Z) <= nor_reduce(u_data);
Flags(FLAG_N) <= u_sign;
regfile(0) <= u_data;
Flags(FLAG_Z) <= nor_reduce(u_data);
Flags(FLAG_N) <= u_sign;
 
when OP_BINV =>
regfile(Oper_Sel) <= u_data;
Flags(FLAG_Z) <= nor_reduce(u_data);
Flags(FLAG_N) <= u_sign;
Flags(FLAG_Z) <= nor_reduce(u_data);
Flags(FLAG_N) <= u_sign;
 
when OP_BSFL | OP_BROL | OP_BSFR | OP_BROR =>
regfile(Oper_Sel) <= u_data;
Flags(FLAG_Z) <= nor_reduce(u_data);
Flags(FLAG_N) <= u_sign;
Flags(FLAG_C) <= u_carry;
Flags(FLAG_Z) <= nor_reduce(u_data);
Flags(FLAG_N) <= u_sign;
Flags(FLAG_C) <= u_carry;
 
when others => null;
end case;
alu_ctrl <= IDLE;
alu_ctrl <= IDLE;
 
when others =>
null;
795,25 → 823,25
 
end case;
 
IDIV_Busy <= '0';
IDIV_Busy <= '0';
if( IDIV_Start = '1' )then
IDIV_Busy <= '1';
count <= 0;
q <= conv_std_logic_vector(0,DIV_WIDTH) & Dividend;
IDIV_Busy <= '1';
count <= 0;
q <= conv_std_logic_vector(0,DIV_WIDTH) & Dividend;
elsif( count < DIV_WIDTH )then
IDIV_Busy <= '1';
count <= count + 1;
q <= diff(DIV_WIDTH-1 downto 0) &
q(DIV_WIDTH-2 downto 0) &
'1';
IDIV_Busy <= '1';
count <= count + 1;
q <= diff(DIV_WIDTH-1 downto 0) &
q(DIV_WIDTH-2 downto 0) &
'1';
if( diff(DIV_WIDTH) = '1' )then
q <= q(DIV_WIDTH*2-2 downto 0) & '0';
q <= q(DIV_WIDTH*2-2 downto 0) & '0';
end if;
end if;
 
-- Fire on the falling edge of Busy
Busy_q <= Busy;
Interrupt <= not Busy and Busy_q;
Busy_q <= Busy;
Interrupt <= not Busy and Busy_q;
 
end if;
end process;
/o8_async_serial.vhd
58,29 → 58,29
 
entity o8_async_serial is
generic(
Disable_Transmit : boolean := FALSE;
Disable_Receive : boolean := FALSE;
Bit_Rate : real;
Enable_Parity : boolean;
Parity_Odd_Even_n : std_logic;
Sys_Freq : real;
Reset_Level : std_logic;
Address : ADDRESS_TYPE
Disable_Transmit : boolean := FALSE;
Disable_Receive : boolean := FALSE;
Bit_Rate : real;
Enable_Parity : boolean;
Parity_Odd_Even_n : std_logic;
Sys_Freq : real;
Reset_Level : std_logic;
Address : ADDRESS_TYPE
);
port(
Clock : in std_logic;
Reset : in std_logic;
Clock : in std_logic;
Reset : in std_logic;
--
Bus_Address : in ADDRESS_TYPE;
Wr_Enable : in std_logic;
Wr_Data : in DATA_TYPE;
Rd_Enable : in std_logic;
Rd_Data : out DATA_TYPE;
Bus_Address : in ADDRESS_TYPE;
Wr_Enable : in std_logic;
Wr_Data : in DATA_TYPE;
Rd_Enable : in std_logic;
Rd_Data : out DATA_TYPE;
--
TX_Out : out std_logic;
CTS_In : in std_logic;
RX_In : in std_logic;
RTS_Out : out std_logic
TX_Out : out std_logic;
CTS_In : in std_logic;
RX_In : in std_logic;
RTS_Out : out std_logic
);
end entity;
 
131,23 → 131,23
io_reg: process( Clock, Reset )
begin
if( Reset = Reset_Level )then
Rd_En <= '0';
Rd_Data <= OPEN8_NULLBUS;
RTS_Out <= '0';
Rd_En <= '0';
Rd_Data <= OPEN8_NULLBUS;
RTS_Out <= '0';
elsif( rising_edge( Clock ) )then
Rd_Data <= OPEN8_NULLBUS;
Rd_En <= Rd_Enable and Addr_Match;
Reg_Sel <= Reg_Addr;
Rd_Data <= OPEN8_NULLBUS;
Rd_En <= Rd_Enable and Addr_Match;
Reg_Sel <= Reg_Addr;
if( Rd_En = '1' and Reg_Sel = '1' )then
Rd_Data(4) <= RX_FIFO_Empty;
Rd_Data(5) <= RX_FIFO_AFull;
Rd_Data(6) <= TX_FIFO_Empty;
Rd_Data(7) <= TX_FIFO_AFull;
Rd_Data(4) <= RX_FIFO_Empty;
Rd_Data(5) <= RX_FIFO_AFull;
Rd_Data(6) <= TX_FIFO_Empty;
Rd_Data(7) <= TX_FIFO_AFull;
end if;
if( Rd_En = '1' and Reg_Sel = '0' )then
Rd_Data <= RX_FIFO_Rd_Data;
Rd_Data <= RX_FIFO_Rd_Data;
end if;
RTS_Out <= not RX_FIFO_AFull;
RTS_Out <= not RX_FIFO_AFull;
end if;
end process;
 
/o8_btn_int.vhd
45,40 → 45,40
 
entity o8_btn_int is
generic(
Num_Buttons : integer range 1 to 8 := 8;
Button_Level : std_logic := '0';
Address : ADDRESS_TYPE := x"0000";
Reset_Level : std_logic := '1'
Num_Buttons : integer range 1 to 8 := 8;
Button_Level : std_logic := '0';
Address : ADDRESS_TYPE := x"0000";
Reset_Level : std_logic := '1'
);
port(
Clock : in std_logic := '0';
Reset : in std_logic := '0';
uSec_Tick : in std_logic := '0';
Clock : in std_logic := '0';
Reset : in std_logic := '0';
uSec_Tick : in std_logic := '0';
--
Bus_Address : in ADDRESS_TYPE := x"0000";
Rd_Enable : in std_logic := '0';
Rd_Data : out DATA_TYPE;
Interrupt : out std_logic;
Bus_Address : in ADDRESS_TYPE := x"0000";
Rd_Enable : in std_logic := '0';
Rd_Data : out DATA_TYPE;
Interrupt : out std_logic;
--
Button_In : in DATA_TYPE := x"00"
Button_In : in DATA_TYPE := x"00"
);
end entity;
 
architecture behave of o8_btn_int is
 
constant User_Addr : std_logic_vector(15 downto 0) := Address;
alias Comp_Addr is Bus_Address(15 downto 0);
signal Addr_Match : std_logic := '0';
signal Rd_En : std_logic := '0';
constant User_Addr : std_logic_vector(15 downto 0) := Address;
alias Comp_Addr is Bus_Address(15 downto 0);
signal Addr_Match : std_logic := '0';
signal Rd_En : std_logic := '0';
 
constant MSEC_DELAY : std_logic_vector(9 downto 0) :=
conv_std_logic_vector(1000,10);
constant MSEC_DELAY : std_logic_vector(9 downto 0) :=
conv_std_logic_vector(1000,10);
 
signal mSec_Timer : std_logic_vector(9 downto 0) := (others => '0');
signal mSec_Tick : std_logic := '0';
signal mSec_Timer : std_logic_vector(9 downto 0) := (others => '0');
signal mSec_Tick : std_logic := '0';
 
signal Button_Pressed : DATA_TYPE := x"00";
signal Button_CoS : DATA_TYPE := x"00";
signal Button_Pressed : DATA_TYPE := x"00";
signal Button_CoS : DATA_TYPE := x"00";
 
begin
 
/o8_clk_detect.vhd
87,20 → 87,20
 
begin
 
Addr_Match <= Rd_Enable when Comp_Addr = User_Addr else '0';
Addr_Match <= Rd_Enable when Comp_Addr = User_Addr else '0';
 
io_reg: process( Clock, Reset )
begin
if( Reset = Reset_Level )then
Rd_En <= '0';
Rd_Data <= OPEN8_NULLBUS;
Rd_En <= '0';
Rd_Data <= OPEN8_NULLBUS;
elsif( rising_edge( Clock ) )then
Rd_En <= Addr_Match;
Rd_En <= Addr_Match;
 
Rd_Data <= OPEN8_NULLBUS;
Rd_Data <= OPEN8_NULLBUS;
if( Rd_En = '1' )then
Rd_Data(6) <= Ref_In_q2;
Rd_Data(7) <= Ref_Detect;
Rd_Data(6) <= Ref_In_q2;
Rd_Data(7) <= Ref_Detect;
end if;
 
end if;
/o8_datalatch.vhd
45,66 → 45,66
 
entity o8_datalatch is
generic(
Reset_Level : std_logic;
Address : ADDRESS_TYPE
Reset_Level : std_logic;
Address : ADDRESS_TYPE
);
port(
Clock : in std_logic;
Reset : in std_logic;
Clock : in std_logic;
Reset : in std_logic;
--
Bus_Address : in ADDRESS_TYPE;
Rd_Enable : in std_logic;
Rd_Data : out DATA_TYPE;
Interrupt : out std_logic;
Bus_Address : in ADDRESS_TYPE;
Rd_Enable : in std_logic;
Rd_Data : out DATA_TYPE;
Interrupt : out std_logic;
--
L_Strobe : in std_logic;
L_Data : in DATA_TYPE
L_Strobe : in std_logic;
L_Data : in DATA_TYPE
);
end entity;
 
architecture behave of o8_datalatch is
 
constant User_Addr : std_logic_vector(15 downto 0) := Address;
alias Comp_Addr is Bus_Address(15 downto 0);
signal Addr_Match : std_logic;
signal Rd_En : std_logic;
constant User_Addr : std_logic_vector(15 downto 0) := Address;
alias Comp_Addr is Bus_Address(15 downto 0);
signal Addr_Match : std_logic;
signal Rd_En : std_logic;
 
signal Strobe_sr : std_logic_vector(3 downto 0);
signal Strobe_re : std_logic;
signal Strobe_sr : std_logic_vector(3 downto 0);
signal Strobe_re : std_logic;
 
signal LData_q1 : DATA_TYPE;
signal LData_q2 : DATA_TYPE;
signal LData_q3 : DATA_TYPE;
signal LData_q1 : DATA_TYPE;
signal LData_q2 : DATA_TYPE;
signal LData_q3 : DATA_TYPE;
 
begin
 
Addr_Match <= Rd_Enable when Comp_Addr = User_Addr else '0';
Strobe_re <= Strobe_sr(2) and not Strobe_sr(3);
Addr_Match <= Rd_Enable when Comp_Addr = User_Addr else '0';
Strobe_re <= Strobe_sr(2) and not Strobe_sr(3);
 
io_reg: process( Clock, Reset )
begin
if( Reset = Reset_Level )then
Rd_En <= '0';
Rd_Data <= OPEN8_NULLBUS;
Strobe_sr <= (others => '0');
Interrupt <= '0';
LData_q1 <= x"00";
LData_q2 <= x"00";
LData_q3 <= x"00";
Rd_En <= '0';
Rd_Data <= OPEN8_NULLBUS;
Strobe_sr <= (others => '0');
Interrupt <= '0';
LData_q1 <= x"00";
LData_q2 <= x"00";
LData_q3 <= x"00";
elsif( rising_edge( Clock ) )then
Strobe_sr <= Strobe_sr(2 downto 0) & L_Strobe;
Strobe_sr <= Strobe_sr(2 downto 0) & L_Strobe;
 
LData_q1 <= L_Data;
LData_q2 <= LData_q1;
Interrupt <= Strobe_re;
LData_q1 <= L_Data;
LData_q2 <= LData_q1;
Interrupt <= Strobe_re;
if( Strobe_re = '1' )then
LData_q3 <= LData_q2;
LData_q3 <= LData_q2;
end if;
 
Rd_Data <= OPEN8_NULLBUS;
Rd_En <= Addr_Match;
Rd_Data <= OPEN8_NULLBUS;
Rd_En <= Addr_Match;
if( Rd_En = '1' )then
Rd_Data <= LData_q3;
Rd_Data <= LData_q3;
end if;
end if;
end process;
/o8_epoch_timer.vhd
65,20 → 65,20
 
entity o8_epoch_timer is
generic(
Reset_Level : std_logic;
Address : ADDRESS_TYPE
Reset_Level : std_logic;
Address : ADDRESS_TYPE
);
port(
Clock : in std_logic;
Reset : in std_logic;
uSec_Tick : in std_logic;
Clock : in std_logic;
Reset : in std_logic;
uSec_Tick : in std_logic;
--
Bus_Address : in ADDRESS_TYPE;
Wr_Enable : in std_logic;
Wr_Data : in DATA_TYPE;
Rd_Enable : in std_logic;
Rd_Data : out DATA_TYPE;
Interrupt : out std_logic
Bus_Address : in ADDRESS_TYPE;
Wr_Enable : in std_logic;
Wr_Data : in DATA_TYPE;
Rd_Enable : in std_logic;
Rd_Data : out DATA_TYPE;
Interrupt : out std_logic
);
end entity;
 
/o8_hd44780_4b.vhd
83,92 → 83,92
 
entity o8_hd44780_4b is
generic(
Use_Contrast : boolean;
Default_Contrast : std_logic_vector(7 downto 0);
Use_Backlight : boolean;
Default_Brightness : std_logic_vector(7 downto 0);
Address : ADDRESS_TYPE;
Reset_Level : std_logic;
Sys_Freq : real
Use_Contrast : boolean;
Default_Contrast : std_logic_vector(7 downto 0);
Use_Backlight : boolean;
Default_Brightness : std_logic_vector(7 downto 0);
Address : ADDRESS_TYPE;
Reset_Level : std_logic;
Sys_Freq : real
);
port(
Clock : in std_logic;
Reset : in std_logic;
Clock : in std_logic;
Reset : in std_logic;
--
uSec_Tick : in std_logic;
uSec_Tick : in std_logic;
--
Bus_Address : in ADDRESS_TYPE;
Wr_Enable : in std_logic;
Wr_Data : in DATA_TYPE;
Rd_Enable : in std_logic;
Rd_Data : out DATA_TYPE;
Interrupt : out std_logic;
Bus_Address : in ADDRESS_TYPE;
Wr_Enable : in std_logic;
Wr_Data : in DATA_TYPE;
Rd_Enable : in std_logic;
Rd_Data : out DATA_TYPE;
Interrupt : out std_logic;
--
LCD_E : out std_logic;
LCD_RW : out std_logic;
LCD_RS : out std_logic;
LCD_D : out std_logic_vector(7 downto 4);
LCD_CN : out std_logic;
LCD_BL : out std_logic
LCD_E : out std_logic;
LCD_RW : out std_logic;
LCD_RS : out std_logic;
LCD_D : out std_logic_vector(7 downto 4);
LCD_CN : out std_logic;
LCD_BL : out std_logic
);
end entity;
 
architecture behave of o8_hd44780_4b is
 
constant User_Addr : std_logic_vector(15 downto 2)
:= Address(15 downto 2);
alias Comp_Addr is Bus_Address(15 downto 2);
signal Addr_Match : std_logic := '0';
constant User_Addr : std_logic_vector(15 downto 2)
:= Address(15 downto 2);
alias Comp_Addr is Bus_Address(15 downto 2);
signal Addr_Match : std_logic := '0';
 
alias Reg_Addr is Bus_Address(1 downto 0);
signal Reg_Addr_q : std_logic_vector(1 downto 0) := (others => '0');
alias Reg_Addr is Bus_Address(1 downto 0);
signal Reg_Addr_q : std_logic_vector(1 downto 0) := (others => '0');
 
signal Wr_En : std_logic := '0';
signal Wr_Data_q : DATA_TYPE := x"00";
signal Rd_En : std_logic := '0';
signal Wr_En : std_logic := '0';
signal Wr_Data_q : DATA_TYPE := x"00";
signal Rd_En : std_logic := '0';
 
signal Reg_Valid : std_logic := '0';
signal Reg_Sel : std_logic := '0';
signal Reg_Data : std_logic_vector(7 downto 0) := x"00";
signal Reg_Valid : std_logic := '0';
signal Reg_Sel : std_logic := '0';
signal Reg_Data : std_logic_vector(7 downto 0) := x"00";
 
signal Tx_Ready : std_logic := '0';
signal Tx_Ready : std_logic := '0';
 
constant LCD_CONFIG1 : std_logic_vector(7 downto 4) := x"3"; -- Init to 4-bit mode
constant LCD_CONFIG2 : std_logic_vector(7 downto 0) := x"28"; -- Set 4-bit, 2-line mode
constant LCD_CONFIG3 : std_logic_vector(7 downto 0) := x"0C"; -- Turn display on, no cursor
constant LCD_CONFIG4 : std_logic_vector(7 downto 0) := x"01"; -- Clear display
constant LCD_CONFIG5 : std_logic_vector(7 downto 0) := x"06"; -- Positive increment, no shift
constant LCD_CONFIG6 : std_logic_vector(7 downto 0) := x"2A"; -- Print a "*"
constant LCD_CONFIG7 : std_logic_vector(7 downto 0) := x"02"; -- Reset the cursor
constant LCD_CONFIG1 : std_logic_vector(7 downto 4) := x"3"; -- Init to 4-bit mode
constant LCD_CONFIG2 : std_logic_vector(7 downto 0) := x"28"; -- Set 4-bit, 2-line mode
constant LCD_CONFIG3 : std_logic_vector(7 downto 0) := x"0C"; -- Turn display on, no cursor
constant LCD_CONFIG4 : std_logic_vector(7 downto 0) := x"01"; -- Clear display
constant LCD_CONFIG5 : std_logic_vector(7 downto 0) := x"06"; -- Positive increment, no shift
constant LCD_CONFIG6 : std_logic_vector(7 downto 0) := x"2A"; -- Print a "*"
constant LCD_CONFIG7 : std_logic_vector(7 downto 0) := x"02"; -- Reset the cursor
 
signal init_count : std_logic_vector(2 downto 0) := (others => '0');
signal init_count : std_logic_vector(2 downto 0) := (others => '0');
 
constant INIT_40MS : integer := 40000;
constant INIT_BITS : integer := ceil_log2(INIT_40MS);
constant INIT_DELAY : std_logic_vector(INIT_BITS-1 downto 0) :=
conv_std_logic_vector(INIT_40MS,INIT_BITS);
constant INIT_40MS : integer := 40000;
constant INIT_BITS : integer := ceil_log2(INIT_40MS);
constant INIT_DELAY : std_logic_vector(INIT_BITS-1 downto 0) :=
conv_std_logic_vector(INIT_40MS,INIT_BITS);
 
-- For "long" instructions, such as clear display and return home, we need to wait for more
-- than 1.52mS. Experimentally, 2mS seems to work ideally, and for init this isn't an issue
constant CLDSP_2MS : integer := 2000;
constant CLDSP_DELAY : std_logic_vector(INIT_BITS-1 downto 0) :=
conv_std_logic_vector(CLDSP_2MS,INIT_BITS);
constant CLDSP_2MS : integer := 2000;
constant CLDSP_DELAY : std_logic_vector(INIT_BITS-1 downto 0) :=
conv_std_logic_vector(CLDSP_2MS,INIT_BITS);
 
-- For some reason, we are required to wait 80uS before checking the busy flag, despite
-- most instructions completing in 37uS. No clue as to why, but it works
constant BUSY_50US : integer := 50;
constant BUSY_DELAY : std_logic_vector(INIT_BITS-1 downto 0) :=
conv_std_logic_vector(BUSY_50US-1, INIT_BITS);
constant BUSY_50US : integer := 50;
constant BUSY_DELAY : std_logic_vector(INIT_BITS-1 downto 0) :=
conv_std_logic_vector(BUSY_50US-1, INIT_BITS);
 
signal busy_timer : std_logic_vector(INIT_BITS-1 downto 0);
signal busy_timer : std_logic_vector(INIT_BITS-1 downto 0);
 
constant SNH_600NS : integer := integer(Sys_Freq * 0.000000600);
constant SNH_BITS : integer := ceil_log2(SNH_600NS);
constant SNH_DELAY : std_logic_vector(SNH_BITS-1 downto 0) :=
conv_std_logic_vector(SNH_600NS-1, SNH_BITS);
constant SNH_600NS : integer := integer(Sys_Freq * 0.000000600);
constant SNH_BITS : integer := ceil_log2(SNH_600NS);
constant SNH_DELAY : std_logic_vector(SNH_BITS-1 downto 0) :=
conv_std_logic_vector(SNH_600NS-1, SNH_BITS);
 
signal io_timer : std_logic_vector(SNH_BITS - 1 downto 0) :=
(others => '0');
signal io_timer : std_logic_vector(SNH_BITS - 1 downto 0) :=
(others => '0');
 
type IO_STATES is (INIT, PWR_WAIT, INIT_S1, INIT_H1,
INIT_WAIT, FN_JUMP, IDLE,
176,106 → 176,18
BUSY_PREP, BUSY_WAIT,
ISSUE_INT );
 
signal io_state : IO_STATES := INIT;
signal io_state : IO_STATES := INIT;
 
signal LCD_Data : std_logic_vector(7 downto 0) := x"00";
signal LCD_Addr : std_logic := '0';
signal LCD_Data : DATA_TYPE := x"00";
signal LCD_Addr : std_logic := '0';
 
--------------------------------------------------------------------------------
-- Backlight & Contrast signals
--------------------------------------------------------------------------------
 
-- Do not adjust alone! DELTA constants must be
-- changed as well.
constant DAC_Width : integer := 8;
signal LCD_Contrast : DATA_TYPE := x"00";
signal LCD_Bright : DATA_TYPE := x"00";
 
constant DELTA_1_I : integer := 1;
constant DELTA_2_I : integer := 5;
constant DELTA_3_I : integer := 25;
constant DELTA_4_I : integer := 75;
constant DELTA_5_I : integer := 125;
constant DELTA_6_I : integer := 195;
 
constant DELTA_1 : std_logic_vector(DAC_Width-1 downto 0) :=
conv_std_logic_vector(DELTA_1_I, DAC_Width);
constant DELTA_2 : std_logic_vector(DAC_Width-1 downto 0) :=
conv_std_logic_vector(DELTA_2_I, DAC_Width);
constant DELTA_3 : std_logic_vector(DAC_Width-1 downto 0) :=
conv_std_logic_vector(DELTA_3_I, DAC_Width);
constant DELTA_4 : std_logic_vector(DAC_Width-1 downto 0) :=
conv_std_logic_vector(DELTA_4_I, DAC_Width);
constant DELTA_5 : std_logic_vector(DAC_Width-1 downto 0) :=
conv_std_logic_vector(DELTA_5_I, DAC_Width);
constant DELTA_6 : std_logic_vector(DAC_Width-1 downto 0) :=
conv_std_logic_vector(DELTA_6_I, DAC_Width);
 
constant MAX_PERIOD : integer := 2**DAC_Width;
constant DIV_WIDTH : integer := DAC_Width * 2;
 
constant PADJ_1_I : integer := DELTA_1_I * MAX_PERIOD;
constant PADJ_2_I : integer := DELTA_2_I * MAX_PERIOD;
constant PADJ_3_I : integer := DELTA_3_I * MAX_PERIOD;
constant PADJ_4_I : integer := DELTA_4_I * MAX_PERIOD;
constant PADJ_5_I : integer := DELTA_5_I * MAX_PERIOD;
constant PADJ_6_I : integer := DELTA_6_I * MAX_PERIOD;
 
constant PADJ_1 : std_logic_vector(DIV_WIDTH-1 downto 0) :=
conv_std_logic_vector(PADJ_1_I,DIV_WIDTH);
constant PADJ_2 : std_logic_vector(DIV_WIDTH-1 downto 0) :=
conv_std_logic_vector(PADJ_2_I,DIV_WIDTH);
constant PADJ_3 : std_logic_vector(DIV_WIDTH-1 downto 0) :=
conv_std_logic_vector(PADJ_3_I,DIV_WIDTH);
constant PADJ_4 : std_logic_vector(DIV_WIDTH-1 downto 0) :=
conv_std_logic_vector(PADJ_4_I,DIV_WIDTH);
constant PADJ_5 : std_logic_vector(DIV_WIDTH-1 downto 0) :=
conv_std_logic_vector(PADJ_5_I,DIV_WIDTH);
constant PADJ_6 : std_logic_vector(DIV_WIDTH-1 downto 0) :=
conv_std_logic_vector(PADJ_6_I,DIV_WIDTH);
 
constant CB : integer := ceil_log2(DIV_WIDTH);
 
signal LCD_Contrast : std_logic_vector(7 downto 0) := x"00";
 
signal CN_DACin_q : std_logic_vector(DAC_WIDTH-1 downto 0) := (others => '0');
 
signal CN_Divisor : std_logic_vector(DIV_WIDTH-1 downto 0) := (others => '0');
signal CN_Dividend : std_logic_vector(DIV_WIDTH-1 downto 0) := (others => '0');
 
signal CN_q : std_logic_vector(DIV_WIDTH*2-1 downto 0) := (others => '0');
signal CN_diff : std_logic_vector(DIV_WIDTH downto 0) := (others => '0');
 
signal CN_count : std_logic_vector(CB-1 downto 0) := (others => '0');
 
signal CN_Next_Wdt : std_logic_vector(DAC_Width-1 downto 0) := (others => '0');
signal CN_Next_Per : std_logic_vector(DAC_Width-1 downto 0) := (others => '0');
 
signal CN_PWM_Wdt : std_logic_vector(DAC_Width-1 downto 0) := (others => '0');
signal CN_PWM_Per : std_logic_vector(DAC_Width-1 downto 0) := (others => '0');
 
signal CN_Wdt_Ctr : std_logic_vector(DAC_Width-1 downto 0) := (others => '0');
signal CN_Per_Ctr : std_logic_vector(DAC_Width-1 downto 0) := (others => '0');
 
signal LCD_Bright : std_logic_vector(7 downto 0) := (others => '0');
 
signal BL_DACin_q : std_logic_vector(DAC_WIDTH-1 downto 0) := (others => '0');
 
signal BL_Divisor : std_logic_vector(DIV_WIDTH-1 downto 0) := (others => '0');
signal BL_Dividend : std_logic_vector(DIV_WIDTH-1 downto 0) := (others => '0');
 
signal BL_q : std_logic_vector(DIV_WIDTH*2-1 downto 0) := (others => '0');
signal BL_diff : std_logic_vector(DIV_WIDTH downto 0) := (others => '0');
 
signal BL_count : std_logic_vector(CB-1 downto 0) := (others => '0');
 
signal BL_Next_Wdt : std_logic_vector(DAC_Width-1 downto 0) := (others => '0');
signal BL_Next_Per : std_logic_vector(DAC_Width-1 downto 0) := (others => '0');
 
signal BL_PWM_Wdt : std_logic_vector(DAC_Width-1 downto 0) := (others => '0');
signal BL_PWM_Per : std_logic_vector(DAC_Width-1 downto 0) := (others => '0');
 
signal BL_Wdt_Ctr : std_logic_vector(DAC_Width-1 downto 0) := (others => '0');
signal BL_Per_Ctr : std_logic_vector(DAC_Width-1 downto 0) := (others => '0');
 
begin
 
--------------------------------------------------------------------------------
282,55 → 194,55
-- Open8 Register interface
--------------------------------------------------------------------------------
 
Addr_Match <= '1' when Comp_Addr = User_Addr else '0';
Addr_Match <= '1' when Comp_Addr = User_Addr else '0';
 
io_reg: process( Clock, Reset )
begin
if( Reset = Reset_Level )then
Reg_Addr_q <= (others => '0');
Wr_Data_q <= (others => '0');
Wr_En <= '0';
Rd_En <= '0';
Rd_Data <= OPEN8_NULLBUS;
Reg_Addr_q <= (others => '0');
Wr_Data_q <= (others => '0');
Wr_En <= '0';
Rd_En <= '0';
Rd_Data <= OPEN8_NULLBUS;
 
Reg_Valid <= '0';
Reg_Sel <= '0';
Reg_Data <= x"00";
Reg_Valid <= '0';
Reg_Sel <= '0';
Reg_Data <= x"00";
 
LCD_Contrast <= Default_Contrast;
LCD_Bright <= Default_Brightness;
LCD_Contrast <= Default_Contrast;
LCD_Bright <= Default_Brightness;
elsif( rising_edge( Clock ) )then
Reg_Addr_q <= Reg_Addr;
Reg_Addr_q <= Reg_Addr;
 
Wr_Data_q <= Wr_Data;
Wr_En <= Addr_Match and Wr_Enable;
Wr_Data_q <= Wr_Data;
Wr_En <= Addr_Match and Wr_Enable;
 
Reg_Valid <= '0';
Reg_Valid <= '0';
 
if( Wr_En = '1' )then
case( Reg_Addr_q )is
when "00" | "01" =>
Reg_Valid <= '1';
Reg_Sel <= Reg_Addr_q(0);
Reg_Data <= Wr_Data_q;
Reg_Valid <= '1';
Reg_Sel <= Reg_Addr_q(0);
Reg_Data <= Wr_Data_q;
when "10" =>
LCD_Contrast<= Wr_Data_q;
LCD_Contrast <= Wr_Data_q;
when "11" =>
LCD_Bright <= Wr_Data_q;
LCD_Bright <= Wr_Data_q;
when others => null;
end case;
end if;
 
Rd_Data <= OPEN8_NULLBUS;
Rd_En <= Addr_Match and Rd_Enable;
Rd_Data <= OPEN8_NULLBUS;
Rd_En <= Addr_Match and Rd_Enable;
if( Rd_En = '1' )then
case( Reg_Addr_q )is
when "00" | "01" =>
Rd_Data(7) <= Tx_Ready;
Rd_Data(7) <= Tx_Ready;
when "10" =>
Rd_Data <= LCD_Contrast;
Rd_Data <= LCD_Contrast;
when "11" =>
Rd_Data <= LCD_Bright;
Rd_Data <= LCD_Bright;
when others => null;
end case;
end if;
341,42 → 253,42
-- LCD and Register logic
--------------------------------------------------------------------------------
 
LCD_RW <= '0'; -- Permanently wire the RW line low
LCD_RW <= '0'; -- Permanently wire the RW line low
 
LCD_IO: process( Clock, Reset )
begin
if( Reset = Reset_Level )then
io_state <= INIT;
init_count <= (others => '0');
io_timer <= (others => '0');
busy_timer <= (others => '0');
LCD_Data <= (others => '0');
LCD_Addr <= '0';
LCD_E <= '0';
LCD_RS <= '0';
LCD_D <= (others => '0');
Tx_Ready <= '0';
Interrupt <= '0';
io_state <= INIT;
init_count <= (others => '0');
io_timer <= (others => '0');
busy_timer <= (others => '0');
LCD_Data <= (others => '0');
LCD_Addr <= '0';
LCD_E <= '0';
LCD_RS <= '0';
LCD_D <= (others => '0');
Tx_Ready <= '0';
Interrupt <= '0';
elsif( rising_edge(Clock) )then
LCD_E <= '0';
LCD_RS <= '0';
LCD_D <= (others => '0');
Tx_Ready <= '0';
Interrupt <= '0';
io_timer <= io_timer - 1;
busy_timer <= busy_timer - uSec_Tick;
LCD_E <= '0';
LCD_RS <= '0';
LCD_D <= (others => '0');
Tx_Ready <= '0';
Interrupt <= '0';
io_timer <= io_timer - 1;
busy_timer <= busy_timer - uSec_Tick;
case( io_state )is
 
when INIT =>
busy_timer <= INIT_DELAY;
init_count <= (others => '1');
io_state <= PWR_WAIT;
busy_timer <= INIT_DELAY;
init_count <= (others => '1');
io_state <= PWR_WAIT;
 
-- We wait for at least 40mS before continuing initalization.
when PWR_WAIT =>
if( busy_timer = 0 )then
io_timer <= SNH_DELAY;
io_state <= INIT_S1;
io_timer <= SNH_DELAY;
io_state <= INIT_S1;
end if;
 
-- We write out the first init byte as if we were using an 8-bit
383,113 → 295,113
-- data bus, with a single cycle. This is an exception, and the
-- rest of the commands are sent using 2-cycle transfers.
when INIT_S1 =>
LCD_D <= LCD_CONFIG1;
LCD_E <= '1';
LCD_D <= LCD_CONFIG1;
LCD_E <= '1';
if( io_timer = 0 )then
io_timer <= SNH_DELAY;
io_state <= INIT_H1;
io_timer <= SNH_DELAY;
io_state <= INIT_H1;
end if;
 
when INIT_H1 =>
LCD_D <= LCD_CONFIG1;
LCD_D <= LCD_CONFIG1;
if( io_timer = 0 )then
busy_timer <= BUSY_DELAY;
io_state <= INIT_WAIT;
busy_timer <= BUSY_DELAY;
io_state <= INIT_WAIT;
end if;
 
when INIT_WAIT =>
if( busy_timer = 0 )then
io_state <= FN_JUMP;
io_state <= FN_JUMP;
end if;
 
when FN_JUMP =>
io_state <= WR_PREP;
io_state <= WR_PREP;
case( init_count )is
when "000" =>
io_state <= IDLE;
io_state <= IDLE;
when "001" =>
LCD_Addr <= '0';
LCD_Data <= LCD_CONFIG7; -- Reset the Cursor
LCD_Addr <= '0';
LCD_Data <= LCD_CONFIG7; -- Reset the Cursor
when "010" =>
LCD_Addr <= '1'; -- Print a "*", and
LCD_Data <= LCD_CONFIG6; -- set RS to 1
LCD_Addr <= '1'; -- Print a "*", and
LCD_Data <= LCD_CONFIG6; -- set RS to 1
when "011" =>
LCD_Data <= LCD_CONFIG5; -- Entry mode
LCD_Data <= LCD_CONFIG5; -- Entry mode
when "100" =>
LCD_Data <= LCD_CONFIG4; -- Clear Display
LCD_Data <= LCD_CONFIG4; -- Clear Display
when "101" =>
LCD_Data <= LCD_CONFIG3; -- Display control
LCD_Data <= LCD_CONFIG3; -- Display control
when "110" | "111" =>
LCD_Addr <= '0';
LCD_Data <= LCD_CONFIG2; -- Function set
LCD_Addr <= '0';
LCD_Data <= LCD_CONFIG2; -- Function set
when others => null;
end case;
 
when IDLE =>
Tx_Ready <= '1';
Tx_Ready <= '1';
if( Reg_Valid = '1' )then
LCD_Addr <= Reg_Sel;
LCD_Data <= Reg_Data;
io_state <= WR_PREP;
LCD_Addr <= Reg_Sel;
LCD_Data <= Reg_Data;
io_state <= WR_PREP;
end if;
 
when WR_PREP =>
io_timer <= SNH_DELAY;
io_state <= WR_SETUP_UB;
io_timer <= SNH_DELAY;
io_state <= WR_SETUP_UB;
 
when WR_SETUP_UB =>
LCD_RS <= LCD_Addr;
LCD_D <= LCD_Data(7 downto 4);
LCD_E <= '1';
LCD_RS <= LCD_Addr;
LCD_D <= LCD_Data(7 downto 4);
LCD_E <= '1';
if( io_timer = 0 )then
io_timer <= SNH_DELAY;
io_state <= WR_HOLD_UB;
io_timer <= SNH_DELAY;
io_state <= WR_HOLD_UB;
end if;
 
when WR_HOLD_UB =>
LCD_RS <= LCD_Addr;
LCD_D <= LCD_Data(7 downto 4);
LCD_RS <= LCD_Addr;
LCD_D <= LCD_Data(7 downto 4);
if( io_timer = 0 )then
LCD_E <= '0';
io_timer <= SNH_DELAY;
io_state <= WR_SETUP_LB;
LCD_E <= '0';
io_timer <= SNH_DELAY;
io_state <= WR_SETUP_LB;
end if;
 
when WR_SETUP_LB =>
LCD_RS <= LCD_Addr;
LCD_D <= LCD_Data(3 downto 0);
LCD_E <= '1';
LCD_RS <= LCD_Addr;
LCD_D <= LCD_Data(3 downto 0);
LCD_E <= '1';
if( io_timer = 0 )then
io_timer <= SNH_DELAY;
io_state <= WR_HOLD_LB;
io_timer <= SNH_DELAY;
io_state <= WR_HOLD_LB;
end if;
 
when WR_HOLD_LB =>
LCD_RS <= LCD_Addr;
LCD_D <= LCD_Data(3 downto 0);
LCD_RS <= LCD_Addr;
LCD_D <= LCD_Data(3 downto 0);
if( io_timer = 0 )then
io_state <= BUSY_WAIT;
io_state <= BUSY_WAIT;
end if;
 
when BUSY_PREP =>
busy_timer <= BUSY_DELAY;
busy_timer <= BUSY_DELAY;
if( LCD_Addr = '0' and LCD_Data < 4 )then
busy_timer <= CLDSP_DELAY;
busy_timer <= CLDSP_DELAY;
end if;
io_state <= BUSY_WAIT;
io_state <= BUSY_WAIT;
 
when BUSY_WAIT =>
if( busy_timer = 0 )then
io_state <= ISSUE_INT;
io_state <= ISSUE_INT;
if( init_count > 0 )then
init_count<= init_count - 1;
io_state <= FN_JUMP;
init_count <= init_count - 1;
io_state <= FN_JUMP;
end if;
end if;
 
when ISSUE_INT =>
Interrupt <= '1';
io_state <= IDLE;
Interrupt <= '1';
io_state <= IDLE;
 
when others => null;
 
508,72 → 420,17
 
Contrast_Enabled: if( Use_Contrast )generate
 
CN_diff <= ('0' & CN_q(DIV_WIDTH*2-2 downto DIV_WIDTH-1)) -
('0' & CN_Divisor);
U_CN : entity work.vdsm8
generic map(
Reset_Level => Reset_Level
)
port map(
Clock => Clock,
Reset => Reset,
DACin => LCD_Contrast,
DACout => LCD_CN
);
 
CN_Dividend<= PADJ_2 when CN_DACin_q >= DELTA_2_I and CN_DACin_q < DELTA_3_I else
PADJ_3 when CN_DACin_q >= DELTA_3_I and CN_DACin_q < DELTA_4_I else
PADJ_4 when CN_DACin_q >= DELTA_4_I and CN_DACin_q < DELTA_5_I else
PADJ_5 when CN_DACin_q >= DELTA_5_I and CN_DACin_q < DELTA_6_I else
PADJ_6 when CN_DACin_q >= DELTA_6_I else
PADJ_1;
 
CN_Next_Wdt<= DELTA_1 when CN_DACin_q >= DELTA_1_I and CN_DACin_q < DELTA_2_I else
DELTA_2 when CN_DACin_q >= DELTA_2_I and CN_DACin_q < DELTA_3_I else
DELTA_3 when CN_DACin_q >= DELTA_3_I and CN_DACin_q < DELTA_4_I else
DELTA_4 when CN_DACin_q >= DELTA_4_I and CN_DACin_q < DELTA_5_I else
DELTA_5 when CN_DACin_q >= DELTA_5_I and CN_DACin_q < DELTA_6_I else
DELTA_6 when CN_DACin_q >= DELTA_6_I else
(others => '0');
 
CN_Next_Per <= BL_q(7 downto 0) - 1;
 
CN_vDSM_proc: process( Clock, Reset )
begin
if( Reset = Reset_Level )then
CN_q <= (others => '0');
CN_count <= (others => '1');
CN_Divisor <= (others => '0');
CN_DACin_q <= (others => '0');
CN_PWM_Wdt <= (others => '0');
CN_PWM_Per <= (others => '0');
CN_Per_Ctr <= (others => '0');
CN_Wdt_Ctr <= (others => '0');
LCD_CN <= '0';
elsif( rising_edge(Clock) )then
CN_q <= CN_diff(DIV_WIDTH-1 downto 0) &
CN_q(DIV_WIDTH-2 downto 0) & '1';
if( CN_diff(DIV_WIDTH) = '1' )then
CN_q <= CN_q(DIV_WIDTH*2-2 downto 0) & '0';
end if;
 
CN_count <= CN_count + 1;
if( CN_count = DIV_WIDTH )then
CN_PWM_Wdt <= CN_Next_Wdt;
CN_PWM_Per <= CN_Next_Per;
CN_DACin_q <= LCD_Contrast;
CN_Divisor <= (others => '0');
CN_Divisor(DAC_Width-1 downto 0) <= CN_DACin_q;
CN_q <= conv_std_logic_vector(0,DIV_WIDTH) & CN_Dividend;
CN_count <= (others => '0');
end if;
 
CN_Per_Ctr <= CN_Per_Ctr - 1;
CN_Wdt_Ctr <= CN_Wdt_Ctr - 1;
 
LCD_CN <= '1';
if( CN_Wdt_Ctr = 0 )then
LCD_CN <= '0';
CN_Wdt_Ctr <= (others => '0');
end if;
 
if( CN_Per_Ctr = 0 )then
CN_Per_Ctr <= CN_PWM_Per;
CN_Wdt_Ctr <= CN_PWM_Wdt;
end if;
 
end if;
end process;
end generate;
 
--------------------------------------------------------------------------------
586,73 → 443,17
 
Backlight_Enabled: if( Use_Backlight )generate
 
BL_diff <= ('0' & BL_q(DIV_WIDTH*2-2 downto DIV_WIDTH-1)) -
('0' & BL_Divisor);
U_BL : entity work.vdsm8
generic map(
Reset_Level => Reset_Level
)
port map(
Clock => Clock,
Reset => Reset,
DACin => LCD_Bright,
DACout => LCD_BL
);
 
BL_Dividend<= PADJ_2 when BL_DACin_q >= DELTA_2_I and BL_DACin_q < DELTA_3_I else
PADJ_3 when BL_DACin_q >= DELTA_3_I and BL_DACin_q < DELTA_4_I else
PADJ_4 when BL_DACin_q >= DELTA_4_I and BL_DACin_q < DELTA_5_I else
PADJ_5 when BL_DACin_q >= DELTA_5_I and BL_DACin_q < DELTA_6_I else
PADJ_6 when BL_DACin_q >= DELTA_6_I else
PADJ_1;
 
BL_Next_Wdt<= DELTA_1 when BL_DACin_q >= DELTA_1_I and BL_DACin_q < DELTA_2_I else
DELTA_2 when BL_DACin_q >= DELTA_2_I and BL_DACin_q < DELTA_3_I else
DELTA_3 when BL_DACin_q >= DELTA_3_I and BL_DACin_q < DELTA_4_I else
DELTA_4 when BL_DACin_q >= DELTA_4_I and BL_DACin_q < DELTA_5_I else
DELTA_5 when BL_DACin_q >= DELTA_5_I and BL_DACin_q < DELTA_6_I else
DELTA_6 when BL_DACin_q >= DELTA_6_I else
(others => '0');
 
BL_Next_Per <= BL_q(7 downto 0) - 1;
 
BL_vDSM_proc: process( Clock, Reset )
begin
if( Reset = Reset_Level )then
BL_q <= (others => '0');
BL_count <= (others => '1');
BL_Divisor <= (others => '0');
BL_DACin_q <= (others => '0');
BL_PWM_Wdt <= (others => '0');
BL_PWM_Per <= (others => '0');
BL_Per_Ctr <= (others => '0');
BL_Wdt_Ctr <= (others => '0');
LCD_BL <= '0';
elsif( rising_edge(Clock) )then
BL_q <= BL_diff(DIV_WIDTH-1 downto 0) &
BL_q(DIV_WIDTH-2 downto 0) & '1';
if( BL_diff(DIV_WIDTH) = '1' )then
BL_q <= BL_q(DIV_WIDTH*2-2 downto 0) & '0';
end if;
 
BL_count <= BL_count + 1;
if( BL_count = DIV_WIDTH )then
BL_PWM_Wdt <= BL_Next_Wdt;
BL_PWM_Per <= BL_Next_Per;
BL_DACin_q <= LCD_Bright;
BL_Divisor <= (others => '0');
BL_Divisor(DAC_Width-1 downto 0) <= BL_DACin_q;
BL_q <= conv_std_logic_vector(0,DIV_WIDTH) & BL_Dividend;
BL_count <= (others => '0');
end if;
 
BL_Per_Ctr <= BL_Per_Ctr - 1;
BL_Wdt_Ctr <= BL_Wdt_Ctr - 1;
 
LCD_BL <= '1';
if( BL_Wdt_Ctr = 0 )then
LCD_BL <= '0';
BL_Wdt_Ctr <= (others => '0');
end if;
 
if( BL_Per_Ctr = 0 )then
BL_Per_Ctr <= BL_PWM_Per;
BL_Wdt_Ctr <= BL_PWM_Wdt;
end if;
 
end if;
end process;
 
end generate;
 
end architecture;
/o8_hd44780_8b.vhd
114,163 → 114,75
 
architecture behave of o8_hd44780_8b is
 
constant User_Addr : std_logic_vector(15 downto 2)
:= Address(15 downto 2);
alias Comp_Addr is Bus_Address(15 downto 2);
signal Addr_Match : std_logic := '0';
constant User_Addr : std_logic_vector(15 downto 2)
:= Address(15 downto 2);
alias Comp_Addr is Bus_Address(15 downto 2);
signal Addr_Match : std_logic := '0';
 
alias Reg_Addr is Bus_Address(1 downto 0);
signal Reg_Addr_q : std_logic_vector(1 downto 0) := (others => '0');
alias Reg_Addr is Bus_Address(1 downto 0);
signal Reg_Addr_q : std_logic_vector(1 downto 0) := (others => '0');
 
signal Wr_En : std_logic := '0';
signal Wr_Data_q : DATA_TYPE := x"00";
signal Rd_En : std_logic := '0';
signal Wr_En : std_logic := '0';
signal Wr_Data_q : DATA_TYPE := x"00";
signal Rd_En : std_logic := '0';
 
signal Reg_Valid : std_logic := '0';
signal Reg_Sel : std_logic := '0';
signal Reg_Data : DATA_TYPE := x"00";
signal Reg_Valid : std_logic := '0';
signal Reg_Sel : std_logic := '0';
signal Reg_Data : DATA_TYPE := x"00";
 
signal Tx_Ready : std_logic := '0';
signal Tx_Ready : std_logic := '0';
 
constant LCD_CONFIG1 : std_logic_vector(7 downto 0) := x"38"; -- Set 4-bit, 2-line mode
constant LCD_CONFIG2 : std_logic_vector(7 downto 0) := x"0C"; -- Turn display on, no cursor
constant LCD_CONFIG3 : std_logic_vector(7 downto 0) := x"01"; -- Clear display
constant LCD_CONFIG4 : std_logic_vector(7 downto 0) := x"06"; -- Positive increment, no shift
constant LCD_CONFIG5 : std_logic_vector(7 downto 0) := x"2A"; -- Print a "*"
constant LCD_CONFIG6 : std_logic_vector(7 downto 0) := x"02"; -- Reset the cursor
constant LCD_CONFIG1 : std_logic_vector(7 downto 0) := x"38"; -- Set 4-bit, 2-line mode
constant LCD_CONFIG2 : std_logic_vector(7 downto 0) := x"0C"; -- Turn display on, no cursor
constant LCD_CONFIG3 : std_logic_vector(7 downto 0) := x"01"; -- Clear display
constant LCD_CONFIG4 : std_logic_vector(7 downto 0) := x"06"; -- Positive increment, no shift
constant LCD_CONFIG5 : std_logic_vector(7 downto 0) := x"2A"; -- Print a "*"
constant LCD_CONFIG6 : std_logic_vector(7 downto 0) := x"02"; -- Reset the cursor
 
signal init_count : std_logic_vector(2 downto 0) := (others => '0');
signal init_count : std_logic_vector(2 downto 0) := (others => '0');
 
constant INIT_40MS : integer := 40000;
constant INIT_BITS : integer := ceil_log2(INIT_40MS);
constant INIT_DELAY : std_logic_vector(INIT_BITS-1 downto 0) :=
conv_std_logic_vector(INIT_40MS,INIT_BITS);
constant INIT_40MS : integer := 40000;
constant INIT_BITS : integer := ceil_log2(INIT_40MS);
constant INIT_DELAY : std_logic_vector(INIT_BITS-1 downto 0) :=
conv_std_logic_vector(INIT_40MS,INIT_BITS);
 
-- For "long" instructions, such as clear display and return home, we need to wait for more
-- than 1.52mS. Experimentally, 2mS seems to work ideally, and for init this isn't an issue
constant CLDSP_2MS : integer := 2000;
constant CLDSP_DELAY : std_logic_vector(INIT_BITS-1 downto 0) :=
conv_std_logic_vector(CLDSP_2MS,INIT_BITS);
constant CLDSP_2MS : integer := 2000;
constant CLDSP_DELAY : std_logic_vector(INIT_BITS-1 downto 0) :=
conv_std_logic_vector(CLDSP_2MS,INIT_BITS);
 
-- For some reason, we are required to wait 80uS before checking the busy flag, despite
-- most instructions completing in 37uS. No clue as to why, but it works
constant BUSY_50US : integer := 50;
constant BUSY_DELAY : std_logic_vector(INIT_BITS-1 downto 0) :=
conv_std_logic_vector(BUSY_50US-1, INIT_BITS);
constant BUSY_50US : integer := 50;
constant BUSY_DELAY : std_logic_vector(INIT_BITS-1 downto 0) :=
conv_std_logic_vector(BUSY_50US-1, INIT_BITS);
 
signal busy_timer : std_logic_vector(INIT_BITS-1 downto 0) := (others => '0');
signal busy_timer : std_logic_vector(INIT_BITS-1 downto 0) := (others => '0');
 
constant SNH_600NS : integer := integer(Sys_Freq * 0.000000600);
constant SNH_BITS : integer := ceil_log2(SNH_600NS);
constant SNH_DELAY : std_logic_vector(SNH_BITS-1 downto 0) :=
conv_std_logic_vector(SNH_600NS-1, SNH_BITS);
constant SNH_600NS : integer := integer(Sys_Freq * 0.000000600);
constant SNH_BITS : integer := ceil_log2(SNH_600NS);
constant SNH_DELAY : std_logic_vector(SNH_BITS-1 downto 0) :=
conv_std_logic_vector(SNH_600NS-1, SNH_BITS);
 
signal io_timer : std_logic_vector(SNH_BITS - 1 downto 0) := (others => '0');
signal io_timer : std_logic_vector(SNH_BITS - 1 downto 0) := (others => '0');
 
type IO_STATES is (INIT, FN_JUMP, IDLE,
WR_PREP, WR_SETUP, WR_HOLD,
BUSY_PREP, BUSY_WAIT,
ISSUE_INT );
signal io_state : IO_STATES;
signal io_state : IO_STATES;
 
signal LCD_Data : std_logic_vector(7 downto 0) := x"00";
signal LCD_Addr : std_logic := '0';
signal LCD_Data : DATA_TYPE := x"00";
signal LCD_Addr : std_logic := '0';
 
--------------------------------------------------------------------------------
-- Backlight & Contrast signals
--------------------------------------------------------------------------------
 
-- Do not adjust alone! DELTA constants must be
-- changed as well.
constant DAC_Width : integer := 8;
signal LCD_Contrast : DATA_TYPE := x"00";
signal LCD_Bright : DATA_TYPE := x"00";
 
constant DELTA_1_I : integer := 1;
constant DELTA_2_I : integer := 5;
constant DELTA_3_I : integer := 25;
constant DELTA_4_I : integer := 75;
constant DELTA_5_I : integer := 125;
constant DELTA_6_I : integer := 195;
 
constant DELTA_1 : std_logic_vector(DAC_Width-1 downto 0) :=
conv_std_logic_vector(DELTA_1_I, DAC_Width);
constant DELTA_2 : std_logic_vector(DAC_Width-1 downto 0) :=
conv_std_logic_vector(DELTA_2_I, DAC_Width);
constant DELTA_3 : std_logic_vector(DAC_Width-1 downto 0) :=
conv_std_logic_vector(DELTA_3_I, DAC_Width);
constant DELTA_4 : std_logic_vector(DAC_Width-1 downto 0) :=
conv_std_logic_vector(DELTA_4_I, DAC_Width);
constant DELTA_5 : std_logic_vector(DAC_Width-1 downto 0) :=
conv_std_logic_vector(DELTA_5_I, DAC_Width);
constant DELTA_6 : std_logic_vector(DAC_Width-1 downto 0) :=
conv_std_logic_vector(DELTA_6_I, DAC_Width);
 
constant MAX_PERIOD : integer := 2**DAC_Width;
constant DIV_WIDTH : integer := DAC_Width * 2;
 
constant PADJ_1_I : integer := DELTA_1_I * MAX_PERIOD;
constant PADJ_2_I : integer := DELTA_2_I * MAX_PERIOD;
constant PADJ_3_I : integer := DELTA_3_I * MAX_PERIOD;
constant PADJ_4_I : integer := DELTA_4_I * MAX_PERIOD;
constant PADJ_5_I : integer := DELTA_5_I * MAX_PERIOD;
constant PADJ_6_I : integer := DELTA_6_I * MAX_PERIOD;
 
constant PADJ_1 : std_logic_vector(DIV_WIDTH-1 downto 0) :=
conv_std_logic_vector(PADJ_1_I,DIV_WIDTH);
constant PADJ_2 : std_logic_vector(DIV_WIDTH-1 downto 0) :=
conv_std_logic_vector(PADJ_2_I,DIV_WIDTH);
constant PADJ_3 : std_logic_vector(DIV_WIDTH-1 downto 0) :=
conv_std_logic_vector(PADJ_3_I,DIV_WIDTH);
constant PADJ_4 : std_logic_vector(DIV_WIDTH-1 downto 0) :=
conv_std_logic_vector(PADJ_4_I,DIV_WIDTH);
constant PADJ_5 : std_logic_vector(DIV_WIDTH-1 downto 0) :=
conv_std_logic_vector(PADJ_5_I,DIV_WIDTH);
constant PADJ_6 : std_logic_vector(DIV_WIDTH-1 downto 0) :=
conv_std_logic_vector(PADJ_6_I,DIV_WIDTH);
 
constant CB : integer := ceil_log2(DIV_WIDTH);
 
signal LCD_Contrast : std_logic_vector(7 downto 0) := x"00";
 
signal CN_DACin_q : std_logic_vector(DAC_WIDTH-1 downto 0) := (others => '0');
 
signal CN_Divisor : std_logic_vector(DIV_WIDTH-1 downto 0) := (others => '0');
signal CN_Dividend : std_logic_vector(DIV_WIDTH-1 downto 0) := (others => '0');
 
signal CN_q : std_logic_vector(DIV_WIDTH*2-1 downto 0) := (others => '0');
signal CN_diff : std_logic_vector(DIV_WIDTH downto 0) := (others => '0');
 
signal CN_count : std_logic_vector(CB-1 downto 0) := (others => '0');
 
signal CN_Next_Wdt : std_logic_vector(DAC_Width-1 downto 0) := (others => '0');
signal CN_Next_Per : std_logic_vector(DAC_Width-1 downto 0) := (others => '0');
 
signal CN_PWM_Wdt : std_logic_vector(DAC_Width-1 downto 0) := (others => '0');
signal CN_PWM_Per : std_logic_vector(DAC_Width-1 downto 0) := (others => '0');
 
signal CN_Wdt_Ctr : std_logic_vector(DAC_Width-1 downto 0) := (others => '0');
signal CN_Per_Ctr : std_logic_vector(DAC_Width-1 downto 0) := (others => '0');
 
signal LCD_Bright : std_logic_vector(7 downto 0) := (others => '0');
 
signal BL_DACin_q : std_logic_vector(DAC_WIDTH-1 downto 0) := (others => '0');
 
signal BL_Divisor : std_logic_vector(DIV_WIDTH-1 downto 0) := (others => '0');
signal BL_Dividend : std_logic_vector(DIV_WIDTH-1 downto 0) := (others => '0');
 
signal BL_q : std_logic_vector(DIV_WIDTH*2-1 downto 0) := (others => '0');
signal BL_diff : std_logic_vector(DIV_WIDTH downto 0) := (others => '0');
 
signal BL_count : std_logic_vector(CB-1 downto 0) := (others => '0');
 
signal BL_Next_Wdt : std_logic_vector(DAC_Width-1 downto 0) := (others => '0');
signal BL_Next_Per : std_logic_vector(DAC_Width-1 downto 0) := (others => '0');
 
signal BL_PWM_Wdt : std_logic_vector(DAC_Width-1 downto 0) := (others => '0');
signal BL_PWM_Per : std_logic_vector(DAC_Width-1 downto 0) := (others => '0');
 
signal BL_Wdt_Ctr : std_logic_vector(DAC_Width-1 downto 0) := (others => '0');
signal BL_Per_Ctr : std_logic_vector(DAC_Width-1 downto 0) := (others => '0');
 
begin
 
--------------------------------------------------------------------------------
277,55 → 189,55
-- Open8 Register interface
--------------------------------------------------------------------------------
 
Addr_Match <= '1' when Comp_Addr = User_Addr else '0';
Addr_Match <= '1' when Comp_Addr = User_Addr else '0';
 
io_reg: process( Clock, Reset )
begin
if( Reset = Reset_Level )then
Reg_Addr_q <= (others => '0');
Wr_Data_q <= (others => '0');
Wr_En <= '0';
Rd_En <= '0';
Rd_Data <= OPEN8_NULLBUS;
Reg_Addr_q <= (others => '0');
Wr_Data_q <= (others => '0');
Wr_En <= '0';
Rd_En <= '0';
Rd_Data <= OPEN8_NULLBUS;
 
Reg_Valid <= '0';
Reg_Sel <= '0';
Reg_Data <= x"00";
Reg_Valid <= '0';
Reg_Sel <= '0';
Reg_Data <= x"00";
 
LCD_Contrast <= Default_Contrast;
LCD_Bright <= Default_Brightness;
LCD_Contrast <= Default_Contrast;
LCD_Bright <= Default_Brightness;
elsif( rising_edge( Clock ) )then
Reg_Addr_q <= Reg_Addr;
Reg_Addr_q <= Reg_Addr;
 
Wr_Data_q <= Wr_Data;
Wr_En <= Addr_Match and Wr_Enable;
Wr_Data_q <= Wr_Data;
Wr_En <= Addr_Match and Wr_Enable;
 
Reg_Valid <= '0';
Reg_Valid <= '0';
 
if( Wr_En = '1' )then
case( Reg_Addr_q )is
when "00" | "01" =>
Reg_Valid <= '1';
Reg_Sel <= Reg_Addr_q(0);
Reg_Data <= Wr_Data_q;
Reg_Valid <= '1';
Reg_Sel <= Reg_Addr_q(0);
Reg_Data <= Wr_Data_q;
when "10" =>
LCD_Contrast<= Wr_Data_q;
LCD_Contrast <= Wr_Data_q;
when "11" =>
LCD_Bright <= Wr_Data_q;
LCD_Bright <= Wr_Data_q;
when others => null;
end case;
end if;
 
Rd_Data <= OPEN8_NULLBUS;
Rd_En <= Addr_Match and Rd_Enable;
Rd_Data <= OPEN8_NULLBUS;
Rd_En <= Addr_Match and Rd_Enable;
if( Rd_En = '1' )then
case( Reg_Addr_q )is
when "00" | "01" =>
Rd_Data(7) <= Tx_Ready;
Rd_Data(7) <= Tx_Ready;
when "10" =>
Rd_Data <= LCD_Contrast;
Rd_Data <= LCD_Contrast;
when "11" =>
Rd_Data <= LCD_Bright;
Rd_Data <= LCD_Bright;
when others => null;
end case;
end if;
336,108 → 248,108
-- LCD and Register logic
--------------------------------------------------------------------------------
 
LCD_RW <= '0'; -- Permanently wire the RW line low
LCD_RW <= '0'; -- Permanently wire the RW line low
 
LCD_IO: process( Clock, Reset )
begin
if( Reset = Reset_Level )then
io_state <= INIT;
init_count <= (others => '0');
io_timer <= (others => '0');
busy_timer <= (others => '0');
LCD_Data <= (others => '0');
LCD_Addr <= '0';
LCD_E <= '0';
LCD_RS <= '0';
LCD_D <= (others => '0');
Tx_Ready <= '0';
Interrupt <= '0';
io_state <= INIT;
init_count <= (others => '0');
io_timer <= (others => '0');
busy_timer <= (others => '0');
LCD_Data <= (others => '0');
LCD_Addr <= '0';
LCD_E <= '0';
LCD_RS <= '0';
LCD_D <= (others => '0');
Tx_Ready <= '0';
Interrupt <= '0';
elsif( rising_edge(Clock) )then
LCD_E <= '0';
LCD_RS <= '0';
LCD_D <= (others => '0');
Tx_Ready <= '0';
Interrupt <= '0';
io_timer <= io_timer - 1;
busy_timer <= busy_timer - uSec_Tick;
LCD_E <= '0';
LCD_RS <= '0';
LCD_D <= (others => '0');
Tx_Ready <= '0';
Interrupt <= '0';
io_timer <= io_timer - 1;
busy_timer <= busy_timer - uSec_Tick;
case( io_state )is
 
when INIT =>
busy_timer <= INIT_DELAY;
init_count <= (others => '1');
io_state <= BUSY_WAIT;
busy_timer <= INIT_DELAY;
init_count <= (others => '1');
io_state <= BUSY_WAIT;
 
when FN_JUMP =>
io_state <= WR_PREP;
io_state <= WR_PREP;
case( init_count )is
when "000" =>
io_state <= IDLE;
io_state <= IDLE;
when "001" =>
LCD_Addr <= '0';
LCD_Data <= LCD_CONFIG6; -- Reset the Cursor
LCD_Addr <= '0';
LCD_Data <= LCD_CONFIG6; -- Reset the Cursor
when "010" =>
LCD_Addr <= '1'; -- Print a "*", and
LCD_Data <= LCD_CONFIG5; -- set RS to 1
LCD_Addr <= '1'; -- Print a "*", and
LCD_Data <= LCD_CONFIG5; -- set RS to 1
when "011" =>
LCD_Data <= LCD_CONFIG4; -- Entry mode
LCD_Data <= LCD_CONFIG4; -- Entry mode
when "100" =>
LCD_Data <= LCD_CONFIG3; -- Clear Display
LCD_Data <= LCD_CONFIG3; -- Clear Display
when "101" =>
LCD_Data <= LCD_CONFIG2; -- Display control
LCD_Data <= LCD_CONFIG2; -- Display control
when "110" | "111" =>
LCD_Addr <= '0';
LCD_Data <= LCD_CONFIG1; -- Function set
LCD_Addr <= '0';
LCD_Data <= LCD_CONFIG1; -- Function set
when others => null;
end case;
 
when IDLE =>
Tx_Ready <= '1';
Tx_Ready <= '1';
if( Reg_Valid = '1' )then
LCD_Addr <= Reg_Sel;
LCD_Data <= Reg_Data;
io_state <= WR_PREP;
LCD_Addr <= Reg_Sel;
LCD_Data <= Reg_Data;
io_state <= WR_PREP;
end if;
 
when WR_PREP =>
io_timer <= SNH_DELAY;
io_state <= WR_SETUP;
io_timer <= SNH_DELAY;
io_state <= WR_SETUP;
 
when WR_SETUP =>
LCD_RS <= LCD_Addr;
LCD_D <= LCD_Data;
LCD_E <= '1';
LCD_RS <= LCD_Addr;
LCD_D <= LCD_Data;
LCD_E <= '1';
if( io_timer = 0 )then
io_timer <= SNH_DELAY;
io_state <= WR_HOLD;
io_timer <= SNH_DELAY;
io_state <= WR_HOLD;
end if;
 
when WR_HOLD =>
LCD_RS <= LCD_Addr;
LCD_D <= LCD_Data;
LCD_RS <= LCD_Addr;
LCD_D <= LCD_Data;
if( io_timer = 0 )then
LCD_E <= '0';
io_state <= BUSY_PREP;
LCD_E <= '0';
io_state <= BUSY_PREP;
end if;
 
when BUSY_PREP =>
busy_timer <= BUSY_DELAY;
busy_timer <= BUSY_DELAY;
if( LCD_Addr = '0' and LCD_Data < 4 )then
busy_timer <= CLDSP_DELAY;
busy_timer <= CLDSP_DELAY;
end if;
io_state <= BUSY_WAIT;
io_state <= BUSY_WAIT;
 
when BUSY_WAIT =>
if( busy_timer = 0 )then
io_state <= ISSUE_INT;
io_state <= ISSUE_INT;
if( init_count > 0 )then
init_count<= init_count - 1;
io_state <= FN_JUMP;
init_count <= init_count - 1;
io_state <= FN_JUMP;
end if;
end if;
 
when ISSUE_INT =>
Interrupt <= '1';
io_state <= IDLE;
Interrupt <= '1';
io_state <= IDLE;
 
when others => null;
 
451,77 → 363,22
--------------------------------------------------------------------------------
 
Contrast_Disabled: if( not Use_Contrast )generate
LCD_CN <= '0';
LCD_CN <= '0';
end generate;
 
Contrast_Enabled: if( Use_Contrast )generate
 
CN_diff <= ('0' & CN_q(DIV_WIDTH*2-2 downto DIV_WIDTH-1)) -
('0' & CN_Divisor);
U_CN : entity work.vdsm8
generic map(
Reset_Level => Reset_Level
)
port map(
Clock => Clock,
Reset => Reset,
DACin => LCD_Contrast,
DACout => LCD_CN
);
 
CN_Dividend<= PADJ_2 when CN_DACin_q >= DELTA_2_I and CN_DACin_q < DELTA_3_I else
PADJ_3 when CN_DACin_q >= DELTA_3_I and CN_DACin_q < DELTA_4_I else
PADJ_4 when CN_DACin_q >= DELTA_4_I and CN_DACin_q < DELTA_5_I else
PADJ_5 when CN_DACin_q >= DELTA_5_I and CN_DACin_q < DELTA_6_I else
PADJ_6 when CN_DACin_q >= DELTA_6_I else
PADJ_1;
 
CN_Next_Wdt<= DELTA_1 when CN_DACin_q >= DELTA_1_I and CN_DACin_q < DELTA_2_I else
DELTA_2 when CN_DACin_q >= DELTA_2_I and CN_DACin_q < DELTA_3_I else
DELTA_3 when CN_DACin_q >= DELTA_3_I and CN_DACin_q < DELTA_4_I else
DELTA_4 when CN_DACin_q >= DELTA_4_I and CN_DACin_q < DELTA_5_I else
DELTA_5 when CN_DACin_q >= DELTA_5_I and CN_DACin_q < DELTA_6_I else
DELTA_6 when CN_DACin_q >= DELTA_6_I else
(others => '0');
 
CN_Next_Per <= BL_q(7 downto 0) - 1;
 
CN_vDSM_proc: process( Clock, Reset )
begin
if( Reset = Reset_Level )then
CN_q <= (others => '0');
CN_count <= (others => '1');
CN_Divisor <= (others => '0');
CN_DACin_q <= (others => '0');
CN_PWM_Wdt <= (others => '0');
CN_PWM_Per <= (others => '0');
CN_Per_Ctr <= (others => '0');
CN_Wdt_Ctr <= (others => '0');
LCD_CN <= '0';
elsif( rising_edge(Clock) )then
CN_q <= CN_diff(DIV_WIDTH-1 downto 0) &
CN_q(DIV_WIDTH-2 downto 0) & '1';
if( CN_diff(DIV_WIDTH) = '1' )then
CN_q <= CN_q(DIV_WIDTH*2-2 downto 0) & '0';
end if;
 
CN_count <= CN_count + 1;
if( CN_count = DIV_WIDTH )then
CN_PWM_Wdt <= CN_Next_Wdt;
CN_PWM_Per <= CN_Next_Per;
CN_DACin_q <= LCD_Contrast;
CN_Divisor <= (others => '0');
CN_Divisor(DAC_Width-1 downto 0) <= CN_DACin_q;
CN_q <= conv_std_logic_vector(0,DIV_WIDTH) & CN_Dividend;
CN_count <= (others => '0');
end if;
 
CN_Per_Ctr <= CN_Per_Ctr - 1;
CN_Wdt_Ctr <= CN_Wdt_Ctr - 1;
 
LCD_CN <= '1';
if( CN_Wdt_Ctr = 0 )then
LCD_CN <= '0';
CN_Wdt_Ctr <= (others => '0');
end if;
 
if( CN_Per_Ctr = 0 )then
CN_Per_Ctr <= CN_PWM_Per;
CN_Wdt_Ctr <= CN_PWM_Wdt;
end if;
 
end if;
end process;
end generate;
 
--------------------------------------------------------------------------------
529,78 → 386,22
--------------------------------------------------------------------------------
 
Backlight_Disabled: if( not Use_Backlight )generate
LCD_BL <= '0';
LCD_BL <= '0';
end generate;
 
Backlight_Enabled: if( Use_Backlight )generate
 
BL_diff <= ('0' & BL_q(DIV_WIDTH*2-2 downto DIV_WIDTH-1)) -
('0' & BL_Divisor);
U_BL : entity work.vdsm8
generic map(
Reset_Level => Reset_Level
)
port map(
Clock => Clock,
Reset => Reset,
DACin => LCD_Bright,
DACout => LCD_BL
);
 
BL_Dividend<= PADJ_2 when BL_DACin_q >= DELTA_2_I and BL_DACin_q < DELTA_3_I else
PADJ_3 when BL_DACin_q >= DELTA_3_I and BL_DACin_q < DELTA_4_I else
PADJ_4 when BL_DACin_q >= DELTA_4_I and BL_DACin_q < DELTA_5_I else
PADJ_5 when BL_DACin_q >= DELTA_5_I and BL_DACin_q < DELTA_6_I else
PADJ_6 when BL_DACin_q >= DELTA_6_I else
PADJ_1;
 
BL_Next_Wdt<= DELTA_1 when BL_DACin_q >= DELTA_1_I and BL_DACin_q < DELTA_2_I else
DELTA_2 when BL_DACin_q >= DELTA_2_I and BL_DACin_q < DELTA_3_I else
DELTA_3 when BL_DACin_q >= DELTA_3_I and BL_DACin_q < DELTA_4_I else
DELTA_4 when BL_DACin_q >= DELTA_4_I and BL_DACin_q < DELTA_5_I else
DELTA_5 when BL_DACin_q >= DELTA_5_I and BL_DACin_q < DELTA_6_I else
DELTA_6 when BL_DACin_q >= DELTA_6_I else
(others => '0');
 
BL_Next_Per <= BL_q(7 downto 0) - 1;
 
BL_vDSM_proc: process( Clock, Reset )
begin
if( Reset = Reset_Level )then
BL_q <= (others => '0');
BL_count <= (others => '1');
BL_Divisor <= (others => '0');
BL_DACin_q <= (others => '0');
BL_PWM_Wdt <= (others => '0');
BL_PWM_Per <= (others => '0');
BL_Per_Ctr <= (others => '0');
BL_Wdt_Ctr <= (others => '0');
LCD_BL <= '0';
elsif( rising_edge(Clock) )then
BL_q <= BL_diff(DIV_WIDTH-1 downto 0) &
BL_q(DIV_WIDTH-2 downto 0) & '1';
if( BL_diff(DIV_WIDTH) = '1' )then
BL_q <= BL_q(DIV_WIDTH*2-2 downto 0) & '0';
end if;
 
BL_count <= BL_count + 1;
if( BL_count = DIV_WIDTH )then
BL_PWM_Wdt <= BL_Next_Wdt;
BL_PWM_Per <= BL_Next_Per;
BL_DACin_q <= LCD_Bright;
BL_Divisor <= (others => '0');
BL_Divisor(DAC_Width-1 downto 0) <= BL_DACin_q;
BL_q <= conv_std_logic_vector(0,DIV_WIDTH) & BL_Dividend;
BL_count <= (others => '0');
end if;
 
BL_Per_Ctr <= BL_Per_Ctr - 1;
BL_Wdt_Ctr <= BL_Wdt_Ctr - 1;
 
LCD_BL <= '1';
if( BL_Wdt_Ctr = 0 )then
LCD_BL <= '0';
BL_Wdt_Ctr <= (others => '0');
end if;
 
if( BL_Per_Ctr = 0 )then
BL_Per_Ctr <= BL_PWM_Per;
BL_Wdt_Ctr <= BL_PWM_Wdt;
end if;
 
end if;
end process;
 
end generate;
 
end architecture;
/o8_lfsr32.vhd
43,63 → 43,63
 
entity o8_lfsr32 is
generic(
Init_Seed : std_logic_vector(31 downto 0) := x"CAFEBABE";
Reset_Level : std_logic;
Address : ADDRESS_TYPE
Init_Seed : std_logic_vector(31 downto 0) := x"CAFEBABE";
Reset_Level : std_logic;
Address : ADDRESS_TYPE
);
port(
Clock : in std_logic;
Reset : in std_logic;
Clock : in std_logic;
Reset : in std_logic;
--
Bus_Address : in ADDRESS_TYPE;
Rd_Enable : in std_logic;
Rd_Data : out DATA_TYPE
Bus_Address : in ADDRESS_TYPE;
Rd_Enable : in std_logic;
Rd_Data : out DATA_TYPE
);
end entity;
 
architecture behave of o8_lfsr32 is
 
constant User_Addr : std_logic_vector(15 downto 1)
:= Address(15 downto 1);
alias Comp_Addr is Bus_Address(15 downto 1);
alias Reg_Sel is Bus_Address(0);
signal Reg_Sel_q : std_logic := '0';
signal Addr_Match : std_logic := '0';
signal Rd_En : std_logic := '0';
constant User_Addr : std_logic_vector(15 downto 1)
:= Address(15 downto 1);
alias Comp_Addr is Bus_Address(15 downto 1);
alias Reg_Sel is Bus_Address(0);
signal Reg_Sel_q : std_logic := '0';
signal Addr_Match : std_logic := '0';
signal Rd_En : std_logic := '0';
 
signal d0 : std_logic := '0';
signal lfsr : std_logic_vector(31 downto 0) := x"00000000";
signal lfsr_q : std_logic_vector(31 downto 0) := x"00000000";
signal d0 : std_logic := '0';
signal lfsr : std_logic_vector(31 downto 0) := x"00000000";
signal lfsr_q : std_logic_vector(31 downto 0) := x"00000000";
 
begin
 
Addr_Match <= Rd_Enable when Comp_Addr = User_Addr else '0';
d0 <= lfsr(31) xnor lfsr(21) xnor lfsr(1) xnor lfsr(0);
Addr_Match <= Rd_Enable when Comp_Addr = User_Addr else '0';
d0 <= lfsr(31) xnor lfsr(21) xnor lfsr(1) xnor lfsr(0);
 
lfsr_proc: process( Clock, Reset )
begin
if( Reset = Reset_Level )then
Reg_Sel_q <= '0';
Rd_En <= '0';
Rd_Data <= x"00";
lfsr <= Init_Seed;
lfsr_q <= x"00000000";
Reg_Sel_q <= '0';
Rd_En <= '0';
Rd_Data <= x"00";
lfsr <= Init_Seed;
lfsr_q <= x"00000000";
elsif( rising_edge(Clock) )then
Rd_Data <= x"00";
Reg_Sel_q <= Reg_Sel;
Rd_En <= Addr_Match;
Rd_Data <= x"00";
Reg_Sel_q <= Reg_Sel;
Rd_En <= Addr_Match;
if( Rd_En = '1' )then
Rd_Data <= lfsr_q(31 downto 24);
lfsr_q <= lfsr_q(23 downto 0) & x"00";
Rd_Data <= lfsr_q(31 downto 24);
lfsr_q <= lfsr_q(23 downto 0) & x"00";
if( Reg_Sel_q = '1' )then
Rd_Data <= lfsr_q(31) & "0000000";
lfsr_q <= lfsr_q(30 downto 0) & '0';
Rd_Data <= lfsr_q(31) & "0000000";
lfsr_q <= lfsr_q(30 downto 0) & '0';
end if;
end if;
 
if( or_reduce(lfsr_q) = '0' )then
lfsr_q <= lfsr;
lfsr <= lfsr(30 downto 0) & d0;
lfsr_q <= lfsr;
lfsr <= lfsr(30 downto 0) & d0;
end if;
end if;
end process;
/o8_max7221.vhd
41,105 → 41,106
 
entity o8_max7221 is
generic(
Bit_Rate : real := 5000000.0;
Sys_Freq : real;
Reset_Level : std_logic;
Address : ADDRESS_TYPE
Bit_Rate : real := 5000000.0;
Sys_Freq : real;
Reset_Level : std_logic;
Address : ADDRESS_TYPE
);
port(
Clock : in std_logic;
Reset : in std_logic;
Clock : in std_logic;
Reset : in std_logic;
--
Bus_Address : in ADDRESS_TYPE;
Wr_Enable : in std_logic;
Wr_Data : in DATA_TYPE;
Bus_Address : in ADDRESS_TYPE;
Wr_Enable : in std_logic;
Wr_Data : in DATA_TYPE;
--
Mx_Data : out std_logic;
Mx_Clock : out std_logic;
MX_LDCSn : out std_logic
Mx_Data : out std_logic;
Mx_Clock : out std_logic;
MX_LDCSn : out std_logic
);
end entity;
 
architecture behave of o8_max7221 is
 
signal FIFO_Reset : std_logic;
signal FIFO_Reset : std_logic;
 
constant User_Addr : std_logic_vector(15 downto 4) := Address(15 downto 4);
alias Comp_Addr is Bus_Address(15 downto 4);
constant User_Addr : std_logic_vector(15 downto 4) :=
Address(15 downto 4);
alias Comp_Addr is Bus_Address(15 downto 4);
 
signal FIFO_Wr_En : std_logic;
signal FIFO_Wr_Data : std_logic_vector(11 downto 0);
signal FIFO_Wr_En : std_logic;
signal FIFO_Wr_Data : std_logic_vector(11 downto 0);
 
signal FIFO_Rd_En : std_logic;
signal FIFO_Empty : std_logic;
signal FIFO_Rd_Data : std_logic_vector(11 downto 0);
signal FIFO_Rd_En : std_logic;
signal FIFO_Empty : std_logic;
signal FIFO_Rd_Data : std_logic_vector(11 downto 0);
 
type TX_CTRL_STATES is (IDLE, TX_BYTE, TX_START, TX_WAIT );
signal TX_Ctrl : TX_CTRL_STATES;
signal TX_Ctrl : TX_CTRL_STATES;
 
signal TX_En : std_logic;
signal TX_Idle : std_logic;
signal TX_En : std_logic;
signal TX_Idle : std_logic;
 
constant BAUD_DLY_VAL : integer := integer((Sys_Freq / Bit_Rate) / 2.0 );
constant BAUD_DLY_WDT : integer := ceil_log2(BAUD_DLY_VAL - 1);
constant BAUD_DLY : std_logic_vector :=
conv_std_logic_vector(BAUD_DLY_VAL - 1, BAUD_DLY_WDT);
constant BAUD_DLY_VAL : integer := integer((Sys_Freq / Bit_Rate)/ 2.0);
constant BAUD_DLY_WDT : integer := ceil_log2(BAUD_DLY_VAL - 1);
constant BAUD_DLY : std_logic_vector :=
conv_std_logic_vector(BAUD_DLY_VAL - 1, BAUD_DLY_WDT);
 
signal Baud_Cntr : std_logic_vector( BAUD_DLY_WDT - 1 downto 0 )
:= (others => '0');
signal Baud_Tick : std_logic;
signal Baud_Cntr : std_logic_vector( BAUD_DLY_WDT - 1 downto 0 )
:= (others => '0');
signal Baud_Tick : std_logic;
 
type IO_STATES is ( IDLE, SYNC_CLK, SCLK_L, SCLK_H, ADV_BIT, DONE );
signal io_state : IO_STATES;
signal bit_cntr : std_logic_vector(3 downto 0);
signal tx_buffer : std_logic_vector(15 downto 0);
signal io_state : IO_STATES;
signal bit_cntr : std_logic_vector(3 downto 0);
signal tx_buffer : std_logic_vector(15 downto 0);
 
begin
 
FIFO_Wr_En <= Wr_Enable when Comp_Addr = User_Addr else '0';
FIFO_Wr_Data <= Bus_Address(3 downto 0) & Wr_Data;
FIFO_Reset <= Reset when Reset_Level = '1' else (not Reset);
FIFO_Wr_En <= Wr_Enable when Comp_Addr = User_Addr else '0';
FIFO_Wr_Data <= Bus_Address(3 downto 0) & Wr_Data;
FIFO_Reset <= Reset when Reset_Level = '1' else (not Reset);
 
U_FIFO : entity work.o8_max7221_fifo
port map(
aclr => FIFO_Reset,
clock => Clock,
data => FIFO_Wr_Data,
rdreq => FIFO_Rd_En,
wrreq => FIFO_Wr_En,
empty => FIFO_Empty,
q => FIFO_Rd_Data
aclr => FIFO_Reset,
clock => Clock,
data => FIFO_Wr_Data,
rdreq => FIFO_Rd_En,
wrreq => FIFO_Wr_En,
empty => FIFO_Empty,
q => FIFO_Rd_Data
);
 
tx_FSM: process( Clock, Reset )
begin
if( Reset = Reset_Level )then
TX_Ctrl <= IDLE;
TX_En <= '0';
FIFO_Rd_En <= '0';
TX_Ctrl <= IDLE;
TX_En <= '0';
FIFO_Rd_En <= '0';
elsif( rising_edge(Clock) )then
TX_En <= '0';
FIFO_Rd_En <= '0';
TX_En <= '0';
FIFO_Rd_En <= '0';
 
case( TX_Ctrl )is
when IDLE =>
if( FIFO_Empty = '0' )then
FIFO_Rd_En <= '1';
TX_Ctrl <= TX_BYTE;
FIFO_Rd_En <= '1';
TX_Ctrl <= TX_BYTE;
end if;
 
when TX_BYTE =>
TX_En <= '1';
TX_Ctrl <= TX_START;
TX_En <= '1';
TX_Ctrl <= TX_START;
 
when TX_START =>
if( TX_Idle = '0' )then
TX_Ctrl <= TX_WAIT;
TX_Ctrl <= TX_WAIT;
end if;
 
when TX_WAIT =>
if( TX_Idle = '1' )then
TX_Ctrl <= IDLE;
TX_Ctrl <= IDLE;
end if;
 
when others => null;
151,13 → 152,13
Baud_Rate_proc: process( Clock, Reset )
begin
if( Reset = Reset_Level )then
Baud_Cntr <= (others => '0');
Baud_Tick <= '0';
Baud_Cntr <= (others => '0');
Baud_Tick <= '0';
elsif( rising_edge( Clock ) )then
Baud_Cntr <= Baud_Cntr - 1;
Baud_Tick <= nor_reduce(Baud_Cntr);
Baud_Cntr <= Baud_Cntr - 1;
Baud_Tick <= nor_reduce(Baud_Cntr);
if( Baud_Cntr = 0 )then
Baud_Cntr <= BAUD_DLY;
Baud_Cntr <= BAUD_DLY;
end if;
end if;
end process;
165,60 → 166,60
io_FSM: process( Clock, Reset )
begin
if( Reset = Reset_Level )then
io_state <= IDLE;
bit_cntr <= (others => '0');
tx_buffer <= (others => '0');
TX_Idle <= '0';
io_state <= IDLE;
bit_cntr <= (others => '0');
tx_buffer <= (others => '0');
TX_Idle <= '0';
 
Mx_Clock <= '0';
Mx_Data <= '0';
MX_LDCSn <= '0';
Mx_Clock <= '0';
Mx_Data <= '0';
MX_LDCSn <= '0';
 
elsif( rising_edge(Clock) )then
 
TX_Idle <= '0';
Mx_Clock <= '0';
TX_Idle <= '0';
Mx_Clock <= '0';
 
case( io_state )is
when IDLE =>
Mx_Data <= '0';
MX_LDCSn <= '1';
TX_Idle <= '1';
Mx_Data <= '0';
MX_LDCSn <= '1';
TX_Idle <= '1';
if( TX_En = '1' )then
tx_buffer <= "0000" & FIFO_Rd_Data;
bit_cntr <= (others => '1');
io_state <= SYNC_CLK;
tx_buffer <= "0000" & FIFO_Rd_Data;
bit_cntr <= (others => '1');
io_state <= SYNC_CLK;
end if;
 
when SYNC_CLK =>
if( Baud_Tick = '1' )then
io_state <= SCLK_L;
io_state <= SCLK_L;
end if;
 
when SCLK_L =>
MX_LDCSn <= '0';
Mx_Data <= tx_buffer(conv_integer(bit_cntr));
MX_LDCSn <= '0';
Mx_Data <= tx_buffer(conv_integer(bit_cntr));
if( Baud_Tick = '1' )then
io_state <= SCLK_H;
io_state <= SCLK_H;
end if;
 
when SCLK_H =>
Mx_Clock <= '1';
Mx_Clock <= '1';
if( Baud_Tick = '1' )then
bit_cntr <= bit_cntr - 1;
io_state <= ADV_BIT;
bit_cntr <= bit_cntr - 1;
io_state <= ADV_BIT;
end if;
 
when ADV_BIT =>
io_state <= SCLK_L;
io_state <= SCLK_L;
if( and_reduce(bit_cntr) = '1' )then
io_state <= DONE;
io_state <= DONE;
end if;
 
when DONE =>
Mx_Data <= '0';
Mx_Data <= '0';
if( Baud_Tick = '1' )then
io_state <= IDLE;
io_state <= IDLE;
end if;
 
when others => null;
/o8_pwm16.vhd
51,137 → 51,137
 
entity o8_pwm16 is
generic(
Reset_Level : std_logic;
Address : ADDRESS_TYPE
Reset_Level : std_logic;
Address : ADDRESS_TYPE
);
port(
Clock : in std_logic;
Reset : in std_logic;
uSec_Tick : in std_logic;
Clock : in std_logic;
Reset : in std_logic;
uSec_Tick : in std_logic;
--
PWM_Out : out std_logic;
PWM_Out : out std_logic;
-- Bus interface
Bus_Address : in ADDRESS_TYPE;
Wr_Enable : in std_logic;
Wr_Data : in DATA_TYPE;
Rd_Enable : in std_logic;
Rd_Data : out DATA_TYPE;
Interrupt : out std_logic
Bus_Address : in ADDRESS_TYPE;
Wr_Enable : in std_logic;
Wr_Data : in DATA_TYPE;
Rd_Enable : in std_logic;
Rd_Data : out DATA_TYPE;
Interrupt : out std_logic
);
end entity;
 
architecture behave of o8_pwm16 is
 
constant User_Addr : std_logic_vector(15 downto 3) :=
Address(15 downto 3);
constant User_Addr : std_logic_vector(15 downto 3) :=
Address(15 downto 3);
 
alias Comp_Addr is Bus_Address(15 downto 3);
signal Addr_Match : std_logic := '0';
alias Comp_Addr is Bus_Address(15 downto 3);
signal Addr_Match : std_logic := '0';
 
alias Reg_Addr is Bus_Address(2 downto 0);
signal Reg_Addr_q : std_logic_vector(2 downto 0) := (others => '0');
alias Reg_Addr is Bus_Address(2 downto 0);
signal Reg_Addr_q : std_logic_vector(2 downto 0) := (others => '0');
 
signal Wr_En : std_logic := '0';
signal Wr_Data_q : DATA_TYPE := x"00";
signal Rd_En : std_logic := '0';
signal Wr_En : std_logic := '0';
signal Wr_Data_q : DATA_TYPE := x"00";
signal Rd_En : std_logic := '0';
 
signal PWM_Enable : std_logic := '0';
signal PWM_Period : std_logic_vector(15 downto 0) := (others => '0');
alias PWM_Period_l is PWM_Period(7 downto 0);
alias PWM_Period_u is PWM_Period(15 downto 8);
signal PWM_Enable : std_logic := '0';
signal PWM_Period : std_logic_vector(15 downto 0) := (others => '0');
alias PWM_Period_l is PWM_Period(7 downto 0);
alias PWM_Period_u is PWM_Period(15 downto 8);
 
signal PWM_Width : std_logic_vector(15 downto 0) := (others => '0');
alias PWM_Width_l is PWM_Width(7 downto 0);
alias PWM_Width_u is PWM_Width(15 downto 8);
signal PWM_Width : std_logic_vector(15 downto 0) := (others => '0');
alias PWM_Width_l is PWM_Width(7 downto 0);
alias PWM_Width_u is PWM_Width(15 downto 8);
 
signal Period_Ctr : std_logic_vector(15 downto 0) := (others => '0');
signal Width_Ctr : std_logic_vector(15 downto 0) := (others => '0');
signal Period_Ctr : std_logic_vector(15 downto 0) := (others => '0');
signal Width_Ctr : std_logic_vector(15 downto 0) := (others => '0');
 
begin
 
Addr_Match <= '1' when Comp_Addr = User_Addr else '0';
Addr_Match <= '1' when Comp_Addr = User_Addr else '0';
 
PWM_proc: process( Clock, Reset )
begin
if( Reset = Reset_Level )then
Wr_Data_q <= (others => '0');
Reg_Addr_q <= (others => '0');
Wr_En <= '0';
Rd_En <= '0';
Rd_Data <= x"00";
Interrupt <= '0';
Wr_Data_q <= (others => '0');
Reg_Addr_q <= (others => '0');
Wr_En <= '0';
Rd_En <= '0';
Rd_Data <= x"00";
Interrupt <= '0';
 
PWM_Enable <= '0';
PWM_Period <= (others => '0');
PWM_Width <= (others => '0');
PWM_Enable <= '0';
PWM_Period <= (others => '0');
PWM_Width <= (others => '0');
 
Period_Ctr <= (others => '0');
Width_Ctr <= (others => '0');
PWM_Out <= '0';
Period_Ctr <= (others => '0');
Width_Ctr <= (others => '0');
PWM_Out <= '0';
elsif( rising_edge(Clock) )then
Reg_Addr_q <= Reg_Addr;
Wr_Data_q <= Wr_Data;
Wr_En <= Addr_Match and Wr_Enable;
Reg_Addr_q <= Reg_Addr;
Wr_Data_q <= Wr_Data;
Wr_En <= Addr_Match and Wr_Enable;
 
if( Wr_En = '1' )then
case( Reg_Addr_q )is
when "000" =>
PWM_Period_l <= Wr_Data_q;
PWM_Period_l <= Wr_Data_q;
when "001" =>
PWM_Period_u <= Wr_Data_q;
PWM_Period_u <= Wr_Data_q;
when "010" =>
PWM_Width_l <= Wr_Data_q;
PWM_Width_l <= Wr_Data_q;
when "011" =>
PWM_Width_u <= Wr_Data_q;
PWM_Width_u <= Wr_Data_q;
when "100" | "101" | "110" | "111" =>
PWM_Enable <= Wr_Data_q(7);
PWM_Enable <= Wr_Data_q(7);
when others => null;
end case;
end if;
 
Rd_Data <= (others => '0');
Rd_En <= Addr_Match and Rd_Enable;
Rd_Data <= (others => '0');
Rd_En <= Addr_Match and Rd_Enable;
if( Rd_En = '1' )then
case( Reg_Addr_q )is
when "000" =>
Rd_Data <= PWM_Period_l;
Rd_Data <= PWM_Period_l;
when "001" =>
Rd_Data <= PWM_Period_u;
Rd_Data <= PWM_Period_u;
when "010" =>
Rd_Data <= PWM_Width_l;
Rd_Data <= PWM_Width_l;
when "011" =>
Rd_Data <= PWM_Width_u;
Rd_Data <= PWM_Width_u;
when "100" | "101" | "110" | "111" =>
Rd_Data <= PWM_Enable & "0000000";
Rd_Data <= PWM_Enable & "0000000";
when others => null;
end case;
end if;
 
Interrupt <= '0';
Period_Ctr <= Period_Ctr - uSec_tick;
Width_Ctr <= Width_Ctr - uSec_tick;
Interrupt <= '0';
Period_Ctr <= Period_Ctr - uSec_tick;
Width_Ctr <= Width_Ctr - uSec_tick;
 
-- Stop the width counter from rolling over at 0
if( or_reduce(Width_Ctr) = '0' )then
Width_Ctr <= (others => '0');
Width_Ctr <= (others => '0');
end if;
 
-- Reload both counters when period reaches 0
if( or_reduce(Period_Ctr) = '0' )then
Period_Ctr <= PWM_Period;
Width_Ctr <= PWM_Width;
Interrupt <= '1';
Period_Ctr <= PWM_Period;
Width_Ctr <= PWM_Width;
Interrupt <= '1';
end if;
 
-- Drive the output high as long as Width > 0 and PWM_Enable is high
PWM_Out <= or_reduce(Width_Ctr) and PWM_Enable;
PWM_Out <= or_reduce(Width_Ctr) and PWM_Enable;
 
-- If the counter is disabled, reload the counters, and drive the output
-- low.
if( PWM_Enable = '0' )then
Period_Ctr <= PWM_Period;
Width_Ctr <= PWM_Width;
Interrupt <= '0';
Period_Ctr <= PWM_Period;
Width_Ctr <= PWM_Width;
Interrupt <= '0';
end if;
 
end if;
/o8_ram_1k.vhd
34,60 → 34,60
 
entity o8_ram_1k is
generic(
Reset_Level : std_logic;
Address : ADDRESS_TYPE
Reset_Level : std_logic;
Address : ADDRESS_TYPE
);
port(
Clock : in std_logic;
Reset : in std_logic;
Clock : in std_logic;
Reset : in std_logic;
--
Bus_Address : in ADDRESS_TYPE;
Wr_Enable : in std_logic;
Wr_Data : in DATA_TYPE;
Rd_Enable : in std_logic;
Rd_Data : out DATA_TYPE
Bus_Address : in ADDRESS_TYPE;
Wr_Enable : in std_logic;
Wr_Data : in DATA_TYPE;
Rd_Enable : in std_logic;
Rd_Data : out DATA_TYPE
);
end entity;
 
architecture behave of o8_ram_1k is
 
constant User_Addr : std_logic_vector(15 downto 10)
:= Address(15 downto 10);
alias Comp_Addr is Bus_Address(15 downto 10);
alias RAM_Addr is Bus_Address(9 downto 0);
constant User_Addr : std_logic_vector(15 downto 10)
:= Address(15 downto 10);
alias Comp_Addr is Bus_Address(15 downto 10);
alias RAM_Addr is Bus_Address(9 downto 0);
 
signal Addr_Match : std_logic := '0';
signal Wr_En : std_logic := '0';
signal Rd_En : std_logic := '0';
signal Rd_Data_i : DATA_TYPE := OPEN8_NULLBUS;
signal Addr_Match : std_logic := '0';
signal Wr_En : std_logic := '0';
signal Rd_En : std_logic := '0';
signal Rd_Data_i : DATA_TYPE := OPEN8_NULLBUS;
 
begin
 
-- This decode needs to happen immediately, to give the RAM a chance to
-- do the lookup before we have to set Rd_Data
Addr_Match <= '1' when Comp_Addr = User_Addr else '0';
Wr_En <= Addr_Match and Wr_Enable;
Addr_Match <= '1' when Comp_Addr = User_Addr else '0';
Wr_En <= Addr_Match and Wr_Enable;
 
-- Note that this RAM should be created without an output FF (unregistered Q)
U_RAM : entity work.ram_1k_core
port map(
address => RAM_Addr,
clock => Clock,
data => Wr_Data,
wren => Wr_En,
q => Rd_Data_i
address => RAM_Addr,
clock => Clock,
data => Wr_Data,
wren => Wr_En,
q => Rd_Data_i
);
 
RAM_proc: process( Reset, Clock )
begin
if( Reset = Reset_Level )then
Rd_En <= '0';
Rd_Data <= OPEN8_NULLBUS;
Rd_En <= '0';
Rd_Data <= OPEN8_NULLBUS;
elsif( rising_edge(Clock) )then
Rd_En <= Addr_Match and Rd_Enable;
Rd_Data <= OPEN8_NULLBUS;
Rd_En <= Addr_Match and Rd_Enable;
Rd_Data <= OPEN8_NULLBUS;
if( Rd_En = '1' )then
Rd_Data <= Rd_Data_i;
Rd_Data <= Rd_Data_i;
end if;
end if;
end process;
/o8_ram_4k.vhd
34,60 → 34,60
 
entity o8_ram_4k is
generic(
Reset_Level : std_logic;
Address : ADDRESS_TYPE
Reset_Level : std_logic;
Address : ADDRESS_TYPE
);
port(
Clock : in std_logic;
Reset : in std_logic;
Clock : in std_logic;
Reset : in std_logic;
--
Bus_Address : in ADDRESS_TYPE;
Wr_Enable : in std_logic;
Wr_Data : in DATA_TYPE;
Rd_Enable : in std_logic;
Rd_Data : out DATA_TYPE
Bus_Address : in ADDRESS_TYPE;
Wr_Enable : in std_logic;
Wr_Data : in DATA_TYPE;
Rd_Enable : in std_logic;
Rd_Data : out DATA_TYPE
);
end entity;
 
architecture behave of o8_ram_4k is
 
constant User_Addr : std_logic_vector(15 downto 12)
:= Address(15 downto 12);
alias Comp_Addr is Bus_Address(15 downto 12);
alias RAM_Addr is Bus_Address(11 downto 0);
constant User_Addr : std_logic_vector(15 downto 12)
:= Address(15 downto 12);
alias Comp_Addr is Bus_Address(15 downto 12);
alias RAM_Addr is Bus_Address(11 downto 0);
 
signal Addr_Match : std_logic := '0';
signal Wr_En : std_logic := '0';
signal Rd_En : std_logic := '0';
signal Rd_Data_i : DATA_TYPE := OPEN8_NULLBUS;
signal Addr_Match : std_logic := '0';
signal Wr_En : std_logic := '0';
signal Rd_En : std_logic := '0';
signal Rd_Data_i : DATA_TYPE := OPEN8_NULLBUS;
 
begin
 
-- This decode needs to happen immediately, to give the RAM a chance to
-- do the lookup before we have to set Rd_Data
Addr_Match <= '1' when Comp_Addr = User_Addr else '0';
Wr_En <= Addr_Match and Wr_Enable;
Addr_Match <= '1' when Comp_Addr = User_Addr else '0';
Wr_En <= Addr_Match and Wr_Enable;
 
-- Note that this RAM should be created without an output FF (unregistered Q)
U_RAM : entity work.ram_4k_core
port map(
address => RAM_Addr,
clock => Clock,
data => Wr_Data,
wren => Wr_En,
q => Rd_Data_i
address => RAM_Addr,
clock => Clock,
data => Wr_Data,
wren => Wr_En,
q => Rd_Data_i
);
 
RAM_proc: process( Reset, Clock )
begin
if( Reset = Reset_Level )then
Rd_En <= '0';
Rd_Data <= OPEN8_NULLBUS;
Rd_En <= '0';
Rd_Data <= OPEN8_NULLBUS;
elsif( rising_edge(Clock) )then
Rd_En <= Addr_Match and Rd_Enable;
Rd_Data <= OPEN8_NULLBUS;
Rd_En <= Addr_Match and Rd_Enable;
Rd_Data <= OPEN8_NULLBUS;
if( Rd_En = '1' )then
Rd_Data <= Rd_Data_i;
Rd_Data <= Rd_Data_i;
end if;
end if;
end process;
/o8_register.vhd
44,73 → 44,63
 
entity o8_register is
generic(
Default_Value : DATA_TYPE := x"00";
Reset_Level : std_logic;
Address : ADDRESS_TYPE
Default_Value : DATA_TYPE := x"00";
Reset_Level : std_logic;
Address : ADDRESS_TYPE
);
port(
Clock : in std_logic;
Reset : in std_logic;
Clock : in std_logic;
Reset : in std_logic;
--
Bus_Address : in ADDRESS_TYPE;
Wr_Enable : in std_logic;
Wr_Data : in DATA_TYPE;
Rd_Enable : in std_logic;
Rd_Data : out DATA_TYPE;
Bus_Address : in ADDRESS_TYPE;
Wr_Enable : in std_logic;
Wr_Data : in DATA_TYPE;
Rd_Enable : in std_logic;
Rd_Data : out DATA_TYPE;
--
Register_Out : out DATA_TYPE
Register_Out : out DATA_TYPE
);
end entity;
 
architecture behave of o8_register is
 
function ceil_log2 (x : in natural) return natural is
variable retval : natural;
begin
retval := 1;
while ((2**retval) - 1) < x loop
retval := retval + 1;
end loop;
return retval;
end function;
constant User_Addr : std_logic_vector(15 downto 0)
:= Address(15 downto 0);
alias Comp_Addr is Bus_Address(15 downto 0);
signal Addr_Match : std_logic;
signal Wr_En : std_logic;
signal Wr_Data_q : DATA_TYPE;
signal Reg_Out : DATA_TYPE;
signal Rd_En : std_logic;
 
constant User_Addr : std_logic_vector(15 downto 0)
:= Address(15 downto 0);
alias Comp_Addr is Bus_Address(15 downto 0);
signal Addr_Match : std_logic;
signal Wr_En : std_logic;
signal Wr_Data_q : DATA_TYPE;
signal Reg_Out : DATA_TYPE;
signal Rd_En : std_logic;
 
begin
 
Addr_Match <= '1' when Comp_Addr = User_Addr else '0';
Addr_Match <= '1' when Comp_Addr = User_Addr else '0';
 
io_reg: process( Clock, Reset )
begin
if( Reset = Reset_Level )then
Wr_En <= '0';
Wr_Data_q <= (others => '0');
Reg_Out <= Default_Value;
Rd_En <= '0';
Rd_Data <= OPEN8_NULLBUS;
Wr_En <= '0';
Wr_Data_q <= (others => '0');
Reg_Out <= Default_Value;
Rd_En <= '0';
Rd_Data <= OPEN8_NULLBUS;
elsif( rising_edge( Clock ) )then
Wr_En <= Addr_Match and Wr_Enable;
Wr_Data_q <= Wr_Data;
Wr_En <= Addr_Match and Wr_Enable;
Wr_Data_q <= Wr_Data;
if( Wr_En = '1' )then
Reg_Out <= Wr_Data_q;
Reg_Out <= Wr_Data_q;
end if;
 
Rd_Data <= OPEN8_NULLBUS;
Rd_En <= Addr_Match and Rd_Enable;
Rd_Data <= OPEN8_NULLBUS;
Rd_En <= Addr_Match and Rd_Enable;
if( Rd_En = '1' )then
Rd_Data <= Reg_Out;
Rd_Data <= Reg_Out;
end if;
 
end if;
end process;
 
Register_Out <= Reg_Out;
Register_Out <= Reg_Out;
 
end architecture;
/o8_rom_32k.vhd
34,29 → 34,29
 
entity o8_rom_32k is
generic(
Reset_Level : std_logic;
Address : ADDRESS_TYPE
Reset_Level : std_logic;
Address : ADDRESS_TYPE
);
port(
Clock : in std_logic;
Reset : in std_logic;
Clock : in std_logic;
Reset : in std_logic;
--
Bus_Address : in ADDRESS_TYPE;
Rd_Enable : in std_logic;
Rd_Data : out DATA_TYPE
Bus_Address : in ADDRESS_TYPE;
Rd_Enable : in std_logic;
Rd_Data : out DATA_TYPE
);
end entity;
 
architecture behave of o8_rom_32k is
 
constant User_Addr : std_logic_vector(15 downto 15) :=
Address(15 downto 15);
alias Comp_Addr is Bus_Address(15 downto 15);
alias ROM_Addr is Bus_Address(14 downto 0);
constant User_Addr : std_logic_vector(15 downto 15) :=
Address(15 downto 15);
alias Comp_Addr is Bus_Address(15 downto 15);
alias ROM_Addr is Bus_Address(14 downto 0);
 
signal Addr_Match : std_logic := '0';
signal Rd_En : std_logic := '0';
signal Rd_Data_i : DATA_TYPE := OPEN8_NULLBUS;
signal Addr_Match : std_logic := '0';
signal Rd_En : std_logic := '0';
signal Rd_Data_i : DATA_TYPE := OPEN8_NULLBUS;
 
begin
 
63,23 → 63,23
-- Note that this RAM should be created without an output FF (unregistered Q)
U_ROM_CORE : entity work.rom_32k_core
port map(
address => ROM_Addr,
clock => Clock,
q => Rd_Data_i
address => ROM_Addr,
clock => Clock,
q => Rd_Data_i
);
 
Addr_Match <= Rd_Enable when Comp_Addr = User_Addr else '0';
Addr_Match <= Rd_Enable when Comp_Addr = User_Addr else '0';
 
RAM_proc: process( Reset, Clock )
begin
if( Reset = Reset_Level )then
Rd_En <= '0';
Rd_Data <= OPEN8_NULLBUS;
Rd_En <= '0';
Rd_Data <= OPEN8_NULLBUS;
elsif( rising_edge(Clock) )then
Rd_En <= Addr_Match;
Rd_Data <= OPEN8_NULLBUS;
Rd_En <= Addr_Match;
Rd_Data <= OPEN8_NULLBUS;
if( Rd_En = '1' )then
Rd_Data <= Rd_Data_i;
Rd_Data <= Rd_Data_i;
end if;
end if;
end process;
/o8_rtc.vhd
98,60 → 98,60
signal uSec_Tick_i : std_logic;
 
type PIT_TYPE is record
timer_cnt : DATA_TYPE;
timer_ro : std_logic;
timer_cnt : DATA_TYPE;
timer_ro : std_logic;
end record;
 
signal pit : PIT_TYPE;
signal pit : PIT_TYPE;
 
type RTC_TYPE is record
frac : std_logic_vector(15 downto 0);
frac_ro : std_logic;
frac : std_logic_vector(15 downto 0);
frac_ro : std_logic;
 
tens_l : std_logic_vector(3 downto 0);
tens_l_ro : std_logic;
tens_l : std_logic_vector(3 downto 0);
tens_l_ro : std_logic;
 
tens_u : std_logic_vector(3 downto 0);
tens_u_ro : std_logic;
tens_u : std_logic_vector(3 downto 0);
tens_u_ro : std_logic;
 
secs_l : std_logic_vector(3 downto 0);
secs_l_ro : std_logic;
secs_l : std_logic_vector(3 downto 0);
secs_l_ro : std_logic;
 
secs_u : std_logic_vector(3 downto 0);
secs_u_ro : std_logic;
secs_u : std_logic_vector(3 downto 0);
secs_u_ro : std_logic;
 
mins_l : std_logic_vector(3 downto 0);
mins_l_ro : std_logic;
mins_l : std_logic_vector(3 downto 0);
mins_l_ro : std_logic;
 
mins_u : std_logic_vector(3 downto 0);
mins_u_ro : std_logic;
mins_u : std_logic_vector(3 downto 0);
mins_u_ro : std_logic;
 
hours_l : std_logic_vector(3 downto 0);
hours_l_ro : std_logic;
hours_l : std_logic_vector(3 downto 0);
hours_l_ro : std_logic;
 
hours_u : std_logic_vector(3 downto 0);
hours_u_ro : std_logic;
hours_u : std_logic_vector(3 downto 0);
hours_u_ro : std_logic;
 
dow : std_logic_vector(2 downto 0);
dow : std_logic_vector(2 downto 0);
end record;
 
constant DECISEC : std_logic_vector(15 downto 0) :=
conv_std_logic_vector(10000,16);
constant DECISEC : std_logic_vector(15 downto 0) :=
conv_std_logic_vector(10000,16);
 
signal rtc : RTC_TYPE;
signal rtc : RTC_TYPE;
 
signal interval : DATA_TYPE;
signal update_interval: std_logic;
signal interval : DATA_TYPE;
signal update_interval : std_logic;
 
signal shd_tens : DATA_TYPE;
signal shd_secs : DATA_TYPE;
signal shd_mins : DATA_TYPE;
signal shd_hours : DATA_TYPE;
signal shd_dow : DATA_TYPE;
signal shd_tens : DATA_TYPE;
signal shd_secs : DATA_TYPE;
signal shd_mins : DATA_TYPE;
signal shd_hours : DATA_TYPE;
signal shd_dow : DATA_TYPE;
 
signal update_rtc : std_logic;
signal update_shd : std_logic;
signal update_ctmr : std_logic_vector(3 downto 0);
signal update_rtc : std_logic;
signal update_shd : std_logic;
signal update_ctmr : std_logic_vector(3 downto 0);
 
begin
 
/o8_status_led.vhd
51,70 → 51,70
 
entity o8_status_led is
generic(
Reset_Level : std_logic;
Address : ADDRESS_TYPE
Reset_Level : std_logic;
Address : ADDRESS_TYPE
);
port(
Clock : in std_logic;
Reset : in std_logic;
Clock : in std_logic;
Reset : in std_logic;
--
Bus_Address : in ADDRESS_TYPE;
Wr_Enable : in std_logic;
Wr_Data : in DATA_TYPE;
Rd_Enable : in std_logic;
Rd_Data : out DATA_TYPE;
Bus_Address : in ADDRESS_TYPE;
Wr_Enable : in std_logic;
Wr_Data : in DATA_TYPE;
Rd_Enable : in std_logic;
Rd_Data : out DATA_TYPE;
--
LED_Out : out std_logic
LED_Out : out std_logic
);
end entity;
 
architecture behave of o8_status_led is
 
constant User_Addr : std_logic_vector(15 downto 0)
:= Address(15 downto 0);
alias Comp_Addr is Bus_Address(15 downto 0);
signal Addr_Match : std_logic;
signal Wr_En : std_logic;
signal Wr_Data_q : std_logic_vector(2 downto 0);
signal LED_Mode : std_logic_vector(2 downto 0);
signal Rd_En : std_logic;
constant User_Addr : std_logic_vector(15 downto 0)
:= Address(15 downto 0);
alias Comp_Addr is Bus_Address(15 downto 0);
signal Addr_Match : std_logic;
signal Wr_En : std_logic;
signal Wr_Data_q : std_logic_vector(2 downto 0);
signal LED_Mode : std_logic_vector(2 downto 0);
signal Rd_En : std_logic;
 
signal Dim50Pct_Out : std_logic;
signal Dim50Pct_Out : std_logic;
 
signal Half_Hz_Timer : std_logic_vector(15 downto 0);
constant HALF_HZ_PRD : std_logic_vector(15 downto 0) :=
conv_std_logic_vector(500000,16);
signal One_Hz_Out : std_logic;
signal Half_Hz_Timer : std_logic_vector(15 downto 0);
constant HALF_HZ_PRD : std_logic_vector(15 downto 0) :=
conv_std_logic_vector(500000,16);
signal One_Hz_Out : std_logic;
 
constant TIMER_MSB : integer range 9 to 20 := 18;
constant TIMER_MSB : integer range 9 to 20 := 18;
 
signal Fade_Timer1 : std_logic_vector(TIMER_MSB downto 0);
signal Fade_Timer2 : std_logic_vector(TIMER_MSB downto 0);
signal Fade_Out : std_logic;
signal Fade_Timer1 : std_logic_vector(TIMER_MSB downto 0);
signal Fade_Timer2 : std_logic_vector(TIMER_MSB downto 0);
signal Fade_Out : std_logic;
 
begin
 
Addr_Match <= '1' when Comp_Addr = User_Addr else '0';
Addr_Match <= '1' when Comp_Addr = User_Addr else '0';
 
io_reg: process( Clock, Reset )
begin
if( Reset = Reset_Level )then
Wr_En <= '0';
Wr_Data_q <= (others => '0');
LED_Mode <= (others => '0');
Rd_En <= '0';
Rd_Data <= OPEN8_NULLBUS;
Wr_En <= '0';
Wr_Data_q <= (others => '0');
LED_Mode <= (others => '0');
Rd_En <= '0';
Rd_Data <= OPEN8_NULLBUS;
elsif( rising_edge( Clock ) )then
Wr_En <= Addr_Match and Wr_Enable;
Wr_Data_q <= Wr_Data(2 downto 0);
Wr_En <= Addr_Match and Wr_Enable;
Wr_Data_q <= Wr_Data(2 downto 0);
if( Wr_En = '1' )then
LED_Mode <= Wr_Data_q;
LED_Mode <= Wr_Data_q;
end if;
 
Rd_Data <= OPEN8_NULLBUS;
Rd_En <= Addr_Match and Rd_Enable;
Rd_Data <= OPEN8_NULLBUS;
Rd_En <= Addr_Match and Rd_Enable;
if( Rd_En = '1' )then
Rd_Data <= "00000" & LED_Mode;
Rd_Data <= "00000" & LED_Mode;
end if;
 
end if;
123,18 → 123,18
Output_FF: process( Clock, Reset )
begin
if( Reset = Reset_Level )then
LED_Out <= '0';
LED_Out <= '0';
elsif( rising_edge(Clock) )then
LED_Out <= '0';
LED_Out <= '0';
case( LED_Mode )is
when "001" =>
LED_Out <= '1';
LED_Out <= '1';
when "010" =>
LED_Out <= Dim50Pct_Out;
LED_Out <= Dim50Pct_Out;
when "011" =>
LED_Out <= One_Hz_Out;
LED_Out <= One_Hz_Out;
when "100" =>
LED_Out <= Fade_out;
LED_Out <= Fade_out;
when others => null;
end case;
end if;
143,28 → 143,29
Timer_proc: process( Clock, Reset )
begin
if( Reset = Reset_Level )then
Dim50Pct_Out <= '0';
Half_Hz_Timer <= (others => '0');
One_Hz_Out <= '0';
Fade_Timer1 <= (others => '0');
Fade_Timer2 <= (others => '0');
Fade_out <= '0';
Dim50Pct_Out <= '0';
Half_Hz_Timer <= (others => '0');
One_Hz_Out <= '0';
Fade_Timer1 <= (others => '0');
Fade_Timer2 <= (others => '0');
Fade_out <= '0';
elsif( rising_edge(Clock) )then
Dim50Pct_Out <= not Dim50Pct_Out;
Dim50Pct_Out <= not Dim50Pct_Out;
 
Half_Hz_Timer <= Half_Hz_Timer - 1;
Half_Hz_Timer <= Half_Hz_Timer - 1;
if( Half_Hz_Timer = 0 )then
Half_Hz_Timer <= HALF_HZ_PRD;
One_Hz_Out <= not One_Hz_Out;
Half_Hz_Timer <= HALF_HZ_PRD;
One_Hz_Out <= not One_Hz_Out;
end if;
 
Fade_Timer1 <= Fade_Timer1 - 1;
Fade_Timer2 <= Fade_Timer2 - 1;
Fade_Timer1 <= Fade_Timer1 - 1;
Fade_Timer2 <= Fade_Timer2 - 1;
if( or_reduce(Fade_Timer2) = '0' )then
Fade_Timer2(TIMER_MSB downto TIMER_MSB - 8) <= (others => '1');
Fade_Timer2(TIMER_MSB - 9 downto 0 ) <= (others => '0');
end if;
Fade_out <= Fade_Timer1(TIMER_MSB) xor Fade_Timer2(TIMER_MSB);
Fade_out <= Fade_Timer1(TIMER_MSB) xor
Fade_Timer2(TIMER_MSB);
end if;
end process;
 
/o8_vdsm12.vhd
47,188 → 47,188
 
entity o8_vdsm12 is
generic(
Reset_Level : std_logic := '1';
Address : ADDRESS_TYPE
Reset_Level : std_logic := '1';
Address : ADDRESS_TYPE
);
port(
Clock : in std_logic;
Reset : in std_logic;
Clock : in std_logic;
Reset : in std_logic;
--
Bus_Address : in ADDRESS_TYPE;
Wr_Enable : in std_logic;
Wr_Data : in DATA_TYPE;
Rd_Enable : in std_logic;
Rd_Data : out DATA_TYPE;
Bus_Address : in ADDRESS_TYPE;
Wr_Enable : in std_logic;
Wr_Data : in DATA_TYPE;
Rd_Enable : in std_logic;
Rd_Data : out DATA_TYPE;
--
PDM_Out : out std_logic
PDM_Out : out std_logic
);
end entity;
 
architecture behave of o8_vdsm12 is
 
constant User_Addr : std_logic_vector(15 downto 2)
:= Address(15 downto 2);
alias Comp_Addr is Bus_Address(15 downto 2);
alias Reg_Addr is Bus_Address(1 downto 0);
signal Reg_Sel : std_logic_vector(1 downto 0) := "00";
signal Addr_Match : std_logic := '0';
signal Wr_En : std_logic := '0';
signal Wr_Data_q : DATA_TYPE := x"00";
signal Rd_En : std_logic := '0';
constant User_Addr : std_logic_vector(15 downto 2)
:= Address(15 downto 2);
alias Comp_Addr is Bus_Address(15 downto 2);
alias Reg_Addr is Bus_Address(1 downto 0);
signal Reg_Sel : std_logic_vector(1 downto 0) := "00";
signal Addr_Match : std_logic := '0';
signal Wr_En : std_logic := '0';
signal Wr_Data_q : DATA_TYPE := x"00";
signal Rd_En : std_logic := '0';
 
constant DAC_Width : integer := 12;
constant DAC_Width : integer := 12;
 
signal DAC_Val_LB : std_logic_vector(7 downto 0) := x"00";
signal DAC_Val_UB : std_logic_vector(3 downto 0) := x"0";
signal DAC_Val : std_logic_vector(DAC_Width-1 downto 0) :=
(others => '0');
signal DAC_Val_LB : std_logic_vector(7 downto 0) := x"00";
signal DAC_Val_UB : std_logic_vector(3 downto 0) := x"0";
signal DAC_Val : std_logic_vector(DAC_Width-1 downto 0) :=
(others => '0');
 
constant DELTA_1_I : integer := 1;
constant DELTA_2_I : integer := 5;
constant DELTA_3_I : integer := 25;
constant DELTA_4_I : integer := 75;
constant DELTA_5_I : integer := 125;
constant DELTA_6_I : integer := 250;
constant DELTA_7_I : integer := 500;
constant DELTA_8_I : integer := 1000;
constant DELTA_9_I : integer := 2000;
constant DELTA_10_I : integer := 3000;
constant DELTA_1_I : integer := 1;
constant DELTA_2_I : integer := 5;
constant DELTA_3_I : integer := 25;
constant DELTA_4_I : integer := 75;
constant DELTA_5_I : integer := 125;
constant DELTA_6_I : integer := 250;
constant DELTA_7_I : integer := 500;
constant DELTA_8_I : integer := 1000;
constant DELTA_9_I : integer := 2000;
constant DELTA_10_I : integer := 3000;
 
constant DELTA_1 : std_logic_vector(DAC_Width-1 downto 0) :=
conv_std_logic_vector(DELTA_1_I, DAC_Width);
constant DELTA_2 : std_logic_vector(DAC_Width-1 downto 0) :=
conv_std_logic_vector(DELTA_2_I, DAC_Width);
constant DELTA_3 : std_logic_vector(DAC_Width-1 downto 0) :=
conv_std_logic_vector(DELTA_3_I, DAC_Width);
constant DELTA_4 : std_logic_vector(DAC_Width-1 downto 0) :=
conv_std_logic_vector(DELTA_4_I, DAC_Width);
constant DELTA_5 : std_logic_vector(DAC_Width-1 downto 0) :=
conv_std_logic_vector(DELTA_5_I, DAC_Width);
constant DELTA_6 : std_logic_vector(DAC_Width-1 downto 0) :=
conv_std_logic_vector(DELTA_6_I, DAC_Width);
constant DELTA_7 : std_logic_vector(DAC_Width-1 downto 0) :=
conv_std_logic_vector(DELTA_7_I, DAC_Width);
constant DELTA_8 : std_logic_vector(DAC_Width-1 downto 0) :=
conv_std_logic_vector(DELTA_8_I, DAC_Width);
constant DELTA_9 : std_logic_vector(DAC_Width-1 downto 0) :=
conv_std_logic_vector(DELTA_9_I, DAC_Width);
constant DELTA_10 : std_logic_vector(DAC_Width-1 downto 0) :=
conv_std_logic_vector(DELTA_10_I, DAC_Width);
constant DELTA_1 : std_logic_vector(DAC_Width-1 downto 0) :=
conv_std_logic_vector(DELTA_1_I, DAC_Width);
constant DELTA_2 : std_logic_vector(DAC_Width-1 downto 0) :=
conv_std_logic_vector(DELTA_2_I, DAC_Width);
constant DELTA_3 : std_logic_vector(DAC_Width-1 downto 0) :=
conv_std_logic_vector(DELTA_3_I, DAC_Width);
constant DELTA_4 : std_logic_vector(DAC_Width-1 downto 0) :=
conv_std_logic_vector(DELTA_4_I, DAC_Width);
constant DELTA_5 : std_logic_vector(DAC_Width-1 downto 0) :=
conv_std_logic_vector(DELTA_5_I, DAC_Width);
constant DELTA_6 : std_logic_vector(DAC_Width-1 downto 0) :=
conv_std_logic_vector(DELTA_6_I, DAC_Width);
constant DELTA_7 : std_logic_vector(DAC_Width-1 downto 0) :=
conv_std_logic_vector(DELTA_7_I, DAC_Width);
constant DELTA_8 : std_logic_vector(DAC_Width-1 downto 0) :=
conv_std_logic_vector(DELTA_8_I, DAC_Width);
constant DELTA_9 : std_logic_vector(DAC_Width-1 downto 0) :=
conv_std_logic_vector(DELTA_9_I, DAC_Width);
constant DELTA_10 : std_logic_vector(DAC_Width-1 downto 0) :=
conv_std_logic_vector(DELTA_10_I, DAC_Width);
 
constant MAX_PERIOD : integer := 2**DAC_Width;
constant DIV_WIDTH : integer := DAC_Width * 2;
constant MAX_PERIOD : integer := 2**DAC_Width;
constant DIV_WIDTH : integer := DAC_Width * 2;
 
constant PADJ_1_I : integer := DELTA_1_I * MAX_PERIOD;
constant PADJ_2_I : integer := DELTA_2_I * MAX_PERIOD;
constant PADJ_3_I : integer := DELTA_3_I * MAX_PERIOD;
constant PADJ_4_I : integer := DELTA_4_I * MAX_PERIOD;
constant PADJ_5_I : integer := DELTA_5_I * MAX_PERIOD;
constant PADJ_6_I : integer := DELTA_6_I * MAX_PERIOD;
constant PADJ_7_I : integer := DELTA_7_I * MAX_PERIOD;
constant PADJ_8_I : integer := DELTA_8_I * MAX_PERIOD;
constant PADJ_9_I : integer := DELTA_9_I * MAX_PERIOD;
constant PADJ_10_I : integer := DELTA_10_I * MAX_PERIOD;
constant PADJ_1_I : integer := DELTA_1_I * MAX_PERIOD;
constant PADJ_2_I : integer := DELTA_2_I * MAX_PERIOD;
constant PADJ_3_I : integer := DELTA_3_I * MAX_PERIOD;
constant PADJ_4_I : integer := DELTA_4_I * MAX_PERIOD;
constant PADJ_5_I : integer := DELTA_5_I * MAX_PERIOD;
constant PADJ_6_I : integer := DELTA_6_I * MAX_PERIOD;
constant PADJ_7_I : integer := DELTA_7_I * MAX_PERIOD;
constant PADJ_8_I : integer := DELTA_8_I * MAX_PERIOD;
constant PADJ_9_I : integer := DELTA_9_I * MAX_PERIOD;
constant PADJ_10_I : integer := DELTA_10_I * MAX_PERIOD;
 
constant PADJ_1 : std_logic_vector(DIV_WIDTH-1 downto 0) :=
conv_std_logic_vector(PADJ_1_I,DIV_WIDTH);
constant PADJ_2 : std_logic_vector(DIV_WIDTH-1 downto 0) :=
conv_std_logic_vector(PADJ_2_I,DIV_WIDTH);
constant PADJ_3 : std_logic_vector(DIV_WIDTH-1 downto 0) :=
conv_std_logic_vector(PADJ_3_I,DIV_WIDTH);
constant PADJ_4 : std_logic_vector(DIV_WIDTH-1 downto 0) :=
conv_std_logic_vector(PADJ_4_I,DIV_WIDTH);
constant PADJ_5 : std_logic_vector(DIV_WIDTH-1 downto 0) :=
conv_std_logic_vector(PADJ_5_I,DIV_WIDTH);
constant PADJ_6 : std_logic_vector(DIV_WIDTH-1 downto 0) :=
conv_std_logic_vector(PADJ_6_I,DIV_WIDTH);
constant PADJ_7 : std_logic_vector(DIV_WIDTH-1 downto 0) :=
conv_std_logic_vector(PADJ_7_I,DIV_WIDTH);
constant PADJ_8 : std_logic_vector(DIV_WIDTH-1 downto 0) :=
conv_std_logic_vector(PADJ_8_I,DIV_WIDTH);
constant PADJ_9 : std_logic_vector(DIV_WIDTH-1 downto 0) :=
conv_std_logic_vector(PADJ_9_I,DIV_WIDTH);
constant PADJ_10 : std_logic_vector(DIV_WIDTH-1 downto 0) :=
conv_std_logic_vector(PADJ_10_I,DIV_WIDTH);
constant PADJ_1 : std_logic_vector(DIV_WIDTH-1 downto 0) :=
conv_std_logic_vector(PADJ_1_I,DIV_WIDTH);
constant PADJ_2 : std_logic_vector(DIV_WIDTH-1 downto 0) :=
conv_std_logic_vector(PADJ_2_I,DIV_WIDTH);
constant PADJ_3 : std_logic_vector(DIV_WIDTH-1 downto 0) :=
conv_std_logic_vector(PADJ_3_I,DIV_WIDTH);
constant PADJ_4 : std_logic_vector(DIV_WIDTH-1 downto 0) :=
conv_std_logic_vector(PADJ_4_I,DIV_WIDTH);
constant PADJ_5 : std_logic_vector(DIV_WIDTH-1 downto 0) :=
conv_std_logic_vector(PADJ_5_I,DIV_WIDTH);
constant PADJ_6 : std_logic_vector(DIV_WIDTH-1 downto 0) :=
conv_std_logic_vector(PADJ_6_I,DIV_WIDTH);
constant PADJ_7 : std_logic_vector(DIV_WIDTH-1 downto 0) :=
conv_std_logic_vector(PADJ_7_I,DIV_WIDTH);
constant PADJ_8 : std_logic_vector(DIV_WIDTH-1 downto 0) :=
conv_std_logic_vector(PADJ_8_I,DIV_WIDTH);
constant PADJ_9 : std_logic_vector(DIV_WIDTH-1 downto 0) :=
conv_std_logic_vector(PADJ_9_I,DIV_WIDTH);
constant PADJ_10 : std_logic_vector(DIV_WIDTH-1 downto 0) :=
conv_std_logic_vector(PADJ_10_I,DIV_WIDTH);
 
signal DACin_q : std_logic_vector(DAC_Width-1 downto 0) :=
(others => '0');
signal DACin_q : std_logic_vector(DAC_Width-1 downto 0) :=
(others => '0');
 
signal Divisor : std_logic_vector(DIV_WIDTH-1 downto 0) :=
(others => '0');
signal Divisor : std_logic_vector(DIV_WIDTH-1 downto 0) :=
(others => '0');
 
signal Dividend : std_logic_vector(DIV_WIDTH-1 downto 0) :=
(others => '0');
signal Dividend : std_logic_vector(DIV_WIDTH-1 downto 0) :=
(others => '0');
 
signal q : std_logic_vector(DIV_WIDTH*2-1 downto 0) :=
(others => '0');
signal q : std_logic_vector(DIV_WIDTH*2-1 downto 0) :=
(others => '0');
 
signal diff : std_logic_vector(DIV_WIDTH downto 0) :=
(others => '0');
signal diff : std_logic_vector(DIV_WIDTH downto 0) :=
(others => '0');
 
constant CB : integer := ceil_log2(DIV_WIDTH);
signal count : std_logic_vector(CB-1 downto 0) :=
(others => '0');
constant CB : integer := ceil_log2(DIV_WIDTH);
signal count : std_logic_vector(CB-1 downto 0) :=
(others => '0');
 
signal Next_Width : std_logic_vector(DAC_Width-1 downto 0) :=
(others => '0');
signal Next_Width : std_logic_vector(DAC_Width-1 downto 0) :=
(others => '0');
 
signal Next_Period : std_logic_vector(DAC_Width-1 downto 0) :=
(others => '0');
signal Next_Period : std_logic_vector(DAC_Width-1 downto 0) :=
(others => '0');
 
signal PWM_Width : std_logic_vector(DAC_Width-1 downto 0) :=
(others => '0');
signal PWM_Width : std_logic_vector(DAC_Width-1 downto 0) :=
(others => '0');
 
signal PWM_Period : std_logic_vector(DAC_Width-1 downto 0) :=
(others => '0');
signal PWM_Period : std_logic_vector(DAC_Width-1 downto 0) :=
(others => '0');
 
signal Width_Ctr : std_logic_vector(DAC_Width-1 downto 0) :=
(others => '0');
signal Width_Ctr : std_logic_vector(DAC_Width-1 downto 0) :=
(others => '0');
 
signal Period_Ctr : std_logic_vector(DAC_Width-1 downto 0) :=
(others => '0');
signal Period_Ctr : std_logic_vector(DAC_Width-1 downto 0) :=
(others => '0');
 
begin
 
Addr_Match <= '1' when Comp_Addr = User_Addr else '0';
Addr_Match <= '1' when Comp_Addr = User_Addr else '0';
 
io_reg: process( Clock, Reset )
begin
if( Reset = Reset_Level )then
Reg_Sel <= "00";
Rd_En <= '0';
Rd_Data <= OPEN8_NULLBUS;
Wr_En <= '0';
Wr_Data_q <= x"00";
DAC_Val_LB <= x"00";
DAC_Val_UB <= x"0";
DAC_Val <= (others => '0');
Reg_Sel <= "00";
Rd_En <= '0';
Rd_Data <= OPEN8_NULLBUS;
Wr_En <= '0';
Wr_Data_q <= x"00";
DAC_Val_LB <= x"00";
DAC_Val_UB <= x"0";
DAC_Val <= (others => '0');
elsif( rising_edge( Clock ) )then
Reg_Sel <= Reg_Addr;
Reg_Sel <= Reg_Addr;
 
Wr_En <= Addr_Match and Wr_Enable;
Wr_Data_q <= Wr_Data;
Wr_En <= Addr_Match and Wr_Enable;
Wr_Data_q <= Wr_Data;
if( Wr_En = '1' )then
case( Reg_Sel )is
when "00" =>
DAC_Val_LB <= Wr_Data_q;
DAC_Val_LB <= Wr_Data_q;
when "01" =>
DAC_Val_UB <= Wr_Data_q(3 downto 0);
DAC_Val_UB <= Wr_Data_q(3 downto 0);
when "10" =>
DAC_Val <= (others => '0');
DAC_Val <= (others => '0');
when "11" =>
DAC_Val <= DAC_Val_UB & DAC_Val_LB;
DAC_Val <= DAC_Val_UB & DAC_Val_LB;
when others => null;
end case;
end if;
 
Rd_Data <= OPEN8_NULLBUS;
Rd_En <= Addr_Match and Rd_Enable;
Rd_Data <= OPEN8_NULLBUS;
Rd_En <= Addr_Match and Rd_Enable;
if( Rd_En = '1' )then
case( Reg_Sel )is
when "00" =>
Rd_Data <= DAC_Val_LB;
Rd_Data <= DAC_Val_LB;
when "01" =>
Rd_Data <= x"0" & DAC_Val_UB;
Rd_Data <= x"0" & DAC_Val_UB;
when others => null;
end case;
end if;
235,8 → 235,8
end if;
end process;
 
diff <= ('0' & q(DIV_WIDTH*2-2 downto DIV_WIDTH-1)) -
('0' & Divisor);
diff <= ('0' & q(DIV_WIDTH*2-2 downto DIV_WIDTH-1)) -
('0' & Divisor);
 
Dividend <= PADJ_2 when DACin_q >= DELTA_2_I and DACin_q < DELTA_3_I else
PADJ_3 when DACin_q >= DELTA_3_I and DACin_q < DELTA_4_I else
261,50 → 261,50
DELTA_10 when DACin_q >= DELTA_10_I else
(others => '0');
 
Next_Period <= q(DAC_Width-1 downto 0) - 1;
Next_Period <= q(DAC_Width-1 downto 0) - 1;
 
vDSM_proc: process( Clock, Reset )
begin
if( Reset = Reset_Level )then
q <= (others => '0');
count <= (others => '1');
Divisor <= (others => '0');
DACin_q <= (others => '0');
PWM_Width <= (others => '0');
PWM_Period <= (others => '0');
Period_Ctr <= (others => '0');
Width_Ctr <= (others => '0');
PDM_Out <= '0';
q <= (others => '0');
count <= (others => '1');
Divisor <= (others => '0');
DACin_q <= (others => '0');
PWM_Width <= (others => '0');
PWM_Period <= (others => '0');
Period_Ctr <= (others => '0');
Width_Ctr <= (others => '0');
PDM_Out <= '0';
elsif( rising_edge(Clock) )then
q <= diff(DIV_WIDTH-1 downto 0) &
q(DIV_WIDTH-2 downto 0) & '1';
q <= diff(DIV_WIDTH-1 downto 0) &
q(DIV_WIDTH-2 downto 0) & '1';
if( diff(DIV_WIDTH) = '1' )then
q <= q(DIV_WIDTH*2-2 downto 0) & '0';
q <= q(DIV_WIDTH*2-2 downto 0) & '0';
end if;
 
count <= count + 1;
count <= count + 1;
if( count = DIV_WIDTH )then
PWM_Width <= Next_Width;
PWM_Period <= Next_Period;
DACin_q <= DAC_val;
Divisor <= (others => '0');
PWM_Width <= Next_Width;
PWM_Period <= Next_Period;
DACin_q <= DAC_val;
Divisor <= (others => '0');
Divisor(DAC_Width-1 downto 0) <= DACin_q;
q <= conv_std_logic_vector(0,DIV_WIDTH) & Dividend;
count <= (others => '0');
q <= conv_std_logic_vector(0,DIV_WIDTH) & Dividend;
count <= (others => '0');
end if;
 
Period_Ctr <= Period_Ctr - 1;
Width_Ctr <= Width_Ctr - 1;
Period_Ctr <= Period_Ctr - 1;
Width_Ctr <= Width_Ctr - 1;
 
PDM_Out <= '1';
PDM_Out <= '1';
if( Width_Ctr = 0 )then
PDM_Out <= '0';
Width_Ctr <= (others => '0');
PDM_Out <= '0';
Width_Ctr <= (others => '0');
end if;
 
if( Period_Ctr = 0 )then
Period_Ctr <= PWM_Period;
Width_Ctr <= PWM_Width;
Period_Ctr <= PWM_Period;
Width_Ctr <= PWM_Width;
end if;
 
end if;
/o8_vdsm8.vhd
22,7 → 22,7
-- THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
--
-- VHDL Units : o8_vdsm8
-- Description: 8-bit variable delta-sigma modulator. Requires Open8_pkg.vhd
-- Description: 8-bit variable delta-sigma modulator.
--
-- Revision History
-- Author Date Change
40,199 → 40,70
 
entity o8_vdsm8 is
generic(
Reset_Level : std_logic;
Address : ADDRESS_TYPE
Reset_Level : std_logic;
Address : ADDRESS_TYPE
);
port(
Clock : in std_logic;
Reset : in std_logic;
Clock : in std_logic;
Reset : in std_logic;
--
Bus_Address : in ADDRESS_TYPE;
Wr_Enable : in std_logic;
Wr_Data : in DATA_TYPE;
Rd_Enable : in std_logic;
Rd_Data : out DATA_TYPE;
Bus_Address : in ADDRESS_TYPE;
Wr_Enable : in std_logic;
Wr_Data : in DATA_TYPE;
Rd_Enable : in std_logic;
Rd_Data : out DATA_TYPE;
--
DACout : out std_logic
DACout : out std_logic
);
end entity;
 
architecture behave of o8_vdsm8 is
 
constant User_Addr : std_logic_vector(15 downto 0) := Address;
alias Comp_Addr is Bus_Address(15 downto 0);
signal Addr_Match : std_logic := '0';
signal Wr_En : std_logic := '0';
signal Wr_Data_q : DATA_TYPE := x"00";
signal Rd_En : std_logic := '0';
signal DACin : DATA_TYPE := x"00";
constant User_Addr : std_logic_vector(15 downto 0) := Address;
alias Comp_Addr is Bus_Address(15 downto 0);
signal Addr_Match : std_logic := '0';
signal Wr_En : std_logic := '0';
signal Wr_Data_q : DATA_TYPE := x"00";
signal Rd_En : std_logic := '0';
signal DACin : DATA_TYPE := x"00";
 
-- DAC WIDTH = 8 is fixed, with all constants normalized
-- against 256 (the MAX PERIOD)
 
constant DAC_WIDTH : integer := 8;
 
constant DELTA_1_I : integer := 1;
constant DELTA_2_I : integer := 5;
constant DELTA_3_I : integer := 25;
constant DELTA_4_I : integer := 75;
constant DELTA_5_I : integer := 125;
constant DELTA_6_I : integer := 195;
 
constant DELTA_1 : std_logic_vector(DAC_WIDTH - 1 downto 0) :=
conv_std_logic_vector(DELTA_1_I, DAC_WIDTH);
constant DELTA_2 : std_logic_vector(DAC_WIDTH - 1 downto 0) :=
conv_std_logic_vector(DELTA_2_I, DAC_WIDTH);
constant DELTA_3 : std_logic_vector(DAC_WIDTH - 1 downto 0) :=
conv_std_logic_vector(DELTA_3_I, DAC_WIDTH);
constant DELTA_4 : std_logic_vector(DAC_WIDTH - 1 downto 0) :=
conv_std_logic_vector(DELTA_4_I, DAC_WIDTH);
constant DELTA_5 : std_logic_vector(DAC_WIDTH - 1 downto 0) :=
conv_std_logic_vector(DELTA_5_I, DAC_WIDTH);
constant DELTA_6 : std_logic_vector(DAC_WIDTH - 1 downto 0) :=
conv_std_logic_vector(DELTA_6_I, DAC_WIDTH);
 
constant MAX_PERIOD : integer := 2**DAC_WIDTH;
constant DIV_WIDTH : integer := 2 * DAC_WIDTH;
 
constant PADJ_1_I : integer := DELTA_1_I * MAX_PERIOD;
constant PADJ_2_I : integer := DELTA_2_I * MAX_PERIOD;
constant PADJ_3_I : integer := DELTA_3_I * MAX_PERIOD;
constant PADJ_4_I : integer := DELTA_4_I * MAX_PERIOD;
constant PADJ_5_I : integer := DELTA_5_I * MAX_PERIOD;
constant PADJ_6_I : integer := DELTA_6_I * MAX_PERIOD;
 
constant PADJ_1 : std_logic_vector(DIV_WIDTH-1 downto 0) :=
conv_std_logic_vector(PADJ_1_I,DIV_WIDTH);
constant PADJ_2 : std_logic_vector(DIV_WIDTH-1 downto 0) :=
conv_std_logic_vector(PADJ_2_I,DIV_WIDTH);
constant PADJ_3 : std_logic_vector(DIV_WIDTH-1 downto 0) :=
conv_std_logic_vector(PADJ_3_I,DIV_WIDTH);
constant PADJ_4 : std_logic_vector(DIV_WIDTH-1 downto 0) :=
conv_std_logic_vector(PADJ_4_I,DIV_WIDTH);
constant PADJ_5 : std_logic_vector(DIV_WIDTH-1 downto 0) :=
conv_std_logic_vector(PADJ_5_I,DIV_WIDTH);
constant PADJ_6 : std_logic_vector(DIV_WIDTH-1 downto 0) :=
conv_std_logic_vector(PADJ_6_I,DIV_WIDTH);
 
signal DACin_q : DATA_TYPE := x"00";
 
signal Divisor : std_logic_vector(DIV_WIDTH-1 downto 0) :=
(others => '0');
signal Dividend : std_logic_vector(DIV_WIDTH-1 downto 0) :=
(others => '0');
 
signal q : std_logic_vector(DIV_WIDTH*2-1 downto 0) :=
(others => '0');
 
signal diff : std_logic_vector(DIV_WIDTH downto 0) :=
(others => '0');
 
constant CB : integer := ceil_log2(DIV_WIDTH);
signal count : std_logic_vector(CB-1 downto 0) :=
(others => '0');
 
signal Next_Width : DATA_TYPE := x"00";
signal Next_Period : DATA_TYPE := x"00";
 
signal PWM_Width : DATA_TYPE := x"00";
signal PWM_Period : DATA_TYPE := x"00";
 
signal Width_Ctr : DATA_TYPE := x"00";
signal Period_Ctr : DATA_TYPE := x"00";
 
begin
 
Addr_Match <= '1' when Comp_Addr = User_Addr else '0';
Addr_Match <= '1' when Comp_Addr = User_Addr else '0';
 
io_reg: process( Clock, Reset )
begin
if( Reset = Reset_Level )then
Wr_En <= '0';
Wr_Data_q <= x"00";
Rd_En <= '0';
Rd_Data <= OPEN8_NULLBUS;
DACin <= x"00";
Wr_En <= '0';
Wr_Data_q <= x"00";
Rd_En <= '0';
Rd_Data <= OPEN8_NULLBUS;
DACin <= x"00";
elsif( rising_edge( Clock ) )then
Wr_En <= Addr_Match and Wr_Enable;
Wr_Data_q <= Wr_Data;
Wr_En <= Addr_Match and Wr_Enable;
Wr_Data_q <= Wr_Data;
if( Wr_En = '1' )then
DACin <= Wr_Data_q;
DACin <= Wr_Data_q;
end if;
 
Rd_Data <= OPEN8_NULLBUS;
Rd_En <= Addr_Match and Rd_Enable;
Rd_Data <= OPEN8_NULLBUS;
Rd_En <= Addr_Match and Rd_Enable;
if( Rd_En = '1' )then
Rd_Data <= DACin;
Rd_Data <= DACin;
end if;
end if;
end process;
 
diff <= ('0' & q(DIV_WIDTH*2-2 downto DIV_WIDTH-1)) -
('0' & Divisor);
U_DAC : entity work.vdsm8
generic map(
Reset_Level => Reset_Level
)
port map(
Clock => Clock,
Reset => Reset,
DACin => DACin,
DACout => DACout
);
 
Dividend <= PADJ_2 when DACin_q >= DELTA_2_I and DACin_q < DELTA_3_I else
PADJ_3 when DACin_q >= DELTA_3_I and DACin_q < DELTA_4_I else
PADJ_4 when DACin_q >= DELTA_4_I and DACin_q < DELTA_5_I else
PADJ_5 when DACin_q >= DELTA_5_I and DACin_q < DELTA_6_I else
PADJ_6 when DACin_q >= DELTA_6_I else
PADJ_1;
 
Next_Width <= DELTA_1 when DACin_q >= DELTA_1_I and DACin_q < DELTA_2_I else
DELTA_2 when DACin_q >= DELTA_2_I and DACin_q < DELTA_3_I else
DELTA_3 when DACin_q >= DELTA_3_I and DACin_q < DELTA_4_I else
DELTA_4 when DACin_q >= DELTA_4_I and DACin_q < DELTA_5_I else
DELTA_5 when DACin_q >= DELTA_5_I and DACin_q < DELTA_6_I else
DELTA_6 when DACin_q >= DELTA_6_I else
(others => '0');
 
Next_Period <= q(7 downto 0) - 1;
 
vDSM_proc: process( Clock, Reset )
begin
if( Reset = Reset_Level )then
q <= (others => '0');
count <= (others => '1');
Divisor <= (others => '0');
DACin_q <= (others => '0');
PWM_Width <= (others => '0');
PWM_Period <= (others => '0');
Period_Ctr <= (others => '0');
Width_Ctr <= (others => '0');
DACout <= '0';
elsif( rising_edge(Clock) )then
q <= diff(DIV_WIDTH-1 downto 0) &
q(DIV_WIDTH-2 downto 0) & '1';
if( diff(DIV_WIDTH) = '1' )then
q <= q(DIV_WIDTH*2-2 downto 0) & '0';
end if;
 
count <= count + 1;
if( count = DIV_WIDTH )then
PWM_Width <= Next_Width;
PWM_Period <= Next_Period;
DACin_q <= DACin;
Divisor <= (others => '0');
Divisor(7 downto 0) <= DACin_q;
q <= conv_std_logic_vector(0,DIV_WIDTH) & Dividend;
count <= (others => '0');
end if;
 
Period_Ctr <= Period_Ctr - 1;
Width_Ctr <= Width_Ctr - 1;
 
DACout <= '1';
if( Width_Ctr = 0 )then
DACout <= '0';
Width_Ctr <= (others => '0');
end if;
 
if( Period_Ctr = 0 )then
Period_Ctr <= PWM_Period;
Width_Ctr <= PWM_Width;
end if;
 
end if;
end process;
 
end architecture;
/sdlc_serial_pkg.vhd
27,10 → 27,10
 
package sdlc_serial_pkg is
 
subtype DATA_IN_TYPE is std_logic_vector(7 downto 0);
subtype CRC_OUT_TYPE is std_logic_vector(15 downto 0);
subtype DATA_IN_TYPE is std_logic_vector(7 downto 0);
subtype CRC_OUT_TYPE is std_logic_vector(15 downto 0);
 
constant SDLC_Flag : DATA_IN_TYPE := x"7E";
constant SDLC_Flag : DATA_IN_TYPE := x"7E";
 
function ceil_log2 (x : in natural) return natural;
 

powered by: WebSVN 2.1.0

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