-
Notifications
You must be signed in to change notification settings - Fork 0
Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
- Loading branch information
Showing
6 changed files
with
192 additions
and
1 deletion.
There are no files selected for viewing
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1 @@ | ||
ghdl uart_rx.vhd uart_tx.vhd uart_top.vhd -e uart_top |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,66 @@ | ||
library ieee; | ||
use ieee.std_logic_1164.all; | ||
|
||
entity uart_rx is | ||
generic ( | ||
C_BITS : integer := 8; | ||
C_CYCLES_PER_BIT : integer := 104 | ||
); | ||
port ( | ||
isl_clk : in std_logic; | ||
isl_data : in std_logic; | ||
oslv_data : out std_logic_vector(C_BITS-1 downto 0); | ||
osl_valid : out std_logic | ||
); | ||
end entity uart_rx; | ||
|
||
architecture rtl of uart_rx is | ||
signal int_cycle_cnt : integer range 0 to C_CYCLES_PER_BIT-1 := 0; | ||
signal int_bit_cnt : integer range 0 to C_BITS+1 := 0; | ||
|
||
signal slv_data : std_logic_vector(C_BITS-1 downto 0) := (others => '0'); | ||
signal sl_valid : std_logic := '0'; | ||
|
||
type t_state is (IDLE, INIT, RECEIVE); | ||
signal state : t_state; | ||
|
||
begin | ||
process(isl_clk) | ||
begin | ||
if rising_edge(isl_clk) then | ||
case state is | ||
when IDLE => | ||
sl_valid <= '0'; | ||
if isl_data = '0' then | ||
-- wait for the start bit | ||
state <= INIT; | ||
end if; | ||
|
||
when INIT => | ||
int_cycle_cnt <= C_CYCLES_PER_BIT / 2; | ||
int_bit_cnt <= 0; | ||
state <= RECEIVE; | ||
|
||
when RECEIVE => | ||
if int_bit_cnt < C_BITS+1 then | ||
if int_cycle_cnt < C_CYCLES_PER_BIT-1 then | ||
int_cycle_cnt <= int_cycle_cnt+1; | ||
else | ||
-- receive data bits | ||
int_cycle_cnt <= 0; | ||
int_bit_cnt <= int_bit_cnt+1; | ||
slv_data <= isl_data & slv_data(slv_data'LEFT downto 1); | ||
end if; | ||
elsif isl_data = '1' then | ||
-- wait for the stop bit | ||
sl_valid <= '1'; | ||
state <= IDLE; | ||
end if; | ||
|
||
end case; | ||
end if; | ||
end process; | ||
|
||
oslv_data <= slv_data; | ||
osl_valid <= sl_valid; | ||
end architecture rtl; |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,49 @@ | ||
library ieee; | ||
use ieee.std_logic_1164.all; | ||
|
||
entity uart_top is | ||
generic ( | ||
C_BITS : integer := 8 | ||
); | ||
port ( | ||
isl_clk : in std_logic; | ||
isl_data : in std_logic; | ||
osl_data : out std_logic; | ||
osl_ready : out std_logic | ||
); | ||
end uart_top; | ||
|
||
architecture behavioral of uart_top is | ||
constant C_QUARTZ_FREQ : integer := 4; -- Hz | ||
constant C_BAUDRATE : integer := 1; -- words / s | ||
constant C_CYCLES_PER_BIT : integer := C_QUARTZ_FREQ / C_BAUDRATE; | ||
|
||
signal sl_valid_out_tx : std_logic := '0'; | ||
signal slv_data_out_tx : std_logic_vector(C_BITS-1 downto 0) := (others => '0'); | ||
|
||
begin | ||
i_uart_rx: entity work.uart_rx | ||
generic map ( | ||
C_BITS => C_BITS, | ||
C_CYCLES_PER_BIT => C_CYCLES_PER_BIT | ||
) | ||
port map ( | ||
isl_clk => isl_clk, | ||
isl_data => isl_data, | ||
oslv_data => slv_data_out_tx, | ||
osl_valid => sl_valid_out_tx | ||
); | ||
|
||
i_uart_tx: entity work.uart_tx | ||
generic map ( | ||
C_BITS => C_BITS, | ||
C_CYCLES_PER_BIT => C_CYCLES_PER_BIT | ||
) | ||
port map ( | ||
isl_clk => isl_clk, | ||
isl_valid => sl_valid_out_tx, | ||
islv_data => slv_data_out_tx, | ||
osl_data => osl_data, | ||
osl_ready => osl_ready | ||
); | ||
end behavioral; |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,62 @@ | ||
library ieee; | ||
use ieee.std_logic_1164.all; | ||
|
||
entity uart_tx is | ||
generic ( | ||
-- TODO: range in submodules is not yet supported by synthesis | ||
-- it would be useful to limit between 5 to 8 | ||
C_BITS : integer := 8; | ||
C_CYCLES_PER_BIT : integer := 104 | ||
); | ||
port ( | ||
isl_clk : in std_logic; | ||
isl_valid : in std_logic; | ||
islv_data : in std_logic_vector(C_BITS-1 downto 0); | ||
osl_ready : out std_logic; | ||
osl_data : out std_logic | ||
); | ||
end entity uart_tx; | ||
|
||
architecture rtl of uart_tx is | ||
signal int_cycle_cnt : integer range 0 to C_CYCLES_PER_BIT-1 := 0; | ||
signal int_bit_cnt : integer range 0 to C_BITS+2 := 0; | ||
|
||
signal slv_data : std_logic_vector(C_BITS downto 0) := (others => '0'); | ||
|
||
type t_state is (IDLE, INIT, SEND); | ||
signal state : t_state; | ||
|
||
begin | ||
process(isl_clk) | ||
begin | ||
if rising_edge(isl_clk) then | ||
case state is | ||
when IDLE => | ||
if isl_valid = '1' then | ||
state <= INIT; | ||
end if; | ||
|
||
when INIT => | ||
int_cycle_cnt <= 0; | ||
int_bit_cnt <= 0; | ||
slv_data <= islv_data & '1'; | ||
state <= SEND; | ||
|
||
when SEND => | ||
if int_cycle_cnt < C_CYCLES_PER_BIT-1 then | ||
int_cycle_cnt <= int_cycle_cnt+1; | ||
elsif int_bit_cnt < C_BITS+1 then | ||
int_cycle_cnt <= 0; | ||
int_bit_cnt <= int_bit_cnt+1; | ||
slv_data <= '0' & slv_data(slv_data'LEFT downto 1); | ||
else | ||
state <= IDLE; | ||
end if; | ||
|
||
end case; | ||
end if; | ||
end process; | ||
|
||
osl_ready <= '1' when state = IDLE else '0'; | ||
osl_data <= slv_data(0); | ||
end architecture rtl; |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,12 @@ | ||
from tb import top | ||
from pysim.sim import Signal, runsim | ||
from pysim.coroutines import clock_coroutine, uart_coroutine | ||
|
||
dut = top(True) | ||
clk = Signal(dut, 'isl__clk') | ||
rxd = Signal(dut, 'isl__data') | ||
clk_co = clock_coroutine(clk, 1, 1, 400) | ||
uart_co = uart_coroutine(rxd, 8, b"Hello!") | ||
coros = [clk_co, uart_co] | ||
runsim(dut, True, coros, 400) | ||
|