mirror of
https://github.com/j-core/j-core-ice40.git
synced 2026-02-27 00:59:59 +00:00
First synthesys for ICE40 UP5k with everything to blink LEDs
This commit is contained in:
22
conv.c
Normal file
22
conv.c
Normal file
@@ -0,0 +1,22 @@
|
||||
#include <stdio.h>
|
||||
#include <stdlib.h>
|
||||
#include <unistd.h>
|
||||
|
||||
int main(int argc, char *argv[])
|
||||
{
|
||||
int i, l;
|
||||
unsigned char v[4] = { 0, 0, 0, 0 };
|
||||
|
||||
printf("-- Machine generated from ram.img.\n");
|
||||
printf("library ieee;\n use ieee.std_logic_1164.all;\nuse ieee.numeric_std.all;\n\n");
|
||||
printf("package bootrom is\n");
|
||||
printf(" type rom_t is array (0 to 2047) of std_logic_vector(31 downto 0);\n constant rom : rom_t := (\n");
|
||||
|
||||
l = read(0,v,4);
|
||||
for (i=0 ; l; i++) {
|
||||
printf (" x\"%.2x%.2x%.2x%.2x\",\n", v[0], v[1], v[2], v[3]);
|
||||
l = read(0,v,4);
|
||||
}
|
||||
printf(" others => x\"00000000\" );\n\n");
|
||||
printf("end package;\n\npackage body bootrom is\nend package body;\n");
|
||||
}
|
||||
150
cpu_lattice.vhd
Normal file
150
cpu_lattice.vhd
Normal file
@@ -0,0 +1,150 @@
|
||||
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;
|
||||
entity cpu_lattice is port (
|
||||
clk : in std_logic;
|
||||
led : out std_logic_vector(7 downto 0));
|
||||
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);
|
||||
begin
|
||||
rst <= '1', '0' after 10 ns;
|
||||
|
||||
-- clk_gen : process
|
||||
-- begin
|
||||
-- clk <= '0';
|
||||
-- wait for 10 ns;
|
||||
-- clk <= '1';
|
||||
-- wait for 10 ns;
|
||||
-- end process;
|
||||
|
||||
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));
|
||||
|
||||
-- intercept and print PIO and UART writes
|
||||
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);
|
||||
led <= 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;
|
||||
51
lattice_ebr.vhd
Normal file
51
lattice_ebr.vhd
Normal file
@@ -0,0 +1,51 @@
|
||||
-- A simple pre-initalized RAM, which reads from a binary file at synthesis time
|
||||
-- single 32 bit read/write port.
|
||||
library ieee;
|
||||
use ieee.std_logic_1164.all;
|
||||
use ieee.numeric_std.all;
|
||||
use work.bootrom.all;
|
||||
|
||||
entity simple_ram is
|
||||
generic (
|
||||
-- 32-bit read/write port. ADDR_WIDTH is in bytes, not words.
|
||||
ADDR_WIDTH : integer := 15 -- default 32k
|
||||
);
|
||||
port (
|
||||
clk : in std_logic;
|
||||
|
||||
en : in std_logic;
|
||||
raddr : in std_logic_vector(ADDR_WIDTH - 3 downto 0);
|
||||
do : out std_logic_vector(31 downto 0);
|
||||
|
||||
we : in std_logic_vector(3 downto 0);
|
||||
waddr : in std_logic_vector(ADDR_WIDTH - 3 downto 0);
|
||||
di : in std_logic_vector(31 downto 0)
|
||||
);
|
||||
end simple_ram;
|
||||
|
||||
architecture behavioral of simple_ram is
|
||||
constant NUM_WORDS : integer := 2**(ADDR_WIDTH - 2);
|
||||
signal ram : rom_t := work.bootrom.rom;
|
||||
begin
|
||||
|
||||
process (clk)
|
||||
variable read : std_logic_vector(31 downto 0);
|
||||
begin
|
||||
if clk'event and clk = '1' and en = '1' then
|
||||
if we(3) = '1' then
|
||||
ram(to_integer(unsigned(waddr)))(31 downto 24) <= di(31 downto 24);
|
||||
end if;
|
||||
if we(2) = '1' then
|
||||
ram(to_integer(unsigned(waddr)))(23 downto 16) <= di(23 downto 16);
|
||||
end if;
|
||||
if we(1) = '1' then
|
||||
ram(to_integer(unsigned(waddr)))(15 downto 8 ) <= di(15 downto 8 );
|
||||
end if;
|
||||
if we(0) = '1' then
|
||||
ram(to_integer(unsigned(waddr)))(7 downto 0 ) <= di(7 downto 0 );
|
||||
end if;
|
||||
read := ram(to_integer(unsigned(raddr)));
|
||||
do <= read;
|
||||
end if;
|
||||
end process;
|
||||
end behavioral;
|
||||
51
lattice_tb.vhd
Normal file
51
lattice_tb.vhd
Normal file
@@ -0,0 +1,51 @@
|
||||
library ieee;
|
||||
use ieee.std_logic_1164.all;
|
||||
use ieee.numeric_std.all;
|
||||
use std.textio.all;
|
||||
|
||||
entity lattice_tb is
|
||||
end lattice_tb;
|
||||
|
||||
architecture beh of lattice_tb is
|
||||
|
||||
function to_hex_string(s: in std_logic_vector) return string is
|
||||
constant hex : string (1 to 16) := "0123456789ABCDEF";
|
||||
variable ss : std_logic_vector(31 downto 0) := (others => '0');
|
||||
variable ret : string (1 to ss'left/4+1);
|
||||
begin
|
||||
ss(s'range) := s;
|
||||
for i in 0 to ss'left/4 loop
|
||||
ret(i+1) := hex(to_integer(unsigned(ss(ss'left - i*4 downto ss'left - i*4 -3)))+1);
|
||||
end loop;
|
||||
return ret;
|
||||
end to_hex_string;
|
||||
|
||||
signal clk : std_logic;
|
||||
signal led : std_logic_vector(7 downto 0) := x"00";
|
||||
signal ol : std_logic_vector(7 downto 0) := x"00";
|
||||
begin
|
||||
|
||||
c0: process
|
||||
begin
|
||||
clk <= '0';
|
||||
wait for 10 ns;
|
||||
clk <= '1';
|
||||
wait for 10 ns;
|
||||
end process;
|
||||
|
||||
fp: entity work.cpu_lattice
|
||||
port map(clk => clk, led => led);
|
||||
|
||||
p0: process(led)
|
||||
variable l : line;
|
||||
begin
|
||||
if led /= ol then
|
||||
ol <= led;
|
||||
write(l, string'("LED: Write "));
|
||||
write(l, to_hex_string(led));
|
||||
write(l, " at " & time'image(now));
|
||||
writeline(output, l);
|
||||
end if;
|
||||
end process;
|
||||
|
||||
end beh;
|
||||
9
nvc_lattice.sh
Normal file
9
nvc_lattice.sh
Normal file
@@ -0,0 +1,9 @@
|
||||
#!/bin/sh
|
||||
|
||||
nvc -a cpu2j0_pkg.vhd components_pkg.vhd mult_pkg.vhd decode_pkg.vhd decode_body.vhd datapath_pkg.vhd cpu.vhd decode.vhd decode_core.vhd decode_table.vhd decode_table_reverse.vhd datapath.vhd register_file.vhd mult.vhd
|
||||
|
||||
nvc -a data_bus_pkg.vhd monitor_pkg.vhd ram_init.vhd lattice_ebr.vhd bus_monitor.vhd timeout_cnt.vhd cpu_simple_sram.vhd cpu_lattice.vhd
|
||||
|
||||
nvc -a lattice_tb.vhd
|
||||
|
||||
nvc -e -V lattice_tb
|
||||
5
ram.sh
5
ram.sh
@@ -4,3 +4,8 @@ rm ram.img
|
||||
make -C testrom
|
||||
sh2-elf-size testrom/main.elf ram.img
|
||||
sh2-elf-objcopy -v -S -O binary --srec-forceS3 testrom/main.elf ram.img
|
||||
|
||||
echo making image for Lattice
|
||||
|
||||
gcc conv.c -o conv
|
||||
./conv < ram.img > ram_init.vhd
|
||||
|
||||
1184
ram_init.vhd
Normal file
1184
ram_init.vhd
Normal file
File diff suppressed because it is too large
Load Diff
@@ -82,6 +82,7 @@ led(int v)
|
||||
void
|
||||
main_sh (void)
|
||||
{
|
||||
volatile int i;
|
||||
led(0x40);
|
||||
|
||||
uart_set_baudrate ();
|
||||
@@ -101,4 +102,11 @@ main_sh (void)
|
||||
putstr ("GDB Stub for HS-2J0 SH2 ROM\n");
|
||||
putstr (version_string);
|
||||
led(0x50);
|
||||
|
||||
for (;;) {
|
||||
for (i=0; i<10; i++) {}
|
||||
led(0x55);
|
||||
for (i=0; i<10; i++) {}
|
||||
led(0xaa);
|
||||
}
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user