spartan3e/lcd: (hw) signale per ext.modul rausziehen (sw) rest
authorBernhard Urban <lewurm@gmail.com>
Sat, 15 Jan 2011 21:23:44 +0000 (22:23 +0100)
committerBernhard Urban <lewurm@gmail.com>
Sat, 15 Jan 2011 21:23:44 +0000 (22:23 +0100)
12 files changed:
cpu/src/core_pkg.vhd
cpu/src/core_top_s3e.vhd
cpu/src/extension_lcd.vhd [new file with mode: 0644]
cpu/src/extension_lcd_b.vhd [new file with mode: 0644]
cpu/src/extension_lcd_pkg.vhd [new file with mode: 0644]
cpu/src/extension_pkg.vhd
cpu/src/writeback_stage.vhd
cpu/src/writeback_stage_b.vhd
progs/Makefile
progs/lcd.s [new file with mode: 0644]
spartan3e/Makefile
spartan3e/spartan3e.ucf

index 9731f37592de2f49322534d87c8968b0f6da25a3..722b196cfb640e5c09f9868c7ebf088318b804f1 100644 (file)
@@ -164,8 +164,9 @@ package core_pkg is
                        sseg2 : out std_logic_vector(0 to 6);
                        sseg3 : out std_logic_vector(0 to 6);
 
-                       int_req : out interrupt_t
+                       int_req : out interrupt_t;
 
+                       lcd_data : out std_logic_vector(6 downto 0)
                );
        end component writeback_stage;
 
index 62b2b5d7f69f4ddbb90ee1ac8cb2784453b3c9d0..26c2ceaad676a72caa37657ca96d8cca229ad24a 100644 (file)
@@ -20,11 +20,8 @@ entity core_top is
                        bus_rx : in std_logic;
                        led1 : out std_logic;
                        led2 : out std_logic;
-                       
-                       sseg0 : out std_logic_vector(0 to 6);
-                       sseg1 : out std_logic_vector(0 to 6);
-                       sseg2 : out std_logic_vector(0 to 6);
-                       sseg3 : out std_logic_vector(0 to 6)
+                       -- RW, EN, RS, DB7, DB6, DB5, DB4
+                       lcd_data : out std_logic_vector(6 downto 0)
                );
 
 end core_top;
@@ -165,7 +162,7 @@ begin
                 reg_wr_data_pin, reg_we_pin, reg_w_addr_pin, jump_result_pin, alu_jump_bit_pin,bus_tx, bus_rx,
                                -- instruction memory program port :D
                                new_im_data, im_addr, im_data,
-                               sseg0, sseg1, sseg2, sseg3, int_req);
+                               open, open, open, open, int_req, lcd_data);
 
 
 syn: process(sys_clk, sys_res)
