From 78a9fd24aa757de9e088709eae264576ad485158 Mon Sep 17 00:00:00 2001 From: Manfred Date: Tue, 14 Dec 2010 13:34:23 +0100 Subject: [PATCH] uart:uart entitiy --- cpu/sim/testcore1.do | 9 +- cpu/src/extension_uart.vhd | 28 +++++ cpu/src/extension_uart_b.vhd | 221 +++++++++++++++++++++++++++++++++ cpu/src/extension_uart_pkg.vhd | 87 +++++++++++++ cpu/src/rs232_tx.vhd | 40 ++++++ cpu/src/rs232_tx_arc.vhd | 115 +++++++++++++++++ 6 files changed, 499 insertions(+), 1 deletion(-) create mode 100644 cpu/src/extension_uart.vhd create mode 100644 cpu/src/extension_uart_b.vhd create mode 100644 cpu/src/extension_uart_pkg.vhd create mode 100755 cpu/src/rs232_tx.vhd create mode 100755 cpu/src/rs232_tx_arc.vhd diff --git a/cpu/sim/testcore1.do b/cpu/sim/testcore1.do index def1de9..0126674 100644 --- a/cpu/sim/testcore1.do +++ b/cpu/sim/testcore1.do @@ -17,7 +17,7 @@ vcom -work work ../src/decode_stage_b.vhd vcom -work work ../src/alu_pkg.vhd vcom -work work ../src/extension_pkg.vhd -vcom -work work ../src/gpm_pkg.vhd + vcom -work work ../src/exec_op.vhd vcom -work work ../src/exec_op/add_op_b.vhd @@ -36,6 +36,13 @@ vcom -work work ../src/extension_pkg.vhd vcom -work work ../src/extension.vhd vcom -work work ../src/extension_b.vhd + +vcom -work work ../src/extension_uart_pkg.vhd +vcom -work work ../src/rs232_tx.vhd +vcom -work work ../src/rs232_tx_arc.vhd +vcom -work work ../src/extension_uart.vhd +vcom -work work ../src/extension_uart_b.vhd + vcom -work work ../src/execute_stage.vhd vcom -work work ../src/execute_stage_b.vhd diff --git a/cpu/src/extension_uart.vhd b/cpu/src/extension_uart.vhd new file mode 100644 index 0000000..9a31d1d --- /dev/null +++ b/cpu/src/extension_uart.vhd @@ -0,0 +1,28 @@ +library IEEE; +use IEEE.std_logic_1164.all; +use IEEE.numeric_std.all; + +use work.common_pkg.all; +use work.extension_uart_pkg.all; + + +entity extension_uart is + + generic ( + -- active reset value + RESET_VALUE : std_logic + ); + port( + --System inputs + clk : in std_logic; + reset : in std_logic; + -- general extension interface + ext_reg : in extmod_rec; + data_out : out gp_register_t; + -- Input + + -- Ouput + bus_tx : out std_logic + ); + +end extension_uart; diff --git a/cpu/src/extension_uart_b.vhd b/cpu/src/extension_uart_b.vhd new file mode 100644 index 0000000..471a9c4 --- /dev/null +++ b/cpu/src/extension_uart_b.vhd @@ -0,0 +1,221 @@ +library IEEE; +use IEEE.std_logic_1164.all; +use IEEE.numeric_std.all; + +use work.common_pkg.all; +use work.core_pkg.all; + +use work.mem_pkg.all; +use work.extension_uart_pkg.all; + +architecture behav of extension_uart is + +signal int_rec,int_rec_nxt : extmod_rec; +signal w1_st_co, w1_st_co_nxt, w2_wewillsee, w2_wewillsee_nxt, w3_wewillsee, w3_wewillsee_nxt, w4_wewillsee, w4_wewillsee_nxt : gp_register_t; +signal new_tx_data, tx_busy : std_logic; + +begin + + +rs232_tx_inst : rs232_tx +port map( + --System inputs + clk, + reset, + + --Bus + bus_tx, + + --From/to sendlogic + new_tx_data, + w3_wewillsee(byte_t'range), + tx_busy +); + + + + + +syn : process (clk, reset) +begin + if (reset = RESET_VALUE) then + int_rec.sel <= '0'; + int_rec.wr_en <= '0'; + int_rec.byte_en <= (others=>'0'); + int_rec.data <= (others=>'0'); + int_rec.addr <= (others=>'0'); + + + elsif rising_edge(clk) then + int_rec <= int_rec_nxt; + + + end if; +end process syn; + +-------------------------- LESEN UND SCHREIBEN ANFANG ------------------------------------------------------------ + +gwriten : process (ext_reg) + +begin + if ext_reg.sel = '1' and ext_reg.wr_en = '1' then + int_rec_nxt <= ext_reg; + end if; +end process gwriten; + +gread : process (clk,ext_reg) + +variable tmp_data : gp_register_t; + +begin + if ext_reg.sel = '1' and ext_reg.wr_en = '0' then + case ext_reg.addr(1 downto 0) is + when "00" => + tmp_data := (others =>'0'); + if ext_reg.byte_en(0) = '1' then + tmp_data(byte_t'range) := w1_st_co(byte_t'range); + end if; + if ext_reg.byte_en(1) = '1' then + tmp_data((2*byte_t'length-1) downto byte_t'length) := w1_st_co((2*byte_t'length-1) downto byte_t'length); + end if; + if ext_reg.byte_en(2) = '1' then + tmp_data((3*byte_t'length-1) downto 2*byte_t'length) := w1_st_co((3*byte_t'length-1) downto 2*byte_t'length); + end if; + if ext_reg.byte_en(3) = '1' then + tmp_data((4*byte_t'length-1) downto 3*byte_t'length) := w1_st_co((4*byte_t'length-1) downto 3*byte_t'length); + end if; + data_out <= tmp_data; + when "01" => + tmp_data := (others =>'0'); + if ext_reg.byte_en(0) = '1' then + tmp_data(byte_t'range) := w2_wewillsee(byte_t'range); + end if; + if ext_reg.byte_en(1) = '1' then + tmp_data((2*byte_t'length-1) downto byte_t'length) := w2_wewillsee((2*byte_t'length-1) downto byte_t'length); + end if; + if ext_reg.byte_en(2) = '1' then + tmp_data((3*byte_t'length-1) downto 2*byte_t'length) := w2_wewillsee((3*byte_t'length-1) downto 2*byte_t'length); + end if; + if ext_reg.byte_en(3) = '1' then + tmp_data((4*byte_t'length-1) downto 3*byte_t'length) := w2_wewillsee((4*byte_t'length-1) downto 3*byte_t'length); + end if; + data_out <= tmp_data; + when "10" => + tmp_data := (others =>'0'); + if ext_reg.byte_en(0) = '1' then + tmp_data(byte_t'range) := w3_wewillsee(byte_t'range); + end if; + if ext_reg.byte_en(1) = '1' then + tmp_data((2*byte_t'length-1) downto byte_t'length) := w3_wewillsee((2*byte_t'length-1) downto byte_t'length); + end if; + if ext_reg.byte_en(2) = '1' then + tmp_data((3*byte_t'length-1) downto 2*byte_t'length) := w3_wewillsee((3*byte_t'length-1) downto 2*byte_t'length); + end if; + if ext_reg.byte_en(3) = '1' then + tmp_data((4*byte_t'length-1) downto 3*byte_t'length) := w3_wewillsee((4*byte_t'length-1) downto 3*byte_t'length); + end if; + data_out <= tmp_data; + when "11" => + tmp_data := (others =>'0'); + if ext_reg.byte_en(0) = '1' then + tmp_data(byte_t'range) := w4_wewillsee(byte_t'range); + end if; + if ext_reg.byte_en(1) = '1' then + tmp_data((2*byte_t'length-1) downto byte_t'length) := w4_wewillsee((2*byte_t'length-1) downto byte_t'length); + end if; + if ext_reg.byte_en(2) = '1' then + tmp_data((3*byte_t'length-1) downto 2*byte_t'length) := w4_wewillsee((3*byte_t'length-1) downto 2*byte_t'length); + end if; + if ext_reg.byte_en(3) = '1' then + tmp_data((4*byte_t'length-1) downto 3*byte_t'length) := w4_wewillsee((4*byte_t'length-1) downto 3*byte_t'length); + end if; + data_out <= tmp_data; + when others => null; + end case; + else + data_out <= (others=>'0'); + end if; +end process gread; + +proc_data : process (clk,int_rec) + +variable tmp_data : gp_register_t; + +begin + case int_rec.addr(1 downto 0) is + when "00" => + tmp_data := (others =>'0'); + if int_rec.byte_en(0) = '1' then + tmp_data(byte_t'range) :=int_rec.data(byte_t'range); + end if; + if int_rec.byte_en(1) = '1' then + tmp_data((2*byte_t'length-1) downto byte_t'length) := int_rec.data((2*byte_t'length-1) downto byte_t'length); + end if; + if int_rec.byte_en(2) = '1' then + tmp_data((3*byte_t'length-1) downto 2*byte_t'length) := int_rec.data((3*byte_t'length-1) downto 2*byte_t'length); + end if; + if int_rec.byte_en(3) = '1' then + tmp_data((4*byte_t'length-1) downto 3*byte_t'length) := int_rec.data((4*byte_t'length-1) downto 3*byte_t'length); + end if; + w1_st_co_nxt <= tmp_data; + when "01" => + tmp_data := (others =>'0'); + if int_rec.byte_en(0) = '1' then + tmp_data(byte_t'range) := int_rec.data(byte_t'range); + end if; + if int_rec.byte_en(1) = '1' then + tmp_data((2*byte_t'length-1) downto byte_t'length) := int_rec.data((2*byte_t'length-1) downto byte_t'length); + end if; + if int_rec.byte_en(2) = '1' then + tmp_data((3*byte_t'length-1) downto 2*byte_t'length) := int_rec.data((3*byte_t'length-1) downto 2*byte_t'length); + end if; + if int_rec.byte_en(3) = '1' then + tmp_data((4*byte_t'length-1) downto 3*byte_t'length) := int_rec.data((4*byte_t'length-1) downto 3*byte_t'length); + end if; + w2_wewillsee_nxt <= tmp_data; + when "10" => + tmp_data := (others =>'0'); + if int_rec.byte_en(0) = '1' then + tmp_data(byte_t'range) :=int_rec.data(byte_t'range); + end if; + if int_rec.byte_en(1) = '1' then + tmp_data((2*byte_t'length-1) downto byte_t'length) := int_rec.data((2*byte_t'length-1) downto byte_t'length); + end if; + if int_rec.byte_en(2) = '1' then + tmp_data((3*byte_t'length-1) downto 2*byte_t'length) := int_rec.data((3*byte_t'length-1) downto 2*byte_t'length); + end if; + if int_rec.byte_en(3) = '1' then + tmp_data((4*byte_t'length-1) downto 3*byte_t'length) := int_rec.data((4*byte_t'length-1) downto 3*byte_t'length); + end if; + w3_wewillsee_nxt <= tmp_data; + when "11" => + tmp_data := (others =>'0'); + if int_rec.byte_en(0) = '1' then + tmp_data(byte_t'range) := w4_wewillsee(byte_t'range); + end if; + if int_rec.byte_en(1) = '1' then + tmp_data((2*byte_t'length-1) downto byte_t'length) := int_rec.data((2*byte_t'length-1) downto byte_t'length); + end if; + if int_rec.byte_en(2) = '1' then + tmp_data((3*byte_t'length-1) downto 2*byte_t'length) := int_rec.data((3*byte_t'length-1) downto 2*byte_t'length); + end if; + if int_rec.byte_en(3) = '1' then + tmp_data((4*byte_t'length-1) downto 3*byte_t'length) := int_rec.data((4*byte_t'length-1) downto 3*byte_t'length); + end if; + w4_wewillsee_nxt <= tmp_data; + when others => null; + end case; +end process proc_data; + +-------------------------- LESEN UND SCHREIBEN ENDE --------------------------------------------------------------- + +-------------------------- INTERNE VERARBEITUNG ANFANG ------------------------------------------------------------ + + + + + +-------------------------- INTERNE VERARBEITUNG ENDE -------------------------------------------------------------- + +end behav; + diff --git a/cpu/src/extension_uart_pkg.vhd b/cpu/src/extension_uart_pkg.vhd new file mode 100644 index 0000000..fb839ff --- /dev/null +++ b/cpu/src/extension_uart_pkg.vhd @@ -0,0 +1,87 @@ +library IEEE; + +use IEEE.std_logic_1164.all; +use IEEE.numeric_std.all; + +use work.common_pkg.all; + + +package extension_uart_pkg is + +constant EXTWORDL : integer := log2c(4); +constant BYTEADDR : integer := log2c(4); +constant PCOUNT : integer := 3; +constant EXTWORDS : integer := EXTWORDL + BYTEADDR; + +subtype ext_addrid_t is std_logic_vector(gp_register_t'high - EXTWORDS downto 0); +subtype ext_addr_t is std_logic_vector((gp_register_t'high-BYTEADDR) downto 0); +subtype paddr_t is std_logic_vector(log2c(PCOUNT)-1 downto 0); + + type extmod_rec is record + sel : std_logic; + wr_en : std_logic; + byte_en : std_logic_vector(gp_register_t'length/byte_t'length-1 downto 0); + data : gp_register_t; + addr : ext_addr_t; + end record; + + +type status_rec is record + zero : std_logic; + oflo : std_logic; + sign : std_logic; + carry : std_logic; +end record; + +constant EXT_7SEG_ADDR: ext_addrid_t := x"FFFFFFA"; +constant EXT_EXTMEM_ADDR: ext_addrid_t := x"FFFFFFB"; +constant EXT_TIMER_ADDR: ext_addrid_t := x"FFFFFFC"; +constant EXT_AC97_ADDR: ext_addrid_t := x"FFFFFFD"; +constant EXT_UART_ADDR: ext_addrid_t := x"FFFFFFE"; +constant EXT_GPMP_ADDR: ext_addrid_t := x"FFFFFFF"; +--RS232 +constant UART_WIDTH : integer := 8; +subtype uart_data is std_logic_vector(UART_WIDTH-1 downto 0); +--CLKs +constant CLK_FREQ_MHZ : real := 33.33; +constant BAUD_RATE : integer := 115200; +constant CLK_PER_BAUD : integer := integer((CLK_FREQ_MHZ * 1000000.0) / real(BAUD_RATE) - 0.5); + + component extension_uart is + --some modules won't need all inputs/outputs + generic ( + -- active reset value + RESET_VALUE : std_logic + ); + port( + --System inputs + clk : in std_logic; + reset : in std_logic; + -- general extension interface + ext_reg : in extmod_rec; + data_out : out gp_register_t; + -- Input + + -- Ouput + bus_tx : out std_logic + ); + end component extension_uart; + +component rs232_tx is + + port( + --System inputs + sys_clk : in std_logic; + sys_res_n : in std_logic; + + --Bus + bus_tx : out std_logic; + + --From/to sendlogic + new_tx_data : in std_logic; + tx_data : in uart_data; + tx_rdy : out std_logic + ); +end component rs232_tx; + +end package extension_uart_pkg; diff --git a/cpu/src/rs232_tx.vhd b/cpu/src/rs232_tx.vhd new file mode 100755 index 0000000..d8fb516 --- /dev/null +++ b/cpu/src/rs232_tx.vhd @@ -0,0 +1,40 @@ +--------------------------------------------------------------------------------- +-- Filename : rs232_tx.vhd +-- ========== +-- +-- Beschreibung : Versand von Daten ueber die RS232 Schnittstelle +-- ============== +-- +-- Autoren : Martin Perner, Schwarz Manfred +-- ========= +---------------------------------------------------------------------------------- + +library IEEE; +use IEEE.std_logic_1164.all; +use IEEE.std_logic_unsigned.all; +use IEEE.std_logic_arith.all; + +use work.common_pkg.all; +use work.core_pkg.all; +use work.extension_uart_pkg.all; + +entity rs232_tx is + generic ( + -- active reset value + RESET_VALUE : std_logic + ); + port( + --System inputs + sys_clk : in std_logic; + sys_res_n : in std_logic; + + --Bus + bus_tx : out std_logic; + + --From/to sendlogic + new_tx_data : in std_logic; + tx_data : in uart_data; + tx_rdy : out std_logic + ); + +end rs232_tx; diff --git a/cpu/src/rs232_tx_arc.vhd b/cpu/src/rs232_tx_arc.vhd new file mode 100755 index 0000000..cc29340 --- /dev/null +++ b/cpu/src/rs232_tx_arc.vhd @@ -0,0 +1,115 @@ +--------------------------------------------------------------------------------- +-- Filename : rs232_tx_arc.vhd +-- ========== +-- +-- Beschreibung : Versand von Daten ueber die RS232 Schnittstelle +-- ============== +-- +-- Autoren : Martin Perner, Schwarz Manfred +-- ========= +---------------------------------------------------------------------------------- + +library IEEE; +use IEEE.std_logic_1164.all; +use IEEE.numeric_std.all; + +use work.common_pkg.all; +use work.core_pkg.all; +use work.extension_uart_pkg.all; + +architecture beh of rs232_tx is + -- definierern der intern verwendeten Signale + type STATE_TYPE is (IDLE,SEND); + signal state, state_next : STATE_TYPE; + signal bus_tx_int, bus_tx_nxt : std_logic := '1'; + signal baud_cnt,baud_cnt_next : integer := CLK_PER_BAUD; + signal cnt, cnt_next : natural range 0 to 11 := 0; + signal idle_sig, idle_sig_next : std_logic := '0'; + +begin + -- syncronisierungs Prozess + rs232_tx_syn : process(sys_clk, sys_res_n) + begin + if (sys_res_n = RESET_VALUE) then + -- reset + cnt <= 0; + baud_cnt <= 0; + state <= IDLE; + idle_sig <= '0'; + bus_tx_int <= '1'; + elsif rising_edge(sys_clk) then + -- sync Zustand, uebernehmen der next-Signale + baud_cnt <= baud_cnt_next; + cnt <= cnt_next; + state <= state_next; + idle_sig <= idle_sig_next; + bus_tx_int <= bus_tx_nxt; + end if; + end process; + + bus_tx <= bus_tx_int; + + -- Zustandsmaschienen Prozess + rs232_tx_state : process(state, new_tx_data, idle_sig) + begin + state_next <= state; + case state is + when IDLE => + -- wenn neue Sendedaten anliegen wird in den Zustand SEND gewechselt + if new_tx_data = '1' then + state_next <= SEND; + end if; + when SEND => + -- wenn das Byte inklusive Start- und Stopbit versendet wurde, geht + -- der Prozess wieder in den IDLE Zustand. + if idle_sig = '1' then + state_next <= IDLE; + end if; + end case; + end process; + + -- Ausgabe Logik + rs232_tx_baud : process(sys_clk, sys_res_n, state, baud_cnt, cnt, tx_data, bus_tx_int) + begin + -- Solang idle_sig auf 0 ist wird im SEND Zustand verblieben + idle_sig_next <= '0'; + bus_tx_nxt <= bus_tx_int; + cnt_next <= cnt; + baud_cnt_next <= baud_cnt; + + case state is + when IDLE => + -- tx-Signale im idle Zustand halten + tx_rdy <= '1'; + baud_cnt_next <= CLK_PER_BAUD; + when SEND => + -- Signalisiert dass gerade ein Byte versendet wird + tx_rdy <= '0'; + -- Counter erhoehen um die Zeit einer Bitdauer abzuwarten + baud_cnt_next <= baud_cnt + 1; + if baud_cnt = CLK_PER_BAUD then + -- wenn die Bitdauer erreicht ist, Counter reseten + baud_cnt_next <= 0; + -- Counter um die einzelen Bits zu versenden + cnt_next <= cnt + 1; + case cnt is + when 0 => + -- counter = 0 => Startbit versenden + bus_tx_nxt <= '0'; + when 9 => + -- counter = 9 => Stopbit versenden + bus_tx_nxt <= '1'; + when 10 => + bus_tx_nxt <= '1'; + cnt_next <= 0; + -- Signalisieren dass der Sendevorgang beendet ist + idle_sig_next <= '1'; + when others => + -- counter von 1 bis 8 => Datenbits versenden + bus_tx_nxt <= tx_data(cnt-1); + end case; + end if; + end case; + end process; + +end architecture beh; -- 2.25.1