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;
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;
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)
--- /dev/null
+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;
--- /dev/null
+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;
--- /dev/null
+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;
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";
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;
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
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;
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)
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';
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;
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;
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;
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;
-- 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;
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;
fibmmem.prog:
testbench.prog:
deepjit.prog:
+lcd.prog:
%.prog: %.dthex
@echo " PROG $<"
../tools/dtprog.py $< $(DPROGFLAGS)
fibmmem.sim:
testbench.sim:
deepjit.sim:
+lcd.sim:
%.sim: %.dthex_sim
@echo " SIM $<"
cd ../3b_sim/; ./sim -f ../progs/$<
--- /dev/null
+#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
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 \
#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 ;