diff --git a/cpu/src/extension_lcd.vhd b/cpu/src/extension_lcd.vhd
new file mode 100644 (file)
index 0000000..8d99b8a
--- /dev/null
@@ -0,0 +1,21 @@
+library IEEE;
+use IEEE.std_logic_1164.all;
+use IEEE.numeric_std.all;
+
+use work.common_pkg.all;
+use work.extension_pkg.all;
+use work.extension_imp_pkg.all;
+
+entity extension_lcd is
+       generic ( 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;
+                       -- out lcd
+                       lcd_data : out std_logic_vector(6 downto 0)
+               );
+end extension_lcd;
diff --git a/cpu/src/extension_lcd_b.vhd b/cpu/src/extension_lcd_b.vhd
new file mode 100644 (file)
index 0000000..d39f848
--- /dev/null
@@ -0,0 +1,73 @@
+library IEEE;
+use IEEE.std_logic_1164.all;
+use IEEE.numeric_std.all;
+use IEEE.STD_LOGIC_ARITH.ALL;
+use IEEE.STD_LOGIC_UNSIGNED.ALL;
+
+use work.common_pkg.all;
+use work.core_pkg.all;
+
+use work.mem_pkg.all;
+use work.extension_pkg.all;
+use work.extension_lcd_pkg.all;
+
+architecture behav of extension_lcd is
+
+signal w1_st_co, w1_st_co_nxt : gp_register_t;
+
+begin
+syn : process (clk, reset)
+begin
+   if (reset = RESET_VALUE) then
+                       w1_st_co <= (others => '0');
+       elsif rising_edge(clk) then
+                       w1_st_co <= w1_st_co_nxt;
+   end if;
+end process syn;
+
+-------------------------- LESEN UND SCHREIBEN ANFANG ------------------------------------------------------------
+-- w1_st_co LAYOUT: (auf addr 0x2050)
+--             w1_st_co(3 downto 0) = DB7 - DB4
+--             w1_st_co(4)          = RS
+--             w1_st_co(5)          = EN
+--             w1_st_co(6)          = RW
+
+gwriten : process (clk, ext_reg, w1_st_co)
+variable tmp_data : gp_register_t;
+begin
+       w1_st_co_nxt <= w1_st_co;
+
+       if ext_reg.sel = '1' and ext_reg.wr_en = '1' then
+               tmp_data := (others =>'0');
+               for i in 0 to 3 loop
+                       if ext_reg.byte_en(i) = '1' then
+                               tmp_data(((i+1)*byte_t'length-1) downto i*byte_t'length) := ext_reg.data(((i+1)*byte_t'length-1) downto i*byte_t'length);
+                       end if;
+               end loop;
+
+               case ext_reg.addr(1 downto 0) is
+               when "00" => -- status/config
+                       w1_st_co_nxt(6 downto 0) <= tmp_data(6 downto 0);
+               when others => null;
+               end case;
+       end if;
+end process gwriten;
+
+gread : process (clk, ext_reg, w1_st_co)
+variable tmp_data : gp_register_t;
+begin
+       tmp_data := (others => '0');
+       if ext_reg.sel = '1' and ext_reg.wr_en = '0' then
+               case ext_reg.addr(1 downto 0) is
+                       when "00" => put_word_be(tmp_data, w1_st_co, ext_reg.byte_en);
+                       when others => null;
+               end case;
+       end if;
+       data_out <= tmp_data;
+end process gread;
+
+-------------------------- LESEN UND SCHREIBEN ENDE ---------------------------------------------------------------
+-------------------------- INTERNE VERARBEITUNG ANFANG ------------------------------------------------------------
+lcd_data <= w1_st_co(6 downto 0);
+-------------------------- INTERNE VERARBEITUNG ENDE --------------------------------------------------------------
+end behav;
diff --git a/cpu/src/extension_lcd_pkg.vhd b/cpu/src/extension_lcd_pkg.vhd
new file mode 100644 (file)
index 0000000..19a35ec
--- /dev/null
@@ -0,0 +1,23 @@
+library IEEE;
+
+use IEEE.std_logic_1164.all;
+use IEEE.numeric_std.all;
+
+use work.common_pkg.all;
+use work.extension_pkg.all;
+
+package extension_lcd_pkg is
+       component extension_lcd is
+       generic ( 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;
+                       -- out lcd
+                       lcd_data : out std_logic_vector(6 downto 0)
+               );
+       end component extension_lcd;
+end package extension_lcd_pkg;
index f20a119af697a134d0e9484e4067fc00a1b4d554..31cc54251f7c90b9d4cee4d53a2df990acc2babf 100644 (file)
@@ -42,6 +42,7 @@ constant EXT_7SEG_ADDR:   ext_addrid_t := x"0000201";
 constant EXT_INT_ADDR:   ext_addrid_t := x"0000202";
 constant EXT_IMP_ADDR:   ext_addrid_t := x"0000203";
 constant EXT_TIMER_ADDR:  ext_addrid_t := x"0000204";
+constant EXT_LCD_ADDR:    ext_addrid_t := x"0000205";
 -- dummy addressen
 constant EXT_EXTMEM_ADDR: ext_addrid_t := x"FFFFFFB";
 constant EXT_AC97_ADDR:   ext_addrid_t := x"FFFFFFD";
index ea82a1edc3e045cd22365abe7181a757bdab8069..4f2c231ffcf25c6f5fb7c4ca0411d7b49cc22637 100644 (file)
@@ -49,8 +49,9 @@ entity writeback_stage is
                        sseg2 : out std_logic_vector(0 to 6);
                        sseg3 : out std_logic_vector(0 to 6);
 
-                       int_req : out interrupt_t
+                       int_req : out interrupt_t;
 
+                       lcd_data : out std_logic_vector(6 downto 0)
                );
                
 end writeback_stage;
index acf0f7db2032a88263d11df7b924e9aeac5450a5..8b208b9d123a7b4bd7aef03b2ac093aaf6a8aa38 100755 (executable)
@@ -11,6 +11,7 @@ use work.extension_uart_pkg.all;
 use work.extension_7seg_pkg.all;
 use work.extension_imp_pkg.all;
 use work.extension_timer_pkg.all;
+use work.extension_lcd_pkg.all;
 
 architecture behav of writeback_stage is
 
@@ -19,8 +20,8 @@ signal data_addr : word_t;
 
 signal wb_reg, wb_reg_nxt : writeback_rec;
 
-signal ext_uart,ext_timer,ext_gpmp,ext_7seg,ext_int,ext_imp :  extmod_rec;
-signal ext_uart_out, ext_timer_out, ext_gpmp_out, ext_int_out,ext_imp_out : gp_register_t;
+signal ext_uart,ext_timer,ext_gpmp,ext_7seg,ext_int,ext_imp, ext_lcd :  extmod_rec;
+signal ext_uart_out, ext_timer_out, ext_gpmp_out, ext_int_out,ext_imp_out, ext_lcd_out : gp_register_t;
 
 --signal int_req : interrupt_t;
 signal uart_int : std_logic;
@@ -130,6 +131,10 @@ interrupt : extension_interrupt
 timer : extension_timer
        generic map(RESET_VALUE)
        port map(clk, reset, ext_timer, ext_timer_out);
+
+lcd : extension_lcd
+       generic map(RESET_VALUE)
+       port map(clk, reset, ext_lcd, ext_lcd_out, lcd_data);
        
 syn: process(clk, reset)
 
@@ -341,6 +346,7 @@ begin
   ext_uart.sel <='0';
   ext_7seg.sel <='0';
   ext_timer.sel <='0';
+  ext_lcd.sel <='0';
   ext_gpmp.sel <='0';
   ext_int.sel <= '0';
   ext_imp.sel <= '0';
@@ -348,6 +354,7 @@ begin
   ext_uart.wr_en <= wr_en;
   ext_7seg.wr_en <= wr_en;
   ext_timer.wr_en <= wr_en;
+  ext_lcd.wr_en <= wr_en;
   ext_gpmp.wr_en <= wr_en;
   ext_int.wr_en <= wr_en;  
   ext_imp.wr_en <= wr_en;  
@@ -355,6 +362,7 @@ begin
   ext_uart.byte_en <= byte_en;
   ext_7seg.byte_en <= byte_en;
   ext_timer.byte_en <= byte_en;
+  ext_lcd.byte_en <= byte_en;
   ext_gpmp.byte_en <= byte_en;
   ext_int.byte_en <= byte_en;  
   ext_imp.byte_en <= byte_en; 
@@ -362,6 +370,7 @@ begin
   ext_uart.addr <= addr;
   ext_7seg.addr <= addr;
   ext_timer.addr <= addr;
+  ext_lcd.addr <= addr;
   ext_gpmp.addr <= addr;
   ext_int.addr <= addr;
   ext_imp.addr <= addr;
@@ -369,6 +378,7 @@ begin
   ext_uart.data <= data;
   ext_7seg.data <= data;
   ext_timer.data <= data;
+  ext_lcd.data <= data;
   ext_gpmp.data <= data;
   ext_int.data <= data;
   ext_imp.data <= data;
@@ -453,6 +463,9 @@ begin
                                -- when "11" => ext_timer.byte_en <= "1000";
                                -- when others => null;
                        -- end case;
+       when EXT_LCD_ADDR =>
+               ext_lcd.sel <= enable;
+               ext_anysel <= enable;
 --     when EXT_GPMP_ADDR => 
  --            ext_gpmp.sel <= enable;
 --             ext_anysel <= enable;
@@ -470,7 +483,7 @@ begin
        when others => ext_anysel <= '0';
        end case;
        
-       data_ram_read_ext <= ext_uart_out or ext_gpmp_out or ext_timer_out;
+       data_ram_read_ext <= ext_uart_out or ext_gpmp_out or ext_timer_out or ext_lcd_out;
 end process;
 
 end behav;
index aee627591dc3917203047c9402af9c79c0605204..86817a3d84ee07472935daf56063bfcffa0007e0 100644 (file)
@@ -28,6 +28,7 @@ all: fibmmem.prog
 fibmmem.prog:
 testbench.prog:
 deepjit.prog:
+lcd.prog:
 %.prog: %.dthex
        @echo "  PROG   $<"
        ../tools/dtprog.py $< $(DPROGFLAGS) 
@@ -43,6 +44,7 @@ deepjit.prog:
 fibmmem.sim:
 testbench.sim:
 deepjit.sim:
+lcd.sim:
 %.sim: %.dthex_sim
        @echo "  SIM    $<"
        cd ../3b_sim/; ./sim -f ../progs/$<
diff --git a/progs/lcd.s b/progs/lcd.s
new file mode 100644 (file)
index 0000000..6c7dbb9
--- /dev/null
@@ -0,0 +1,153 @@
+#include "dt_inc.s"
+.text
+.org 0x0
+start:
+       br+ main
+       br+ main
+       ret
+main:
+       call+ u_init
+       call+ u_recv_byte
+       call u_send_newline
+
+       ldis r1, 0x41 ; 'A'
+       call u_send_byte
+
+       call lcd_init
+       ldis r1, 0x42 ; 'B'
+       call u_send_byte
+
+       call lcd_clear
+       ldis r1, 0x43 ; 'C'
+       call u_send_byte
+
+       call lcd_home
+       ldis r1, 0x44 ; 'D'
+       call u_send_byte
+
+       call delay5ms ; print 'E' on LCD and UART
+       ldis r1, 0x45 ; 'E'
+       push r1
+       call lcd_data
+       pop r1
+       call+ u_send_byte
+       call+ u_send_newline
+
+loop:
+       call+ u_recv_byte ; print received Char on LCD
+       addi r1, r0, 0
+       call+ lcd_data
+       br loop
+
+hang: br+ hang
+
+       .define LCD_BASE, 0x2050
+       ; http://www.mikrocontroller.net/articles/AVR-Tutorial:_LCD#Routinen_zur_LCD-Ansteuerung
+lcd_data:
+       lrs r2, r1, 4
+       andx r2, 0xf
+       orx r2, 0x10
+       stw r2, 0(r12)
+       call+ lcd_enable
+
+       andx r1, 0xf
+       orx r1, 0x10
+       stw r1, 0(r12)
+       call+ lcd_enable
+
+       call+ delay50us
+       ret
+
+lcd_command:
+       lrs r2, r1, 4
+       andx r2, 0xf
+       stw r2, 0(r12)
+       call+ lcd_enable
+
+       andx r1, 0xf
+       stw r1, 0(r12)
+       call+ lcd_enable
+
+       call+ delay50us
+       ret
+
+lcd_enable:
+       addinv r0, r0, 0
+       addinv r0, r0, 0
+       addinv r0, r0, 0
+       ldw r0, 0(r12)
+       orx r0, 0x20
+       stw r0, 0(r12)
+       addinv r0, r0, 0
+       addinv r0, r0, 0
+       addinv r0, r0, 0
+       addinv r0, r0, 0
+       addinv r0, r0, 0
+       ldw r0, 0(r12)
+       ldis r5, 0xffdf
+       and r0, r0, r5
+       stw r0, 0(r12)
+       ret
+
+delay50us: ; @ 50 MHz
+       ldis r0, 2500/2
+       ;ldis r0, 4000/2
+delay50us_:
+       subi r0, r0, 1
+       brnz+ delay50us_ ; not zero
+       ret
+
+delay5ms: ; @ 50 MHz
+       ldis r0, 5
+       ;ldis r0, 7
+delay5ms_1:
+       ldis r1, 50000/2
+delay5ms_2:
+       subi r1, r1, 1
+       brnz+ delay5ms_2 ; not zero
+       subi r0, r0, 1
+       brnz+ delay5ms_1 ; not zero
+       ret
+
+lcd_init:
+       ldis r12, LCD_BASE@lo
+       ldih r12, LCD_BASE@hi
+       ldis r3, 50
+powerupwait:
+       call+ delay5ms
+       subi r3, r3, 1
+       brnz+ powerupwait
+
+       ldis r3, 0x3
+       stw r3, 0(r12)
+       call+ lcd_enable
+       call+ delay5ms
+       call+ lcd_enable
+       call+ delay5ms
+       call+ lcd_enable
+       call+ delay5ms
+
+       ldis r3, 0x2
+       stw r3, 0(r12)
+       call+ lcd_enable
+       call+ delay5ms
+
+       ldis r1, 0x24
+       call+ lcd_command
+       ldis r1, 0xc
+       call+ lcd_command
+       ldis r1, 0x4
+       call+ lcd_command
+       ret
+
+lcd_clear:
+       ldis r1, 0x1
+       call lcd_command
+       call delay5ms
+       ret
+
+lcd_home:
+       ldis r1, 0x2
+       call lcd_command
+       call delay5ms
+       ret
index c81a97324e5ac1422f8eefc6e0a0143936827df4..173903055287101c6cc9e1212a410e1d086c58ea 100644 (file)
@@ -33,6 +33,12 @@ PROJ_VHDL = \
        extension_imp_b.vhd \
        extension_imp_pkg.vhd \
        extension_imp.vhd \
+       extension_timer_b.vhd \
+       extension_timer_pkg.vhd \
+       extension_timer.vhd \
+       extension_lcd_b.vhd \
+       extension_lcd_pkg.vhd \
+       extension_lcd.vhd \
        extension.vhd \
        fetch_stage_b.vhd \
        fetch_stage.vhd \
index e260c464997307923edce72a2dc6edac0fe84a73..8cc37589bf4b432f96ae0543209cc4a9df54dbe6 100644 (file)
@@ -126,6 +126,20 @@ NET "led2" LOC = "E11" | IOSTANDARD = LVCMOS33 | SLEW = FAST | DRIVE = 8 ;
 #NET "LCD_RS" LOC = "L18" | IOSTANDARD = LVCMOS33 | DRIVE = 4 | SLEW = SLOW ;
 #NET "LCD_RW" LOC = "L17" | IOSTANDARD = LVCMOS33 | DRIVE = 4 | SLEW = SLOW ;
 # LCD data connections are shared with StrataFlash connections SF_D<11:8>
+# DB4
+NET "LCD_DATA<0>" LOC = "R15" | IOSTANDARD = LVCMOS33 | DRIVE = 4 | SLEW = SLOW ;
+# DB5
+NET "LCD_DATA<1>" LOC = "R16" | IOSTANDARD = LVCMOS33 | DRIVE = 4 | SLEW = SLOW ;
+# DB6
+NET "LCD_DATA<2>" LOC = "P17" | IOSTANDARD = LVCMOS33 | DRIVE = 4 | SLEW = SLOW ;
+# DB7
+NET "LCD_DATA<3>" LOC = "M15" | IOSTANDARD = LVCMOS33 | DRIVE = 4 | SLEW = SLOW ;
+# RS
+NET "LCD_DATA<4>" LOC = "L18" | IOSTANDARD = LVCMOS33 | DRIVE = 4 | SLEW = SLOW ;
+# EN
+NET "LCD_DATA<5>" LOC = "M18" | IOSTANDARD = LVCMOS33 | DRIVE = 4 | SLEW = SLOW ;
+# RW
+NET "LCD_DATA<6>" LOC = "L17" | IOSTANDARD = LVCMOS33 | DRIVE = 4 | SLEW = SLOW ;
 #NET "SF_D<8>" LOC = "R15" | IOSTANDARD = LVCMOS33 | DRIVE = 4 | SLEW = SLOW ;
 #NET "SF_D<9>" LOC = "R16" | IOSTANDARD = LVCMOS33 | DRIVE = 4 | SLEW = SLOW ;
 #NET "SF_D<10>" LOC = "P17" | IOSTANDARD = LVCMOS33 | DRIVE = 4 | SLEW = SLOW ;