Whole project can now be build using make

This commit is contained in:
Dreaded_X 2021-01-28 22:47:06 +01:00
parent c661c10757
commit 12b49eff1c
10 changed files with 635 additions and 8 deletions

1
.gitignore vendored
View File

@ -1,3 +1,2 @@
.build
.Xil
hdmi.sdk

53
Makefile Normal file
View File

@ -0,0 +1,53 @@
BUILD = .build
VERILOG = \
src/char_map.v \
src/color_map.v \
src/dvi_top.v \
src/dvid.v \
src/encode.v \
src/hdmi.xdc \
src/simple_dual_ram.v \
.PHONY: all clean
all: $(BUILD)/impl.bin
$(BUILD)/ip/clk_wiz_0/clk_wiz_0.xci: scripts/clk_wiz_0.tcl | $(BUILD)/ip
/opt/Xilinx/Vivado/2019.1/bin/vivado -mode batch -source scripts/clk_wiz_0.tcl -nolog -nojournal
$(BUILD)/ip/microblaze_mcs_0/microblaze_mcs_0.xci: scripts/microblaze_mcs_0.tcl | $(BUILD)/ip
/opt/Xilinx/Vivado/2019.1/bin/vivado -mode batch -source scripts/microblaze_mcs_0.tcl -nolog -nojournal
$(BUILD)/5_route.dcp: $(VERILOG) $(BUILD)/ip/clk_wiz_0/clk_wiz_0.xci $(BUILD)/ip/microblaze_mcs_0/microblaze_mcs_0.xci scripts/build.tcl | $(BUILD)
/opt/Xilinx/Vivado/2019.1/bin/vivado -mode batch -source scripts/build.tcl -nolog -nojournal
$(BUILD)/impl.bin: $(BUILD)/5_route.dcp $(BUILD)/controller.elf scripts/write.tcl | $(BUILD)
/opt/Xilinx/Vivado/2019.1/bin/vivado -mode batch -source scripts/write.tcl -nolog -nojournal
$(BUILD)/bsp/system.mss: $(BUILD)/system.hdf | $(BUILD)
/opt/Xilinx/SDK/2019.1/bin/xsdk -batch scripts/sdk.tcl
$(BUILD)/bsp/microblaze_I/lib/libxil.a: $(BUILD)/bsp/system.mss
$(MAKE) -C $(BUILD)/bsp all
OBJ = \
$(BUILD)/obj/main.o
$(BUILD)/obj/%.o: software/src/%.c $(BUILD)/bsp/microblaze_I/lib/libxil.a | $(BUILD)/obj
mb-gcc -Wall -O2 -c -fmessage-length=0 -MT"$@" -I$(BUILD)/bsp/microblaze_I/include -mno-xl-reorder -mlittle-endian -mcpu=v11.0 -mxl-soft-mul -Wl,--no-relax -ffunction-sections -fdata-sections -MMD -MP -MF"$(@:%.o=%.d)" -MT"$(@)" -o "$@" "$<"
$(BUILD)/controller.elf: $(OBJ) software/src/lscript.ld $(BUILD)/bsp/microblaze_I/lib/libxil.a | $(BUILD)
mb-gcc -Wl,-T -Wl,software/src/lscript.ld -L$(BUILD)/bsp/microblaze_I/lib -mlittle-endian -mcpu=v11.0 -mxl-soft-mul -Wl,--no-relax -Wl,--gc-sections -o "$@" $(OBJ) -Wl,--start-group,-lxil,-lgcc,-lc,--end-group
$(BUILD):
mkdir $@
$(BUILD)/ip: | $(BUILD)
mkdir $@
$(BUILD)/obj: | $(BUILD)
mkdir $@
clean:
rm -fr $(BUILD)

Binary file not shown.

View File

