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; |
|