1
0
mirror of https://github.com/j-core/j-core-ice40.git synced 2026-03-09 20:18:40 +00:00

Drives LCD with ASCII renderer. Split main.c off for 42s

This commit is contained in:
J
2019-03-18 17:39:56 -04:00
parent 2246a52244
commit 07afa61fa1
8 changed files with 907 additions and 672 deletions

180
cpu_up5k_42s.vhd Normal file
View File

@@ -0,0 +1,180 @@
library ieee;
use ieee.std_logic_1164.all;
use ieee.numeric_std.all;
use std.textio.all;
use work.cpu2j0_pack.all;
use work.data_bus_pkg.all;
use work.disp_drv_pkg.all;
library sb_ice40_components_syn;
use sb_ice40_components_syn.components.all;
entity cpu_lattice is port (
led : inout std_logic_vector(7 downto 0);
lcs : inout std_logic;
la0 : inout std_logic;
lscl : inout std_logic;
lsi : inout std_logic);
end;
architecture behaviour of cpu_lattice is
type instrd_bus_i_t is array(instr_bus_device_t'left to instr_bus_device_t'right) of cpu_data_i_t;
type instrd_bus_o_t is array(instr_bus_device_t'left to instr_bus_device_t'right) of cpu_data_o_t;
signal instr_master_o : cpu_instruction_o_t;
signal instr_master_i : cpu_instruction_i_t := (( others => 'Z' ),'0');
signal instr_slaves_i : instr_bus_i_t;
signal instr_slaves_o : instr_bus_o_t;
signal instrd_slaves_i : instrd_bus_i_t;
signal instrd_slaves_o : instrd_bus_o_t;
signal data_master_o : cpu_data_o_t;
signal data_master_i : cpu_data_i_t := (( others => 'Z' ),'0');
signal data_slaves_i : data_bus_i_t;
signal data_slaves_o : data_bus_o_t;
signal sram_d_o : cpu_data_o_t;
signal debug_i : cpu_debug_i_t := CPU_DEBUG_NOP;
signal debug_i_cmd : std_logic_vector(1 downto 0) := "00";
signal debug_o : cpu_debug_o_t;
signal slp_o : std_logic;
signal event_i : cpu_event_i_t := NULL_CPU_EVENT_I;
signal event_o : cpu_event_o_t;
signal clk : std_logic := '1';
signal rst : std_logic := '1';
signal dummy : bit;
signal pio_data_o : cpu_data_o_t := NULL_DATA_O;
signal pio_data_i : cpu_data_i_t := (ack => '0', d => (others => '0'));
signal data_select : data_bus_device_t;
signal db_we : std_logic_vector(3 downto 0);
signal lcd_d_i : disp_drv_i_t;
signal lcd_d_o : disp_drv_o_t;
signal lcd_o : disp_o_t;
signal le : std_logic_vector(7 downto 0);
signal vh : std_logic;
begin
rst <= '1', '0' after 10 ns;
vh <= '1';
ck: SB_HFOSC generic map (clkhf_div => "0b10")
port map (clkhfen => vh, clkhf => clk, clkhfpu => vh);
process (data_master_o)
variable dev : data_bus_device_t;
begin
if data_master_o.en = '0' then
dev := DEV_NONE;
else
dev := decode_data_address(data_master_o.a);
-- Make SRAM the default. Would prefer not to do this, but not
-- sure how many things depend on defaulting to SRAM. For example,
-- my build of sdboot has a 4 byte stack at 0x300000 and loading
-- it in gdb prints errors.
if dev = DEV_NONE then
dev := DEV_SRAM;
end if;
end if;
data_select <= dev;
end process;
data_buses(master_i => data_master_i, master_o => data_master_o,
selected => data_select,
slaves_i => data_slaves_i, slaves_o => data_slaves_o);
data_slaves_i(DEV_NONE) <= loopback_bus(data_slaves_o(DEV_NONE));
-- data_slaves_i(DEV_SPI) <= loopback_bus(data_slaves_o(DEV_SPI));
data_slaves_i(DEV_UART0) <= loopback_bus(data_slaves_o(DEV_UART0));
data_slaves_i(DEV_DDR) <= loopback_bus(data_slaves_o(DEV_DDR));
pio_data_i.d <= (others => '0');
pio_data_i.ack <= pio_data_o.en;
instruction_buses(master_i => instr_master_i, master_o => instr_master_o,
selected => decode_instr_address(instr_master_o.a),
slaves_i => instr_slaves_i, slaves_o => instr_slaves_o);
pio_data_o <= data_slaves_o(DEV_PIO);
data_slaves_i(DEV_PIO) <= pio_data_i;
with debug_i_cmd select
debug_i.cmd <=
BRK when "00",
STEP when "01",
INSERT when "10",
CONTINUE when others;
splice_instr_data_bus(instr_slaves_o(DEV_DDR), instr_slaves_i(DEV_DDR),
instrd_slaves_o(DEV_DDR), instrd_slaves_i(DEV_DDR));
cpu1: cpu
port map(clk => clk, rst => rst,
db_o => data_master_o, db_i => data_master_i,
inst_o => instr_master_o, inst_i => instr_master_i,
debug_o => debug_o, debug_i => debug_i,
event_i => event_i, event_o => event_o);
sram : entity work.cpu_sram
port map(clk => clk,
ibus_i => instr_slaves_o(DEV_SRAM),
ibus_o => instr_slaves_i(DEV_SRAM),
db_i => data_slaves_o(DEV_SRAM),
db_o => data_slaves_i(DEV_SRAM));
lcd : disp_drv port map (clk => clk, rst => rst, a => lcd_d_i, y => lcd_d_o, yl => lcd_o);
lcd_d_i.d <= data_slaves_o(DEV_SPI).d;
lcd_d_i.a <= data_slaves_o(DEV_SPI).a(3 downto 2);
lcd_d_i.wr <= data_slaves_o(DEV_SPI).wr;
lcd_d_i.en <= data_slaves_o(DEV_SPI).en;
data_slaves_i(DEV_SPI).d <= lcd_d_o.d;
data_slaves_i(DEV_SPI).ack <= lcd_d_o.ack;
lcs <= lcd_o.cs;
la0 <= lcd_o.a0;
lscl <= lcd_o.clk;
lsi <= lcd_o.d;
-- intercept and print PIO and UART writes
led <= le;
l0: process(clk)
variable uart_line : line;
variable l : line;
variable c : character;
begin
if clk'event and clk = '1' then
if pio_data_o.wr = '1' and pio_data_o.a = x"ABCD0000" then
-- write(l, string'("LED: Write "));
-- write(l, " at " & time'image(now));
-- writeline(output, l);
le <= pio_data_o.d(7 downto 0);
end if;
if data_slaves_o(DEV_UART0).wr = '1' and data_slaves_o(DEV_UART0).a = x"ABCD0104" then
-- c := character'val(to_integer(unsigned(data_slaves_o(DEV_UART0).d(7 downto 0))));
-- if character'pos(c) = 10 then -- newline
-- writeline(output, uart_line);
-- else
-- write(uart_line, c);
-- if c = ';' then
-- hack to better display the gdb remote protocol messages
-- writeline(output, uart_line);
-- end if;
-- end if;
end if;
end if;
end process;
end;

View File

@@ -8,6 +8,8 @@ ghdl -a data_bus_pkg.vhd monitor_pkg.vhd ram_init.vhd lattice_ebr.vhd bus_monit
ghdl -a --work=sb_ice40_components_syn clk_sim.vhd
ghdl -a ../disp_drv/disp_drv_pkg.vhd ../disp_drv/disp_drv.vhd
ghdl -a cpu_lattice.vhd lattice_tb.vhd
ghdl -e lattice_tb

BIN
ram.img

Binary file not shown.

File diff suppressed because it is too large Load Diff

View File

@@ -1,4 +1,4 @@
OBJS := entry.o gdb.o sh2.o main.o version.o
OBJS := entry.o gdb.o sh2.o version.o
OBJS += uartlite.o
#OBJS += uart16550.o
@@ -37,8 +37,8 @@ tests/libtests.a: $(TESTS_OBJS)
@echo Built test library
main.elf: $(OBJS) tests/libtests.a
$(LD) $(LDFLAGS) $(OBJS) -Ltests -ltests $(LIBGCC) -o $@
main.elf: main_up5k_42s.o $(OBJS) tests/libtests.a
$(LD) $(LDFLAGS) main_up5k_42s.o $(OBJS) -Ltests -ltests $(LIBGCC) -o $@
main.o: main.c
$(CC) $(CFLAGS) -fno-inline -c $<

View File

@@ -230,13 +230,11 @@ __asm__(
" mov.l testdiv_k, r0\n"
" jsr @r0\n"
" nop\n"
#endif
" mov.l testmacw_k, r0\n"
" jsr @r0\n"
" nop\n"
" mov.l testmacl_k, r0\n"
" jsr @r0\n"
#if 0
#endif /* NO_TESTS */
" nop\n"
" mov #0, r0\n"
@@ -282,10 +280,8 @@ __asm__(
"testdmuls_k: .long _testdmuls\n"
"testmulconf_k: .long _testmulconf\n"
"testdiv_k: .long _testdiv\n"
#endif
"testmacw_k: .long _testmacw\n"
"testmacl_k: .long _testmacl\n"
#ifndef NO_TESTS
#endif /* NO_TESTS */
"pio_addr: .long 0xABCD0000\n"
"start_leds: .long 0x000000ff\n"

106
testrom/font5x7.h Normal file
View File

@@ -0,0 +1,106 @@
#ifndef __FONT5X7_H__
#define __FONT5X7_H__
#define FONT5X7_START 32
#define FONT5X7_END 127
static unsigned char font[] = {
0x00, 0x00, 0x00, 0x00, 0x00, // (space)
0x00, 0x00, 0x5F, 0x00, 0x00, // !
0x00, 0x07, 0x00, 0x07, 0x00, // "
0x14, 0x7F, 0x14, 0x7F, 0x14, // #
0x24, 0x2A, 0x7F, 0x2A, 0x12, // $
0x23, 0x13, 0x08, 0x64, 0x62, // %
0x36, 0x49, 0x55, 0x22, 0x50, // &
0x00, 0x05, 0x03, 0x00, 0x00, // '
0x00, 0x1C, 0x22, 0x41, 0x00, // (
0x00, 0x41, 0x22, 0x1C, 0x00, // )
0x08, 0x2A, 0x1C, 0x2A, 0x08, // *
0x08, 0x08, 0x3E, 0x08, 0x08, // +
0x00, 0x50, 0x30, 0x00, 0x00, // ,
0x08, 0x08, 0x08, 0x08, 0x08, // -
0x00, 0x60, 0x60, 0x00, 0x00, // .
0x20, 0x10, 0x08, 0x04, 0x02, // /
0x3E, 0x51, 0x49, 0x45, 0x3E, // 0
0x00, 0x42, 0x7F, 0x40, 0x00, // 1
0x42, 0x61, 0x51, 0x49, 0x46, // 2
0x21, 0x41, 0x45, 0x4B, 0x31, // 3
0x18, 0x14, 0x12, 0x7F, 0x10, // 4
0x27, 0x45, 0x45, 0x45, 0x39, // 5
0x3C, 0x4A, 0x49, 0x49, 0x30, // 6
0x01, 0x71, 0x09, 0x05, 0x03, // 7
0x36, 0x49, 0x49, 0x49, 0x36, // 8
0x06, 0x49, 0x49, 0x29, 0x1E, // 9
0x00, 0x36, 0x36, 0x00, 0x00, // :
0x00, 0x56, 0x36, 0x00, 0x00, // ;
0x00, 0x08, 0x14, 0x22, 0x41, // <
0x14, 0x14, 0x14, 0x14, 0x14, // =
0x41, 0x22, 0x14, 0x08, 0x00, // >
0x02, 0x01, 0x51, 0x09, 0x06, // ?
0x32, 0x49, 0x79, 0x41, 0x3E, // @
0x7E, 0x11, 0x11, 0x11, 0x7E, // A
0x7F, 0x49, 0x49, 0x49, 0x36, // B
0x3E, 0x41, 0x41, 0x41, 0x22, // C
0x7F, 0x41, 0x41, 0x22, 0x1C, // D
0x7F, 0x49, 0x49, 0x49, 0x41, // E
0x7F, 0x09, 0x09, 0x01, 0x01, // F
0x3E, 0x41, 0x41, 0x51, 0x32, // G
0x7F, 0x08, 0x08, 0x08, 0x7F, // H
0x00, 0x41, 0x7F, 0x41, 0x00, // I
0x20, 0x40, 0x41, 0x3F, 0x01, // J
0x7F, 0x08, 0x14, 0x22, 0x41, // K
0x7F, 0x40, 0x40, 0x40, 0x40, // L
0x7F, 0x02, 0x04, 0x02, 0x7F, // M
0x7F, 0x04, 0x08, 0x10, 0x7F, // N
0x3E, 0x41, 0x41, 0x41, 0x3E, // O
0x7F, 0x09, 0x09, 0x09, 0x06, // P
0x3E, 0x41, 0x51, 0x21, 0x5E, // Q
0x7F, 0x09, 0x19, 0x29, 0x46, // R
0x46, 0x49, 0x49, 0x49, 0x31, // S
0x01, 0x01, 0x7F, 0x01, 0x01, // T
0x3F, 0x40, 0x40, 0x40, 0x3F, // U
0x1F, 0x20, 0x40, 0x20, 0x1F, // V
0x7F, 0x20, 0x18, 0x20, 0x7F, // W
0x63, 0x14, 0x08, 0x14, 0x63, // X
0x03, 0x04, 0x78, 0x04, 0x03, // Y
0x61, 0x51, 0x49, 0x45, 0x43, // Z
0x00, 0x00, 0x7F, 0x41, 0x41, // [
0x02, 0x04, 0x08, 0x10, 0x20, // "\"
0x41, 0x41, 0x7F, 0x00, 0x00, // ]
0x04, 0x02, 0x01, 0x02, 0x04, // ^
0x40, 0x40, 0x40, 0x40, 0x40, // _
0x00, 0x01, 0x02, 0x04, 0x00, // `
0x20, 0x54, 0x54, 0x54, 0x78, // a
0x7F, 0x48, 0x44, 0x44, 0x38, // b
0x38, 0x44, 0x44, 0x44, 0x20, // c
0x38, 0x44, 0x44, 0x48, 0x7F, // d
0x38, 0x54, 0x54, 0x54, 0x18, // e
0x08, 0x7E, 0x09, 0x01, 0x02, // f
0x08, 0x14, 0x54, 0x54, 0x3C, // g
0x7F, 0x08, 0x04, 0x04, 0x78, // h
0x00, 0x44, 0x7D, 0x40, 0x00, // i
0x20, 0x40, 0x44, 0x3D, 0x00, // j
0x00, 0x7F, 0x10, 0x28, 0x44, // k
0x00, 0x41, 0x7F, 0x40, 0x00, // l
0x7C, 0x04, 0x18, 0x04, 0x78, // m
0x7C, 0x08, 0x04, 0x04, 0x78, // n
0x38, 0x44, 0x44, 0x44, 0x38, // o
0x7C, 0x14, 0x14, 0x14, 0x08, // p
0x08, 0x14, 0x14, 0x18, 0x7C, // q
0x7C, 0x08, 0x04, 0x04, 0x08, // r
0x48, 0x54, 0x54, 0x54, 0x20, // s
0x04, 0x3F, 0x44, 0x40, 0x20, // t
0x3C, 0x40, 0x40, 0x20, 0x7C, // u
0x1C, 0x20, 0x40, 0x20, 0x1C, // v
0x3C, 0x40, 0x30, 0x40, 0x3C, // w
0x44, 0x28, 0x10, 0x28, 0x44, // x
0x0C, 0x50, 0x50, 0x50, 0x3C, // y
0x44, 0x64, 0x54, 0x4C, 0x44, // z
0x00, 0x08, 0x36, 0x41, 0x00, // {
0x00, 0x00, 0x7F, 0x00, 0x00, // |
0x00, 0x41, 0x36, 0x08, 0x00, // }
0x20, 0x10, 0x20, 0x10, 0x00, // ~
0x00, 0x00, 0x07, 0x05, 0x07 // °
};
#endif /* __FONT5X7_H__ */

180
testrom/main_up5k_42s.c Normal file
View File

@@ -0,0 +1,180 @@
#define LEDPORT (*(volatile unsigned long *)0xabcd0000)
#define LCDDATA (*(volatile unsigned long *)0xabcd0044)
#define LCDINST (*(volatile unsigned long *)0xabcd0040)
#include "font5x7.h"
extern char version_string[];
char ram0[256]; /* working ram for CPU tests */
void
putstr (char *str)
{
while (*str)
{
if (*str == '\n')
uart_tx ('\r');
uart_tx (*(str++));
}
}
#ifndef NO_DDR
#define DDR_BASE 0x10000000
#define MemoryRead(A) (*(volatile int*)(A))
#define MemoryWrite(A,V) *(volatile int*)(A)=(V)
//SD_A <= address_reg(25 downto 13); --address row
//SD_BA <= address_reg(12 downto 11); --bank_address
//cmd := address_reg(6 downto 4); --bits RAS & CAS & WE
int DdrInitData[] = {
// AddressLines Bank Command
#ifndef LPDDR
(0x000 << 13) | (0 << 11) | (7 << 4), //CKE=1; NOP="111"
(0x400 << 13) | (0 << 11) | (2 << 4), //A10=1; PRECHARGE ALL="010"
(0x001 << 13) | (1 << 11) | (0 << 4), //EMR disable DLL; BA="01"; LMR="000"
#ifndef DDR_BL4
(0x121 << 13) | (0 << 11) | (0 << 4), //SMR reset DLL, CL=2, BL=2; LMR="000"
#else
(0x122 << 13) | (0 << 11) | (0 << 4), //SMR reset DLL, CL=2, BL=4; LMR="000"
#endif
(0x400 << 13) | (0 << 11) | (2 << 4), //A10=1; PRECHARGE ALL="010"
(0x000 << 13) | (0 << 11) | (1 << 4), //AUTO REFRESH="001"
(0x000 << 13) | (0 << 11) | (1 << 4), //AUTO REFRESH="001
#ifndef DDR_BL4
(0x021 << 13) | (0 << 11) | (0 << 4) //clear DLL, CL=2, BL=2; LMR="000"
#else
(0x022 << 13) | (0 << 11) | (0 << 4) //clear DLL, CL=2, BL=4; LMR="000"
#endif
#else // LPDDR
(0x000 << 13) | (0 << 11) | (7 << 4), //CKE=1; NOP="111"
(0x000 << 13) | (0 << 11) | (7 << 4), //NOP="111" after 200 uS
(0x400 << 13) | (0 << 11) | (2 << 4), //A10=1; PRECHARGE ALL="010"
(0x000 << 13) | (0 << 11) | (1 << 4), //AUTO REFRESH="001"
(0x000 << 13) | (0 << 11) | (1 << 4), //AUTO REFRESH="001"
(0x021 << 13) | (0 << 11) | (0 << 4), //SMR CL=2, BL=2; LMR="000"
(0x000 << 13) | (1 << 11) | (0 << 4), //EMR BA="01"; LMR="000" Full strength full array
(0x000 << 13) | (0 << 11) | (7 << 4) //NOP="111" after ? uS
#endif
};
int
ddr_init (void)
{
volatile int i, j, k = 0;
for (i = 0; i < sizeof (DdrInitData) / sizeof (int); ++i)
{
MemoryWrite (DDR_BASE + DdrInitData[i], 0);
for (j = 0; j < 4; ++j)
++k;
}
for (j = 0; j < 100; ++j)
++k;
k += MemoryRead (DDR_BASE); //Enable DDR
return k;
}
#endif /* NO_DDR */
void
led(int v)
{
LEDPORT = v;
}
void
lcd_data(unsigned int v)
{
while((LCDDATA) & 1) {led(0x81); led(0x82);}
LCDDATA = v;
}
void
lcd_inst(unsigned int v)
{
while((LCDDATA) & 1) {led(0x83); led(0x84);}
LCDINST = v;
}
void
lcd_loc(unsigned int x, unsigned int y)
{
lcd_inst(0xB0 | (y & 3));
lcd_inst(0x10 | (((x*6) & 0xf0) >> 4));
lcd_inst(0x00 | ((x*6) & 0x0f));
}
void
lcd_puts(char *s)
{
int i, j;
unsigned char v[4];
unsigned int *l = v;
i = 0;
for (;*s;s++) {
for (j=0; j<6; j++) {
v[i++] = j == 5 ? 0 : font[(*s - FONT5X7_START)*5 + j];
if (i>3) {
lcd_data(*l);
i = 0;
}
}
}
for (;i<4;i++) v[i] = 0;
lcd_data(*l);
}
unsigned char lcd_init[] = { 0x40, 0xA1, 0xC0, 0xA6, 0xA2, 0x2F, 0xF8, 0x00, 0x23, 0x81, 0x1F, 0xAC, 0x00, 0xAF, 0xFF };
void
main_sh (void)
{
volatile int i;
led(0x40);
uart_set_baudrate ();
led(0x042);
#ifndef NO_TESTS
putstr ("CPU tests passed\n");
led(0x043);
#endif
#ifndef NO_DDR
putstr ("DDR Init\n");
led(0x042);
ddr_init ();
#endif /* NO_DDR */
putstr ("GDB Stub for HS-2J0 SH2 ROM\n");
putstr (version_string);
led(0x50);
for (i=0; lcd_init[i] != 0xff; i++) lcd_inst(lcd_init[i]);
lcd_loc(0, 1);
lcd_puts("Hello 123!");
for (i=0; i<8; i++) {
lcd_data(
(1<<(i+0 )) |
(1<<(i+8 )) |
(1<<(i+16)) |
(1<<(i+24)));
}
led(0x51);
for (i=0; i<800; i++) {}
led(0x55);
for (i=0; i<800; i++) {}
led(0xaa);
for (;;) {
for (i=0; i<1200000; i++) {}
led(0x55);
for (i=0; i<1200000; i++) {}
led(0xaa);
}
}