@ -10,17 +10,17 @@ foreach fname [glob -nocomplain -type f $out_dir/*] {
}
set step 0_ip
if { [file isdirectory ./.build/ip] } {
read_ip ./.build/ip/clk_wiz_0/clk_wiz_0.xci
read_ip ./.build/ip/microblaze_mcs_0/microblaze_mcs_0.xci
if { [file isdirectory ${out_dir}/ip] } {
read_ip ${out_dir}/ip/clk_wiz_0/clk_wiz_0.xci
read_ip ${out_dir}/ip/microblaze_mcs_0/microblaze_mcs_0.xci
} else {
file mkdir ./.build/ip
file mkdir ${out_dir}/ip
create_project -in_memory
create_ip -name clk_wiz -vendor xilinx.com -library ip \
-version 6.0 -module_name clk_wiz_0 \
-dir ./.build/ip
-dir ${out_dir}/ip
set_property -dict [list \
CONFIG.PRIMARY_PORT {clk_in} \
@ -58,7 +58,7 @@ if { [file isdirectory ./.build/ip] } {
create_ip -name microblaze_mcs -vendor xilinx.com -library ip \
-version 3.0 -module_name microblaze_mcs_0 \
-dir ./.build/ip
-dir ${out_dir}/ip
set_property -dict [list \
CONFIG.FREQ {150} \
@ -134,4 +134,4 @@ report_drc -file $out_dir/${step}_drc.rpt
write_verilog -force $out_dir/imp_netlist.v
write_xdc -no_fixed_only -force $out_dir/imp.xdc
source write.tcl
write_hwdef -force -file ${out_dir}/system.hdf

50
scripts/clk_wiz_0.tcl Normal file
View File

@ -0,0 +1,50 @@
set out_dir ./.build
set part_num xc7a35tftg256-1
set_part $part_num
file delete -force $out_dir/ip/clk_wiz_0
create_project -in_memory
create_ip -name clk_wiz -vendor xilinx.com -library ip \
-version 6.0 -module_name clk_wiz_0 \
-dir ${out_dir}/ip
set_property -dict [list \
CONFIG.PRIMARY_PORT {clk_in} \
CONFIG.CLKOUT2_USED {true} \
CONFIG.CLKOUT3_USED {true} \
CONFIG.CLKOUT4_USED {true} \
CONFIG.CLK_OUT1_PORT {clk_dvi} \
CONFIG.CLK_OUT2_PORT {clk_dvin} \
CONFIG.CLK_OUT3_PORT {clk_pix} \
CONFIG.CLK_OUT4_PORT {clk_mcu} \
CONFIG.CLKOUT1_REQUESTED_OUT_FREQ {375} \
CONFIG.CLKOUT2_REQUESTED_OUT_FREQ {375} \
CONFIG.CLKOUT2_REQUESTED_PHASE {180} \
CONFIG.CLKOUT3_REQUESTED_OUT_FREQ {75} \
CONFIG.CLKOUT4_REQUESTED_OUT_FREQ {150} \
CONFIG.CLKOUT1_DRIVES {BUFG} \
CONFIG.FEEDBACK_SOURCE {FDBK_AUTO} \
CONFIG.MMCM_DIVCLK_DIVIDE {1} \
CONFIG.MMCM_CLKFBOUT_MULT_F {7.500} \
CONFIG.MMCM_CLKOUT0_DIVIDE_F {2.000} \
CONFIG.MMCM_CLKOUT1_DIVIDE {2} \
CONFIG.MMCM_CLKOUT1_PHASE {180.000} \
CONFIG.MMCM_CLKOUT2_DIVIDE {10} \
CONFIG.MMCM_CLKOUT3_DIVIDE {5} \
CONFIG.NUM_OUT_CLKS {4} \
CONFIG.CLKOUT1_JITTER {111.604} \
CONFIG.CLKOUT1_PHASE_ERROR {116.405} \
CONFIG.CLKOUT2_JITTER {111.604} \
CONFIG.CLKOUT2_PHASE_ERROR {116.405} \
CONFIG.CLKOUT3_JITTER {152.549} \
CONFIG.CLKOUT3_PHASE_ERROR {116.405} \
CONFIG.CLKOUT4_JITTER {132.464} \
CONFIG.CLKOUT4_PHASE_ERROR {116.405} \
] [get_ips clk_wiz_0]
generate_target all [get_ips]
synth_ip [get_ips] > $out_dir/clk_wiz_0.log

View File

@ -0,0 +1,36 @@
set out_dir ./.build
set part_num xc7a35tftg256-1
set_part $part_num
file delete -force $out_dir/ip/microblaze_mcs_0
create_project -in_memory
create_ip -name microblaze_mcs -vendor xilinx.com -library ip \
-version 3.0 -module_name microblaze_mcs_0 \
-dir ${out_dir}/ip
set_property -dict [list \
CONFIG.FREQ {150} \
CONFIG.MEMSIZE {131072} \
CONFIG.USE_GPO1 {1} \
CONFIG.GPO1_SIZE {16} \
CONFIG.USE_GPO2 {1} \
CONFIG.GPO2_SIZE {16} \
CONFIG.USE_GPO3 {1} \
CONFIG.GPO3_SIZE {2} \
CONFIG.USE_GPO4 {1} \
CONFIG.GPO4_SIZE {6} \
CONFIG.USE_GPI1 {1} \
CONFIG.GPI1_SIZE {8} \
CONFIG.USE_GPI2 {1} \
CONFIG.GPI2_SIZE {1} \
CONFIG.GPI2_INTERRUPT {3} \
CONFIG.USE_GPI3 {1} \
CONFIG.GPI3_SIZE {1} \
] [get_ips microblaze_mcs_0]
generate_target all [get_ips]
synth_ip [get_ips] > $out_dir/microblaze_mcs_0.log

9
scripts/sdk.tcl Normal file
View File

@ -0,0 +1,9 @@
set out_dir ./.build
file delete -force ${out_dir}/.metadata
file delete -force ${out_dir}/hw_platform
file delete -force ${out_dir}/bsp
setws .build
createhw -name hw_platform -hwspec .build/system.hdf
createbsp -name bsp -hwproject hw_platform -os standalone -proc microblaze_I

212
software/src/lscript.ld Normal file
View File

@ -0,0 +1,212 @@
/*******************************************************************/
/* */
/* This file is automatically generated by linker script generator.*/
/* */
/* Version: 2019.1 */
/* */
/* Copyright (c) 2010-2016 Xilinx, Inc. All rights reserved. */
/* */
/* Description : MicroBlaze Linker Script */
/* */
/*******************************************************************/
_STACK_SIZE = DEFINED(_STACK_SIZE) ? _STACK_SIZE : 0x400;
_HEAP_SIZE = DEFINED(_HEAP_SIZE) ? _HEAP_SIZE : 0x800;
/* Define Memories in the system */
MEMORY
{
ilmb_cntlr_Mem_dlmb_cntlr_Mem : ORIGIN = 0x50, LENGTH = 0x7FB0
}
/* Specify the default entry point to the program */
ENTRY(_start)
/* Define the sections, and where they are mapped in memory */
SECTIONS
{
.vectors.reset 0x0 : {
KEEP (*(.vectors.reset))
}
.vectors.sw_exception 0x8 : {
KEEP (*(.vectors.sw_exception))
}
.vectors.interrupt 0x10 : {
KEEP (*(.vectors.interrupt))
}
.vectors.hw_exception 0x20 : {
KEEP (*(.vectors.hw_exception))
}
.text : {
*(.text)
*(.text.*)
*(.gnu.linkonce.t.*)
} > ilmb_cntlr_Mem_dlmb_cntlr_Mem
.init : {
KEEP (*(.init))
} > ilmb_cntlr_Mem_dlmb_cntlr_Mem
.fini : {
KEEP (*(.fini))
} > ilmb_cntlr_Mem_dlmb_cntlr_Mem
.ctors : {
__CTOR_LIST__ = .;
___CTORS_LIST___ = .;
KEEP (*crtbegin.o(.ctors))
KEEP (*(EXCLUDE_FILE(*crtend.o) .ctors))
KEEP (*(SORT(.ctors.*)))
KEEP (*(.ctors))
__CTOR_END__ = .;
___CTORS_END___ = .;
} > ilmb_cntlr_Mem_dlmb_cntlr_Mem
.dtors : {
__DTOR_LIST__ = .;
___DTORS_LIST___ = .;
KEEP (*crtbegin.o(.dtors))
KEEP (*(EXCLUDE_FILE(*crtend.o) .dtors))
KEEP (*(SORT(.dtors.*)))
KEEP (*(.dtors))
PROVIDE(__DTOR_END__ = .);
PROVIDE(___DTORS_END___ = .);
} > ilmb_cntlr_Mem_dlmb_cntlr_Mem
.rodata : {
__rodata_start = .;
*(.rodata)
*(.rodata.*)
*(.gnu.linkonce.r.*)
__rodata_end = .;
} > ilmb_cntlr_Mem_dlmb_cntlr_Mem
.sdata2 : {
. = ALIGN(8);
__sdata2_start = .;
*(.sdata2)
*(.sdata2.*)
*(.gnu.linkonce.s2.*)
. = ALIGN(8);
__sdata2_end = .;
} > ilmb_cntlr_Mem_dlmb_cntlr_Mem
.sbss2 : {
__sbss2_start = .;
*(.sbss2)
*(.sbss2.*)
*(.gnu.linkonce.sb2.*)
__sbss2_end = .;
} > ilmb_cntlr_Mem_dlmb_cntlr_Mem
.data : {
. = ALIGN(4);
__data_start = .;
*(.data)
*(.data.*)
*(.gnu.linkonce.d.*)
__data_end = .;
} > ilmb_cntlr_Mem_dlmb_cntlr_Mem
.got : {
*(.got)
} > ilmb_cntlr_Mem_dlmb_cntlr_Mem
.got1 : {
*(.got1)
} > ilmb_cntlr_Mem_dlmb_cntlr_Mem
.got2 : {
*(.got2)
} > ilmb_cntlr_Mem_dlmb_cntlr_Mem
.eh_frame : {
*(.eh_frame)
} > ilmb_cntlr_Mem_dlmb_cntlr_Mem
.jcr : {
*(.jcr)
} > ilmb_cntlr_Mem_dlmb_cntlr_Mem
.gcc_except_table : {
*(.gcc_except_table)
} > ilmb_cntlr_Mem_dlmb_cntlr_Mem
.sdata : {
. = ALIGN(8);
__sdata_start = .;
*(.sdata)
*(.sdata.*)
*(.gnu.linkonce.s.*)
__sdata_end = .;
} > ilmb_cntlr_Mem_dlmb_cntlr_Mem
.sbss (NOLOAD) : {
. = ALIGN(4);
__sbss_start = .;
*(.sbss)
*(.sbss.*)
*(.gnu.linkonce.sb.*)
. = ALIGN(8);
__sbss_end = .;
} > ilmb_cntlr_Mem_dlmb_cntlr_Mem
.tdata : {
__tdata_start = .;
*(.tdata)
*(.tdata.*)
*(.gnu.linkonce.td.*)
__tdata_end = .;
} > ilmb_cntlr_Mem_dlmb_cntlr_Mem
.tbss : {
__tbss_start = .;
*(.tbss)
*(.tbss.*)
*(.gnu.linkonce.tb.*)
__tbss_end = .;
} > ilmb_cntlr_Mem_dlmb_cntlr_Mem
.bss (NOLOAD) : {
. = ALIGN(4);
__bss_start = .;
*(.bss)
*(.bss.*)
*(.gnu.linkonce.b.*)
*(COMMON)
. = ALIGN(4);
__bss_end = .;
} > ilmb_cntlr_Mem_dlmb_cntlr_Mem
_SDA_BASE_ = __sdata_start + ((__sbss_end - __sdata_start) / 2 );
_SDA2_BASE_ = __sdata2_start + ((__sbss2_end - __sdata2_start) / 2 );
/* Generate Stack and Heap definitions */
.heap (NOLOAD) : {
. = ALIGN(8);
_heap = .;
_heap_start = .;
. += _HEAP_SIZE;
_heap_end = .;
} > ilmb_cntlr_Mem_dlmb_cntlr_Mem
.stack (NOLOAD) : {
_stack_end = .;
. += _STACK_SIZE;
. = ALIGN(8);
_stack = .;
__stack = _stack;
} > ilmb_cntlr_Mem_dlmb_cntlr_Mem
_end = .;
}

268
software/src/main.c Normal file
View File

@ -0,0 +1,268 @@
#include <xparameters.h>
#include <xiomodule.h>
#include <stdint.h>
XIOModule gpo;
int8_t x = 0;
int8_t y = 0;
int8_t scroll = 0;
uint8_t reversed = 0;
uint8_t foreground = 0b111;
uint8_t background = 0;
uint16_t properties = 0;
void commit() {
XIOModule_DiscreteSet(&gpo, 3, 1);
XIOModule_DiscreteClear(&gpo, 3, 1);
}
void calculate_properties() {
if (reversed) {
properties = ((foreground << 4) + background) << 8;
} else {
properties = ((background << 4) + foreground) << 8;
}
}
void set_foreground(uint8_t color) {
foreground = color;
calculate_properties();
}
void set_background(uint8_t color) {
background = color;
calculate_properties();
}
void reverse(uint8_t enable) {
reversed = enable;
calculate_properties();
}
void clear_screen() {
reverse(0);
set_foreground(0b111);
set_background(0);
XIOModule_DiscreteWrite(&gpo, 1, 0);
XIOModule_DiscreteWrite(&gpo, 2, 0);
XIOModule_DiscreteSet(&gpo, 3, 1);
for (int y = 0; y < (45+2); ++y) {
int16_t temp = (y << 8);
for (int x = 0; x < (80+24); ++x) {
XIOModule_DiscreteWrite(&gpo, 2, temp + x);
}
}
XIOModule_DiscreteClear(&gpo, 3, 1);
x = 0;
y = 0;
scroll = 0;
XIOModule_DiscreteWrite(&gpo, 2, (y << 8) + x);
XIOModule_DiscreteWrite(&gpo, 4, scroll);
}
void clear_eol() {
reverse(0);
set_foreground(0b111);
set_background(0);
int16_t temp = (y << 8);
XIOModule_DiscreteWrite(&gpo, 1, 0);
XIOModule_DiscreteWrite(&gpo, 2, temp + x);
XIOModule_DiscreteSet(&gpo, 3, 1);
for (int i = x; i < (80+24); ++i) {
XIOModule_DiscreteWrite(&gpo, 2, temp + i);
}
XIOModule_DiscreteClear(&gpo, 3, 1);
}
void write(uint8_t c) {
XIOModule_DiscreteWrite(&gpo, 1, properties + c);
XIOModule_DiscreteWrite(&gpo, 2, (y << 8) + x);
commit();
}
void next() {
x++;
if (x >= 80) {
y++;
x %= 80;
}
if (y >= 45) {
y--;
scroll = (scroll + 1) % 45;
XIOModule_DiscreteWrite(&gpo, 4, scroll);
clear_eol();
}
}
// @todo This does not appear to work quite correctly
void previous() {
x--;
if (x < 0) {
y--;
x %= 80;
}
if (y < 0) {
y = 0;
x = 0;
}
}
uint8_t data = 0;
uint8_t had = 0;
uint8_t escape = 0;
uint8_t escape_parameter_1 = 0;
uint8_t escape_parameter_2 = 0;
void clock() {
uint8_t io_write = XIOModule_DiscreteRead(&gpo, 3);
if (io_write && !had) {
XIOModule_DiscreteClear(&gpo, 3, 2);
had = 1;
data = XIOModule_DiscreteRead(&gpo, 1) & 0xFF;
if (escape == 1) {
if (data == '[') {
escape = 2;
} else {
escape = 0;
}
} else if (escape) {
switch (data) {
// For now we are only going to implement what we actually use
case 'K':
// Assume parameter 0
clear_eol();
escape = 0;
break;
case 'H':
if (escape_parameter_1 == 0) {
escape_parameter_1 = 1;
}
if (escape_parameter_2 == 0) {
escape_parameter_2 = 1;
}
x = escape_parameter_1 - 1;
y = escape_parameter_2 - 1;
escape = 0;
break;
case 'm':
if (escape_parameter_1 == 0) {
reverse(0);
set_foreground(0b111);
set_background(0);
} else if (escape_parameter_1 == 7) {
reverse(1);
} else if (escape_parameter_1 >= 30 && escape_parameter_1 <= 37) {
set_foreground(escape_parameter_1 - 30);
} else if (escape_parameter_1 >= 40 && escape_parameter_1 <= 47) {
set_background(escape_parameter_1 - 40);
} else if (escape_parameter_1 >= 90 && escape_parameter_1 <= 97) {
set_foreground(escape_parameter_1 - 90 + 8);
} else if (escape_parameter_1 >= 100 && escape_parameter_1 <= 107) {
set_background(escape_parameter_1 - 100 + 8);
}
escape = 0;
break;
case 'J':
// Assume parameter 2
clear_screen();
escape = 0;
break;
case '0' ... '9':
escape_parameter_1 *= 10;
escape_parameter_1 += (data - 48);
break;
case ';':
escape_parameter_2 = escape_parameter_1;
escape_parameter_1 = 0;
break;
default:
escape = 0;
break;
}
} else {
switch (data) {
case '\n':
y++;
if (y >= 45) {
y--;
scroll = (scroll + 1) % 45;
XIOModule_DiscreteWrite(&gpo, 4, scroll);
clear_eol();
}
break;
case '\r':
x = 0;
break;
case 0x08:
previous();
break;
case 0x1B:
escape = 1;
escape_parameter_1 = 0;
escape_parameter_2 = 0;
// Handle escape code
break;
default:
write(data);
next();
break;
}
}
XIOModule_DiscreteWrite(&gpo, 2, (y << 8) + x);
} else if (had && !io_write) {
had = 0;
XIOModule_DiscreteSet(&gpo, 3, 2);
}
}
int main() {
XIOModule_Initialize(&gpo, XPAR_IOMODULE_0_DEVICE_ID); // Initialize the GPO module
microblaze_register_handler(XIOModule_DeviceInterruptHandler,
XPAR_IOMODULE_0_DEVICE_ID); // register the interrupt handler
XIOModule_Start(&gpo); // start the GPO module
XIOModule_Connect(&gpo, XIN_IOMODULE_GPI_2_INTERRUPT_INTR, clock,
NULL); // register timerTick() as our interrupt handler
XIOModule_Enable(&gpo, XIN_IOMODULE_GPI_2_INTERRUPT_INTR); // enable the interrupt
microblaze_enable_interrupts(); // enable global interrupts
// Clear the screen
clear_screen();
XIOModule_DiscreteSet(&gpo, 3, 2);
while (1) {
}
}