mirror of
https://github.com/stnolting/neorv32.git
synced 2025-04-24 06:07:52 -04:00
[rtl] update ONEWIRE module
🐛 fixing a regressions: busy signal was stuck at zero
This commit is contained in:
parent
d307bf5fa1
commit
8da24440c6
1 changed files with 183 additions and 107 deletions
|
@ -16,6 +16,9 @@ library neorv32;
|
|||
use neorv32.neorv32_package.all;
|
||||
|
||||
entity neorv32_onewire is
|
||||
generic (
|
||||
ONEWIRE_FIFO : natural range 1 to 2**15 -- RTX fifo depth, has to be a power of two, min 1
|
||||
);
|
||||
port (
|
||||
clk_i : in std_ulogic; -- global clock line
|
||||
rstn_i : in std_ulogic; -- global reset line, low-active
|
||||
|
@ -25,13 +28,14 @@ entity neorv32_onewire is
|
|||
clkgen_i : in std_ulogic_vector(7 downto 0);
|
||||
onewire_i : in std_ulogic; -- 1-wire line state
|
||||
onewire_o : out std_ulogic; -- 1-wire line pull-down
|
||||
irq_o : out std_ulogic -- transfer done IRQ
|
||||
irq_o : out std_ulogic -- transfer done IRQ
|
||||
);
|
||||
end neorv32_onewire;
|
||||
|
||||
architecture neorv32_onewire_rtl of neorv32_onewire is
|
||||
|
||||
-- timing configuration (absolute time in multiples of the base tick time t_base) --
|
||||
-- timing configuration (known-good, no need to change) --
|
||||
-- absolute time in multiples of the base tick time t_base; see data sheet for more information about the t* timing values
|
||||
constant t_write_one_c : unsigned(6 downto 0) := to_unsigned( 1, 7); -- t0
|
||||
constant t_read_sample_c : unsigned(6 downto 0) := to_unsigned( 2, 7); -- t1
|
||||
constant t_slot_end_c : unsigned(6 downto 0) := to_unsigned( 7, 7); -- t2
|
||||
|
@ -39,40 +43,62 @@ architecture neorv32_onewire_rtl of neorv32_onewire is
|
|||
constant t_reset_end_c : unsigned(6 downto 0) := to_unsigned(48, 7); -- t4
|
||||
constant t_presence_sample_c : unsigned(6 downto 0) := to_unsigned(55, 7); -- t5
|
||||
constant t_presence_end_c : unsigned(6 downto 0) := to_unsigned(96, 7); -- t6
|
||||
-- -> see data sheet for more information about the t* timing values --
|
||||
|
||||
-- control register --
|
||||
constant ctrl_en_c : natural := 0; -- r/w: TWI enable
|
||||
constant ctrl_prsc0_c : natural := 1; -- r/w: prescaler select bit 0
|
||||
constant ctrl_prsc1_c : natural := 2; -- r/w: prescaler select bit 1
|
||||
constant ctrl_clkdiv0_c : natural := 3; -- r/w: clock divider bit 0
|
||||
constant ctrl_clkdiv7_c : natural := 10; -- r/w: clock divider bit 7
|
||||
constant ctrl_trig_rst_c : natural := 11; -- -/w: trigger reset pulse, auto-clears
|
||||
constant ctrl_trig_bit_c : natural := 12; -- -/w: trigger single-bit transmission, auto-clears
|
||||
constant ctrl_trig_byte_c : natural := 13; -- -/w: trigger full-byte transmission, auto-clears
|
||||
constant ctrl_en_c : natural := 0; -- r/w: TWI enable
|
||||
constant ctrl_clear_c : natural := 1; -- -/w: clear FIFO, bit auto-clears
|
||||
constant ctrl_prsc0_c : natural := 2; -- r/w: prescaler select bit 0
|
||||
constant ctrl_prsc1_c : natural := 3; -- r/w: prescaler select bit 1
|
||||
constant ctrl_clkdiv0_c : natural := 4; -- r/w: clock divider bit 0
|
||||
constant ctrl_clkdiv7_c : natural := 11; -- r/w: clock divider bit 7
|
||||
--
|
||||
constant ctrl_sense_c : natural := 29; -- r/-: current state of the bus line
|
||||
constant ctrl_presence_c : natural := 30; -- r/-: bus presence detected
|
||||
constant ctrl_busy_c : natural := 31; -- r/-: set while operation in progress
|
||||
constant ctrl_fifo_size0_c : natural := 15; -- r/-: log2(fifo size), bit 0 (lsb)
|
||||
constant ctrl_fifo_size3_c : natural := 18; -- r/-: log2(fifo size), bit 3 (msb)
|
||||
--
|
||||
constant ctrl_tx_full_c : natural := 28; -- r/-: TX FIFO full
|
||||
constant ctrl_rx_avail_c : natural := 29; -- r/-: RX FIFO data available
|
||||
constant ctrl_sense_c : natural := 30; -- r/-: current state of the bus line
|
||||
constant ctrl_busy_c : natural := 31; -- r/-: set while operation in progress
|
||||
|
||||
-- data/command register --
|
||||
constant dcmd_lsb_c : natural := 0; -- r/w: RX/TX data MSB
|
||||
constant dcmd_msb_c : natural := 7; -- r/w: RX/TX data MSB
|
||||
constant dcmd_cmd_lo_c : natural := 8; -- -/w: operation command
|
||||
constant dcmd_cmd_hi_c : natural := 9; -- -/w: operation command
|
||||
constant dcmd_pres_c : natural := 10; -- r/-: bus presence detected
|
||||
|
||||
-- commands --
|
||||
constant cmd_nop_c : std_ulogic_vector(1 downto 0) := "00"; -- do nothing
|
||||
constant cmd_bit_c : std_ulogic_vector(1 downto 0) := "01"; -- trigger single-bit transmission
|
||||
constant cmd_byt_c : std_ulogic_vector(1 downto 0) := "10"; -- trigger full-byte transmission
|
||||
constant cmd_rst_c : std_ulogic_vector(1 downto 0) := "11"; -- trigger reset pulse and sample presence
|
||||
|
||||
-- control register --
|
||||
type ctrl_t is record
|
||||
enable : std_ulogic;
|
||||
clear : std_ulogic;
|
||||
clk_prsc : std_ulogic_vector(1 downto 0);
|
||||
clk_div : std_ulogic_vector(7 downto 0);
|
||||
trig_rst : std_ulogic;
|
||||
trig_bit : std_ulogic;
|
||||
trig_byte : std_ulogic;
|
||||
end record;
|
||||
signal ctrl : ctrl_t;
|
||||
|
||||
-- write data --
|
||||
signal tx_data : std_ulogic_vector(7 downto 0);
|
||||
-- FIFO interface --
|
||||
type fifo_t is record
|
||||
rx_clr, tx_clr : std_ulogic;
|
||||
rx_we, tx_we : std_ulogic;
|
||||
rx_re, tx_re : std_ulogic;
|
||||
rx_rdata, rx_wdata : std_ulogic_vector(8 downto 0);
|
||||
tx_rdata, tx_wdata : std_ulogic_vector(9 downto 0);
|
||||
rx_avail, tx_avail : std_ulogic;
|
||||
rx_free, tx_free : std_ulogic;
|
||||
end record;
|
||||
signal fifo : fifo_t;
|
||||
|
||||
-- clock generator --
|
||||
signal clk_sel : std_ulogic_vector(3 downto 0);
|
||||
signal clk_tick : std_ulogic;
|
||||
signal clk_cnt : unsigned(7 downto 0);
|
||||
signal clk_src : std_ulogic_vector(3 downto 0);
|
||||
signal clk_cnt : unsigned(7 downto 0);
|
||||
signal clk_tick : std_ulogic;
|
||||
signal clk_tick2 : std_ulogic;
|
||||
|
||||
-- serial engine --
|
||||
type serial_t is record
|
||||
|
@ -80,14 +106,13 @@ architecture neorv32_onewire_rtl of neorv32_onewire is
|
|||
busy : std_ulogic;
|
||||
bit_cnt : unsigned(2 downto 0);
|
||||
tick_cnt : unsigned(6 downto 0);
|
||||
tick : std_ulogic;
|
||||
tick_ff : std_ulogic;
|
||||
sreg : std_ulogic_vector(7 downto 0);
|
||||
wire_in : std_ulogic_vector(1 downto 0);
|
||||
wire_lo : std_ulogic;
|
||||
wire_hi : std_ulogic;
|
||||
sample : std_ulogic;
|
||||
presence : std_ulogic;
|
||||
done : std_ulogic;
|
||||
end record;
|
||||
signal serial : serial_t;
|
||||
|
||||
|
@ -98,38 +123,23 @@ begin
|
|||
bus_access: process(rstn_i, clk_i)
|
||||
begin
|
||||
if (rstn_i = '0') then
|
||||
bus_rsp_o <= rsp_terminate_c;
|
||||
ctrl.enable <= '0';
|
||||
ctrl.clk_prsc <= (others => '0');
|
||||
ctrl.clk_div <= (others => '0');
|
||||
ctrl.trig_rst <= '0';
|
||||
ctrl.trig_bit <= '0';
|
||||
ctrl.trig_byte <= '0';
|
||||
tx_data <= (others => '0');
|
||||
bus_rsp_o <= rsp_terminate_c;
|
||||
ctrl.enable <= '0';
|
||||
ctrl.clk_prsc <= (others => '0');
|
||||
ctrl.clk_div <= (others => '0');
|
||||
ctrl.clear <= '0';
|
||||
elsif rising_edge(clk_i) then
|
||||
-- bus handshake --
|
||||
bus_rsp_o.ack <= bus_req_i.stb;
|
||||
bus_rsp_o.err <= '0';
|
||||
bus_rsp_o.data <= (others => '0');
|
||||
-- write access --
|
||||
if (bus_req_i.stb = '1') and (bus_req_i.rw = '1') then
|
||||
if (bus_req_i.addr(2) = '0') then -- control register
|
||||
ctrl.enable <= bus_req_i.data(ctrl_en_c);
|
||||
ctrl.clk_prsc <= bus_req_i.data(ctrl_prsc1_c downto ctrl_prsc0_c);
|
||||
ctrl.clk_div <= bus_req_i.data(ctrl_clkdiv7_c downto ctrl_clkdiv0_c);
|
||||
else -- data register
|
||||
tx_data <= bus_req_i.data(7 downto 0);
|
||||
end if;
|
||||
end if;
|
||||
-- operation triggers --
|
||||
if (bus_req_i.stb = '1') and (bus_req_i.rw = '1') and (bus_req_i.addr(2) = '0') then -- set by host
|
||||
ctrl.trig_rst <= bus_req_i.data(ctrl_trig_rst_c);
|
||||
ctrl.trig_bit <= bus_req_i.data(ctrl_trig_bit_c);
|
||||
ctrl.trig_byte <= bus_req_i.data(ctrl_trig_byte_c);
|
||||
elsif (ctrl.enable = '0') or (serial.state(1) = '1') then -- cleared when disabled or when in RTX/RESET state
|
||||
ctrl.trig_rst <= '0';
|
||||
ctrl.trig_bit <= '0';
|
||||
ctrl.trig_byte <= '0';
|
||||
-- control register write access --
|
||||
ctrl.clear <= '0';
|
||||
if (bus_req_i.stb = '1') and (bus_req_i.rw = '1') and (bus_req_i.addr(2) = '0') then -- control register
|
||||
ctrl.enable <= bus_req_i.data(ctrl_en_c);
|
||||
ctrl.clear <= bus_req_i.data(ctrl_clear_c);
|
||||
ctrl.clk_prsc <= bus_req_i.data(ctrl_prsc1_c downto ctrl_prsc0_c);
|
||||
ctrl.clk_div <= bus_req_i.data(ctrl_clkdiv7_c downto ctrl_clkdiv0_c);
|
||||
end if;
|
||||
-- read access --
|
||||
if (bus_req_i.stb = '1') and (bus_req_i.rw = '0') then
|
||||
|
@ -138,10 +148,15 @@ begin
|
|||
bus_rsp_o.data(ctrl_prsc1_c downto ctrl_prsc0_c) <= ctrl.clk_prsc;
|
||||
bus_rsp_o.data(ctrl_clkdiv7_c downto ctrl_clkdiv0_c) <= ctrl.clk_div;
|
||||
--
|
||||
bus_rsp_o.data(ctrl_sense_c) <= serial.wire_in(1);
|
||||
bus_rsp_o.data(ctrl_presence_c) <= serial.presence;
|
||||
bus_rsp_o.data(ctrl_fifo_size3_c downto ctrl_fifo_size0_c) <= std_ulogic_vector(to_unsigned(index_size_f(ONEWIRE_FIFO), 4));
|
||||
--
|
||||
bus_rsp_o.data(ctrl_tx_full_c) <= not fifo.tx_free;
|
||||
bus_rsp_o.data(ctrl_rx_avail_c) <= fifo.rx_avail;
|
||||
bus_rsp_o.data(ctrl_sense_c) <= serial.wire_in(1);
|
||||
bus_rsp_o.data(ctrl_busy_c) <= fifo.tx_avail or serial.busy;
|
||||
else -- data register
|
||||
bus_rsp_o.data(7 downto 0) <= serial.sreg;
|
||||
bus_rsp_o.data(dcmd_msb_c downto dcmd_lsb_c) <= fifo.rx_rdata(7 downto 0);
|
||||
bus_rsp_o.data(dcmd_pres_c) <= fifo.rx_rdata(8);
|
||||
end if;
|
||||
end if;
|
||||
|
||||
|
@ -149,40 +164,114 @@ begin
|
|||
end process bus_access;
|
||||
|
||||
|
||||
-- Tick Generator -------------------------------------------------------------------------
|
||||
-- Data FIFO ("Ring Buffer") --------------------------------------------------------------
|
||||
-- -------------------------------------------------------------------------------------------
|
||||
tick_generator: process(rstn_i, clk_i)
|
||||
|
||||
-- TX FIFO --
|
||||
tx_fifo_inst: entity neorv32.neorv32_fifo
|
||||
generic map (
|
||||
FIFO_DEPTH => ONEWIRE_FIFO,
|
||||
FIFO_WIDTH => 10, -- 2-bit command + 8-bit data
|
||||
FIFO_RSYNC => true,
|
||||
FIFO_SAFE => true,
|
||||
FULL_RESET => false
|
||||
)
|
||||
port map (
|
||||
-- control --
|
||||
clk_i => clk_i,
|
||||
rstn_i => rstn_i,
|
||||
clear_i => fifo.tx_clr,
|
||||
half_o => open,
|
||||
-- write port --
|
||||
wdata_i => fifo.tx_wdata,
|
||||
we_i => fifo.tx_we,
|
||||
free_o => fifo.tx_free,
|
||||
-- read port --
|
||||
re_i => fifo.tx_re,
|
||||
rdata_o => fifo.tx_rdata,
|
||||
avail_o => fifo.tx_avail
|
||||
);
|
||||
|
||||
fifo.tx_clr <= '1' when (ctrl.enable = '0') or (ctrl.clear = '1') else '0';
|
||||
fifo.tx_we <= '1' when (bus_req_i.stb = '1') and (bus_req_i.rw = '1') and (bus_req_i.addr(2) = '1') else '0';
|
||||
fifo.tx_wdata <= bus_req_i.data(dcmd_cmd_hi_c downto dcmd_cmd_lo_c) & bus_req_i.data(dcmd_msb_c downto dcmd_lsb_c);
|
||||
fifo.tx_re <= '1' when (serial.state = "101") and (clk_tick = '1') else '0';
|
||||
|
||||
|
||||
-- RX FIFO --
|
||||
rx_fifo_inst: entity neorv32.neorv32_fifo
|
||||
generic map (
|
||||
FIFO_DEPTH => ONEWIRE_FIFO,
|
||||
FIFO_WIDTH => 9, -- 1-bit presence status + 8-bit data
|
||||
FIFO_RSYNC => true,
|
||||
FIFO_SAFE => true,
|
||||
FULL_RESET => false
|
||||
)
|
||||
port map (
|
||||
-- control --
|
||||
clk_i => clk_i,
|
||||
rstn_i => rstn_i,
|
||||
clear_i => fifo.rx_clr,
|
||||
half_o => open,
|
||||
-- write port --
|
||||
wdata_i => fifo.rx_wdata,
|
||||
we_i => fifo.rx_we,
|
||||
free_o => fifo.rx_free,
|
||||
-- read port --
|
||||
re_i => fifo.rx_re,
|
||||
rdata_o => fifo.rx_rdata,
|
||||
avail_o => fifo.rx_avail
|
||||
);
|
||||
|
||||
fifo.rx_clr <= '1' when (ctrl.enable = '0') or (ctrl.clear = '1') else '0';
|
||||
fifo.rx_wdata <= serial.presence & serial.sreg;
|
||||
fifo.rx_we <= serial.done;
|
||||
fifo.rx_re <= '1' when (bus_req_i.stb = '1') and (bus_req_i.rw = '0') and (bus_req_i.addr(2) = '1') else '0';
|
||||
|
||||
|
||||
-- IRQ if enabled and TX FIFO is empty and serial engine is idle --
|
||||
irq_generator: process(rstn_i, clk_i)
|
||||
begin
|
||||
if (rstn_i = '0') then
|
||||
clk_tick <= '0';
|
||||
clk_cnt <= (others => '0');
|
||||
serial.tick <= '0';
|
||||
serial.tick_ff <= '0';
|
||||
irq_o <= '0';
|
||||
elsif rising_edge(clk_i) then
|
||||
clk_tick <= clk_sel(to_integer(unsigned(ctrl.clk_prsc)));
|
||||
serial.tick <= '0'; -- default
|
||||
irq_o <= ctrl.enable and (not fifo.tx_avail) and (not serial.busy);
|
||||
end if;
|
||||
end process irq_generator;
|
||||
|
||||
|
||||
-- Clock Generator ------------------------------------------------------------------------
|
||||
-- -------------------------------------------------------------------------------------------
|
||||
clock_generator: process(rstn_i, clk_i)
|
||||
begin
|
||||
if (rstn_i = '0') then
|
||||
clk_cnt <= (others => '0');
|
||||
clk_tick <= '0';
|
||||
clk_tick2 <= '0';
|
||||
elsif rising_edge(clk_i) then
|
||||
clk_tick <= '0'; -- default
|
||||
if (ctrl.enable = '0') then
|
||||
clk_cnt <= (others => '0');
|
||||
elsif (clk_tick = '1') then
|
||||
elsif (clk_src(to_integer(unsigned(ctrl.clk_prsc))) = '1') then
|
||||
if (clk_cnt = unsigned(ctrl.clk_div)) then
|
||||
clk_cnt <= (others => '0');
|
||||
serial.tick <= '1'; -- signal is high for 1 clk_i cycle every 't_base'
|
||||
clk_cnt <= (others => '0');
|
||||
clk_tick <= '1'; -- signal is high for 1 clk_i cycle every 't_base'
|
||||
else
|
||||
clk_cnt <= clk_cnt + 1;
|
||||
end if;
|
||||
end if;
|
||||
serial.tick_ff <= serial.tick; -- tick delayed by one clock cycle (for precise bus state sampling)
|
||||
clk_tick2 <= clk_tick; -- tick delayed by one clock cycle (for precise bus state sampling)
|
||||
end if;
|
||||
end process tick_generator;
|
||||
end process clock_generator;
|
||||
|
||||
-- enable SoC clock generator --
|
||||
clkgen_en_o <= ctrl.enable;
|
||||
|
||||
-- only use the lowest 4 clocks of the system clock generator --
|
||||
clk_sel <= clkgen_i(3 downto 0);
|
||||
clk_src <= clkgen_i(3 downto 0);
|
||||
|
||||
|
||||
-- Serial Engine --------------------------------------------------------------------------
|
||||
-- Serial Engine (1-Wire PHY) -------------------------------------------------------------
|
||||
-- -------------------------------------------------------------------------------------------
|
||||
serial_engine: process(rstn_i, clk_i)
|
||||
begin
|
||||
|
@ -195,6 +284,7 @@ begin
|
|||
serial.bit_cnt <= (others => '0');
|
||||
serial.sreg <= (others => '0');
|
||||
serial.sample <= '0';
|
||||
serial.done <= '0';
|
||||
onewire_o <= '0';
|
||||
elsif rising_edge(clk_i) then
|
||||
-- input synchronizer --
|
||||
|
@ -210,6 +300,7 @@ begin
|
|||
-- defaults --
|
||||
serial.wire_lo <= '0';
|
||||
serial.wire_hi <= '0';
|
||||
serial.done <= '0';
|
||||
|
||||
-- FSM --
|
||||
serial.state(2) <= ctrl.enable; -- module enabled? force reset state otherwise
|
||||
|
@ -218,27 +309,26 @@ begin
|
|||
when "100" => -- enabled, but IDLE: wait for new request
|
||||
-- ------------------------------------------------------------
|
||||
serial.tick_cnt <= (others => '0');
|
||||
-- transmission size --
|
||||
if (ctrl.trig_bit = '1') then
|
||||
serial.bit_cnt <= "000"; -- single bit
|
||||
else
|
||||
serial.bit_cnt <= "111"; -- full-byte
|
||||
end if;
|
||||
-- any operation request? --
|
||||
if (ctrl.trig_rst = '1') or (ctrl.trig_bit = '1') or (ctrl.trig_byte = '1') then
|
||||
if (fifo.tx_avail = '1') then -- new command/data available?
|
||||
serial.state(1 downto 0) <= "01"; -- SYNC
|
||||
end if;
|
||||
|
||||
when "101" => -- SYNC: start operation with next base tick
|
||||
-- ------------------------------------------------------------
|
||||
serial.sreg <= tx_data;
|
||||
if (serial.tick = '1') then -- synchronize
|
||||
if (fifo.tx_rdata(dcmd_cmd_hi_c downto dcmd_cmd_lo_c) = cmd_bit_c) then
|
||||
serial.bit_cnt <= "000"; -- single bit
|
||||
else
|
||||
serial.bit_cnt <= "111"; -- full byte
|
||||
end if;
|
||||
serial.sreg <= fifo.tx_rdata(dcmd_msb_c downto dcmd_lsb_c);
|
||||
if (clk_tick = '1') then -- synchronize
|
||||
serial.wire_lo <= '1'; -- force bus to low
|
||||
if (ctrl.trig_rst = '1') then
|
||||
serial.state(1 downto 0) <= "11"; -- RESET
|
||||
else
|
||||
serial.state(1 downto 0) <= "10"; -- RTX
|
||||
end if;
|
||||
case fifo.tx_rdata(dcmd_cmd_hi_c downto dcmd_cmd_lo_c) is -- operation command
|
||||
when cmd_bit_c => serial.state(1 downto 0) <= "10"; -- RTX (single bit)
|
||||
when cmd_byt_c => serial.state(1 downto 0) <= "10"; -- RTX (full byte)
|
||||
when cmd_rst_c => serial.state(1 downto 0) <= "11"; -- RESET
|
||||
when others => serial.state(1 downto 0) <= "00"; -- IDLE (NOP)
|
||||
end case;
|
||||
end if;
|
||||
|
||||
when "110" => -- RTX: read/write 'serial.bit_cnt-1' bits
|
||||
|
@ -248,26 +338,27 @@ begin
|
|||
serial.wire_hi <= '1'; -- release bus
|
||||
end if;
|
||||
-- sample input (precisely / just once!) --
|
||||
if (serial.tick_cnt = t_read_sample_c) and (serial.tick_ff = '1') then
|
||||
if (serial.tick_cnt = t_read_sample_c) and (clk_tick2 = '1') then
|
||||
serial.sample <= serial.wire_in(1);
|
||||
end if;
|
||||
-- inter-slot pause (end of bit) & iteration control --
|
||||
-- inter-slot pause (end of bit) and iteration control --
|
||||
if (serial.tick_cnt = t_pause_end_c) then -- bit done
|
||||
serial.tick_cnt <= (others => '0');
|
||||
serial.sreg <= serial.sample & serial.sreg(7 downto 1); -- new bit; LSB first
|
||||
serial.bit_cnt <= serial.bit_cnt - 1;
|
||||
if (serial.bit_cnt = "000") then -- all done
|
||||
serial.state(1 downto 0) <= "00"; -- go back to IDLE
|
||||
serial.done <= '1';
|
||||
serial.state(1 downto 0) <= "00"; -- IDLE
|
||||
else -- next bit
|
||||
serial.wire_lo <= '1'; -- force bus to low again
|
||||
end if;
|
||||
elsif (serial.tick = '1') then
|
||||
elsif (clk_tick = '1') then
|
||||
serial.tick_cnt <= serial.tick_cnt + 1;
|
||||
end if;
|
||||
|
||||
when "111" => -- RESET: generate reset pulse and check for bus presence
|
||||
-- ------------------------------------------------------------
|
||||
if (serial.tick = '1') then
|
||||
if (clk_tick = '1') then
|
||||
serial.tick_cnt <= serial.tick_cnt + 1;
|
||||
end if;
|
||||
-- end of reset pulse --
|
||||
|
@ -275,12 +366,13 @@ begin
|
|||
serial.wire_hi <= '1'; -- release bus
|
||||
end if;
|
||||
-- sample device presence (precisely / just once!) --
|
||||
if (serial.tick_cnt = t_presence_sample_c) and (serial.tick_ff = '1') then
|
||||
if (serial.tick_cnt = t_presence_sample_c) and (clk_tick2 = '1') then
|
||||
serial.presence <= not serial.wire_in(1); -- set if bus is pulled low by any device
|
||||
end if;
|
||||
-- end of presence phase --
|
||||
if (serial.tick_cnt = t_presence_end_c) then
|
||||
serial.state(1 downto 0) <= "00"; -- go back to IDLE
|
||||
serial.done <= '1';
|
||||
serial.state(1 downto 0) <= "00"; -- IDLE
|
||||
end if;
|
||||
|
||||
when others => -- "0--" OFFLINE: deactivated, reset externally-readable signals
|
||||
|
@ -297,20 +389,4 @@ begin
|
|||
serial.busy <= '0' when (serial.state(1 downto 0) = "00") else '1';
|
||||
|
||||
|
||||
-- Interrupt Generator --------------------------------------------------------------------
|
||||
-- -------------------------------------------------------------------------------------------
|
||||
irq_generator: process(rstn_i, clk_i)
|
||||
begin
|
||||
if (rstn_i = '0') then
|
||||
irq_o <= '0';
|
||||
elsif rising_edge(clk_i) then
|
||||
if (serial.state = "100") then -- enabled and in idle state
|
||||
irq_o <= '1';
|
||||
else
|
||||
irq_o <= '0';
|
||||
end if;
|
||||
end if;
|
||||
end process irq_generator;
|
||||
|
||||
|
||||
end neorv32_onewire_rtl;
|
||||
|
|
Loading…
Add table
Add a link
Reference in a new issue