From 01e672d02826a9532fe64a875f07c5bf14fb3d2b Mon Sep 17 00:00:00 2001 From: Carlos Camargo Date: Thu, 27 May 2010 21:26:56 -0500 Subject: [PATCH] Fixing plasma files.. Now works :) --- Examples/sram/logic/Makefile | 3 +- plasma/bootldr/bootldr.c | 5 +- plasma/logic/Makefile | 4 +- plasma/logic/code.txt | 658 ----------------------------- plasma/logic/control.vhd | 7 +- plasma/logic/mlite_cpu.vhd | 2 +- plasma/logic/mlite_pack.vhd | 75 +++- plasma/logic/plasma.vhd | 219 ++++++---- plasma/logic/plasma_TB.vhd | 19 +- plasma/logic/ram_image.vhd | 11 +- plasma/logic/ram_xilinx.vhd | 11 +- plasma/logic/reg_bank.vhd | 85 ++++ plasma/logic/simulation/output.txt | 0 plasma/logic/simulation/wave.do | 47 +-- plasma/logic/uart.vhd | 150 ++++--- 15 files changed, 421 insertions(+), 875 deletions(-) delete mode 100644 plasma/logic/code.txt delete mode 100644 plasma/logic/simulation/output.txt diff --git a/Examples/sram/logic/Makefile b/Examples/sram/logic/Makefile index c45fbd9..f4b5f68 100644 --- a/Examples/sram/logic/Makefile +++ b/Examples/sram/logic/Makefile @@ -89,8 +89,7 @@ timesim: build/project_r.v cd simulation; $(SIM_CMD) -do $(DESIGN)_TIMING_TB.do iversim: - $(IVERILOG) -Wall -y $(XILINXCADROOT)/unisims -y $(XILINXCADROOT)/XilinxCoreLib -o simulation/$(DESIGN)_TB.vvp $(VINCDIR) $(SRC) $(SIM_SRC) -s $(DESIGN)_TB -# $(IVERILOG) -Wall -y $(XILINXCADROOT)/unisims -y $(XILINXCADROOT)/XilinxCoreLib -o simulation/$(DESIGN)_TB.vvp $(VINCDIR) build/project.v $(SIM_SRC) -s $(DESIGN)_TB + $(IVERILOG) -Wall -o simulation/$(DESIGN)_TB.vvp $(VINCDIR) $(SRC) $(SIM_SRC) -s $(DESIGN)_TB vvp simulation/$(DESIGN)_TB.vvp; mv $(DESIGN)_TB.vcd simulation/ gtkwave simulation/$(DESIGN)_TB.vcd& diff --git a/plasma/bootldr/bootldr.c b/plasma/bootldr/bootldr.c index 0295e45..d2d6735 100644 --- a/plasma/bootldr/bootldr.c +++ b/plasma/bootldr/bootldr.c @@ -122,10 +122,7 @@ int main(void) DdrInit(); //Harmless if SDRAM instead of DDR - puts("\n1233456Greetings from the bootloader "); - puts(__DATE__); - puts(" "); - puts(__TIME__); + puts("\nSAKC bootloader "); puts(":\n"); MemoryWrite(FLASH_BASE, 0xff); //read mode if((MemoryRead(GPIOA_IN) & 1) && (MemoryRead(FLASH_BASE) & 0xffff) == 0x3c1c) diff --git a/plasma/logic/Makefile b/plasma/logic/Makefile index d3cf6cc..702fe27 100644 --- a/plasma/logic/Makefile +++ b/plasma/logic/Makefile @@ -1,14 +1,14 @@ DESIGN = plasma PINS = $(DESIGN).ucf DEVICE = xc3s500e-VQ100-4 -#DEVICE = xc3s250e-fg320-4 +#DEVICE = xc3s500e-fg320-4 BGFLAGS = -g TdoPin:PULLNONE -g DonePin:PULLUP \ -g CRC:enable -g StartUpClk:CCLK SIM_CMD = /opt/cad/modeltech/bin/vsim SIM_COMP_SCRIPT = simulation/$(DESIGN)_TB.do SIMGEN_OPTIONS = -p $(FPGA_ARCH) -lang $(LANGUAGE) -SRC_HDL = plasma.vhd ram_image.vhd alu.vhd control.vhd mem_ctrl.vhd mult.vhd shifter.vhd bus_mux.vhd mlite_cpu.vhd pc_next.vhd mlite_pack.vhd pipeline.vhd reg_bank.vhd uart.vhd +SRC_HDL = mlite_pack.vhd plasma.vhd ram_image.vhd alu.vhd control.vhd mem_ctrl.vhd mult.vhd shifter.vhd bus_mux.vhd mlite_cpu.vhd pc_next.vhd pipeline.vhd reg_bank.vhd uart.vhd all: bits diff --git a/plasma/logic/code.txt b/plasma/logic/code.txt deleted file mode 100644 index 934d128..0000000 --- a/plasma/logic/code.txt +++ /dev/null @@ -1,658 +0,0 @@ -3c1c0000 -379c8a34 -3c040000 -34840a48 -3c050000 -34a50a64 -3c1d0000 -37bd0c60 -ac800000 -0085182a -1460fffd -24840004 -0c0001d5 -00000000 -0800000e -23bdff98 -afa10010 -afa20014 -afa30018 -afa4001c -afa50020 -afa60024 -afa70028 -afa8002c -afa90030 -afaa0034 -afab0038 -afac003c -afad0040 -afae0044 -afaf0048 -afb8004c -afb90050 -afbf0054 -401a7000 -235afffc -afba0058 -0000d810 -afbb005c -0000d812 -afbb0060 -23a50000 -3c062000 -8cc40020 -8cc60010 -0c00020a -00862024 -8fa10010 -8fa20014 -8fa30018 -8fa4001c -8fa50020 -8fa60024 -8fa70028 -8fa8002c -8fa90030 -8faa0034 -8fab0038 -8fac003c -8fad0040 -8fae0044 -8faf0048 -8fb8004c -8fb90050 -8fbf0054 -8fba0058 -8fbb005c -03600011 -8fbb0060 -03600013 -23bd0068 -341b0001 -03400008 -409b6000 -40026000 -03e00008 -40846000 -3c050000 -24a50160 -8ca60000 -ac06003c -8ca60004 -ac060040 -8ca60008 -ac060044 -8ca6000c -03e00008 -ac060048 -3c1a1000 -375a003c -03400008 -00000000 -ac900000 -ac910004 -ac920008 -ac93000c -ac940010 -ac950014 -ac960018 -ac97001c -ac9e0020 -ac9c0024 -ac9d0028 -ac9f002c -03e00008 -34020000 -8c900000 -8c910004 -8c920008 -8c93000c -8c940010 -8c950014 -8c960018 -8c97001c -8c9e0020 -8c9c0024 -8c9d0028 -8c9f002c -03e00008 -34a20000 -00850019 -00001012 -00002010 -03e00008 -acc40000 -3c020000 -24420a48 -a0400008 -24050007 -00403825 -3083000f -2862000a -10400003 -00a73021 -10000002 -24620030 -24620037 -a0c20000 -24a5ffff -04a1fff6 -00042102 -3c020000 -03e00008 -24420a48 -3c020000 -24420a58 -a040000a -00803025 -24050009 -00404025 -3c07cccc -34e7cccd -00c70019 -00a82021 -24a5ffff -00004810 -000918c2 -00031080 -00431021 -00021040 -00c21023 -24420030 -a0820000 -04a1fff4 -00603025 -3c020000 -03e00008 -24420a58 -27bdffe0 -afbf0018 -afb10014 -afb00010 -0c000090 -00808825 -0c0001ef -00402025 -3c040000 -0c0001ef -24840980 -3c023b9a -3442c9ff -0051102b -1040001e -3c030004 -34634b83 -00111242 -00430019 -3c030000 -246309cc -00002810 -000581c2 -00101080 -00431021 -8c440000 -0c0001ef -00000000 -3c040000 -0c0001ef -24840984 -00101140 -00501023 -00021080 -00501023 -00021100 -00501021 -000210c0 -00501023 -00021940 -00621823 -00031880 -00701821 -00031a40 -02238823 -3c0205f5 -3442e0ff -0051102b -10400023 -3c0255e6 -34423b89 -02220019 -3c030000 -246309cc -00002810 -00058642 -00101080 -00431021 -8c440000 -0c0001ef -00000000 -3c040000 -0c0001ef -24840990 -00101040 -00501021 -00021180 -00501023 -00021080 -00501023 -00021100 -00501023 -00021140 -00501021 -00021200 -02228823 -3c02000f -3442423f -0051102b -14400005 -3c020131 -3c040000 -0c0001ef -2484099c -3c020131 -34422cff -0051102b -10400021 -3c026b5f -3442ca6b -02220019 -3c030000 -246309cc -00002810 -00058582 -26020014 -00021080 -00431021 -8c440000 -0c0001ef -00000000 -0c0001de -24040020 -00101940 -00701823 -00031180 -00431023 -000210c0 -00501021 -00021880 -00431021 -000211c0 -02228823 -3c02000f -3442423f -0051102b -14400009 -3c02431b -3c040000 -0c0001ef -2484099c -3c02000f -3442423f -0051102b -10400017 -3c02431b -3442de83 -02220019 -3c030000 -246309cc -00002810 -00058482 -00101080 -00431021 -8c440000 -0c0001ef -00000000 -3c040000 -0c0001ef -248409a8 -00101940 -00701823 -00031180 -00431023 -000210c0 -00501021 -00021180 -02228823 -3c020001 -3442869f -0051102b -10400020 -3c030a7c -34635ac5 -00111142 -00430019 -3c030000 -246309cc -00002810 -000581c2 -00101080 -00431021 -8c440000 -0c0001ef -00000000 -3c040000 -0c0001ef -24840990 -00101040 -00501021 -00021980 -00431021 -00021080 -00501021 -00021080 -00501021 -00021140 -02228823 -2e2203e8 -10400005 -2e224e20 -3c040000 -0c0001ef -248409b4 -2e224e20 -1440001f -2e2203e8 -3c02d1b7 -34421759 -02220019 -3c030000 -246309cc -00002810 -00058342 -26020014 -00021080 -00431021 -8c440000 -0c0001ef -00000000 -0c0001de -24040020 -00101080 -00501021 -000210c0 -00501023 -00021100 -00501021 -00021100 -02228823 -2e2203e8 -10400008 -3c021062 -3c040000 -0c0001ef -248409b4 -2e2203e8 -14400017 -2e220064 -3c021062 -34424dd3 -02220019 -3c030000 -246309cc -00002810 -00058182 -00101080 -00431021 -8c440000 -0c0001ef -00000000 -3c040000 -0c0001ef -248409c0 -00101140 -00501023 -00021080 -00501021 -000210c0 -02228823 -2e220064 -14400017 -2e220014 -3c0251eb -3442851f -02220019 -3c030000 -246309cc -00002810 -00058142 -00101080 -00431021 -8c440000 -0c0001ef -00000000 -3c040000 -0c0001ef -24840990 -00101040 -00501021 -000210c0 -00501021 -00021080 -02228823 -2e220014 -14400014 -3c030000 -3c02cccc -3442cccd -02220019 -246309cc -00002810 -000580c2 -26020014 -00021080 -00431021 -8c440000 -0c0001ef -00000000 -0c0001de -24040020 -00101080 -00501021 -00021040 -02228823 -3c030000 -246309cc -00111080 -00431021 -8c440000 -0c0001ef -00000000 -0c0001de -2404000d -0c0001de -2404000a -8fbf0018 -8fb10014 -8fb00010 -03e00008 -27bd0020 -27bdffe8 -afbf0014 -afb00010 -24100003 -0c0000a8 -02002025 -00101040 -1000fffc -02028021 -3c022000 -34420020 -8c420000 -00000000 -30420002 -14400008 -3c022000 -3c032000 -34630020 -8c620000 -00000000 -30420002 -1040fffc -3c022000 -ac440000 -03e00008 -00000000 -27bdffe0 -afb00010 -00808025 -afbf0018 -afb10014 -92020000 -00000000 -1040000d -2411000a -00000000 -14510003 -00000000 -0c0001de -2404000d -92040000 -0c0001de -26100001 -92020000 -00000000 -1440fff5 -00000000 -8fbf0018 -8fb10014 -8fb00010 -00001025 -03e00008 -27bd0020 -27bdffe8 -afbf0010 -0c0001de -24040049 -8fbf0010 -00000000 -03e00008 -27bd0018 -3c022000 -34420020 -8c420000 -03e00008 -30420001 -27bdffe8 -afbf0010 -0c000212 -00000000 -1040fffd -3c022000 -8c420000 -8fbf0010 -00000000 -03e00008 -27bd0018 -00000000 -00000000 -00000000 -00000000 -00000000 -00000000 -6e696e65 -74790000 -65696768 -74790000 -73657665 -6e747900 -73697874 -79000000 -66696674 -79000000 -666f7274 -79000000 -74686972 -74790000 -7477656e -74790000 -6e696e65 -7465656e -00000000 -65696768 -7465656e -00000000 -73657665 -6e746565 -6e000000 -73697874 -65656e00 -66696674 -65656e00 -666f7572 -7465656e -00000000 -74686972 -7465656e -00000000 -7477656c -76650000 -656c6576 -656e0000 -74656e00 -6e696e65 -00000000 -65696768 -74000000 -73657665 -6e000000 -73697800 -66697665 -00000000 -666f7572 -00000000 -74687265 -65000000 -74776f00 -6f6e6500 -00000000 -3a200000 -2062696c -6c696f6e -20000000 -2068756e -64726564 -20000000 -6d696c6c -696f6e20 -00000000 -206d696c -6c696f6e -20000000 -74686f75 -73616e64 -20000000 -2074686f -7573616e -64200000 -0000097c -00000978 -00000974 -0000096c -00000964 -0000095c -00000958 -00000950 -00000948 -00000940 -0000093c -00000934 -0000092c -00000920 -00000914 -0000090c -00000904 -000008f8 -000008ec -000008e0 -0000097c -0000093c -000008d8 -000008d0 -000008c8 -000008c0 -000008b8 -000008b0 -000008a8 -000008a0 -00000000 diff --git a/plasma/logic/control.vhd b/plasma/logic/control.vhd index 04ad06d..aa240bf 100644 --- a/plasma/logic/control.vhd +++ b/plasma/logic/control.vhd @@ -136,7 +136,7 @@ begin c_source := C_FROM_MULT; mult_function := MULT_READ_HI; - when "010001" => --FTHI s->hi=r[rs]; + when "010001" => --MTHI s->hi=r[rs]; mult_function := MULT_WRITE_HI; when "010010" => --MFLO r[rd]=s->lo; @@ -240,8 +240,8 @@ begin --when "10011" => --BGEZALL r[31]=s->pc_next; lbranch=r[rs]>=0; --when "00011" => --BGEZL lbranch=r[rs]>=0; - when others => - end case; + when others => + end case; when "000011" => --JAL r[31]=s->pc_next; s->pc_next=(s->pc&0xf0000000)|target; c_source := C_FROM_PC_PLUS4; @@ -479,3 +479,4 @@ begin end process; end; --logic + diff --git a/plasma/logic/mlite_cpu.vhd b/plasma/logic/mlite_cpu.vhd index d005a28..c512661 100644 --- a/plasma/logic/mlite_cpu.vhd +++ b/plasma/logic/mlite_cpu.vhd @@ -72,7 +72,7 @@ use ieee.std_logic_1164.all; use ieee.std_logic_unsigned.all; entity mlite_cpu is - generic(memory_type : string := "XILINX_16X"; + generic(memory_type : string := "XILINX_16X"; --ALTERA_LPM, or DUAL_PORT_ mult_type : string := "DEFAULT"; --AREA_OPTIMIZED shifter_type : string := "DEFAULT"; --AREA_OPTIMIZED alu_type : string := "DEFAULT"; --AREA_OPTIMIZED diff --git a/plasma/logic/mlite_pack.vhd b/plasma/logic/mlite_pack.vhd index 691cb16..20f2391 100644 --- a/plasma/logic/mlite_pack.vhd +++ b/plasma/logic/mlite_pack.vhd @@ -107,6 +107,59 @@ package mlite_pack is ) return std_logic_vector; function bv_inc(a : in std_logic_vector ) return std_logic_vector; + + -- For Altera + COMPONENT lpm_ram_dp + generic ( + LPM_WIDTH : natural; -- MUST be greater than 0 + LPM_WIDTHAD : natural; -- MUST be greater than 0 + LPM_NUMWORDS : natural := 0; + LPM_INDATA : string := "REGISTERED"; + LPM_OUTDATA : string := "REGISTERED"; + LPM_RDADDRESS_CONTROL : string := "REGISTERED"; + LPM_WRADDRESS_CONTROL : string := "REGISTERED"; + LPM_FILE : string := "UNUSED"; + LPM_TYPE : string := "LPM_RAM_DP"; + USE_EAB : string := "OFF"; + INTENDED_DEVICE_FAMILY : string := "UNUSED"; + RDEN_USED : string := "TRUE"; + LPM_HINT : string := "UNUSED"); + port ( + RDCLOCK : in std_logic := '0'; + RDCLKEN : in std_logic := '1'; + RDADDRESS : in std_logic_vector(LPM_WIDTHAD-1 downto 0); + RDEN : in std_logic := '1'; + DATA : in std_logic_vector(LPM_WIDTH-1 downto 0); + WRADDRESS : in std_logic_vector(LPM_WIDTHAD-1 downto 0); + WREN : in std_logic; + WRCLOCK : in std_logic := '0'; + WRCLKEN : in std_logic := '1'; + Q : out std_logic_vector(LPM_WIDTH-1 downto 0)); + END COMPONENT; + + -- For Altera + component LPM_RAM_DQ + generic ( + LPM_WIDTH : natural; -- MUST be greater than 0 + LPM_WIDTHAD : natural; -- MUST be greater than 0 + LPM_NUMWORDS : natural := 0; + LPM_INDATA : string := "REGISTERED"; + LPM_ADDRESS_CONTROL: string := "REGISTERED"; + LPM_OUTDATA : string := "REGISTERED"; + LPM_FILE : string := "UNUSED"; + LPM_TYPE : string := "LPM_RAM_DQ"; + USE_EAB : string := "OFF"; + INTENDED_DEVICE_FAMILY : string := "UNUSED"; + LPM_HINT : string := "UNUSED"); + port ( + DATA : in std_logic_vector(LPM_WIDTH-1 downto 0); + ADDRESS : in std_logic_vector(LPM_WIDTHAD-1 downto 0); + INCLOCK : in std_logic := '0'; + OUTCLOCK : in std_logic := '0'; + WE : in std_logic; + Q : out std_logic_vector(LPM_WIDTH-1 downto 0)); + end component; + -- For Xilinx component RAM16X1D -- synthesis translate_off @@ -309,15 +362,17 @@ package mlite_pack is end component; --cache component ram + generic(memory_type : string := "DEFAULT"); port(clk : in std_logic; enable : in std_logic; write_byte_enable : in std_logic_vector(3 downto 0); - address : in std_logic_vector(10 downto 0); + address : in std_logic_vector(31 downto 2); data_write : in std_logic_vector(31 downto 0); data_read : out std_logic_vector(31 downto 0)); end component; --ram component uart + generic(log_file : string := "UNUSED"); port(clk : in std_logic; reset : in std_logic; cs : in std_logic; @@ -326,7 +381,8 @@ package mlite_pack is data_out : out std_logic_vector(7 downto 0); uart_read : in std_logic; uart_write : out std_logic; - addr : in std_logic_vector(3 downto 0)); + busy_write : out std_logic; + data_avail : out std_logic); end component; --uart component eth_dma @@ -357,18 +413,19 @@ package mlite_pack is end component; --eth_dma component plasma - generic(memory_type : string := "XILINX_X16"); - port(clk : in std_logic; - reset : in std_logic; - U_TxD : out std_logic; - U_RxD : in std_logic; + generic(memory_type : string := "XILINX_X16"; --"DUAL_PORT_" "ALTERA_LPM"; + log_file : string := "UNUSED"); + port(clk_in : in std_logic; + rst_in : in std_logic; + uart_write : out std_logic; + uart_read : in std_logic; + addr : in std_logic_vector(12 downto 0); sram_data : in std_logic_vector(7 downto 0); nwe : in std_logic; noe : in std_logic; ncs : in std_logic; - led : out std_logic - ); + led : out std_logic); end component; --plasma component ddr_ctrl diff --git a/plasma/logic/plasma.vhd b/plasma/logic/plasma.vhd index 418be4e..8c5d764 100644 --- a/plasma/logic/plasma.vhd +++ b/plasma/logic/plasma.vhd @@ -17,22 +17,25 @@ -- 0x20000000 Uart Read -- 0x20000010 IRQ Mask -- 0x20000020 IRQ Status --- 0x20000030 GPIO0 Out Set bits --- 0x20000040 GPIO0 Out Clear bits --- 0x20000050 GPIOA In +-- 0x20000030 Peripheric 1 +-- 0x20000040 Peripheric 2 +-- 0x20000050 Peripheric 3 +-- 0x20000060 Peripheric 4 +-- IRQ bits: +-- 1 ^UartWriteBusy +-- 0 UartDataAvailable --------------------------------------------------------------------- library ieee; use ieee.std_logic_1164.all; use work.mlite_pack.all; -library UNISIM; -use UNISIM.vcomponents.all; entity plasma is - generic(memory_type : string := "XILINX_16X"); - port(clk : in std_logic; - reset : in std_logic; - U_TxD : out std_logic; - U_RxD : in std_logic; + generic(memory_type : string := "XILINX_16X"; --"DUAL_PORT_" "ALTERA_LPM"; + log_file : string := "UNUSED"); + port(clk_in : in std_logic; + rst_in : in std_logic; + uart_write : out std_logic; + uart_read : in std_logic; addr : in std_logic_vector(12 downto 0); sram_data : in std_logic_vector(7 downto 0); nwe : in std_logic; @@ -43,7 +46,9 @@ entity plasma is end; --entity plasma architecture logic of plasma is - signal address_next : std_logic_vector(31 downto 0); + signal reset : std_logic; + signal clk : std_logic; + signal address_next : std_logic_vector(31 downto 2); signal byte_we_next : std_logic_vector(3 downto 0); signal cpu_address : std_logic_vector(31 downto 0); signal cpu_byte_we : std_logic_vector(3 downto 0); @@ -52,8 +57,18 @@ architecture logic of plasma is signal cpu_pause : std_logic; signal data_read_uart : std_logic_vector(7 downto 0); + signal data_read_pic : std_logic_vector(7 downto 0); + signal write_enable : std_logic; + signal mem_busy : std_logic; + signal cs_pher : std_logic; signal cs_uart : std_logic; + signal cs_pic : std_logic; + signal cs_p1 : std_logic; + signal cs_p2 : std_logic; + signal cs_p3 : std_logic; + signal cs_p4 : std_logic; + signal uart_write_busy : std_logic; signal uart_data_avail : std_logic; signal irq_mask_reg : std_logic_vector(7 downto 0); @@ -61,12 +76,31 @@ architecture logic of plasma is signal irq : std_logic; signal cs_ram : std_logic; + signal ram_byte_we : std_logic_vector(3 downto 0); signal ram_address : std_logic_vector(31 downto 2); + signal ram_data_w : std_logic_vector(31 downto 0); signal ram_data_r : std_logic_vector(31 downto 0); - signal nreset : std_logic; -begin --architecture +begin +--%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% +-- PROCESSOR +--%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% + led <= not(rst_in); + reset <= not(rst_in); + + clk_div: process(reset, clk, clk_in) + begin + if reset = '1' then + clk <= '0'; + elsif rising_edge(clk_in) then + clk <= not clk; + end if; + end process; + + write_enable <= '1' when cpu_byte_we /= "0000" else '0'; + cpu_pause <= (uart_write_busy and cs_uart and write_enable); + --%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% -- PROCESSOR --%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% @@ -74,89 +108,128 @@ begin --architecture generic map (memory_type => memory_type) PORT MAP ( clk => clk, - reset_in => nreset, + reset_in => reset, intr_in => irq, - - address_next => address_next(31 downto 2), --before rising_edge(clk) + address_next => address_next, --before rising_edge(clk) byte_we_next => byte_we_next, - address => cpu_address(31 downto 2), --after rising_edge(clk) byte_we => cpu_byte_we, data_w => cpu_data_w, data_r => cpu_data_r, mem_pause => cpu_pause); +--%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% +-- ADDRESS DECODER +--%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% + cpu_address(1 downto 0) <= "00"; + + addr_decoder: process (cpu_address) + variable addr_dec : std_logic_vector(6 downto 0); + begin + addr_dec := cpu_address(30 downto 28) & cpu_address(7 downto 4); + case addr_dec is + when "0100000" => cs_uart <= '1'; cs_pic <= '0'; cs_p1 <= '0'; cs_p2 <= '0'; cs_p3 <= '0'; cs_p4 <= '0'; + when "0100001" => cs_uart <= '0'; cs_pic <= '1'; cs_p1 <= '0'; cs_p2 <= '0'; cs_p3 <= '0'; cs_p4 <= '0'; + when "0100010" => cs_uart <= '0'; cs_pic <= '1'; cs_p1 <= '0'; cs_p2 <= '0'; cs_p3 <= '0'; cs_p4 <= '0'; + when "0100011" => cs_uart <= '0'; cs_pic <= '0'; cs_p1 <= '1'; cs_p2 <= '0'; cs_p3 <= '0'; cs_p4 <= '0'; + when "0100100" => cs_uart <= '0'; cs_pic <= '0'; cs_p1 <= '0'; cs_p2 <= '1'; cs_p3 <= '0'; cs_p4 <= '0'; + when "0100101" => cs_uart <= '0'; cs_pic <= '0'; cs_p1 <= '0'; cs_p2 <= '0'; cs_p3 <= '1'; cs_p4 <= '0'; + when "0100110" => cs_uart <= '0'; cs_pic <= '0'; cs_p1 <= '0'; cs_p2 <= '0'; cs_p3 <= '0'; cs_p4 <= '1'; + when others => cs_uart <= '0'; cs_pic <= '0'; cs_p1 <= '0'; cs_p2 <= '0'; cs_p3 <= '0'; cs_p4 <= '0'; + end case; + end process; + +--%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% +-- BUS MULTIPLEXOR +--%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% + + bus_mux: process (cpu_address, ram_data_r, data_read_uart, data_read_pic) + variable bus_dec : std_logic_vector(6 downto 0); + begin + bus_dec := cpu_address(30 downto 28) & cpu_address(7 downto 4); + case bus_dec is + when "000----" => cpu_data_r <= ram_data_r; + when "0100000" => cpu_data_r <= ZERO(31 downto 8) & data_read_uart; + when "0100001" => cpu_data_r <= ZERO(31 downto 8) & data_read_pic; + when "0100010" => cpu_data_r <= ZERO(31 downto 8) & data_read_pic; + when "0100011" => cpu_data_r <= ZERO; + when "0100100" => cpu_data_r <= ZERO; + when "0100101" => cpu_data_r <= ZERO; + when "0100110" => cpu_data_r <= ZERO; + when others => cpu_data_r <= ZERO; + end case; + end process; + +--%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% +-- PIC +--%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% + pic_proc: process(clk, reset, cpu_address, cs_pic, cpu_pause, cpu_byte_we, irq_mask_reg, irq_status, cpu_data_w) + begin + + irq_status <= ZERO(5 downto 0) & not uart_write_busy & uart_data_avail; + + if cs_pic = '1' and cpu_byte_we = "0000" then + case cpu_address(5 downto 4) is + when "01" => data_read_pic <= irq_mask_reg; + when "10" => data_read_pic <= irq_status; + when others => data_read_pic <= ZERO(7 downto 0); + end case; + end if; + + if reset = '1' then + irq_mask_reg <= ZERO(7 downto 0); + elsif rising_edge(clk) then + if cpu_pause = '0' then + if cs_pic = '1' and cpu_byte_we = "1111" then + if cpu_address(6 downto 4) = "001" then + irq_mask_reg <= cpu_data_w(7 downto 0); + end if; + end if; + end if; + end if; + + if (irq_status and irq_mask_reg) /= ZERO(7 downto 0) then + irq <= '1'; + else + irq <= '0'; + end if; + + end process; + + +--%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% +-- RAM +--%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% + cs_ram <= '1' when address_next(30 downto 28) = "000" else '0'; + ram_address(31 downto 2) <= ZERO(31 downto 13) & address_next(12 downto 2); + u2_ram: ram + generic map (memory_type => memory_type) port map ( clk => clk, enable => cs_ram, write_byte_enable => byte_we_next, - address => ram_address(12 downto 2), + address => ram_address, data_write => cpu_data_w, data_read => ram_data_r); +--%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% +-- UART +--%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% + u3_uart: uart + generic map (log_file => log_file) port map( clk => clk, - reset => nreset, + reset => reset, cs => cs_uart, nRdWr => cpu_byte_we(0), data_in => cpu_data_w(7 downto 0), data_out => data_read_uart, - uart_read => U_RxD, - uart_write => U_TxD, - addr => cpu_address(7 downto 4)); - ---%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% --- ADDRESS DECODER ---%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% - cpu_pause <= '0'; --(uart_write_busy and enable_uart and write_enable) or --UART busy - ram_address <= ZERO(31 downto 13) & (address_next(12)) & address_next(11 downto 2); - cpu_address(1 downto 0) <= "00"; - address_next(1 downto 0) <= "00"; - - nreset <= not(reset); - - - led <= not(reset); - - addr_dec: process (cpu_address(30 downto 4)) - begin - if (cpu_address(30 downto 28) = "000") then - cs_ram <= '1'; - cs_uart <= '0'; - elsif ( (cpu_address(30 downto 28) = "010") and ( (cpu_address(11 downto 8) = "0000") )) then - cs_ram <= '0'; - cs_uart <= '1'; - else - cs_ram <= '0'; - cs_uart <= '0'; - end if; - end process; - - misc_proc: process(clk, nreset, cpu_address, - ram_data_r, data_read_uart, cpu_pause, - irq_mask_reg, irq_status, cpu_data_w) - begin - case cpu_address(30 downto 28) is - when "000" => --internal RAM - cpu_data_r <= ram_data_r; - when "010" => --misc - case cpu_address(6 downto 4) is - when "000" => --uart - cpu_data_r <= ZERO(31 downto 8) & data_read_uart; - when "010" => --uart - cpu_data_r <= ZERO(31 downto 8) & data_read_uart; - when others => - cpu_data_r <= ZERO; - end case; - when others => - cpu_data_r <= ZERO; - end case; - end process; - - - + uart_read => uart_read, + uart_write => uart_write, + busy_write => uart_write_busy, + data_avail => uart_data_avail); end; --architecture logic diff --git a/plasma/logic/plasma_TB.vhd b/plasma/logic/plasma_TB.vhd index 2be526e..e496540 100644 --- a/plasma/logic/plasma_TB.vhd +++ b/plasma/logic/plasma_TB.vhd @@ -21,8 +21,8 @@ architecture logic of tbench is constant memory_type : string := "TRI_PORT_X"; - signal clk : std_logic := '1'; - signal reset : std_logic := '0'; + signal clk_in : std_logic := '1'; + signal rst_in : std_logic := '0'; signal addr : std_logic_vector(12 downto 0); signal sram_data : std_logic_vector(7 downto 0); signal nwe : std_logic; @@ -31,18 +31,21 @@ architecture logic of tbench is signal led : std_logic; signal TxD : std_logic; + signal RxD : std_logic; + begin --architecture - clk <= not clk after 50 ns; - reset <= '1' after 500 ns; + clk_in <= not clk_in after 50 ns; + rst_in <= '1' after 500 ns; + RxD <= '1'; u1_plasma: plasma generic map (memory_type => memory_type) PORT MAP ( - clk => clk, - reset => reset, - U_RxD => TxD, - U_TxD => TxD, + clk_in => clk_in, + rst_in => rst_in, + uart_read => RxD, + uart_write => TxD, addr => addr, sram_data => sram_data, nwe => nwe, diff --git a/plasma/logic/ram_image.vhd b/plasma/logic/ram_image.vhd index a036101..a399e20 100644 --- a/plasma/logic/ram_image.vhd +++ b/plasma/logic/ram_image.vhd @@ -27,10 +27,11 @@ library UNISIM; use UNISIM.vcomponents.all; entity ram is + generic(memory_type : string := "DEFAULT"); port(clk : in std_logic; enable : in std_logic; write_byte_enable : in std_logic_vector(3 downto 0); - address : in std_logic_vector(10 downto 0); + address : in std_logic_vector(31 downto 2); data_write : in std_logic_vector(31 downto 0); data_read : out std_logic_vector(31 downto 0)); end; --entity ram @@ -107,7 +108,7 @@ INIT_3F => X"0000000000000000000000000000000000000000000000000000000000000000") port map ( DO => data_read(31 downto 24), DOP => open, - ADDR => address(10 downto 0), + ADDR => address(12 downto 2), CLK => clk, DI => data_write(31 downto 24), DIP => ZERO(0 downto 0), @@ -184,7 +185,7 @@ INIT_3F => X"0000000000000000000000000000000000000000000000000000000000000000") port map ( DO => data_read(23 downto 16), DOP => open, - ADDR => address(10 downto 0), + ADDR => address(12 downto 2), CLK => clk, DI => data_write(23 downto 16), DIP => ZERO(0 downto 0), @@ -261,7 +262,7 @@ INIT_3F => X"0000000000000000000000000000000000000000000000000000000000000000") port map ( DO => data_read(15 downto 8), DOP => open, - ADDR => address(10 downto 0), + ADDR => address(12 downto 2), CLK => clk, DI => data_write(15 downto 8), DIP => ZERO(0 downto 0), @@ -338,7 +339,7 @@ INIT_3F => X"0000000000000000000000000000000000000000000000000000000000000000") port map ( DO => data_read(7 downto 0), DOP => open, - ADDR => address(10 downto 0), + ADDR => address(12 downto 2), CLK => clk, DI => data_write(7 downto 0), DIP => ZERO(0 downto 0), diff --git a/plasma/logic/ram_xilinx.vhd b/plasma/logic/ram_xilinx.vhd index c09aa9f..ac24e1f 100644 --- a/plasma/logic/ram_xilinx.vhd +++ b/plasma/logic/ram_xilinx.vhd @@ -27,10 +27,11 @@ library UNISIM; use UNISIM.vcomponents.all; entity ram is + generic(memory_type : string := "DEFAULT"); port(clk : in std_logic; enable : in std_logic; write_byte_enable : in std_logic_vector(3 downto 0); - address : in std_logic_vector(10 downto 0); + address : in std_logic_vector(31 downto 2); data_write : in std_logic_vector(31 downto 0); data_read : out std_logic_vector(31 downto 0)); end; --entity ram @@ -107,7 +108,7 @@ INIT_3F => X"0000000000000000000000000000000000000000000000000000000000000000") port map ( DO => data_read(31 downto 24), DOP => open, - ADDR => address(10 downto 0), + ADDR => address(12 downto 2), CLK => clk, DI => data_write(31 downto 24), DIP => ZERO(0 downto 0), @@ -184,7 +185,7 @@ INIT_3F => X"0000000000000000000000000000000000000000000000000000000000000000") port map ( DO => data_read(23 downto 16), DOP => open, - ADDR => address(10 downto 0), + ADDR => address(12 downto 2), CLK => clk, DI => data_write(23 downto 16), DIP => ZERO(0 downto 0), @@ -261,7 +262,7 @@ INIT_3F => X"0000000000000000000000000000000000000000000000000000000000000000") port map ( DO => data_read(15 downto 8), DOP => open, - ADDR => address(10 downto 0), + ADDR => address(12 downto 2), CLK => clk, DI => data_write(15 downto 8), DIP => ZERO(0 downto 0), @@ -338,7 +339,7 @@ INIT_3F => X"0000000000000000000000000000000000000000000000000000000000000000") port map ( DO => data_read(7 downto 0), DOP => open, - ADDR => address(10 downto 0), + ADDR => address(12 downto 2), CLK => clk, DI => data_write(7 downto 0), DIP => ZERO(0 downto 0), diff --git a/plasma/logic/reg_bank.vhd b/plasma/logic/reg_bank.vhd index f2b1d93..f7a0552 100644 --- a/plasma/logic/reg_bank.vhd +++ b/plasma/logic/reg_bank.vhd @@ -235,4 +235,89 @@ end process; data_out2 <= data_out2A when addr_read2(4)='0' else data_out2B; end generate; --xilinx_16x1d + + -- Option #4 + -- Altera LPM_RAM_DP + altera_mem: + if memory_type = "ALTERA_LPM" generate + signal clk_delayed : std_logic; + signal addr_reg : std_logic_vector(4 downto 0); + signal data_reg : std_logic_vector(31 downto 0); + signal q1 : std_logic_vector(31 downto 0); + signal q2 : std_logic_vector(31 downto 0); + begin + -- Altera dual port RAMs must have the addresses registered (sampled + -- at the rising edge). This is very unfortunate. + -- Therefore, the dual port RAM read clock must delayed so that + -- the read address signal can be sent from the mem_ctrl block. + -- This solution also delays the how fast the registers are read so the + -- maximum clock speed is cut in half (12.5 MHz instead of 25 MHz). + + clk_delayed <= not clk; --Could be delayed by 1/4 clock cycle instead + dpram_bypass: process(clk, addr_write, reg_dest_new) + begin + if rising_edge(clk) and write_enable = '1' then + addr_reg <= addr_write; + data_reg <= reg_dest_new; + end if; + end process; --dpram_bypass + + -- Bypass dpram if reading what was just written (Altera limitation) + data_out1 <= q1 when addr_read1 /= addr_reg else data_reg; + data_out2 <= q2 when addr_read2 /= addr_reg else data_reg; + + lpm_ram_dp_component1 : lpm_ram_dp + generic map ( + LPM_WIDTH => 32, + LPM_WIDTHAD => 5, + --LPM_NUMWORDS => 0, + LPM_INDATA => "REGISTERED", + LPM_OUTDATA => "UNREGISTERED", + LPM_RDADDRESS_CONTROL => "REGISTERED", + LPM_WRADDRESS_CONTROL => "REGISTERED", + LPM_FILE => "UNUSED", + LPM_TYPE => "LPM_RAM_DP", + USE_EAB => "ON", + INTENDED_DEVICE_FAMILY => "UNUSED", + RDEN_USED => "FALSE", + LPM_HINT => "UNUSED") + port map ( + RDCLOCK => clk_delayed, + RDCLKEN => '1', + RDADDRESS => addr_read1, + RDEN => '1', + DATA => reg_dest_new, + WRADDRESS => addr_write, + WREN => write_enable, + WRCLOCK => clk, + WRCLKEN => '1', + Q => q1); + lpm_ram_dp_component2 : lpm_ram_dp + generic map ( + LPM_WIDTH => 32, + LPM_WIDTHAD => 5, + --LPM_NUMWORDS => 0, + LPM_INDATA => "REGISTERED", + LPM_OUTDATA => "UNREGISTERED", + LPM_RDADDRESS_CONTROL => "REGISTERED", + LPM_WRADDRESS_CONTROL => "REGISTERED", + LPM_FILE => "UNUSED", + LPM_TYPE => "LPM_RAM_DP", + USE_EAB => "ON", + INTENDED_DEVICE_FAMILY => "UNUSED", + RDEN_USED => "FALSE", + LPM_HINT => "UNUSED") + port map ( + RDCLOCK => clk_delayed, + RDCLKEN => '1', + RDADDRESS => addr_read2, + RDEN => '1', + DATA => reg_dest_new, + WRADDRESS => addr_write, + WREN => write_enable, + WRCLOCK => clk, + WRCLKEN => '1', + Q => q2); + end generate; --altera_mem + end; --architecture ram_block diff --git a/plasma/logic/simulation/output.txt b/plasma/logic/simulation/output.txt deleted file mode 100644 index e69de29..0000000 diff --git a/plasma/logic/simulation/wave.do b/plasma/logic/simulation/wave.do index f8acb40..87588ea 100644 --- a/plasma/logic/simulation/wave.do +++ b/plasma/logic/simulation/wave.do @@ -1,32 +1,27 @@ onerror {resume} quietly WaveActivateNextPane {} 0 -add wave -noupdate -format Logic /tbench/clk -add wave -noupdate -format Logic /tbench/reset -add wave -noupdate -format Logic /tbench/pause1 -add wave -noupdate -format Logic /tbench/pause2 -add wave -noupdate -format Logic /tbench/pause +add wave -noupdate -format Logic /tbench/clk_in +add wave -noupdate -format Logic /tbench/rst_in +add wave -noupdate -format Literal /tbench/addr +add wave -noupdate -format Literal /tbench/sram_data +add wave -noupdate -format Logic /tbench/nwe +add wave -noupdate -format Logic /tbench/noe +add wave -noupdate -format Logic /tbench/ncs +add wave -noupdate -format Logic /tbench/led +add wave -noupdate -format Logic /tbench/txd +add wave -noupdate -format Logic /tbench/rxd +add wave -noupdate -format Literal /tbench/u1_plasma/address_next +add wave -noupdate -format Literal /tbench/u1_plasma/byte_we_next +add wave -noupdate -format Literal /tbench/u1_plasma/cpu_address add wave -noupdate -format Literal /tbench/u1_plasma/cpu_byte_we -add wave -noupdate -format Literal -expand /tbench/u1_plasma/byte_we_next -add wave -noupdate -format Literal -radix hexadecimal /tbench/u1_plasma/cpu_address -add wave -noupdate -format Literal -radix hexadecimal /tbench/u1_plasma/address_next -add wave -noupdate -format Literal -radix hexadecimal /tbench/u1_plasma/cpu_data_w -add wave -noupdate -format Literal -radix hexadecimal /tbench/u1_plasma/cpu_data_r -add wave -noupdate -format Logic /tbench/u1_plasma/cs_ram -add wave -noupdate -format Logic /tbench/u1_plasma/cs_uart -add wave -noupdate -format Literal /tbench/u1_plasma/u3_uart/addr -add wave -noupdate -format Logic /tbench/u1_plasma/u3_uart/enable_read -add wave -noupdate -format Literal /tbench/u1_plasma/u3_uart/addr -add wave -noupdate -format Logic /tbench/u1_plasma/u3_uart/enable_write -add wave -noupdate -format Logic /tbench/u1_plasma/u_txd -add wave -noupdate -format Logic /tbench/u1_plasma/u3_uart/busy_write -add wave -noupdate -format Logic /tbench/u1_plasma/u_rxd -add wave -noupdate -format Logic /tbench/u1_plasma/u3_uart/data_avail -add wave -noupdate -format Literal -radix hexadecimal /tbench/u1_plasma/u3_uart/data_in -add wave -noupdate -format Literal -radix hexadecimal /tbench/u1_plasma/u3_uart/data_out +add wave -noupdate -format Literal /tbench/u1_plasma/cpu_data_w +add wave -noupdate -format Literal /tbench/u1_plasma/cpu_data_r +add wave -noupdate -format Literal /tbench/u1_plasma/data_read_uart +add wave -noupdate -format Literal /tbench/u1_plasma/data_read_pic TreeUpdate [SetDefaultTree] -WaveRestoreCursors {{Cursor 1} {999785196 ps} 0} -configure wave -namecolwidth 285 -configure wave -valuecolwidth 40 +WaveRestoreCursors {{Cursor 1} {999999246 ps} 0} +configure wave -namecolwidth 150 +configure wave -valuecolwidth 100 configure wave -justifyvalue left configure wave -signalnamewidth 0 configure wave -snapdistance 10 @@ -38,4 +33,4 @@ configure wave -gridperiod 1 configure wave -griddelta 40 configure wave -timeline 0 update -WaveRestoreZoom {0 ps} {1050 us} +WaveRestoreZoom {999999050 ps} {1000000050 ps} diff --git a/plasma/logic/uart.vhd b/plasma/logic/uart.vhd index 7a133fc..761b897 100644 --- a/plasma/logic/uart.vhd +++ b/plasma/logic/uart.vhd @@ -19,6 +19,7 @@ use std.textio.all; use work.mlite_pack.all; entity uart is + generic(log_file : string := "UNUSED"); port(clk : in std_logic; reset : in std_logic; cs : in std_logic; @@ -27,8 +28,8 @@ entity uart is data_out : out std_logic_vector(7 downto 0); uart_read : in std_logic; uart_write : out std_logic; - addr : in std_logic_vector(3 downto 0) - ); + busy_write : out std_logic; + data_avail : out std_logic); end; --entity uart architecture logic of uart is @@ -44,41 +45,25 @@ architecture logic of uart is signal uart_read2 : std_logic; signal enable_read : std_logic; signal enable_write : std_logic; - signal busy_write : std_logic; - signal data_avail : std_logic; - signal data_out_sig : std_logic_vector(7 downto 0); - begin -interface_proc: process(cs, nRdWr, addr, data_out_sig, busy_write, data_avail, data_save_reg) +interface_proc: process(cs, nRdWr) begin if cs = '1' then if nRdWr = '1' then enable_read <= '0'; enable_write <= '1'; - data_out_sig <= "00000000"; else enable_read <= '1'; enable_write <= '0'; - case addr(3 downto 0) is - when "0000" => - data_out_sig <= data_save_reg(7 downto 0); - when "0010" => - data_out_sig(7 downto 0) <= "000000" & busy_write & data_avail; - when others => - data_out_sig <= "00000000"; - end case; end if; else enable_read <= '0'; enable_write <= '0'; - data_out_sig <= "00000000"; end if; - data_out <= data_out_sig; end process; - uart_proc: process(clk, reset, enable_read, enable_write, data_in, data_write_reg, bits_write_reg, delay_write_reg, data_read_reg, bits_read_reg, delay_read_reg, @@ -86,8 +71,8 @@ uart_proc: process(clk, reset, enable_read, enable_write, data_in, busy_write_sig, uart_read) constant COUNT_VALUE : std_logic_vector(9 downto 0) := -- "0100011110"; --33MHz/2/57600Hz = 0x11e - "1101100100"; --50MHz/57600Hz = 0x364 --- "0110110010"; --25MHz/57600Hz = 0x1b2 -- Plasma IF uses div2 +-- "1101100100"; --50MHz/57600Hz = 0x364 + "0110110010"; --25MHz/57600Hz = 0x1b2 -- Plasma IF uses div2 -- "0011011001"; --12.5MHz/57600Hz = 0xd9 -- "0000000100"; --for debug (shorten read_value_reg) begin @@ -105,67 +90,72 @@ begin elsif rising_edge(clk) then --Write UART - if bits_write_reg = "0000" then --nothing left to write? - if enable_write = '1' then - delay_write_reg <= ZERO(9 downto 0); --delay before next bit - bits_write_reg <= "1010"; --number of bits to write - data_write_reg <= data_in & '0'; --remember data & start bit - end if; - else - if delay_write_reg /= COUNT_VALUE then - delay_write_reg <= delay_write_reg + 1; --delay before next bit - else - delay_write_reg <= ZERO(9 downto 0); --reset delay - bits_write_reg <= bits_write_reg - 1; --bits left to write - data_write_reg <= '1' & data_write_reg(8 downto 1); - end if; - end if; - --Average uart_read signal - if uart_read = '1' then - if read_value_reg /= ONES(read_value_reg'length - 1 downto 0) then - read_value_reg <= read_value_reg + 1; - end if; - else - if read_value_reg /= ZERO(read_value_reg'length - 1 downto 0) then - read_value_reg <= read_value_reg - 1; - end if; - end if; - --Read UART - if delay_read_reg = ZERO(9 downto 0) then --done delay for read? - if bits_read_reg = "0000" then --nothing left to read? - if uart_read2 = '0' then --wait for start bit - delay_read_reg <= '0' & COUNT_VALUE(9 downto 1); --half period - bits_read_reg <= "1001"; --bits left to read - end if; - else - delay_read_reg <= COUNT_VALUE; --initialize delay - bits_read_reg <= bits_read_reg - 1; --bits left to read - data_read_reg <= uart_read2 & data_read_reg(7 downto 1); - end if; - else - delay_read_reg <= delay_read_reg - 1; --delay - end if; - --Control character buffer - if bits_read_reg = "0000" and delay_read_reg = COUNT_VALUE then - if data_save_reg(8) = '0' or - (enable_read = '1' and data_save_reg(17) = '0') then - --Empty buffer - data_save_reg(8 downto 0) <= '1' & data_read_reg; - else - --Second character in buffer - data_save_reg(17 downto 9) <= '1' & data_read_reg; - if enable_read = '1' then - data_save_reg(8 downto 0) <= data_save_reg(17 downto 9); - end if; - end if; - elsif enable_read = '1' then - data_save_reg(17) <= '0'; --data_available - data_save_reg(8 downto 0) <= data_save_reg(17 downto 9); - end if; - end if; --rising_edge(clk) + if bits_write_reg = "0000" then --nothing left to write? + if enable_write = '1' then + delay_write_reg <= ZERO(9 downto 0); --delay before next bit + bits_write_reg <= "1010"; --number of bits to write + data_write_reg <= data_in & '0'; --remember data & start bit + end if; + else + if delay_write_reg /= COUNT_VALUE then + delay_write_reg <= delay_write_reg + 1; --delay before next bit + else + delay_write_reg <= ZERO(9 downto 0); --reset delay + bits_write_reg <= bits_write_reg - 1; --bits left to write + data_write_reg <= '1' & data_write_reg(8 downto 1); + end if; + end if; + + --Average uart_read signal + if uart_read = '1' then + if read_value_reg /= ONES(read_value_reg'length - 1 downto 0) then + read_value_reg <= read_value_reg + 1; + end if; + else + if read_value_reg /= ZERO(read_value_reg'length - 1 downto 0) then + read_value_reg <= read_value_reg - 1; + end if; + end if; + + --Read UART + if delay_read_reg = ZERO(9 downto 0) then --done delay for read? + if bits_read_reg = "0000" then --nothing left to read? + if uart_read2 = '0' then --wait for start bit + delay_read_reg <= '0' & COUNT_VALUE(9 downto 1); --half period + bits_read_reg <= "1001"; --bits left to read + end if; + else + delay_read_reg <= COUNT_VALUE; --initialize delay + bits_read_reg <= bits_read_reg - 1; --bits left to read + data_read_reg <= uart_read2 & data_read_reg(7 downto 1); + end if; + else + delay_read_reg <= delay_read_reg - 1; --delay + end if; + + --Control character buffer + if bits_read_reg = "0000" and delay_read_reg = COUNT_VALUE then + if data_save_reg(8) = '0' or + (enable_read = '1' and data_save_reg(17) = '0') then + --Empty buffer + data_save_reg(8 downto 0) <= '1' & data_read_reg; + else + --Second character in buffer + data_save_reg(17 downto 9) <= '1' & data_read_reg; + if enable_read = '1' then + data_save_reg(8 downto 0) <= data_save_reg(17 downto 9); + end if; + end if; + elsif enable_read = '1' then + data_save_reg(17) <= '0'; --data_available + data_save_reg(8 downto 0) <= data_save_reg(17 downto 9); + end if; + end if; --rising_edge(clk) uart_write <= data_write_reg(0); if bits_write_reg /= "0000" +-- Comment out the following line for full UART simulation (much slower) + and log_file = "UNUSED" then busy_write_sig <= '1'; else @@ -173,6 +163,8 @@ begin end if; busy_write <= busy_write_sig; data_avail <= data_save_reg(8); + data_out <= data_save_reg(7 downto 0); end process; --uart_proc + end; --architecture logic