diff --git a/.nojekyll b/.nojekyll new file mode 100644 index 0000000..e69de29 diff --git a/assets/clang-format.png b/assets/clang-format.png new file mode 100644 index 0000000..4380db2 Binary files /dev/null and b/assets/clang-format.png differ diff --git a/assets/format-on-save.png b/assets/format-on-save.png new file mode 100644 index 0000000..2e8b331 Binary files /dev/null and b/assets/format-on-save.png differ diff --git a/assets/import-code.png b/assets/import-code.png new file mode 100644 index 0000000..d56deee Binary files /dev/null and b/assets/import-code.png differ diff --git a/assets/locks.c b/assets/locks.c new file mode 100644 index 0000000..6447c64 --- /dev/null +++ b/assets/locks.c @@ -0,0 +1,46 @@ +#include +#include +#include +#include + +int glob = 0; +static pthread_mutex_t mtx = PTHREAD_MUTEX_INITIALIZER; + +void *thread_func(void *arg) { + int loops = *((int *)arg); + int loc; + + for (int i = 0; i < loops; i++) { + pthread_mutex_lock(&mtx); + loc = glob; + loc++; + glob = loc; + pthread_mutex_unlock(&mtx); + } + + return NULL; +} + +int main() { + printf("******* Threading Example *******\n"); + pthread_t thread1; + pthread_t thread2; + int loops = 10000000; + + if (pthread_create(&thread1, NULL, thread_func, &loops)) { + printf("An error occurred while creating thread.\n"); + return EXIT_FAILURE; + } + + if (pthread_create(&thread2, NULL, thread_func, &loops)) { + printf("An error occurred while creating thread.\n"); + return EXIT_FAILURE; + } + + pthread_join(thread1, NULL); + pthread_join(thread2, NULL); + + printf("glob = %d\n", glob); + + return EXIT_SUCCESS; +} \ No newline at end of file diff --git a/assets/threads.c b/assets/threads.c new file mode 100644 index 0000000..8465029 --- /dev/null +++ b/assets/threads.c @@ -0,0 +1,36 @@ +#include +#include +#include +#include + +void *do_work(void *arg); + +int main() { + printf("******* Threading Example *******\n"); + pthread_t thread; + int i = 0; + + if (pthread_create(&thread, NULL, do_work, NULL)) { + printf("An error occurred while creating thread.\n"); + return EXIT_FAILURE; + } + + printf("Parent: Hi!\n"); + for (int i = 0; i < 10; i++) { + printf("Parent: Doing work... (%d)\n", i); + sleep(1); + } + + pthread_exit(NULL); + return EXIT_SUCCESS; +} + +void *do_work(void *arg) { + printf("Child: Hi!\n"); + + for (int i = 0; i < 10; i++) { + printf("Child: Doing work... (%d)\n", i); + sleep(1); + } + pthread_exit(NULL); +} \ No newline at end of file diff --git a/assets/under-construction.gif b/assets/under-construction.gif new file mode 100644 index 0000000..90ca163 Binary files /dev/null and b/assets/under-construction.gif differ diff --git a/assets/vim.png b/assets/vim.png new file mode 100644 index 0000000..da9b246 Binary files /dev/null and b/assets/vim.png differ diff --git a/css/main.css b/css/main.css new file mode 100644 index 0000000..952d398 --- /dev/null +++ b/css/main.css @@ -0,0 +1,314 @@ +/** Reset some basic elements */ +body, h1, h2, h3, h4, h5, h6, p, blockquote, pre, hr, dl, dd, ol, ul, figure { margin: 0; padding: 0; } + +/** Basic styling */ +body { font: 300 16px/1.5 "neue-haas-unica", "Helvetica Neue", Helvetica, Arial, sans-serif; color: #111; background-color: #fdfdfd; -webkit-text-size-adjust: 100%; -webkit-font-feature-settings: "kern" 1; -moz-font-feature-settings: "kern" 1; -o-font-feature-settings: "kern" 1; font-feature-settings: "kern" 1; font-kerning: normal; } + +/** Set `margin-bottom` to maintain vertical rhythm */ +h1, h2, h3, h4, h5, h6, p, blockquote, pre, ul, ol, dl, figure, .highlight { margin-bottom: 15px; } + +h1, h2, h3, h4, h5 { color: #424242; font-family: muli, sans-serif; letter-spacing: normal; } + +/** Images */ +img { max-width: 100%; vertical-align: middle; } + +/** Figures */ +figure > img { display: block; } + +figcaption { font-size: 14px; } + +/** Lists */ +ul, ol { margin-left: 30px; } + +li > ul, li > ol { margin-bottom: 0; } + +/** Headings */ +h1, h2, h3, h4, h5, h6 { font-weight: 300; } + +/** Links */ +a { color: #e98074; text-decoration: none; } + +a:hover { color: #df4432; text-decoration: underline; } + +/** Blockquotes */ +blockquote { color: #424242; border-left: 4px solid #a8a8a8; padding-left: 15px; font-size: 18px; letter-spacing: -1px; font-style: italic; } + +blockquote > :last-child { margin-bottom: 0; } + +/** Code formatting */ +pre, code { font-size: 15px; border: 1px solid #a8a8a8; border-radius: 3px; background-color: #eef; } + +code { padding: 1px 5px; } + +code { color: #e85a4f; } + +pre { padding: 8px 12px; overflow-x: auto; } + +pre > code { border: 0; padding-right: 0; padding-left: 0; } + +/** Wrapper */ +.wrapper { max-width: -webkit-calc(800px - (30px * 2)); max-width: calc(800px - (30px * 2)); margin-right: auto; margin-left: auto; padding-right: 30px; padding-left: 30px; } + +@media screen and (max-width: 800px) { .wrapper { max-width: -webkit-calc(800px - (30px)); max-width: calc(800px - (30px)); padding-right: 15px; padding-left: 15px; } } + +/** Clearfix */ +.wrapper:after { content: ""; display: table; clear: both; } + +/** Icons */ +.icon > svg { display: inline-block; width: 16px; height: 16px; vertical-align: middle; } + +.icon > svg path { fill: #424242; } + +.pixelated { image-rendering: pixelated; } + +.sidebar-color { background-color: #fdfdfd; } + +.navbar { background-color: #fdfdfd; } + +/** Syntax highlighting styles */ +.highlight { background: #fff; } + +.highlighter-rouge .highlight { background: #eef; } + +.highlight .c { color: #998; font-style: italic; } + +.highlight .err { color: #a61717; background-color: #e3d2d2; } + +.highlight .k { font-weight: bold; } + +.highlight .o { font-weight: bold; } + +.highlight .cm { color: #998; font-style: italic; } + +.highlight .cp { color: #999; font-weight: bold; } + +.highlight .c1 { color: #998; font-style: italic; } + +.highlight .cs { color: #999; font-weight: bold; font-style: italic; } + +.highlight .gd { color: #000; background-color: #fdd; } + +.highlight .gd .x { color: #000; background-color: #faa; } + +.highlight .ge { font-style: italic; } + +.highlight .gr { color: #a00; } + +.highlight .gh { color: #999; } + +.highlight .gi { color: #000; background-color: #dfd; } + +.highlight .gi .x { color: #000; background-color: #afa; } + +.highlight .go { color: #888; } + +.highlight .gp { color: #555; } + +.highlight .gs { font-weight: bold; } + +.highlight .gu { color: #aaa; } + +.highlight .gt { color: #a00; } + +.highlight .kc { font-weight: bold; } + +.highlight .kd { font-weight: bold; } + +.highlight .kp { font-weight: bold; } + +.highlight .kr { font-weight: bold; } + +.highlight .kt { color: #458; font-weight: bold; } + +.highlight .m { color: #099; } + +.highlight .s { color: #d14; } + +.highlight .na { color: #008080; } + +.highlight .nb { color: #0086B3; } + +.highlight .nc { color: #458; font-weight: bold; } + +.highlight .no { color: #008080; } + +.highlight .ni { color: #800080; } + +.highlight .ne { color: #900; font-weight: bold; } + +.highlight .nf { color: #900; font-weight: bold; } + +.highlight .nn { color: #555; } + +.highlight .nt { color: #000080; } + +.highlight .nv { color: #008080; } + +.highlight .ow { font-weight: bold; } + +.highlight .w { color: #bbb; } + +.highlight .mf { color: #099; } + +.highlight .mh { color: #099; } + +.highlight .mi { color: #099; } + +.highlight .mo { color: #099; } + +.highlight .sb { color: #d14; } + +.highlight .sc { color: #d14; } + +.highlight .sd { color: #d14; } + +.highlight .s2 { color: #d14; } + +.highlight .se { color: #d14; } + +.highlight .sh { color: #d14; } + +.highlight .si { color: #d14; } + +.highlight .sx { color: #d14; } + +.highlight .sr { color: #009926; } + +.highlight .s1 { color: #d14; } + +.highlight .ss { color: #990073; } + +.highlight .bp { color: #999; } + +.highlight .vc { color: #008080; } + +.highlight .vg { color: #008080; } + +.highlight .vi { color: #008080; } + +.highlight .il { color: #099; } + +/*! Start Bootstrap - Simple Sidebar (https://startbootstrap.com/template-overviews/simple-sidebar) Copyright 2013-2019 Start Bootstrap Licensed under MIT (https://github.com/BlackrockDigital/startbootstrap-simple-sidebar/blob/master/LICENSE) */ +body { overflow-x: hidden; } + +.sidebar-sticky { position: -webkit-sticky; position: sticky; top: 0; height: calc(100vh); padding-top: 0.5rem; overflow-x: hidden; overflow-y: auto; padding-bottom: 50px; } + +#sidebar-wrapper { min-height: 100vh; margin-left: -16rem; -webkit-transition: margin 0.25s ease-out; -moz-transition: margin 0.25s ease-out; -o-transition: margin 0.25s ease-out; transition: margin 0.25s ease-out; } + +#sidebar-wrapper .sidebar-heading-big { padding: 0.875rem 1.25rem; font-size: 1.5rem; font-family: muli, sans-serif; } + +.sidebar-heading-big img { max-width: 50px; } + +.sidebar-heading-big a { color: #111; } + +.sidebar-heading-big a:hover { text-decoration: none; color: #111; } + +a.sidebar-item:focus, a.sidebar-item:hover { background-color: rgba(233, 128, 116, 0.7) !important; } + +#sidebar-wrapper .sidebar-heading { padding: 2rem 1.25rem 0.3rem 1.25rem; font-size: 1rem; text-transform: uppercase; color: grey; font-family: muli, sans-serif; } + +#sidebar-wrapper .list-group { width: 16rem; } + +#page-content-wrapper { min-width: 100vw; } + +#wrapper.toggled #sidebar-wrapper { margin-left: 0; } + +@media (min-width: 768px) { #sidebar-wrapper { margin-left: 0; } #page-content-wrapper { min-width: 0; width: 100%; } #wrapper.toggled #sidebar-wrapper { margin-left: -16rem; } } + +::selection { background-color: #ffde16; } + +.badge-dark-grey { border: solid 1.5px #495057; } + +h1 { padding-top: 20px; } + +h2 { margin-top: 50px; } + +h3 { text-transform: uppercase; color: gray; font-size: 1.3rem; margin-top: 50px; } + +.container { margin-bottom: 150px; } + +.navbar-nav { margin-left: 0; } + +ul li { margin-bottom: 8px; } + +.btn-brand { color: #e98074 !important; border-color: #e98074; background-color: rgba(0, 0, 0, 0); } + +.btn-brand:hover { background-color: #e98074; color: white !important; } + +.suggest-edits { padding-left: 0.5rem !important; padding-right: 0.5rem !important; } + +.page-title i { font-size: 1.8rem; } + +.page-title-bar { font-family: muli, sans-serif; } + +.lab-toc { border: 1px solid #e3e3e3; border-radius: 4px; -webkit-box-shadow: inset 0 1px 1px rgba(0, 0, 0, 0.05); -moz-box-shadow: inset 0 1px 1px rgba(0, 0, 0, 0.05); box-shadow: inset 0 1px 1px rgba(0, 0, 0, 0.05); margin-bottom: 20px; } + +.lab-toc h4 { display: block; padding: 3px 15px; font-size: 11px; font-weight: bold; line-height: 20px; color: #999999; text-shadow: 0 1px 0 rgba(255, 255, 255, 0.5); text-transform: uppercase; padding-top: 15px; margin-bottom: 0px; } + +.lab-toc ul { margin-left: 15px; } + +.lab-toc li { display: block; font-size: 14px; margin-bottom: 0px; } + +.lab-toc a { text-decoration: none; } + +.card-seperator { display: none; } + +@media (max-width: 1000px) { .card-seperator { display: block; } } + +.home-cards .col { margin-bottom: 30px; } + +.home-card { height: 100%; background-color: rgba(255, 255, 255, 0.8); } + +.firstcharacter { color: #e98074; float: left; font-family: omnium, sans-serif; font-size: 75px; line-height: 60px; padding-top: 0px; padding-right: 8px; padding-left: 3px; } + +table { margin: 20px; } + +td, th { border: 1px solid rgba(0, 0, 0, 0.125); padding: 8px; } + +tr:nth-child(even) { background-color: #f2f2f2; } + +th { min-width: 150px; padding-top: 12px; padding-bottom: 12px; text-align: center; background-color: #c3e6ef; color: black; text-transform: uppercase; font-size: 1rem; } + +table .section { text-align: center; font-weight: bold; padding-top: 20px; text-transform: uppercase; color: gray; font-size: 1rem; } + +.home-nav-bg { border-bottom: 0px !important; } + +.home-image { background-repeat: no-repeat; background-size: cover; background-position: 20% 0%; background-image: url("../images/background.svg"); } + +@media screen and (max-width: 991.98px) { .home-image { background-image: url("../images/background-medium.svg"); padding-bottom: 450px; } } + +@media screen and (max-width: 767.98px) { .home-image { background-image: url("../images/background-small.svg"); padding-bottom: 250px; } } + +.home-icon { margin: 0 auto; margin-top: 20px; width: 70px; height: 70px; } + +.cloud-icon { background: url("../images/cloud-icon.svg") no-repeat center center; } + +.socket-icon { background: url("../images/socket-icon.svg") no-repeat center center; } + +.concurrency-icon { background: url("../images/concurrency-icon.svg") no-repeat center center; } + +.nodes-icon { background: url("../images/nodes-icon.svg") no-repeat center center; } + +.wireless-icon { background: url("../images/wireless-icon.svg") no-repeat center center; } + +.almost-hide { margin-top: 200px; } + +.almost-hide span { color: rgba(0, 0, 0, 0); } + +.almost-hide ::selection { color: rgba(0, 0, 0, 0.1); } + +.thanks { position: fixed; bottom: 0; right: 10px; color: rgba(0, 0, 0, 0.3); font-size: 12px; } + +.thanks a { opacity: 0.3; } + +.card-deck .card { min-width: 220px; background-color: rgba(195, 230, 239, 0.5); } + +.lab .fa-github { font-size: 1.3rem; } + +.list-item-tall { padding-top: 12pt; padding-bottom: 12pt; } + +.list-item-normal { padding-top: 4pt; padding-bottom: 4pt; } + +.list-item-narrow { padding-top: 1pt; padding-bottom: 1pt; } + +/*# sourceMappingURL=main.css.map */ \ No newline at end of file diff --git a/css/main.css.map b/css/main.css.map new file mode 100644 index 0000000..d06fc1f --- /dev/null +++ b/css/main.css.map @@ -0,0 +1,22 @@ +{ + "version": 3, + "file": "main.css", + "sources": [ + "main.scss", + "_sass/_base.scss", + "_sass/_fonts.scss", + "_sass/_syntax-highlighting.scss", + "_sass/simple-sidebar.scss", + "_sass/_pages.scss" + ], + "sourcesContent": [ + "@charset \"utf-8\";\n\n// Our variables\n$base-font-family: \"neue-haas-unica\", \"Helvetica Neue\", Helvetica, Arial, sans-serif;\n$base-font-size: 16px;\n$base-font-weight: 300;\n$small-font-size: $base-font-size * 0.875;\n$base-line-height: 1.5;\n\n$spacing-unit: 30px;\n\n\n// $color1: #8d8741;\n// $color2: #659dbd;\n// $color3: #daad86;\n// $color4: #bc986a;\n// $color5: #fbeec1;\n\n\n$color1: #eae7dc;\n$color2: #d8c3a5;\n$color3: #8e8d8a;\n$color4: #e98074;\n$color5: #e85a4f;\n\n\n$text-color: #111;\n$background-color: #fdfdfd;\n$brand-color: $color4;\n$secondary-color: #c3e6ef;\n\n$selection-color: #ffde16;\n$sidebar-color: $background-color;\n$sidebar-hover-color: $color4;\n$nav-color: $background-color;\n\n$code-color: $color5;\n\n$grey-color: #424242;\n$grey-color-light: lighten($grey-color, 40%);\n$grey-color-dark: darken($grey-color, 25%);\n\n// Width of the content area\n$content-width: 800px;\n\n$on-palm: 600px;\n$on-laptop: 800px;\n$on-xs: 575.98px;\n$on-sm: 767.98px;\n$on-md: 991.98px;\n$on-lg: 1199.98px;\n\n@mixin media-query($device) {\n @media screen and (max-width: $device) {\n @content;\n }\n}\n\n// Import partials from `sass_dir` (defaults to `_sass`)\n@import \"base\", \"fonts\", \"syntax-highlighting\", \"simple-sidebar\", \"pages\";\n", + "/**\n * Reset some basic elements\n */\nbody,\nh1,\nh2,\nh3,\nh4,\nh5,\nh6,\np,\nblockquote,\npre,\nhr,\ndl,\ndd,\nol,\nul,\nfigure {\n margin: 0;\n padding: 0;\n}\n\n/**\n * Basic styling\n */\nbody {\n font: $base-font-weight #{$base-font-size}/#{$base-line-height} $base-font-family;\n color: $text-color;\n background-color: $background-color;\n -webkit-text-size-adjust: 100%;\n -webkit-font-feature-settings: \"kern\" 1;\n -moz-font-feature-settings: \"kern\" 1;\n -o-font-feature-settings: \"kern\" 1;\n font-feature-settings: \"kern\" 1;\n font-kerning: normal;\n}\n\n/**\n * Set `margin-bottom` to maintain vertical rhythm\n */\nh1,\nh2,\nh3,\nh4,\nh5,\nh6,\np,\nblockquote,\npre,\nul,\nol,\ndl,\nfigure,\n%vertical-rhythm {\n margin-bottom: $spacing-unit / 2;\n}\n\nh1,\nh2,\nh3,\nh4,\nh5 {\n color: #424242;\n // font-family: 'Ubuntu', sans-serif;\n font-family: muli, sans-serif;\n letter-spacing: normal;\n}\n\n/**\n * Images\n */\nimg {\n max-width: 100%;\n vertical-align: middle;\n}\n\n/**\n * Figures\n */\nfigure > img {\n display: block;\n}\n\nfigcaption {\n font-size: $small-font-size;\n}\n\n/**\n * Lists\n */\nul,\nol {\n margin-left: $spacing-unit;\n}\n\nli {\n > ul,\n > ol {\n margin-bottom: 0;\n }\n}\n\n/**\n * Headings\n */\nh1,\nh2,\nh3,\nh4,\nh5,\nh6 {\n font-weight: $base-font-weight;\n}\n\n/**\n * Links\n */\na {\n color: $brand-color;\n text-decoration: none;\n\n &:visited {\n }\n\n &:hover {\n color: darken($brand-color, 15%);\n text-decoration: underline;\n }\n}\n\n/**\n * Blockquotes\n */\nblockquote {\n color: $grey-color;\n border-left: 4px solid $grey-color-light;\n padding-left: $spacing-unit / 2;\n font-size: 18px;\n letter-spacing: -1px;\n font-style: italic;\n\n > :last-child {\n margin-bottom: 0;\n }\n}\n\n/**\n * Code formatting\n */\npre,\ncode {\n font-size: 15px;\n border: 1px solid $grey-color-light;\n border-radius: 3px;\n background-color: #eef;\n}\n\ncode {\n padding: 1px 5px;\n}\n\ncode {\n color: $code-color;\n}\n\npre {\n padding: 8px 12px;\n overflow-x: auto;\n\n > code {\n border: 0;\n padding-right: 0;\n padding-left: 0;\n }\n}\n\n/**\n * Wrapper\n */\n.wrapper {\n max-width: -webkit-calc(#{$content-width} - (#{$spacing-unit} * 2));\n max-width: calc(#{$content-width} - (#{$spacing-unit} * 2));\n margin-right: auto;\n margin-left: auto;\n padding-right: $spacing-unit;\n padding-left: $spacing-unit;\n @extend %clearfix;\n\n @include media-query($on-laptop) {\n max-width: -webkit-calc(#{$content-width} - (#{$spacing-unit}));\n max-width: calc(#{$content-width} - (#{$spacing-unit}));\n padding-right: $spacing-unit / 2;\n padding-left: $spacing-unit / 2;\n }\n}\n\n/**\n * Clearfix\n */\n%clearfix {\n &:after {\n content: \"\";\n display: table;\n clear: both;\n }\n}\n\n/**\n * Icons\n */\n.icon {\n > svg {\n display: inline-block;\n width: 16px;\n height: 16px;\n vertical-align: middle;\n\n path {\n fill: $grey-color;\n }\n }\n}\n\n.pixelated {\n image-rendering: pixelated;\n}\n\n.sidebar-color {\n background-color: $sidebar-color;\n}\n\n.navbar {\n background-color: $nav-color;\n}", + "", + "/**\n * Syntax highlighting styles\n */\n.highlight {\n background: #fff;\n @extend %vertical-rhythm;\n\n .highlighter-rouge & {\n background: #eef;\n }\n\n .c { color: #998; font-style: italic } // Comment\n .err { color: #a61717; background-color: #e3d2d2 } // Error\n .k { font-weight: bold } // Keyword\n .o { font-weight: bold } // Operator\n .cm { color: #998; font-style: italic } // Comment.Multiline\n .cp { color: #999; font-weight: bold } // Comment.Preproc\n .c1 { color: #998; font-style: italic } // Comment.Single\n .cs { color: #999; font-weight: bold; font-style: italic } // Comment.Special\n .gd { color: #000; background-color: #fdd } // Generic.Deleted\n .gd .x { color: #000; background-color: #faa } // Generic.Deleted.Specific\n .ge { font-style: italic } // Generic.Emph\n .gr { color: #a00 } // Generic.Error\n .gh { color: #999 } // Generic.Heading\n .gi { color: #000; background-color: #dfd } // Generic.Inserted\n .gi .x { color: #000; background-color: #afa } // Generic.Inserted.Specific\n .go { color: #888 } // Generic.Output\n .gp { color: #555 } // Generic.Prompt\n .gs { font-weight: bold } // Generic.Strong\n .gu { color: #aaa } // Generic.Subheading\n .gt { color: #a00 } // Generic.Traceback\n .kc { font-weight: bold } // Keyword.Constant\n .kd { font-weight: bold } // Keyword.Declaration\n .kp { font-weight: bold } // Keyword.Pseudo\n .kr { font-weight: bold } // Keyword.Reserved\n .kt { color: #458; font-weight: bold } // Keyword.Type\n .m { color: #099 } // Literal.Number\n .s { color: #d14 } // Literal.String\n .na { color: #008080 } // Name.Attribute\n .nb { color: #0086B3 } // Name.Builtin\n .nc { color: #458; font-weight: bold } // Name.Class\n .no { color: #008080 } // Name.Constant\n .ni { color: #800080 } // Name.Entity\n .ne { color: #900; font-weight: bold } // Name.Exception\n .nf { color: #900; font-weight: bold } // Name.Function\n .nn { color: #555 } // Name.Namespace\n .nt { color: #000080 } // Name.Tag\n .nv { color: #008080 } // Name.Variable\n .ow { font-weight: bold } // Operator.Word\n .w { color: #bbb } // Text.Whitespace\n .mf { color: #099 } // Literal.Number.Float\n .mh { color: #099 } // Literal.Number.Hex\n .mi { color: #099 } // Literal.Number.Integer\n .mo { color: #099 } // Literal.Number.Oct\n .sb { color: #d14 } // Literal.String.Backtick\n .sc { color: #d14 } // Literal.String.Char\n .sd { color: #d14 } // Literal.String.Doc\n .s2 { color: #d14 } // Literal.String.Double\n .se { color: #d14 } // Literal.String.Escape\n .sh { color: #d14 } // Literal.String.Heredoc\n .si { color: #d14 } // Literal.String.Interpol\n .sx { color: #d14 } // Literal.String.Other\n .sr { color: #009926 } // Literal.String.Regex\n .s1 { color: #d14 } // Literal.String.Single\n .ss { color: #990073 } // Literal.String.Symbol\n .bp { color: #999 } // Name.Builtin.Pseudo\n .vc { color: #008080 } // Name.Variable.Class\n .vg { color: #008080 } // Name.Variable.Global\n .vi { color: #008080 } // Name.Variable.Instance\n .il { color: #099 } // Literal.Number.Integer.Long\n}\n", + "/*!\n * Start Bootstrap - Simple Sidebar (https://startbootstrap.com/template-overviews/simple-sidebar)\n * Copyright 2013-2019 Start Bootstrap\n * Licensed under MIT (https://github.com/BlackrockDigital/startbootstrap-simple-sidebar/blob/master/LICENSE)\n */\nbody {\n overflow-x: hidden;\n}\n\n.sidebar-sticky {\n position: -webkit-sticky;\n position: sticky;\n top: 0;\n height: calc(100vh);\n padding-top: 0.5rem;\n overflow-x: hidden;\n overflow-y: auto;\n padding-bottom: 50px;\n}\n\n#sidebar-wrapper {\n min-height: 100vh;\n margin-left: -16rem;\n -webkit-transition: margin 0.25s ease-out;\n -moz-transition: margin 0.25s ease-out;\n -o-transition: margin 0.25s ease-out;\n transition: margin 0.25s ease-out;\n}\n\n#sidebar-wrapper .sidebar-heading-big {\n padding: 0.875rem 1.25rem;\n font-size: 1.5rem;\n font-family: muli, sans-serif;\n}\n\n.sidebar-heading-big img {\n max-width: 50px;\n}\n\n.sidebar-heading-big a {\n color: #111;\n}\n\n.sidebar-heading-big a:hover {\n text-decoration: none;\n color: #111;\n}\n\na.sidebar-item:focus,\na.sidebar-item:hover {\n background-color: rgba($sidebar-hover-color, 0.7) !important;\n}\n\n#sidebar-wrapper .sidebar-heading {\n padding: 2rem 1.25rem 0.3rem 1.25rem;\n font-size: 1rem;\n text-transform: uppercase;\n color: grey;\n font-family: muli, sans-serif;\n}\n\n#sidebar-wrapper .list-group {\n width: 16rem;\n}\n\n#page-content-wrapper {\n min-width: 100vw;\n}\n\n#wrapper.toggled #sidebar-wrapper {\n margin-left: 0;\n}\n\n@media (min-width: 768px) {\n #sidebar-wrapper {\n margin-left: 0;\n }\n\n #page-content-wrapper {\n min-width: 0;\n width: 100%;\n }\n\n #wrapper.toggled #sidebar-wrapper {\n margin-left: -16rem;\n }\n}\n", + "::selection {\n // background-color: rgba(237, 63, 149, .2);\n background-color: $selection-color;\n}\n\n.badge-dark-grey {\n border: solid 1.5px #495057;\n}\n\nh1 {\n padding-top: 20px;\n}\n\nh2 {\n margin-top: 50px;\n}\n\nh3 {\n text-transform: uppercase;\n color: gray;\n font-size: 1.3rem;\n margin-top: 50px;\n}\n\n.container {\n margin-bottom: 150px;\n}\n\n.navbar-nav {\n margin-left: 0;\n}\n\nul li {\n margin-bottom: 8px;\n}\n\n.btn-brand {\n color: $brand-color !important;\n border-color: $brand-color;\n background-color: rgba(0, 0, 0, 0);\n\n &:hover {\n background-color: $brand-color;\n color: white !important;\n }\n}\n\n.suggest-edits {\n padding-left: 0.5rem !important;\n padding-right: 0.5rem !important;\n // font-size: .8rem;\n}\n\n.page-title i {\n font-size: 1.8rem;\n}\n\n.page-title-bar {\n font-family: muli, sans-serif;\n}\n\n.lab-toc {\n border: 1px solid #e3e3e3;\n border-radius: 4px;\n -webkit-box-shadow: inset 0 1px 1px rgba(0, 0, 0, 0.05);\n -moz-box-shadow: inset 0 1px 1px rgba(0, 0, 0, 0.05);\n box-shadow: inset 0 1px 1px rgba(0, 0, 0, 0.05);\n margin-bottom: 20px;\n\n h4 {\n display: block;\n padding: 3px 15px;\n font-size: 11px;\n font-weight: bold;\n line-height: 20px;\n color: #999999;\n text-shadow: 0 1px 0 rgba(255, 255, 255, 0.5);\n text-transform: uppercase;\n padding-top: 15px;\n margin-bottom: 0px;\n }\n\n ul {\n margin-left: 15px;\n }\n\n li {\n display: block;\n font-size: 14px;\n margin-bottom: 0px;\n }\n\n a {\n text-decoration: none;\n }\n}\n\n.card-seperator {\n display: none;\n\n @media (max-width: 1000px) {\n display: block;\n }\n}\n\n.home-cards .col {\n margin-bottom: 30px;\n}\n\n.home-card {\n height: 100%;\n background-color: rgba(white, 0.8);\n}\n\n.firstcharacter {\n color: $brand-color;\n float: left;\n font-family: omnium, sans-serif;\n font-size: 75px;\n line-height: 60px;\n padding-top: 0px;\n padding-right: 8px;\n padding-left: 3px;\n}\n\ntable {\n margin: 20px;\n}\n\ntd,\nth {\n border: 1px solid rgba(0, 0, 0, 0.125);\n padding: 8px;\n}\n\ntr:nth-child(even) {\n background-color: #f2f2f2;\n // background-color: rgba($selection-color, 0.2);\n}\n\ntr:hover {\n // background-color: #ddd;\n // background-color: rgba($sidebar-hover-color, 0.7);\n}\n\nth {\n min-width: 150px;\n padding-top: 12px;\n padding-bottom: 12px;\n text-align: center;\n background-color: rgba($secondary-color, 1);\n // background-color: rgba($brand-color, 0.7);\n color: black;\n text-transform: uppercase;\n font-size: 1rem;\n}\n\ntable {\n .section {\n text-align: center;\n font-weight: bold;\n padding-top: 20px;\n text-transform: uppercase;\n color: gray;\n font-size: 1rem;\n }\n}\n\n.home-nav-bg {\n border-bottom: 0px !important;\n}\n\n.home-image {\n // background-image: url(\"../images/background.svg\");\n background-repeat: no-repeat;\n background-size: cover;\n background-position: 20% 0%;\n background-image: url(\"../images/background.svg\");\n}\n\n@include media-query($on-md) {\n .home-image {\n // background-position: 0% -40px;\n background-image: url(\"../images/background-medium.svg\");\n padding-bottom: 450px;\n }\n}\n\n@include media-query($on-sm) {\n .home-image {\n background-image: url(\"../images/background-small.svg\");\n padding-bottom: 250px;\n }\n}\n\n.home-icon {\n // background-size: contain;\n margin: 0 auto;\n margin-top: 20px;\n width: 70px;\n height: 70px;\n}\n\n.cloud-icon {\n background: url(\"../images/cloud-icon.svg\") no-repeat center center;\n}\n\n.socket-icon {\n background: url(\"../images/socket-icon.svg\") no-repeat center center;\n}\n\n.concurrency-icon {\n background: url(\"../images/concurrency-icon.svg\") no-repeat center center;\n}\n\n.nodes-icon {\n background: url(\"../images/nodes-icon.svg\") no-repeat center center;\n}\n\n.wireless-icon {\n background: url(\"../images/wireless-icon.svg\") no-repeat center center;\n}\n\n.almost-hide {\n margin-top: 200px;\n\n span {\n color: rgba(0, 0, 0, 0);\n }\n\n ::selection {\n color: rgba(0, 0, 0, 0.1);\n }\n}\n\n.thanks {\n position: fixed;\n bottom: 0;\n right: 10px;\n color: rgba(0, 0, 0, 0.3);\n font-size: 12px;\n\n a {\n opacity: 0.3;\n }\n}\n\n.card-deck .card {\n min-width: 220px;\n background-color: rgba($secondary-color, 0.5);\n}\n\n.lab {\n .fa-github {\n font-size: 1.3rem;\n }\n}\n\n.list-item-tall {\n padding-top: 12pt;\n padding-bottom: 12pt;\n}\n\n.list-item-normal {\n padding-top: 4pt;\n padding-bottom: 4pt;\n}\n\n.list-item-narrow {\n padding-top: 1pt;\n padding-bottom: 1pt;\n}" + ], + "names": [], + "mappings": "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" +} \ No newline at end of file diff --git a/final-project/index.html b/final-project/index.html new file mode 100644 index 0000000..df54c0b --- /dev/null +++ b/final-project/index.html @@ -0,0 +1,291 @@ + + + + + + + + + + + + + Final Project • ECEn 625: Compilation Strategies for High-Performance Systems + + + + + + + + + + + + + + + + + + + + +
+ + + + + +
+ + + +
+
+

+ + Final Project +

+ +
+ + +

The project for this course is very open-ended. You are welcome to propose any topic that is related to the class material. See the lecture slides about the final project for more ideas. As discussed a few options include:

+ +
    +
  1. Implementing and optimizing an algorithm of your choice in HLS.
  2. +
  3. Exploring, improving, or evaluating some aspect of HLS tools (open-source or commercial).
  4. +
  5. Exploring, improving, or evaluating the growing space of DSL to HLS compilers.
  6. +
+ +

You can work alone, or in a group of two.

+ +

Project Deliverables

+

There will be four deliverables for the project:

+ +

Project Proposal

+
    +
  1. +

    A project proposal. You will present your proposal in a 5 minute presentation in class on March 30th. You should indicate the project title and the members of your group (if you are not working on your own). Prepare a few slides about: 1) what you are going to work on, 2) issues/risks you anticipate and how you plan to mitigate them, and 3) what results you plan to collect.

    +
  2. +
  3. +

    An interim class presentation on the last two day of class. In this presentation, you will describe the problem you are trying to solve, any relevant previous work, and your approach. You should have some results to present. Like the mini-lecture, your goal is to make sure that the class understands what you are tying to do, and why you are trying to do it. Presentations should be close to 15 minutes.

    +
  4. +
  5. +

    The final technical report. This should be prepared in IEEE conference format (11pt, two columns), with a 4 page limit (6 page limit for groups of two). The paper should be of similar writing quality to a IEEE conference paper. Introduce your problem, describe what you did, and include results. Use figures where appropriate to help describe your project. If your project is better presented in another format (jupyter notebook page, wiki page), discuss this with the instructor. The final report is due Wednesday, April 26st, 11:59pm

    +
  6. +
  7. +

    Commit any code or code products to your Github repo. Include some basic documentation that outlines the organization of your files and how someone would use them.

    +
  8. +
+ +

Grading Breakdown

+ +

Your final project will be graded on these categories:

+
    +
  • 50%: Work completed for project. (Difficulty of problem tackled, amount of work completed, auality and clarity of results, etc.)
  • +
  • 20%: Class presentation (Clarity, organization, engagement)
  • +
  • 20%: Report (Clarity of presentation, context with related work, writing quality, qualtiy of graphics and/or figures)
  • +
  • 10%: Organization and documentation of code products
  • +
+ + +
+
+
+
+ + +
+ + + + + + + + + + + + + + \ No newline at end of file diff --git a/hls-integration-tutorial/index.html b/hls-integration-tutorial/index.html new file mode 100644 index 0000000..2bbcf13 --- /dev/null +++ b/hls-integration-tutorial/index.html @@ -0,0 +1,360 @@ + + + + + + + + + + + + + Vitis HLS Integration Tutorial • ECEn 625: Compilation Strategies for High-Performance Systems + + + + + + + + + + + + + + + + + + + + +
+ + + + + +
+ + + +
+
+

+ + Vitis HLS Integration Tutorial +

+ +
+ + +

Previous: Vitis Tutorial

+ +

This page discusses how you can export your IP from Vitis HLS to be used in a Vivado project, and ultimately to communicate with the HLS accelerator from a Vitis software proj ect.

+ +

Modifying Your Hardware

+ +

Exporting your HLS as IP

+

Since our goal is to communicate with the HLS IP from software, we will add a Slave AXI connection to our HLS IP core so that it can be connected to the ARM AXI bus.

+ +
    +
  • Run Vitis HLS and open your project from the last assignment.
  • +
  • Add a directive to your top-level hardware function. Choose the INTERFACE directive type, and change the mode to an AXI4-Lite Slave (s_axilite).
  • +
  • Set the INTERFACE of the input parameter to also be the AXI4-Lite bus.
  • +
  • Run C Synthesis.
  • +
  • Click Solution->Export RTL, and make sure the Format Selection is set to * Vivado IP (.zip)*.
  • +
  • Close Vitis HLS.
  • +
  • Unzip your IP to a folder, for example, I used unzip digitrec.zip -d lab_vitis/ip/digitrec/
  • +
+ +

Bug fix: I ran into a bug in Vitis 2020.2 that I had to fix. Look in your <ip_dir>/drivers/digitrec_v1_0/src/Makefile and look for three commented out lines that start with ‘#echo’. Remove these lines from the Makefile. See https://forums.xilinx.com/t5/High-Level-Synthesis-HLS/Bug-HLS-2020-2-generated-makefile-compilation-error-in-vitis/td-p/1206772

+ +

Adding your IP to Vivado

+
    +
  • Run Vivado, open your existing project, and open the block design.
  • +
  • If you do not already have a Processor System Reset IP, add one to your design. This will use the reset signal output by the processing system to reset IP in the FPGA fabric. +
      +
    • Connect the system clock ( FCLK_CLK0 from ZYNQ7 Processing System) to the slowest_sync_clk input.
    • +
    • Connect the processor reset output (FCLK_RESET0_N) to the ext_reset_in input.
    • +
    +
  • +
  • If you do not already have an AXI Interconnect IP, add one to your design. This is the bus that will allow the ARM CPU to communicate with the IP implemented in the FPGA fabric. +
      +
    • Configure the bus to have 1 Slave Interface and 1 Master Interface.
    • +
    • Connect the PS bus master (M_AXI_GP0 from ZYNQ7 Processing System) to the S00_AXI slave port.
    • +
    • Connect your clock (FCLK_CLK0 from ZYNQ7 Processing System) to all the clock inputs (*ACLK)
    • +
    • Connect your interconnect reset (interconnect_aresetn from Processor System Reset) to the ARESETN input.
    • +
    • Connect your peripheral reset (peripheral_aresetn from Processor System Reset) to the other reset inputs (*ARESETN)
    • +
    +
  • +
  • Add your HLS IP: +
      +
    • Open the IP catalog +
        +
      • Right-click, Add Repository
      • +
      • Navigate to the ip folder that contains your HLS IP extracted in the earlier step, and add this directory.
      • +
      +
    • +
    • Go back to your block design and add the HLS IP to your design.
    • +
    +
  • +
  • Connect up your HLS IP: +
      +
    • Connect the clock (FCLK_CLK0) to the clock input (ap_clk)
    • +
    • Connect the reset (peripheral_aresetn) to the reset input (ap_rst_n)
    • +
    • Connect the bus (M00_AXI from the AXI Interconnect) to the bus slave port (s_axi_control)
    • +
    +
  • +
  • Assign an address to your HLS IP: +
      +
    • Open the Address Editor, find your IP, right-click Assign.
    • +
    • Save the block design.
    • +
    +
  • +
  • +

    Run Generate Bitstream.

    +
  • +
  • +

    Export the new XSA file and overwrite your old one.

    +
  • +
  • Close Vivado
  • +
+ +

Communicating with your HLS IP from Software

+ +

Updating Platform Project

+
    +
  • Launch Vitis and reopen your existing workspace.
  • +
  • Right-click on your platform project, and choose Update Hardware Specifiction. Make sure you select your new XSA file.
  • +
  • If done correctly, you should see your HLS driver located at ps7_cortexa9_0/standalone_ps7_cortexa9_0/bsp/ps7_cortexa9_0/libsrc/digitrec_v1_0/src. Inspect the source code and locate: +
      +
    • xdigitrec_hw.h has register offsets for your IP core. If you followed the steps correctly, you should have: +
        +
      • control register (XDIGITREC_CONTROL_ADDR_AP_CTRL)
      • +
      • interrupt registers
      • +
      • return value register (XDIGITREC_CONTROL_ADDR_AP_RETURN)
      • +
      • function argument register (XDIGITREC_CONTROL_ADDR_INPUT_R_DATA) and more.
      • +
      +
    • +
    • xdigitrec.h provides a higher-level driver interface, with functions for starting your accelerator, checking if it’s done, setting argument inputs, etc.
    • +
    +
  • +
  • Build your platform project.
  • +
+ +

Using the Driver in Your Code

+
    +
  • Include the necessary header file in your application code and write software to test that you can start your IP, wait for it to complete, and retrieve the return value.
  • +
  • You will need to initialize the HLS device driver before you can call any of the function. As with most Xilinx drivers, this is done by calling _LookupConfig, providing the device ID from xparameters.h, and then calling _CfgInitialize:
  • +
+ +
XDigitrec digitrec;
+XDigitrec_Config* digitrec_config = XDigitrec_LookupConfig(XPAR_DIGITREC_0_DEVICE_ID);
+XDigitrec_CfgInitialize(&digitrec, digitrec_config);
+
+ +
    +
  • Try running the HLS accelerator and waiting for it to complete. Provide a test value and check the return value.
  • +
+ +
+
+
+
+ + +
+ + + + + + + + + + + + + + \ No newline at end of file diff --git a/icon/application-layer.svg b/icon/application-layer.svg new file mode 100644 index 0000000..4964cbc --- /dev/null +++ b/icon/application-layer.svg @@ -0,0 +1,28 @@ + + + + + Produced by OmniGraffle 7.17.2\n2020-08-24 18:12:46 +0000 + + Canvas 1 + + Application + + + + + + + + + + + + + + + + + + + diff --git a/icon/favicon-16x16.png.phil b/icon/favicon-16x16.png.phil new file mode 100644 index 0000000..33b1192 Binary files /dev/null and b/icon/favicon-16x16.png.phil differ diff --git a/icon/favicon-32x32.png.phil b/icon/favicon-32x32.png.phil new file mode 100644 index 0000000..e6469a3 Binary files /dev/null and b/icon/favicon-32x32.png.phil differ diff --git a/icon/favicon-96x96.png.phil b/icon/favicon-96x96.png.phil new file mode 100644 index 0000000..342159a Binary files /dev/null and b/icon/favicon-96x96.png.phil differ diff --git a/icon/icon.svg.phil b/icon/icon.svg.phil new file mode 100644 index 0000000..d0f474f --- /dev/null +++ b/icon/icon.svg.phil @@ -0,0 +1 @@ + \ No newline at end of file diff --git a/icon/layers-icon.svg b/icon/layers-icon.svg new file mode 100644 index 0000000..63e2088 --- /dev/null +++ b/icon/layers-icon.svg @@ -0,0 +1,29 @@ + + + + + Produced by OmniGraffle 7.17.2\n2020-08-24 16:34:41 +0000 + + Canvas 1 + + + Layer 1 + + + + + + + + + + + + + + + + + + + diff --git a/icon/layers.graffle b/icon/layers.graffle new file mode 100644 index 0000000..438f9c9 Binary files /dev/null and b/icon/layers.graffle differ diff --git a/icon/link-layer.svg b/icon/link-layer.svg new file mode 100644 index 0000000..bf26502 --- /dev/null +++ b/icon/link-layer.svg @@ -0,0 +1,28 @@ + + + + + Produced by OmniGraffle 7.17.2\n2020-08-24 18:13:37 +0000 + + Canvas 1 + + Link + + + + + + + + + + + + + + + + + + + diff --git a/icon/network-layer.svg b/icon/network-layer.svg new file mode 100644 index 0000000..dcc9f87 --- /dev/null +++ b/icon/network-layer.svg @@ -0,0 +1,28 @@ + + + + + Produced by OmniGraffle 7.17.2\n2020-08-24 18:13:22 +0000 + + Canvas 1 + + Network + + + + + + + + + + + + + + + + + + + diff --git a/icon/networking.graffle b/icon/networking.graffle new file mode 100644 index 0000000..56cfa2c Binary files /dev/null and b/icon/networking.graffle differ diff --git a/icon/networking.svg b/icon/networking.svg new file mode 100644 index 0000000..c2cbe8b --- /dev/null +++ b/icon/networking.svg @@ -0,0 +1,46 @@ + + + + + Produced by OmniGraffle 7.17.2\n2020-08-24 17:47:17 +0000 + + Canvas 1 + + Layer 1 + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + diff --git a/icon/transport-layer.svg b/icon/transport-layer.svg new file mode 100644 index 0000000..dbdfa93 --- /dev/null +++ b/icon/transport-layer.svg @@ -0,0 +1,28 @@ + + + + + Produced by OmniGraffle 7.17.2\n2020-08-24 18:13:10 +0000 + + Canvas 1 + + Transport + + + + + + + + + + + + + + + + + + + diff --git a/index.html b/index.html new file mode 100644 index 0000000..541e58e --- /dev/null +++ b/index.html @@ -0,0 +1,270 @@ + + + + + + + + + + + + Home • ECEn 625: Compilation Strategies for High-Performance Systems + + + + + + + + + + + + + + + + + + + +
+ + + + + +
+ + + +
+ +
+

ECEn 625: Compilation Strategies for High-Performance Systems +

+
+

+ As an undergrad, you learned how to design digital circuits, first by connecting simple + logic gates and flip-flops, and then by designing more complex circuits using a hardware + description + language (HDL), such as Verilog. This class is all about High-Level Synthesis (HLS), which + focuses on creating higher-level abstractions for digital design. Rather than describing + finite state machines and cycle-by-cyle circuit behavior using an HDL, HLS tools allow you + to describe your circuit behavior using software-like descriptions, typically using C, C++, + or + OpenCL. +

+

+ HLS diagram +

+ +

+ In this class you will first learn the behind-the-scenes algorithms that make it possible to + create hardware from software, and then you will gain some experience using commerical HLS + tools. Along the way you will learn about software compilers and various optimizations that + allow us to create high-performance hardware designs. +

+
+
+
+ +
+
+
+
+
+ +
+
+
+ + + + + + + + + + + + + + + + + \ No newline at end of file diff --git a/install-vitis/index.html b/install-vitis/index.html new file mode 100644 index 0000000..21fc814 --- /dev/null +++ b/install-vitis/index.html @@ -0,0 +1,336 @@ + + + + + + + + + + + + + Install Vivado/Vitis • ECEn 625: Compilation Strategies for High-Performance Systems + + + + + + + + + + + + + + + + + + + + +
+ + + + + +
+ + + +
+
+

+ + Install Vivado/Vitis +

+ +
+ + +

We will be using several Xilinx software tools, including Vivado, Vitis, and Vitis HLS. These can all be installed using a single Vitis installer.

+ +

Download

+ +
    +
  1. +

    Go to https://www.xilinx.com/support/download/index.html/content/xilinx/en/downloadNav/vitis.html

    +
  2. +
  3. +

    On the left-hand bar, select 2020.2, and find the section Vitis Core Development Kit - 2020.2 Full Product Installation.

    +
  4. +
  5. You can either: +
      +
    • Download all the files upfront (All OS installer Single-File Download), or
    • +
    • Download files as you install using the Web Installer: +
        +
      • Windows: Xilinx Unified Installer 2020.2: Windows Self Extracting Web Installer
      • +
      • Linux: Xilinx Unified Installer 2020.2: Linux Self Extracting Web Installer
      • +
      +
    • +
    +
  6. +
  7. You will need a free Xilinx account in order to download the software.
  8. +
+ +

Running the Installer

+

Depending on how you downloaded the files, you will run the installer differently:

+
    +
  • All OS installer Single-File Download: +
      +
    • Windows +
        +
      • Extract the files from the Xilinx_Unified_2020.2_1118_1232.tar.gz archive using a program like 7-zip.
      • +
      • Run xsetup.exe
      • +
      +
    • +
    • Linux: +
        +
      • Extract the files from the Xilinx_Unified_2020.2_1118_1232.tar.gz archive: tar -xvf Xilinx_Unified_2020.2_1118_1232.tar.gz
      • +
      • Run the installer: sudo ./xsetup
      • +
      +
    • +
    +
  • +
  • Web installer: +
      +
    • Windows: +
        +
      • Run Xilinx_Unified_2020.2_1118_1232_Win64.exe
      • +
      +
    • +
    • Linux: +
        +
      • Run the installer: sudo ./Xilinx_Unified_2020.2_1118_1232_Lin64.bin
      • +
      +
    • +
    +
  • +
+ +

Installer Options

+
    +
  1. Enter your Xilinx account information, and select Download and Install Now.
  2. +
  3. On the Select Product to Install screen, choose Vitis.
  4. +
  5. On the customization screen, uncheck everything, except make sure you have: +
      +
    • SoCs/Zynq-7000 or SoCs/Zynq Ultrascale+ MPSoC, depending on which board type you are using.
    • +
    • Install Cable Drivers
    • +
    +
  6. +
  7. On the next screen, agree to all boxes.
  8. +
  9. On the next screen, choose an installation location with enough space.
  10. +
  11. On the next screen, click Install and wait a while.
  12. +
+ +

Install Cable Drivers

+ +

If you are using Windows, your cable driver will have been installed during the installation process. If you are using Linux, you must install them manually:

+ +
cd /tools/Xilinx/Vivado/2020.2/data/xicom/cable_drivers/lin64/install_script/install_drivers
+sudo ./install_drivers
+
+ +

Next: Vivado Tutorial

+ +
+
+
+
+ + +
+ + + + + + + + + + + + + + \ No newline at end of file diff --git a/js/jquery.visible.min.js b/js/jquery.visible.min.js new file mode 100644 index 0000000..417039c --- /dev/null +++ b/js/jquery.visible.min.js @@ -0,0 +1 @@ +!function(t){var i=t(window);t.fn.visible=function(t,e,o){if(!(this.length<1)){var r=this.length>1?this.eq(0):this,n=r.get(0),f=i.width(),h=i.height(),o=o?o:"both",l=e===!0?n.offsetWidth*n.offsetHeight:!0;if("function"==typeof n.getBoundingClientRect){var g=n.getBoundingClientRect(),u=g.top>=0&&g.top0&&g.bottom<=h,c=g.left>=0&&g.left0&&g.right<=f,v=t?u||s:u&&s,b=t?c||a:c&&a;if("both"===o)return l&&v&&b;if("vertical"===o)return l&&v;if("horizontal"===o)return l&&b}else{var d=i.scrollTop(),p=d+h,w=i.scrollLeft(),m=w+f,y=r.offset(),z=y.top,B=z+r.height(),C=y.left,R=C+r.width(),j=t===!0?B:z,q=t===!0?z:B,H=t===!0?R:C,L=t===!0?C:R;if("both"===o)return!!l&&p>=q&&j>=d&&m>=L&&H>=w;if("vertical"===o)return!!l&&p>=q&&j>=d;if("horizontal"===o)return!!l&&m>=L&&H>=w}}}}(jQuery); diff --git a/lab-setup/index.html b/lab-setup/index.html new file mode 100644 index 0000000..5ed9321 --- /dev/null +++ b/lab-setup/index.html @@ -0,0 +1,329 @@ + + + + + + + + + + + + + Lab Setup • ECEn 625: Compilation Strategies for High-Performance Systems + + + + + + + + + + + + + + + + + + + + +
+ + + + + +
+ + + +
+
+

+ + + + Lab Setup +

+ +
+ + + + +

Prerequisite Skills

+

In this class you are expected to be familiar with the Linux command line, Git and Github. If you haven’t used these tools before, here are links to a few tutorials:

+ + + +

Environment

+ +

The assignments assume you are running an Ubuntu 22.04 Linux Operating System. You may be able to complete some assignments on other Linux variants; however, for the assignments that use the Xilinx Vivado tools, you will need a supported operating system.

+ +

You will need a Linux OS environment set up to complete the assignments. A few options:

+
    +
  • You install a full Ubuntu image (including Xilinx tools) in Windows using WSL2.
  • +
  • You can set up a computer with Linux, or even dual-boot Linux and Windows/MacOS (dual-boot is a bit more complicated than these other options).
  • +
  • Alternatively, I have a server available that you can ssh into. You will have to be connected to the CAEDM VPN to use this, so if you choose this option, make sure you have a good internet connection. If you want to go this route, please email me your desired username and I will create a login for you.
  • +
+ +

Note: The Xilinx Vitis tool that we will be using requires about 80-90GB of disk space. So whatever option you choose, make sure you give yourself plenty of room.

+ +

Tools

+

Some notes on software tools we will be using.

+
    +
  • I recommend you use VS Code for code editing as the repository is preconfigured for VS Code.
  • +
  • We will be using Xilinx’s Vitis 2022.2 tool, but not starting until Lab 4.
  • +
  • The earlier labs will only use open-source software available via apt. Make sure you have sudo permissions on your Linux machine so that you can install the necessary packages (ie. you can’t complete the class labs using the CAEDM servers).
  • +
+ +

Class Repository

+
    +
  1. +

    You must use this invitation link to set up a Github classroom repo for the class: https://classroom.github.com/a/DryPhSIw

    +
  2. +
  3. This will create a blank repository for you. On the github website for your repo, click the Import Code button (shown below), and import from https://github.com/byu-cpe/ecen625_student. +Screen shot of how to import code
  4. +
  5. Clone your repository to your local machine.
  6. +
+ +

Getting Code Updates

+

If for some reason, I need to fix a problem with the starter code, you will need a way of pulling those changes down onto your computer. The easiest approach is to create another remote for your git repo. By default, you will have one remote, origin, which will point to your GitHub repo. Add another one using the following command:

+ +
  git remote add startercode https://github.com/byu-cpe/ecen625_student.git
+
+ +

If you ever need to pull down changes I made (I will let you know when this is the case), you can do the following:

+ +
git pull startercode main
+
+ +

Submitting Code

+

Lab submissions will be done by creating a tag in your Git repository. You can do this like so:

+ +
git tag lab1_submission
+git push origin lab1_submission
+
+ +

If, after you create this tag, you want to change it (ie, re-submit your code), you can re-run the above commands and include the –force option, ie:

+
git tag --force lab1_submission
+git push --force origin lab1_submission
+
+ +
+
+
+
+ + +
+ + + + + + + + + + + + + + \ No newline at end of file diff --git a/labs/lab-graphs/index.html b/labs/lab-graphs/index.html new file mode 100644 index 0000000..f6581e0 --- /dev/null +++ b/labs/lab-graphs/index.html @@ -0,0 +1,502 @@ + + + + + + + + + + + + + Graphs & C++ Warmup • ECEn 625: Compilation Strategies for High-Performance Systems + + + + + + + + + + + + + + + + + + + + +
+ + + + + +
+ + + +
+
+

+ Graphs & C++ Warmup + + + +

+ +
+ + + + +

Learning Outcomes

+

The goals of this assignment are to:

+
    +
  • Familiarize yourself with graph algorithms that are most applicable to HLS techniques, namely topological sorting and identifying the critical path.
  • +
  • Observe the structure of commercial HLS data flow graphs.
  • +
  • Practice C++ skills.
  • +
+ +

Preliminary

+

This assignent is located in the lab_graphs folder. All commands shown assume you are located in that folder in your terminal.

+ +

Install Packages

+

You will need the following packages:

+
sudo apt install cmake graphviz clang-12 clang-tidy-12 valgrind
+
+ +

Extract Graphs

+

Due to size contraints on Github, the graphs are in a zip files and need to be extracted. Run the following to extract the graphs:

+ +
make unzip_graphs
+
+ +

Inspect the code

+
    +
  • niGraphs/ – This folder contains 2333 graphs of customer designs from National Instrument’s HLS tool (LabVIEW Communications System Design Suite – https://www.ni.com/labview-communications/). Feel free to look at these files. You will see each file defines a set of nodes and edges with associated properties. As we progress through the class material you will learn more about these properties, but you can ignore most of them for now, aside from a few that are specifically mentioned in this assignment.
  • +
  • src/niGraphReader/ – This contains the NIGraphReader class, which will parse the graph files into NIGraph* data structures.
  • +
  • src/niGraph/ – This contains the NIGraph class, as well as NIGraphNode and NIGraphEdge classes, which are the data structures for the graphs.
  • +
  • src/main.cpp – You will need to implement several functions in this file. You are free to split your code into additional files if you desire.
  • +
+ +

Build the code

+

The project uses cmake as a build manager. Cmake is a tool that will automatically create necessary makefiles for use with the make tool. The code can be built using the following commands:

+
cd build
+cmake ../src
+make
+
+ +

This will produce an executable located in build/main. If you change any file contents, you only need to re-run make to recompile. If you add new files, you will need to edit the src/CMakeLists.txt file.

+ +

main()

+ +

The provided main function can be run in two modes:

+ +
    +
  • Mode 1: Selective graphs: You can provide a list of graph numbers as arguments to main: +
    ./main 1 7 1300
    +
    +

    For each graph this will perform topological sorting and print the sorted list of nodes, find the longest path, and generate a DOT file and PDF. Statistics are printed to a results.txt file. Note: Generating PDF files may not be possible for large graphs, and the program will stall.

    +
  • +
  • Mode 2: All graphs: If you provide no arguments, all graphs will be processed. The sorted graph nodes won’t be printed, and no DOT files will be generated.
  • +
+ +

Requirements

+ +

The goal of this lab is to perform a topological sort of a dataflow graph, identify the longest delay path, and create a graph visualization. Graph 0 shows a the graph for DelayGraph_0.graphml. +Your graphs should have the following properties:

+
    +
  • Show all nodes and edges. Some nodes don’t have edges.
  • +
  • Nodes should be labeled with the node id, and the longest delay path to reach the node.
  • +
  • Edges should be labeled with the edge delay.
  • +
  • Edges along the longest delay path (ie, the critical path), should be colored red. Some edges have delay=0; these edges can optionally be included in your critical path (it doesn’t matter if you include them or not).
  • +
  • The provided graphs are almost directed acyclic graphs (DAGs), except for a few feedback edges, which create cycles. These feedback edges should be colored in blue.
  • +
+ +

Code Checking

+

In addition to completing the code functionality described above, you code should also:

+
    +
  1. Build without warnings. I have configured clang-tidy to be run when you compile your code. This will enforce some extra checking that you might have not seen in the past. Hopefully this will help you learn more about C++ best practises and improving your coding skills.
  2. +
  3. Run in Valgrind without any reported issues.
  4. +
+ +

These two checks are new for this year, so please reach out on Slack if you have questions.

+ +

Part 1: Visualizing Graphs

+ +

You must write code to output an NIGraph structure in DOT language. The code should be added to the following function, that you should implement in solution.cpp.

+ +
void createDOT(const NIGraph &graph, const std::string outputPath,
+    NIGraphNodeList &longestPath,
+    std::map<NIGraphNode *, int> &nodeDelays);
+
+ +

See https://www.graphviz.org/content/dot-language for the specification of the DOT language. For example, a simple DAG with two nodes (a and b) and one edge (delay = 3) may have a DOT file like this:

+ +
strict digraph {
+  a [label="a\n0"];
+  b [label="b\n3"];
+  a -> b [label=3; color=red];  
+}
+
+ +

Although the graph visualization relies on the longest path data, it is included first in this document as visualizing the graphs can sometimes be helpful in debugging your sorting or longest path analysis code. So, I suggest you complete the graph visualization without the longest path data first, then return and finish this step once you have the longest path analysis working.

+ +

Part 2: Topological Sorting

+ +

You will write code to perform a topological sort of a graph. See lecture slides or https://en.wikipedia.org/wiki/Topological_sorting.

+ +

The code should be implemented in this function, as part of solution.cpp:

+
NIGraphNodeList topologicalSort(const NIGraph &graph);
+
+ +

The function has a single input, an NIGraph, and returns a topologically sorted list of nodes (NIGraphNode*). Since a topological sort is only possible for directed acyclic graphs (DAGs), you will need to ignore the feedback edges.

+ +

Part 3: Longest Path

+ +

In this last section you will write code to find the longest delay path in the graph, using the topologically sorted nodes from Part 2. The code should be implemented in this function, as part of solution.cpp:

+ +
int longestDelayPath(const NIGraphNodeList &topolSortedNodes,
+    NIGraphNodeList &longestPath,
+    std::map<NIGraphNode *, int> &nodeDelays);
+
+

The first arugment to this function is the topologically sorted list of nodes in the graph. The function populates two data structures: longestPath should be populated with a list of nodes that make up the longest path, from start to finish, and nodeDelays provides a map indicating the longest delay to each node in the graph. The delay of the longest path is returned from the function.

+ +

See lecture slides, wikipedia, or search on the web for how to determine the longest path from a topological sort. For a DAG, the longest delay path is also known as the critical path. This term is likely familiar to you in the circuit domain, as combinational logic can be represented using a DAG, and the critical path restricts the maximum frequency of the circuit.

+ +

Again, to ensure the graph is a DAG, you will \uline{need to ignore feedback edges}. Remember to ignore these edges when finding the longest back, and during the backtracking portion.

+ +

Deliverables

+ +
    +
  • +

    Make sure your code is pushed up to your Github repo.

    +
  • +
  • +

    Add a 1 page PDF report, that includes a short paragraph about how your topological sorting algorithm works. Include a scatter plot, which plots the run-time for your topological sort code for ALL 2333 of the provided graphs. The plot should be of the following format:

    +
      +
    • The x-axis should show the size of the graph (V + E)
    • +
    • The y-axis should show the runtime of the topological sorting.
    • +
    • Both the x and y axis should be in logarithmic scale, with appropriate ranges to fit your data points.
    • +
    +
  • +
+ +

There are many ways to do a topological sort. For full marks, your chart data should show that your algorithm complexity is approximately O(V+E). Please don’t spend extra time performing analysis to show this; a visual inspection of the scatter plot is fine.

+ +
    +
  • Include the following data using your longest path code:
  • +
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
Graphsize (V+E)Delay
DelayGraph_01978077
DelayGraph_1  
DelayGraph_2  
DelayGraph_3  
DelayGraph_4  
DelayGraph_5  
DelayGraph_6  
DelayGraph_7  
DelayGraph_8  
DelayGraph_9  
DelayGraph_10  
+ +
    +
  • Include the longest path for DelayGraph_3. For example, the longest path for DelayGraph_0 is: +
    n0 -> n14 -> n15 -> n19 -> n21 -> n23 -> n24 -> n25 -> n26 -> n27 -> 
    +n29 -> n43 -> n44 -> n50 -> n51 -> n56 -> n60 -> n70 -> n71 -> n74 -> 
    +n75 -> n78 -> n76 -> n77 -> n79 -> n80 -> n81 -> n82 -> n83 -> n84 -> 
    +n88
    +
    +
  • +
+ +

Submission Instructions

+ +

Submit your code using a Github tag: lab1_submission. +Instructions are provided here

+ +
+
+
+
+ + +
+ + + + + + + + + + + + + + \ No newline at end of file diff --git a/labs/lab-llvm/index.html b/labs/lab-llvm/index.html new file mode 100644 index 0000000..5c6c830 --- /dev/null +++ b/labs/lab-llvm/index.html @@ -0,0 +1,587 @@ + + + + + + + + + + + + + LLVM • ECEn 625: Compilation Strategies for High-Performance Systems + + + + + + + + + + + + + + + + + + + + +
+ + + + + +
+ + + +
+
+

+ LLVM + + + +

+ +
+ + + + +

Background

+ +

Learning Outcomes

+

The goals of this assignment are to:

+
    +
  • Understand the benefits of applying optimizations to the IR code, prior to the standard HLS algorithms.
  • +
  • Gain experience using LLVM to modify the IR code of a program.
  • +
  • Practise C++ skills.
  • +
+ +

Motivation

+

In this assignment you will get to write your own compiler optimization pass! You will use LLVM (a commonly used compiler, like GCC). The goal of the transformation will be to identify adder trees in the IR, and perform tree balancing, as shown below. This optimization is especially helpful when targeting hardware.

+ +

Example of adder balancer

+ +

Consider the following code (from simple.c) that sums the values of a 100-entry array.

+
int A[100];
+for (int i = 0; i < 100; i++)
+    sum += A[i];
+
+ +

To implement this in hardware, we could build an RTL circuit with a state machine that repeatedly read a value from memory, added it to a sum register, and incremented the address. We could also use an HLS tool to build that RTL for us, and it may take a similar approach if no optimizations were applied.

+ +

The code could be made much faster by performing multiple loop iterations in parallel. This is referred to as loop unrolling.

+ +

The following code, (from simple_unrolled_partitioned/simple.c), shows the array summation unrolled by a factor of 10. One issue with unrolling like this is that it is usually not possible to load 10 values from memory at once. If values are loaded sequentially, there will be little to no benefits to loop unrolling. To get around this problem, the code also includes memory banking, where the A array is split into 5 equal sized arrays, A1, A2, A3, A4, and A5. Each of these can be placed in a separate dual-ported memory, allowing us to read 10 values from memory simultaneously. (While this C code implements loop unrolling and memory banking manually, modern HLS tools will do this for you when requested. Certain tools may even be smart enough to do it automatically.)

+ +
int A1[20];
+int A2[20];
+int A3[20];
+int A4[20];
+int A5[20];
+
+for (int i = 0; i < 20; i += 2) {
+    sum += A1[i] + A1[i + 1] + 
+           A2[i] + A2[i + 1] + 
+           A3[i] + A3[i + 1] +
+           A4[i] + A4[i + 1] + 
+           A5[i] + A5[i + 1];
+
+ +

The above code will end up creating a cascading adder tree as shown in the left side of the figure above. We would like to automatically optimize the IR to balance the adder tree, producing a structure similar to the right-hand side of the figure above. This optimization can improve the critical path of the resulting hardware, or if timing constraints are imposed, reduce the latency of each loop iteration.

+ +

Getting Started

+ +

Required Packages

+
sudo apt install llvm-12 llvm-12-dev libclang-common-12-dev clang-12 liblpsolve55-dev texlive-latex-base texlive-pictures
+
+ +

Running LLVM

+

Your scheduler is going to run as an LLVM pass. This means that after you compile a C program to LLVM IR, you are doing to run your pass on the LLVM IR.

+ +

You are given a few different C programs in the benchmarks directory. You can cd into these benchmark directories, and run make <target> to compile them. Try running just clang (C front-end compiler) to compile the simple benchmark your C code into LLVM IR.

+ +
cd benchmarks/simple
+make clang
+
+ +

The provided Makefile will first run clang to produce a binary IR file (simple.clang.bc), after which it will run llvm-dis to dissassemble the binary into human readable IR (simple.clang.ll)

+ +

Look through the LLVM IR file and try to understand how it implements the simple.c program. Then go to the simple_unrolled_partitioned bechmark and look at the IR that program produces. Make sure you can find the long sequence of cascaing add instructions.

+ +

Writing an LLVM pass

+ +

While you could download the LLVM source code, and add your pass code to it, compiling LLVM from source can take 20-30 minutes. Instead, we are going to develop your pass out-of-tree. Above you should have installed the LLVM binaries using the Ubuntu package manger. We are going to compile your pass code into a shared library object (.so) file, than can be loaded by LLVM at runtime.

+ +

Your pass code and CMakeLists.txt file are provided in the src directory. For this assignment we will be using a FunctionPasfs in LLVM. That is, it is a transformation pass that modifies code contained with a single function.

+ +

Take a look at AdderTreeBalancer.cpp, specifically these lines:

+ +
char AdderTreeBalancer::ID = 0;
+static RegisterPass<AdderTreeBalancer> X("ATB_625", "Adder Tree Balancer Pass");
+
+bool AdderTreeBalancer::runOnFunction(Function &f) {
+	...
+}
+
+ +

The RegisterPass registers your pass with LLVM and specifies that it can be called using the -ATB_625 flag. The AdderTreeBalancer class is a subclass of llvm::FunctionPass , meaning this pass should be called for every Function in the code. Specifically, the runOnFunction() function will be called for each Function.

+ +

You can also create passes that operate at different scopes, including Module (entire C program), Loop, Region, and more. More information on these types of passes can be found at WritingAnLLVMPass.

+ +

Go ahead and compile the provided code:

+
cd lab_llvm/build
+cmake ../src
+make
+
+ +

This will produce your library ATB_625.so.

+ +

Running Your LLVM Pass

+ +

The benchmark Makfile contains several targets that can be used to run your AdderTreeBalancer pass.:

+
    +
  • make atb: This will run your pass, followed by dead code elimination (which will remove unused instructions). This will produce a file *.atb.ll which contains the LLVM IR after your pass is run.
  • +
  • make atb_check: Since you are modifying the original program, you will want to double check that you haven’t broken the functionality. This target will first run the atb target to produce the transformed IR, followed by running it using the LLVM emulator (lli). The simple_unrolled_partitioned and shared_add_tree benchmarks both print CORRECT or ERROR, depending on whether the sum is correct.
  • +
  • make atb_schedule: This will run the atb pass, and then pass the new LLVM IR to an HLS scheduler, which will determine which instructions can run in each cycle in hardware. This will produce PDF files which display the schedule of each IR instructions. If you implement the pass correctly, you will see improvements made to the produced schedule.
  • +
  • make schedule: This will run the HLS schedule without your ATB pass.
  • +
+ +

Code Organization

+ +
    +
  • +

    lab_llvm/src/AdderTreeBalancer.cpp/.h – You will add all your code for this assignment in theses files. You are welcome to add additional source files if you like.

    +
  • +
  • +

    benchmarks – This contains some C programs to test your code. You are welcome to test your pass with any design in this folder (or create your own test designs); however, only the simple_unrolled_partitioned and shared_add_tree designs have large adder trees. The shared_add_tree design has an adder tree used by another adder tree, so it’s useful to test that you are handling that correctly (see the first tip listed later on this page).

    +
  • +
+ +

Implementation

+ +

How you code the tree balancer is up to you.

+ +

You probably want to follow this general approach:

+
    +
  1. Look through the Instructions in the BasicBlock for add instructions, treat this instruction I as the root of an adder tree, and collect a list of inputs to this adder tree.
  2. +
  3. Create a balanced adder tree with these inputs, and add these new add instructions to the BasicBlock.
  4. +
  5. Replace uses of the root adder instruction, I, with the output of your newly created adder tree.
  6. +
  7. Repeat until all adder trees are balanced.
  8. +
+ +

Some tips with this approach:

+
    +
  • When recursively visiting adders, you need to make sure the output of an intermediate node is not used elsewhere in the code. You can do this by checking that the number of uses is one (Value.getNumUses()). The reason for this is that all of these instructions will be deleted and replaced by your adder tree; only the final output of the adder tree can be used multiple places in the code.
  • +
  • The inputs to your adder tree may be instructions, constants, function arguments, etc. You should use the LLVM Value to keep track of the inputs.
  • +
  • You will need to add all of your newly created addition instructions to the BasicBlock. Make sure you add them in a valid position, and order (ie. the final addition in your tree should be located before any uses, and adder nodes in your tree should be in a valid ordering). If you are smart in how you create your adder tree, you can build a list of add instructions that are already in the correct order. You can then add all of these add instructions immediately before instruction I (as described in Step 3 of the technique above).
  • +
  • You don’t need to delete the adder instructions you are replacing with your tree. As long as you complete Step 3, these additions will become dead code. Since dead code elimination is performed after your pass, these instructions will automatically be removed. Likewise, if you only complete Step 1 and 2, and never use your new adder tree, dead code elimination will remove it.
  • +
  • In Step 1 you are iterating over the BasicBlock. However, if you end up inserting an adder tree, you are modifying the very data structure you are iterating over. You cannot continue iterating at this point. Either exit out of the iteration and start over, or keep a track of pending changes and wait until the iteration is complete before actually making the changes.
  • +
  • You will probably want to keep track of which additions are part of your balanced adder trees, and then skip over them in Step 1. Otherwise you can end up in an endless loop of replacing your balanced adder trees with new identical adder trees. The other benefit of this approach is that you don’t need to check whether existing adder networks in the user’s code are balanced or not. Simply replace them with a balanced adder tree regardless of whether the existing structure is already optimal.
  • +
+ +

LLVM Coding Tips

+

Here are a few suggestions to help you with the LLVM API. If you are still unsure how you do something in LLVM, please post on Slack and I would be happy to help you out.

+ +

Resources

+ +

We are using LLVM version 12.0. The documentation can be found at https://releases.llvm.org/12.0.0/docs/. Some useful pages:

+ + +

The LLVM Classes

+ +

LLVM is an object-oriented code base, with lots of inheritance. You can find auto-generated documentation for each class. For example, check out the Instruction class. Usually the quickest way to find these documentation pages is a google search.

+ +

Take a look at the illustrated class hierarchy on that webpage. You will see that Instruction inherits from User, which in turn inherits from Value. From LLVM programmers manual:

+
    +
  • Value: The Value class is the most important class in the LLVM Source base. It represents a typed value that may be used (among other things) as an operand to an instruction. There are many different types of Values, such as Constants, Arguments. Even Instructions and Functions are Values.
  • +
  • User: The User class is the common base class of all LLVM nodes that may refer to other Values. It exposes a list of “Operands” that are all of the Values that the User is referring to. The User class itself is a subclass of Value.
  • +
  • Instruction: The Instruction class is the common base class for all LLVM instructions. It provides only a few methods, but is a very commonly used class. The primary data tracked by the Instruction class itself is the opcode (instruction type) and the parent BasicBlock the Instruction is embedded into. To represent a specific type of instruction, one of many subclasses of Instruction are used.
  • +
+ +

In this assignment you will be frequently using the add instruction. This instruction is of type BinaryOperator (a subclass of Instruction), which is used by all instructions that operate on two pieces of data (thus Binary). To check if it is an adder, you can call getOpcode(), which for an adder will return the constant Instruction::Add.

+ +

Debugging

+ +

In LLVM, you can use outs() << to print out just about any class you want. You can print Values, Users, Instructions, BasicBlocks, Functions, etc. Just keep in mind that to print an object you should use the object itself, not a pointer to the object. If you have a pointer, you should dereference it, such as:

+
Instruction * I = ...;
+outs() << *I << "\n";
+
+ +

You can also use report_fatal_error("message") to stop execution immediately and report an error.

+ +

Checking Instruction Types

+ +

When iterating through the Instruction objects in a BasicBlock, you may need to check the type of Instruction. This can be done a few different ways. For example, here are a few ways to check if an Instruction is a BinaryOperator.

+ +
Instruction * I;
+if (isa<BinaryOperator>(I)) {
+   // I is a BinaryOperator
+}
+
+ +
Instruction * I;
+if (BinaryOperator * bo = dyn_cast<BinaryOperator>(I)) {
+    dbgs() << "Instruction is a binary operator with opcode " << bo->getOpcode() << "\n";
+}
+
+ +

Creating Instructions

+ +

Generally to create new instructions, you do not call the constructor directly, but rather call a static class method. For example, one way to create a new add instruction:

+ +
Value * in1 = ...
+Value * in2 = ...
+BinaryOperator * bo = BinaryOperator::Create(BinaryOperator::Add, in1, in2, "myInsnName", (Instruction*) NULL);
+
+ +

The last argument in this case is a pointer to an existing Instruction, and the new Instruction will be inserted preceeding it. If you pass in NULL, the new instruction is not inserted into the code, but you will need to do so later.

+ +

Inserting Instructions

+

There are many ways to insert instructions into a basic block. These are discussed in the Programmers Manual, although I have found this is somewhat out of date. In particular, the pages gives this example, but it is missing the required ->getIterator() on the existing Instruction.

+ +

Replacing Instructions or Usage

+ +

If you want to swap out an Instruction for a different one, there are a few options:

+
void ReplaceInstWithInst(Instruction *From, Instruction *To);
+
+

This adds the instruction To to a basic block, such that it is positioned immediately before From, replaces all uses of From with To and then removes From. Important: This function will add the new To instruction to the basic block, so make sure you have not already added it. If you have, you can use this method instead:

+ +
/// Replace all uses of an instruction (specified by BI) with a value, then
+/// remove and delete the original instruction.
+void ReplaceInstWithValue(BasicBlock::InstListType &BIL,
+                          BasicBlock::iterator &BI, Value *V);
+
+

This replaces all uses of the instruction referenced by the iterator BI with the Value V, and then removes the instruction referenced by the iterator BI. This is similar to ReplaceInstWithInst, except that it doesn’t add V into the code anywhere – it assumes this was already done. It also requires you to pass in an interator to the old instruction, rather than a pointer to the instruction itself. This can easily be done with code such as the following:

+ +
BinaryOperator * oldAdder = ...;
+BinaryOperator * adderTree = ...;
+BasicBlock::iterator BI(oldAdder);
+ReplaceInstWithValue(BB.getInstList(), BI, adderTree);
+
+ +

Deliverables

+ +
    +
  1. +

    Submit your code on Github using the tag lab2_submission

    +
  2. +
  3. +

    Include a 1-page PDF document (lab_llvm/report.pdf) that includes the following:

    +
  4. +
+ +

For the simple_unrolled_partitioned program, obtain the missing results in the following tables (there are 8 cells to fill in), and include the completed tables in your report. You can find the HLS schedule by looking at the main.schedule.rpt file, and the longest path by looking at the main.timing.rpt file, which lists the longest path for each BasicBlock. The cycles per loop iteration can be obtained from the scheduling report (or Gantt chart PDF), by manually looking at how many states are created for the summation loop. The total summation time is simply the product of the longest path, loop iteration latency, and number of iterations (10).

+ +

CLOCK_PERIOD <= 20ns

+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
 Longest Path (ns)Loop iteration latencySummation Time (ns)
WITHOUT TreeBalancer17.54700
WITH TreeBalancer   
Speedup--?x
+ +

CLOCK_PERIOD <= 5ns

+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
 Longest Path (ns)Loop iteration latencySummation Time (ns)
WITHOUT TreeBalancer5.012600
WITH TreeBalancer   
Speedup--?x
+ + +
+
+
+
+ + +
+ + + + + + + + + + + + + + \ No newline at end of file diff --git a/labs/lab-scheduling/index.html b/labs/lab-scheduling/index.html new file mode 100644 index 0000000..22da61d --- /dev/null +++ b/labs/lab-scheduling/index.html @@ -0,0 +1,481 @@ + + + + + + + + + + + + + Scheduling • ECEn 625: Compilation Strategies for High-Performance Systems + + + + + + + + + + + + + + + + + + + + +
+ + + + + +
+ + + +
+
+

+ Scheduling + + + +

+ +
+ + + + +

Learning Outcomes

+

The goals of this assignment are to:

+
    +
  • Familiarize yourself with HLS scheduling algorithms.
  • +
  • Use and explore a popular open-source HLS tool, LegUp, which is built on a widely used open-source compiler framework, LLVM.
  • +
  • Gain experience formulating and coding linear programming solutions.
  • +
  • Practice C++ skills.
  • +
+ +

Getting Started

+ +

Required Packages

+
sudo apt install llvm-12 libclang-common-12-dev clang-12 liblpsolve55-dev texlive-latex-base texlive-pictures
+
+ +

How this lab works

+

In this lab you are going to write an HLS scheduler that operates on LLVM intermediate representation. You are going to formulate a schedule (ie, pick a cycle number for each instruction), such that the schedule completes are soon as possible. But you can’t just run all the instructions at once! You need to respect data and memory dependencies, as well as respecting functional unit limits (ie. you can’t read unlimited things from memory at once), and the critical path constraint.

+ +

This provided code isn’t part of a real HLS tool (your schedule won’t be used to produce any RTL), but the concepts and techniques are very similar to what is done in commerical HLS tools.

+ +

Like the last lab, you will be writing an LLVM pass. Your pass won’t be changing the LLVM code, but rather reading the LLVM IR for a basic block (DAG), and using information about the hardware units for each instructions in order to determine a good HLS schedule.

+ +

Compiling your LLVM pass

+

Your pass code and CMakeLists.txt file are provided in the src directory. Your LLVM pass will be a FunctionPass, and will be run via the runOnFunction() function:

+
bool Scheduler625::runOnFunction(Function &F) {
+  ...
+}
+
+

The code for this function is already given to you. You can look through it and see that it will call scheduleASAP() and scheduleILP() to perform the scheduling, and then generate the reports that you should have already used last lab.

+ +

You can compile this pass in the same manner as last lab:

+
cd build
+cmake ../src
+make
+
+ +

This will produce your library scheduler_625.so.
+

+ +

Running Your Scheduler

+

You can run your scheduler the same way you ran the provided scheduler in the last lab, except you should define MYSCHEDULER=1. For example, you can schedule the simple benchmark:

+
cd benchmarks/simple
+make schedule MYSCHEDULER=1
+
+ +

You don’t need to run your ATB pass from last lab, so just always run make schedule and not make atb_schedule when gathering your results. (Of course you’re always welcome to try your scheduler out on your ATB-generated IR code if you want to try it out.)

+ +

How Scheduling Works

+ +

In our pretend HLS tool, we’re going to assume that it will create a circuit that executes the instructions from one basic block at a time. That is, all instructions within a basic block will execute before transitioning to the next basic block (this approach is used in many HLS tools). This means that we really only need to worry about scheduling the instructions relative to each other within each Basic Block. If our schedule was used by an actual HLS tool, it would generate controlling logic that would then sequence the execution of these different basic blocks.

+ +

The provided code will schedule the Instructions within each Basic Block one at a time:

+
// Loop through basic blocks
+for (auto &bb : F.getBasicBlockList()) {
+  if (ILPFlag)
+    scheduleILP(bb);
+  else
+    scheduleASAP(bb);
+}
+
+ +

The bulk of this assignment will be implementing these two scheduling approaches: scheduleASAP() and scheduleILP().

+ +

Code Framework

+ +

In the two scheduling functions you should write code that schedules the Instructions of a basic block to a set of cycle numbers (0, 1, 2, 3, …, n). You can do this by populating the following data structure:

+
std::map<Instruction *, int> Scheduler625::schedule;
+
+

Not all instructions need to be scheduled. Some instructions don’t get translated into hardware logic. You can check using the following:

+
static bool SchedHelper::needsScheduling(Instruction &I);
+
+

For example, the following code is a very simple (and invalid) scheduler that would schedule all Instructions to cycle number 0.

+
for (auto & I : bb) {
+  if (!SchedHelper::needsScheduling(I))
+    continue;
+  schedule[&I] = 0;
+}
+
+ +

Debugging

+ +

I’ve given you a few aids to help you debug your code. You will see that after calling your scheduling functions I will print the schedule out, and then validate it. The validation checks that the schedule is functionally correct, that is, it checks that you have assigned all instructions to states, that data dependencies are met, that available functional units are not exeeded. If you specify a target period (discussed later), it will also check that the critical path is within the constraint. It does not check that your solution is good! You could create a very bad schedule that simply executed each instruction in a different cycle, which may pass validation, but will not get you a very good grade on the assignment.

+ +

Getting the Info You Need

+ +

LLVM has no idea that you are going to perform mock HLS scheduling, and knows nothing about the potential hardware we are going to target. As such, you are given some extra classes that contain the information you need:

+
    +
  • FunctionHLS: This is a wrapper aound each Function and contains HLS-specific information for the function. This object is available as a private variable fHLS inside your Scheduler class. It provides the following information: +
      +
    • FunctionalUnit *getFU(Instruction &I) returns the FunctionalUnit for an Instruction. This will return NULL for certain Instructions that don’t require hardware units (ie control-flow instructions).
    • +
    • std::vector<Instruction *> &getDeps(Instruction &I) returns a list of Instructions that the scheduling of Instruction I is dependent upon. These dependencies will always be Instructions that execute earlier in the same BasicBlock. This includes: +
        +
      • Data dependencies: For example, if I=%3 = add %1, %2 then both the %1 = ... and %2 = ... Instructions could be in the list.
      • +
      • Memory dependencies: For example, if you have two instructions that access the same physical memory, store %A, %1 and load %A, %2, then the former would be included in the dependency list of the latter.
      • +
      +
    • +
    +
  • +
  • bool needsScheduling(Instruction &I): Not all Instructions need to be scheduled. Make sure you check this value before trying to schedule an Instruction. For example, if you pass a non-scheduled Instruction to getDeps() it will throw an error.
  • +
  • int SchedHelper::getInsnLatency(Instruction &I): Returns the number of cycles of latency for Instruction I. For example, a latency of 1 means the data produced by this operation can be used in the next cycle. A latency of 0 means that this Instruction is implemented by purely combinational logic, and it’s output can be chained into the input of another operation in the same cycle.
  • +
  • double getInsnDelay(Instruction &I): Returns the estimated nanosecond delay for Instruction I. This is useful if you want to limit chaining to meet a certain clock frequency.
  • +
  • FunctionalUnit: This class represents a hardware functional unit that implements an operation. +
      +
    • int getNumUnits(): The represents how many Instructions can use this unit at one time. For example, load and store Instructions will access dual-ported RAMs on the FPGA that allow two memory operations to be issued at once. Most operations (addition, subtraction, comparison, etc) can be implemented using the FPGA fabric. For the “fabric” FunctionalUnit, a 0 is returned, indicating there is no limit placed on the number of these functional units.
    • +
    • int getInitiationInterval(): Even though some FunctionalUnits may have a multi-cycle latency, pipelining allows for these units to accept new data more often than the latency. This function returns the cycle interval that new data can be provided. For example, a load operation will take two cycles to retrieve the data, but a new read request can be issued each cycle.
    • +
    +
  • +
+ +

Integer Linear Programming

+ +

In this assignment we will use the lp_solve} linear programmer tool. We will discuss formulating ILP problems in class. Generally you should use the following functions (in this order), to set up and solve an ILP problem:

+
    +
  • lprec * Not a function, but the structure which contains your ILP problem. This will be initialized from make_lp() and you will pass it into every other function you call. Unfortunately lp_solve is not object oriented.
  • +
  • make_lp() To create a new ILP problem.
  • +
  • add_constraintex() To add a new constraint using sparse column format.
  • +
  • set_obj_fnex() To set the objective function using sparse column format.
  • +
  • set_minim() or set_maxim() To select minimization or maximization of objective.
  • +
  • write_LP() if you wish to output the ILP after it is formed.
  • +
  • solve() To solve the problem.
  • +
  • get_variables() To extract the solution.
  • +
+ +

Documentation on these functions can be found online. Post on Piazza if you have further questions.

+ +

Implementation

+ +

Part 1: ASAP Scheduler (25% of grade)

+ +

For this deliverable you must write code to perform unconstrained ASAP scheduling. See class notes or section 5.3.1 from the De Micheli textbook. Unconstrained means you do not need to consider resource or timing constraints. You still need to consider data dependencies.

+ +

This is to be completed in the following function:

+
void Scheduler625::scheduleASAP(BasicBlock &bb) {}
+
+ +

For this function, don’t create an ILP solution. You can simply treat the instructions in the basic block as a topologically sorted DAG and propagate start times as you work through the list of instructions. This should be a fairly simple task, especially considering the previous assignment, and is mainly to get you used to the APIs and data structures.

+ +

A few pieces of advice:

+
    +
  • Remember, not every Instruction in the BasicBlock needs to be scheduled. Call SchedHelper::needsScheduling() to check.
  • +
  • The terminating Instruction (branch, return) should always be scheduled in the last cycle. This can be done like so: +
    schedule[bb.getTerminator()] = getMaxCycle(bb);
    +
    +
  • +
+ +

Try this scheduler out on the simple benchmark:

+
cd benchmarks/simple
+make schedule MYSCHEDULER=1 ASAP=1
+
+ +

This program is simple enough that you should end up with a valid scheduling, even when ignoring resource constraints. You can then test out the simple_unrolled example, to see that this scheduling technique fails on a more complicated design.

+ +

Look at the design and make sure you understand why it introduces issues with resource usage.

+ +

Part 2: ASAP Scheduler with Resource Constraints (40% of grade)

+

For this deliverable you must write code to perform resource-constrained ASAP scheduling. You will use an ILP formulation to determine an optimal scheduling. Use the following approach:

+
    +
  • Use an ILP variable to represent the start cycle of each Instruction. This code is already provided to you.
  • +
  • An extra variable is used to represent the NOP at the end of the schedule.
  • +
  • Add constraints to ensure data dependencies are met. If there is a dependency I1->I2, then create a dependency “S(I2) >= S(I1) + latency(I1)”, where S(I) is the start cycle of Instruction I.
  • +
  • Add resource constraints. We will discuss for this in class, but the approach is that for each FunctionalUnit, you should find all Instructions that use it, then choose a heuristic ordering in order to bind the Instructions to the available FunctionalUnits. Then, for the various Instructions bound to each individual FunctionalUnit instance, their start times must be separated by at least the InitiationInterval of the FunctionalUnit.
  • +
  • Set the objective function to be start time of the terminating NOP.
  • +
+ +

The code to execute the ILP solver and extract the schedule is provided to you.

+ +

Once you have this implemented, test out the simple_unrolled example to see that a valid schedule is obtained. Run your design like so:

+
make schedule MYSCHEDULER=1 ILP=1 
+
+ +

Part 3: Adding timing constraints (25% of grade)

+ +

You can apply a 10ns clock period constraint to the schedule like so:

+
make schedule MYSCHEDULER=1 ILP=1 PERIOD=10.0
+
+ +

This will cause the Schedule validation code to also check that the delay of each combinational path is within the target period. If you run this on the simple or simple_runrolled benchmarks, you should see that your scheduler now fails.

+ +

Add additional constraints to your ILP formulation to prevent long combinational chaining. It’s up to you to come up with a solution for this. In my solutions I use a recursive function to search for all combinational paths that exist from one Instruction (I1) to another (I2) that exceed the target period, and esure that S(I2) > S(I1).

+ +

Report (10% of grade)

+

Include a short PDF report, located at lab_scheduling/report.pdf. Include the following items:

+
    +
  • Why did we need to include the terminating NOP instruction in our problem formulation?
  • +
  • Given an example of something else you could use ILP for. Try to come up with something relating to your research.
  • +
  • Report the number of constraints you used for the simple_unrolled benchmark. You can report the total for all your ILP forumlations (across all BasicBlocks), or just the maximum of any BasicBlock. Either is fine, just state in your report what you chose. You can get this by keeping track yourself as you add the constraints, or printing the entire ILP formulation after you are done. There is no need to perform any optimizations to try and minimize the number of constraints; this is only included so that you can get a feel for the size of the ILP problem you are formulating.
  • +
  • If you completed Part 3, explain in a paragraph the approach you took.
  • +
+ +

Submission

+

Submit your code on Github using the tag lab3_submission

+ + +
+
+
+
+ + +
+ + + + + + + + + + + + + + \ No newline at end of file diff --git a/labs/lab-vitis-hls/index.html b/labs/lab-vitis-hls/index.html new file mode 100644 index 0000000..4939185 --- /dev/null +++ b/labs/lab-vitis-hls/index.html @@ -0,0 +1,454 @@ + + + + + + + + + + + + + Vitis HLS • ECEn 625: Compilation Strategies for High-Performance Systems + + + + + + + + + + + + + + + + + + + + +
+ + + + + +
+ + + +
+
+

+ Vitis HLS + + + +

+ +
+ + + + +

Learning Outcomes

+

The goals of this assignment are to:

+
    +
  • Gain experience using a commerical HLS tool, Xilinx’s Vitis HLS tool.
  • +
  • Observe how changes to the source code affect the resulting resource usage and performance.
  • +
  • Explore HLS design optimization techniques, and the effect on resource usage and performance.
  • +
  • Learn about a simple machine learning algorithm.
  • +
+ +

Background

+ +

Handwriting recognition refers to the computer’s ability to intelligently interpret handwritten inputs and is +broadly applied in document processing, signature verification, and bank check clearing. An important step in +handwriting recognition is classification, which classifies data into one of a fixed number of classes. In this lab, +you will design and implement a handwritten digit recognition system based on the k-nearest-neighbors +(k-NN) classifier algorithm [wiki, good youtube video].

+ +

In the assignment you are provided with a set of already classified handwritten digits (called the training sets), and will implement a k-NN algorithm in C++ that is able to identify any input handwritten digit (called the testing instance) using the training sets. In addition, you will use two commonly-used high-level synthesis (HLS) optimizations to parallelize the synthesized hardware and explore design trade-offs in performance and area.

+ +

Getting Started

+ +

Install Dependencies

+ +
sudo apt install libc6-dev-i386 libtinfo5 libswt-gtk-4-java
+
+ +

Code Organization

+

You are provided the following files:

+
    +
  • digitrec.cpp: an incomplete source file where you write your k-NN based digit recognition algorithm +in C++.
  • +
  • digitrec.h: the header file that defines the interface for the core functions update_knn and knn_vote.
  • +
  • typedefs.h: the header file that defines the key data types used in the design.
  • +
  • training_data.h: the header file that contains all the training data.
  • +
  • test_data.h: a set of test data with golden values for testing your prediction accuracy.
  • +
  • digitrec_test.cpp: a test bench (only useful for simulation) that helps verify your code and perform +experiments with various handwritten input digits.
  • +
  • Makefile: a makefile for you to easily compile source code into an executable named digitrec and execute +the program to check results (enter make).
  • +
  • run.tcl: the template project Tcl script that allows you to run Vitis HLS synthesis in command line +(vivado_hls -f run.tcl).
  • +
+ +

Setting up Vitis HLS

+

For this assignment we will be using Vitis HLS. +You can install Vitis on your local machine (https://www.xilinx.com/support/download.html). If you do this, you should install Vitis 2022.2 on an Ubuntu 22.04 (or newer) machine.

+ +

Note: If you prefer, you can install Vitis on a Windows machine. I haven’t tested this. It should work with the assignment, with a few extra considerations. For example, the Makefile which has been provided to quickly compile and run your design may not work unless you have a build system setup. You can still build and run within Vitis HLS, so it is not a big difference, but keep in mind you may run into problems such as this.

+ + + +

To run the Vitis tools you should do the following (Note: Exporting the LIBRARY_PATH was necessary on a prevous version of Vitis, but may have been fixed in 2022 and may not be necessary):

+
source /tools/Xilinx/Vitis_HLS/2022.2/settings64.sh
+export LIBRARY_PATH=/usr/lib/x86_64-linux-gnu:$LIBRARY_PATH
+vitis_hls
+
+ +

The first step will add the Xilinx binaries to your PATH. I second step was needed on my machine to solve a bug (might not be needed with different Ubuntu versions). The last command runs Vitis HLS. If you don’t want to setup your own machine, contact me and I can give you access to a server with Vitis 2020.2 installed.

+ +

Vivado GUI vs command line

+

For this assignment you can use the Vitis HLS GUI, or you can work entirely via command line. If you are using the GUI, create a new project with this configuration:

+
    +
  • Design Files: +
      +
    • digitrec.cpp (Top Function: digitrec)
    • +
    +
  • +
  • TestBench Files: +
      +
    • digitrec_test.cpp
    • +
    • data (this is a folder)
    • +
    +
  • +
  • Part: xc7z020clg484-1
  • +
+ +

When you are ready to collect results you can use the run.tcl script to automatically run C simulation and synthesis, and extract results for k=1,2,3,4,5.

+ +
vitis_hls -f run.tcl
+
+ +

If you look inside run.tcl you will see it creates five projects with the same properties as above, each with a different k value.

+ +

Design Overview

+ +

You are given 10 training sets, each of which contains 1800 49-bit training instances for a +different digit (0-9). Each hexadecimal string in training_set_# represents a 49-bit training +instance for digit #. The 49 bits of each instance encodes a 7x7 matrix of binary values (i.e., a bitmap). For example, e3664d8e0016 in training_set_0 is a training instance for digit 0 and translates into the following binary 2D matrix and bitmap:

+ +

Binary image of number 0 +Bitmap image of number 0

+ +

41c082041016 in training set 7 is a training instance for digit 7 and translates into the binary 2D matrix and bitmap shown below:

+ +

Binary image of number 7 +Bitmap image of number 7

+ +

As you can see, the resolution of the digit is limited by the number of bits (49 bits in our assignment) used to represent it. Typically, increasing the number of bits per instance would improve the resolution and possibly the accuracy of recognition.

+ +

We would like to devise an algorithm that takes in a binary string representing a handwritten digit (i.e. the testing instance) and classify it to a particular digit (0-9) by first identifying k training instances that are closest to the testing instance (i.e., the nearest neighbors), and then determining the result based on the most common digit represented by these nearest neighbors.

+ +

You are encouraged to read through the links provided above to familiarize yourself with the basic concepts of the k-NN algorithm. In this assignment, we define the distance between two instances as the number of corresponding bits that are different in the two binary strings. For example, 10112 and 01112 differ in the two most significant bits and therefore have a distance of 2. 10112 and 10102 differ only in the least significant bit and have a distance of 1. As a result, 10112 is closer to 10102 than to 01112.

+ +

Implementation

+ +

Coding and Debugging

+

Your first task is to complete the digit recognition algorithm based on the code skeleton provided in digitrec.cpp. In particular, you are expected to fill in the code for the following functions:

+ +
    +
  • update_knn: Given the testing instance and a (new) training instance, this function maintains/updates an array of k minimum distances per training set.
  • +
  • knn_vote: Among 10·k minimum distance values, this function finds the k nearest neighbors and determines the final output based on the most common digit represented by these nearest neighbors.
  • +
+ +

Note that the skeleton code takes advantage of arbitrary precision integer type ap_uint. \textbf{A useful reference of arbitrary precision integer data types can be found starting on p.144 and p.485 of the user guide.

+ +

How you choose to implement the algorithm may affect the resulting accuracy of your design as reported by the test bench. We expect that your design would achieve an error of less than 10% on the provided testing set. You may use the console output or the generated out.dat file to debug your code.

+ +

Design Exploration

+

The second part of the assignment is to explore the impact of the k value on your digit recognition design. Specifically, you are expected to experiment with the k values ranging from 1 through 5, and collect the performance and area numbers of the synthesized design for each specific k.

+
    +
  • The actual k value can be provided to the Makefile (make K=4) and changed in run.tcl. You can run simulation and synthesis in batch with run.tcl. This script will also automatically collect important stats (i.e., accuracy, performance, and resource usage) from the Vitis HLS reports and generate a \emph{knn_result.csv} file under the result folder.
  • +
  • In this assignment, you will use a fixed 10ns clock period targeting a specific Xilinx Zynq FPGA device. Clock period and target device have been specified in the run Tcl script.
  • +
+ +

Design Optimization

+

The third part of the assignment is to optimize the design with HLS pragmas or directives. In particular, we +will focus on exploring the effect of the following optimizations in our design and apply them appropriately +to minimize the latency of the synthesized design.

+
    +
  • loop pipelining: Allows for overlapped execution of loop iterations by leveraging pipelining techniques.
  • +
  • loop unrolling: unfolds a loop by creating multiple copies of its loop body and reducing its trip count accordingly. This technique is often used to achieve shorter latency when loop iterations can be executed in parallel.
  • +
  • array partitioning: partitions an array into smaller arrays, which may result in an RTL with multiple small memories or multiple registers instead of one large memory. This effectively increases the amount +of read and write ports for the storage.
  • +
+ +

Please refer to the user guide for details on how to apply these optimizations. You may insert pragmas or set directives to apply optimizations. You can find code snippets with inserted pragmas throughout the user guide, and a full reference is given in Chapter 4.

+ +

Your proposed solution must meet the clock period constraint, and must not exceed the resources available on the targeted FPGA (xc7z020clg484-1).

+ +

For the sake of simplicity, please try to only use fixed-bound +for loop(s) in your program. Note that data-dependent for and while loops are synthesizable but may lead to a variable-latency design that would complicate your reporting (You would need to perform C-RTL co-simulation to get the actual cycle count for a design with data-dependent loop bounds).

+ +

Class Results

+

On Slack I will post a link to a Google Sheets document where you should post the results of your best solution. There will be two categories for rankings:

+
    +
  • Minimum Latency: Minimum latency provided the design fits within the resources constraints of the chip, and achieves 90% accuracy.
  • +
  • Most resource efficient: The goal in this category is to minimize the expression r2 · L, where r is the resource usage and L is the total latency. The resource usage will be defined as the maximum fraction of resource usage for any given resource type (BRAM, DSP, FF, LUT).
  • +
+ +

Report

+ +

Include a short report located as lab_vitis_hls/report.pdf with the following:

+
    +
  • Describe how you implemented the update_knn and knn_vote functions.
  • +
  • Compare different k values with a table that summarizes the key statistics including the error rate (accuracy), area in terms of resource utilization (number of BRAMs, DSP48s, LUTs, and FFs), and and performance in latency in number of clock cycles. Use the csv file generated by the script, or manually inspect knn.prj/solution1/syn/report/.
  • +
  • Describe how you added HLS pragmas/directives to minimize the latency of the synthesized design. Please contrast the performance and area of your most optimized design (i.e., with smallest latency) with the baseline design. For this comparison, you only need to set k to 3.
  • +
  • Use charts, snippets of code, or any other presentation techniques to communicate your design decisions and results.
  • +
+ +

Submission

+ +

Submit your code using tag lab4_submission.

+ +

Acknowledgement

+

This assignment was originally written by Professor Zhiru Zhang from Cornell University. I have modified it slightly for our class. The design was originally created by Professor Zhang’s students, Ackerley Tng and Edgar Munoz.

+ + +
+
+
+
+ + +
+ + + + + + + + + + + + + + \ No newline at end of file diff --git a/labs/lab-vitis/index.html b/labs/lab-vitis/index.html new file mode 100644 index 0000000..99a0e30 --- /dev/null +++ b/labs/lab-vitis/index.html @@ -0,0 +1,392 @@ + + + + + + + + + + + + + Vitis Integration • ECEn 625: Compilation Strategies for High-Performance Systems + + + + + + + + + + + + + + + + + + + + +
+ + + + + +
+ + + +
+
+

+ Vitis Integration + + + +

+ +
+ + + + +

Learning Outcomes

+

The goals of this assignment are to:

+
    +
  • Test your HLS hardware from the last lab, and implement it on an SoC platform.
  • +
  • Learn how to connect Vitis HLS cores in a larger Vivado hardware project.
  • +
  • Learn how to call HLS accelerators from software in an SoC environment.
  • +
  • Measure performance of your HLS accelerator.
  • +
+ +

Preliminary

+ +

In this lab you will export your HLS accelerator as an IP to include in a Vivado project on the FPGA. You will then create an embedded software application in Vitis (different from Vitis HLS), that will communicate with your accelerator.

+ +

Most of the direction for this lab are included in a set of tutorial pages. Depending on your experience you may need to complete some or all of these tutorials in order to complete this lab:

+
    +
  • Vivado Tutorial: Tutorial on creating a block-design Vivado project with the ARM processor.
  • +
  • Vitis Tutorial: Running a bare-metal Hello World application in Vitis.
  • +
  • HLS Integration Tutorial: Exporting your HLS accelerator as an AXI4 IP and integrating it into your hardware and software projects.
  • +
+ +

Note: The tutorials were created with an earlier version of Vivado, and are somewhat brief. You can earn an a bonus 10\% on this assignment if you create a pull request on Github to improve the tutorials in some meaningful way (adding extra explanation text, updating images, etc.; basically anything beyond just fixing a small typo).

+ +

Implementation

+ +

Part 1: System Setup

+

As described in the tutorials, export your HLS IP to RTL, include it in an SoC Vivado project, and write software to run your accelerator. You can use any version of your HLS IP from the last lab (ie, unoptimized, min area, min latency, etc.)

+
    +
  • Add your Vivado project Tcl file to your Git repo in the lab_vitis/hw folder.
  • +
  • Add your IP files to your Git repo in the lab_vitis/ip folder.
  • +
+ +

Part 2: Measuring Execution Time

+ +

You are provided with an incomplete main.cpp that is similar to the test program used in the last lab. It will test the accuracy of your accelerator with the same set of test data. Complete the rest of the program and measure the runtime of your accelerator.

+ +

There are a few different ways you can perform high-resolution timing on your board. A few alternatives:

+
    +
  • For the 7-series ZYNQ, the ZYNQ global timer xtime_l.h
  • +
  • For the 7-series ZYNQ, the per-core private timer xscutimer.h
  • +
  • Adding an AXI Timer to the FPGA fabric (\url{https://www.xilinx.com/support/documentation/ip_documentation/axi_timer/v2_0/pg079-axi-timer.pdf})
  • +
  • If you are using an MPSoC platform, the A53 also has public/privates timers that can be used. Be sure you understand the API for these timers so that you know you are measuring time accurately.
  • +
+ +

In order to minimize the time spent in software, you should disable any printing while timing your code (set logging to false), and you should set compiler optimizations to O2 or O3. You can enable compiler optimizations in Vitis by right-clicking your application project (ie, 625_lab5, not 625_lab5_system), selecting Properties, and in the popup navigate to C/C++ Build->Settings->Tool Settings->ARM v7 g++ compiler->Optimization (may be slightly different for your processor/tool version).

+ +

Part 3: Software Runtime

+ +

Replace the call to your hardware accelerator with a software implementation of the function. You should be able to use your existing HLS code with some minor modifications. Measure and collect the runtime.

+ +

Part 4: Exploring Interfaces

+

The way your kNN accelerator is currently configured, the training samples are stored within the accelerator, which means they are implemented using the FPGA fabric, likely using the BRAMs.

+ +

Modify your design in order to build a system where the training data is stored within main memory. To do this, the training arrays should be declared in your software code, not in the code that is synthesized to hardware.

+ +

The Vitis HLS manual contains descriptions of how you can alter the interfaces to your IP block (Chapter 15: Managing Interface Synthesis). At this point you should have already changed the Block-Level Interface Protocol, when you added the interface directive to control your HLS core using an AXILite slave connection.

+ +

In order for your HLS core to receive the training data, you will have to add a new argument to your function, const digit training_data[]. You must then decide how you want to provide training data to your HLS core through this new argument, that will become a port on the hardware block. The section on Port-Level I/O Protocols discusses this in detail. You probably want to implement either an AXI4-Stream interface or AXI4 master. It is completely up to you how you implement this, and what protocols you would like to explore. Make sure you read the section titled Using AXI4 Interfaces.

+ +

If you’re not sure where to start, try something like this:

+
    +
  1. Add a pointer or array argument to your function to provide the training data.
  2. +
  3. Pass in this data from your test function and make sure your solution still passes C Simulation.
  4. +
  5. Choose between a memory-mapped or streaming interface: +
      +
    • Memory Mapped: +
        +
      • Configure the interface for this port to be an memory-mapped AXI Master (m_axi)
      • +
      • Read about how the master port determines the address offset to use, and configure your interface appropriately.
      • +
      • Modify you your Vivado project to add a Slave interface (HP Slave AXI Interface) on your ZYNQ7 Processing System. This gives a different block access to the DRAM.
      • +
      • Connect your new AXI master port in your HLS IP to this port.give the new master port access to the main memory.
      • +
      +
    • +
    • Streaming: +
        +
      • Configure the interface for this port to be an AXI Stream (\emph{axis})
      • +
      • Add a DMA core to your Vivado project that can read data from main memory and send it over an AXI Stream to your IP core.
      • +
      • Modify you your Vivado project to add a Slave interface (HP Slave AXI Interface) on your ZYNQ7 Processing System. This can be used to give the DMA core access to the DRAM.
      • +
      +
    • +
    +
  6. +
+ +

Bug Reminder: Just a reminder of the Vitis HLS 2020.2 driver Makefile bug. When you export your new IP core, remember to fix the Makefile. (I’m not sure if this has been fixed in 2022.2)

+ +

Once configured, create a Vitis software application that will run this modified system and measure its runtime.

+ +

Report

+

Include a short PDF report, located at lab_vitis/report.pdf. Include the following items:

+
    +
  • +

    Briefly describe your hardware implementation. What board did you use? What version of your HLS accelerator did you use? For example, you may find your largest configuration does not actually fit on the FPGA. How did you verify that your HLS core was operating correctly?

    +
  • +
  • Runtimes: +
      +
    • Provide software-only runtime (from Part 3)
    • +
    • Provide accelerated runtime (from Part 2). Does the per item runtime match the latency reported by Vitis HLS? (it should be pretty close)
    • +
    +
  • +
  • Interfaces: +
      +
    • Describe the approach you used to provide training data from main memory to your HLS accelerator.
    • +
    • Include HLS resource usage before/after making this change, to demonstrate that BRAMs are no longer being used for the training data.
    • +
    • Provide runtime data for this configuration, and comment on how it compares to the previous approach of storing training data within the accelerator.
    • +
    • What are the advantages and disadvantages of storing the data in the hardware accelerator versus in main memory?
    • +
    +
  • +
+ +

Submission

+

Submit your code on Github using the tag lab5_submission.

+ +

Be sure your Git repo contains at minimum:

+
    +
  • The .tcl file that can be used to create your project in Vivado. I’ll run this when grading, so please make sure it works. This means that you need to have your HLS IP committed into your repo or it won’t work. This should be committed to the hw directory.
  • +
  • The C/C++ source file that you use to run your accelerator and collect runtimes. This should be committed to the sw directory.
  • +
+ + +
+
+
+
+ + +
+ + + + + + + + + + + + + + \ No newline at end of file diff --git a/links/index.html b/links/index.html new file mode 100644 index 0000000..25f4a05 --- /dev/null +++ b/links/index.html @@ -0,0 +1,297 @@ + + + + + + + + + + + + + Links • ECEn 625: Compilation Strategies for High-Performance Systems + + + + + + + + + + + + + + + + + + + + +
+ + + + + +
+ + + +
+ +
+
+ + +
+ + + + + + + + + + + + + + \ No newline at end of file diff --git a/media/graphs/graph0.pdf b/media/graphs/graph0.pdf new file mode 100644 index 0000000..17ded29 Binary files /dev/null and b/media/graphs/graph0.pdf differ diff --git a/media/hls.png b/media/hls.png new file mode 100644 index 0000000..5c8fb33 Binary files /dev/null and b/media/hls.png differ diff --git a/media/llvm/balancer_example.pdf b/media/llvm/balancer_example.pdf new file mode 100644 index 0000000..f1498ae Binary files /dev/null and b/media/llvm/balancer_example.pdf differ diff --git a/media/llvm/balancer_example.svg b/media/llvm/balancer_example.svg new file mode 100644 index 0000000..fb12983 --- /dev/null +++ b/media/llvm/balancer_example.svg @@ -0,0 +1,577 @@ + +image/svg+xml+ + ++ + ++ + ++ + ++ + ++ + ++ + +a b c d e f g h + ++ + ++ + ++ + ++ + ++ + ++ + ++ + +a b c d e f g h + + \ No newline at end of file diff --git a/media/mini_lecture_grading_scheme.pdf b/media/mini_lecture_grading_scheme.pdf new file mode 100644 index 0000000..67e1790 Binary files /dev/null and b/media/mini_lecture_grading_scheme.pdf differ diff --git a/media/paper_review_grading.pdf b/media/paper_review_grading.pdf new file mode 100644 index 0000000..31974d7 Binary files /dev/null and b/media/paper_review_grading.pdf differ diff --git a/media/tutorials/bsp_stdout.png b/media/tutorials/bsp_stdout.png new file mode 100755 index 0000000..b6c168d Binary files /dev/null and b/media/tutorials/bsp_stdout.png differ diff --git a/media/tutorials/hw_platform.png b/media/tutorials/hw_platform.png new file mode 100755 index 0000000..5707701 Binary files /dev/null and b/media/tutorials/hw_platform.png differ diff --git a/media/tutorials/open_bsp.png b/media/tutorials/open_bsp.png new file mode 100755 index 0000000..76159fa Binary files /dev/null and b/media/tutorials/open_bsp.png differ diff --git a/media/tutorials/run_program.png b/media/tutorials/run_program.png new file mode 100644 index 0000000..dde106d Binary files /dev/null and b/media/tutorials/run_program.png differ diff --git a/media/tutorials/select_console.png b/media/tutorials/select_console.png new file mode 100644 index 0000000..133fd21 Binary files /dev/null and b/media/tutorials/select_console.png differ diff --git a/media/tutorials/vitis_application.png b/media/tutorials/vitis_application.png new file mode 100755 index 0000000..425c297 Binary files /dev/null and b/media/tutorials/vitis_application.png differ diff --git a/media/vitis/binary_string0.png b/media/vitis/binary_string0.png new file mode 100644 index 0000000..7a49ad0 Binary files /dev/null and b/media/vitis/binary_string0.png differ diff --git a/media/vitis/binary_string1.png b/media/vitis/binary_string1.png new file mode 100644 index 0000000..7850c46 Binary files /dev/null and b/media/vitis/binary_string1.png differ diff --git a/media/vitis/binary_strings.png b/media/vitis/binary_strings.png new file mode 100644 index 0000000..edf59d1 Binary files /dev/null and b/media/vitis/binary_strings.png differ diff --git a/media/vitis/img1.png b/media/vitis/img1.png new file mode 100644 index 0000000..04ba2eb Binary files /dev/null and b/media/vitis/img1.png differ diff --git a/media/vitis/img2.png b/media/vitis/img2.png new file mode 100644 index 0000000..82a05b9 Binary files /dev/null and b/media/vitis/img2.png differ diff --git a/mini-lecture/index.html b/mini-lecture/index.html new file mode 100644 index 0000000..2051b15 --- /dev/null +++ b/mini-lecture/index.html @@ -0,0 +1,331 @@ + + + + + + + + + + + + + Student Mini Lecture • ECEn 625: Compilation Strategies for High-Performance Systems + + + + + + + + + + + + + + + + + + + + +
+ + + + + +
+ + + +
+
+

+ + Student Mini Lecture +

+ +
+ + +

Each of you will have the opportunity to teach a portion of a class period. You will teach as a group of 2-3. Please sign up for a time/topic on Slack.

+ +

Guidelines and Suggestions

+
    +
  • Each mini-lecture should cover half of the class period. Plan for about 35 minutes, accounting for questions along the way.
  • +
  • You can use power-point slides, the white board, handouts, or a combination of any of these.
  • +
  • Make sure you prioritize student learning. Your goal is not simply to transfer the chapter text to Powerpoint slides and deliver the content. Consider how to best help students learn about these concepts. For example, you might want to experiment with these concepts in the Vitis HLS tool and share your experiences with the class, or do a live demo.
  • +
  • You might not have time to cover all the material in the chapter. It is more important to do a good job covering the basics than to try and cram all of the content into your presentation.
  • +
  • Look over the grading scheme below.
  • +
  • You should first read “Section I: Introduction, and “Section II, Chapter 1: Design Principles”, before diving into the later chapters.
  • +
  • There will inevitibly be some difficulty in “fitting together” the different presentations from the various groups. For example, the earlier chapters sometimes refer to concepts that will be covered in later chapters by other group’s presentations. Likewise, when presenting a later chapter, you may be unsure of what will be fully covered by earlier presentations. Just do your best, don’t feel like you need to cover every detail, and be flexible in your presentations and willing to adapt on the fly.
  • +
+ +

Topics

+

This semester the topics will cover materials from the Vitis High-Level Synthesis User Guide (UG1399). Your group should choose one of the following topics from “Section II: HLS Programmers Guide”:

+ +
    +
  1. Chapter 2: Abstract Parallel Programming Model for HLS +
      +
    • Note: This chapter is somewhat unique from the other chapters. While the other chapters generally focus on programming techniques localized to one function of your code, this chapter discusses the broader architecture of how to parellelize multiple tasks/functions in your system and how to connect them to pass data between them.
    • +
    +
  2. +
  3. +

    Chapter 3: Loops Primer

    +
  4. +
  5. Chapter 4: Arrays Primer +
      +
    • You don’t need to focus on Interfaces, as we will cover “Chapter 8: Interfaces of the HLS Design” in a later lecture.
    • +
    +
  6. +
  7. Chapter 5: Functions Primer & Chapter 6: Data Types +
      +
    • Chapter 6 has a lot of information, so focus on the “Standard Types”, “Arbitrary Precision (AP) Data Types”, and “Global Variables”.
    • +
    • You may want to discuss pointers briefly, but don’t spend time on the interfaces, as we will cover “Chapter 8: Interfaces of the HLS Design” in a later lecture.
    • +
    +
  8. +
+ +

If you aren’t sure if a particular sub-topic is important to cover, please reach out to me and ask.

+ +

Note: You are strongly encouraged to consult the textbook: Parallel Programming for FPGAs, which has many concrete examples of how these concepts can be applied to accelerating real-world algorithms. A portion of the grading scheme evaluates whether you have examples in your presentation. You don’t have to use examples from this textbook, but it’s a good place to start.

+ +

Schedule

+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
DateTopicGroup
March 7: First half of classChapter 2 
March 7: Second half of classChapter 3 
March 9: First half of classChapter 4 
March 9: Second half of classChapter 5 
+ +

Grading Scheme

+ +

Grading Scheme

+ +
+
+
+
+ + +
+ + + + + + + + + + + + + + \ No newline at end of file diff --git a/overview/index.html b/overview/index.html new file mode 100644 index 0000000..ca768a3 --- /dev/null +++ b/overview/index.html @@ -0,0 +1,374 @@ + + + + + + + + + + + + + Overview • ECEn 625: Compilation Strategies for High-Performance Systems + + + + + + + + + + + + + + + + + + + + +
+ + + + + +
+ + + +
+
+

+ + + + Overview +

+ +
+ + + + +

Content

+ +

This course will investigate high-level automated compilation strategies for digital circuits. This course will focus on the theoretical foundations of behavioral synthesis as well as applied practice of high-level synthesis (HLS) with modern tools. The major topics addressed in this course include:

+
    +
  • Graph Theory, Algorithms, and Analysis
  • +
  • HLS Algorithms (Scheduling, Allocation, Binding, Retiming)
  • +
  • Compilers (Passes, SSA, IR)
  • +
  • HLS Optimizations (Pipelining, IR transformations)
  • +
  • Modern HLS research topics
  • +
  • Design using open-source and commercial HLS tools
  • +
+ +

Prerequisites

+ +

Students should be familiar with RTL (Verilog or VHDL), and be comfortable writing C++. If you are unsure if you have the necessary experience, contact the instructor.

+ +

Textbook

+ + + +

Grade Breakdown

+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
Component% of Grade
Labs45
Project & Presentation15
Midterm Exam15
Mini-Lecture10
Research Papers10
Class Participation5
+ +

Class Participation

+

Active participation by all students is an essential component of learning in this course. Class participation includes attending class, preparing for class (usually by reading and understanding the reading), participating in the class discussion, and providing additional insight or help to the instructor or fellow students. The class participation score is subjective and will be computed at the end of the semester based on feedback from fellow students and observations from the instructor.

+ +

Mini-Lecture

+

Several classes will be spent on student-led lectures from the “Parallel Programming for FPGAs” textbook. Each student will participate in one presentation, as part of a group of two.

+ +

Labs

+

There are 5 labs. While none of the labs require you to write a huge amount of code (most can be completed in ~100 lines), you may find the coding challenging as you will be working with new tools and C++ features you may not have used before. Start early and give yourself lots of time to debug and ask questions on Slack.

+ +

Paper Reviews

+

Mid-Term Exam

+

One midterm examination will be given to test your understanding of the course material. This examination will be closed book and taken at the testing center. The test is scheduled for the following three days: TBD. Make sure you complete the test during this time. No makeup examinations will be given.

+ +

Project and Presentation

+

Each student will be required to complete a project related to the topics covered in the course and present the results from this project in a class presentation. The project will begin during the second half of the semester and the presentations will occur during the last week of class. Details of the project requirements and grading will be given at a later time. +There will be no final exam for the course.

+ +

Late Policy

+

For assignments submitted late, the penalty will be 20% for each week late (rounding up), to a maximum of 60% deduction. (Example: submitting 1 day late will result in a 20% penalty and 13 days late will result in a 40% penalty). No assignments will be accepted after the last day of class.
+This policy applies to assignments only. The final project deliverables must be completed on time, or no credit will be given.

+ +

Course Schedule

+

The course lecture and reading schedule for the semester will be posted on the course website.

+ +

Honor Code Standards

+

In keeping with the principles of the BYU Honor Code, students are expected to be honest in all of their academic work. Academic honesty means, most fundamentally, that any work you present as your own must in fact be your own work and not that of another. Violations of this principle may result in a failing grade in the course and additional disciplinary action by the university.

+ +

Students are also expected to adhere to the Dress and Grooming Standards. Adherence demonstrates respect for yourself and others and ensures an effective learning and working environment. It is the university’s expectation, and my own expectation in class, that each student will abide by all Honor Code standards. Please call the Honor Code Office at 422-2847 if you have questions about those standards.

+ +

Preventing & Responding to Sexual Misconduct

+ +

In accordance with Title IX of the Education Amendments of 1972, Brigham Young University prohibits unlawful sex discrimination against any participant in its education programs or activities. The university also prohibits sexual harassment—including sexualviolence—committed by or against students, university employees, and visitors to campus. As outlined in university policy, sexual harassment, dating violence, domestic violence,sexual assault, and stalking are considered forms of “Sexual Misconduct” prohibited by the university.

+ +

University policy requires all university employees in a teaching, managerial, or supervisory role to report all incidents of Sexual Misconduct that come to their attention in any way, including but not limited to face-to-face conversations, a written class assignment or paper, class discussion, email, text, or social media post. Incidents of Sexual Misconduct should be reported to the Title IX Coordinator at t9coordinator@byu.edu or (801) 422-8692. Reports may also be submitted through EthicsPoint at https://titleix.byu.edu/reportor 1-888-238-1062 (24-hours a day).

+ +

BYU offers confidential resources for those affected by Sexual Misconduct, including the university’s Victim Advocate, as well as a number of non-confidential resources and services that may be helpful. Additional information about Title IX, the university’s SexualMisconduct Policy, reporting requirements, and resources can be found athttp://titleix.byu.edu or by contacting the university’s Title IX Coordinator.
+Students With Disabilities +If you have a disability that may affect your performance in this course, you should get in touch with the office of Services for Students with Disabilities (1520 WSC). This office can evaluate your disability and assist the professor in arranging for reasonable accommodations.

+ + +
+
+
+
+ + +
+ + + + + + + + + + + + + + \ No newline at end of file diff --git a/paper-reviews/index.html b/paper-reviews/index.html new file mode 100644 index 0000000..c038a2f --- /dev/null +++ b/paper-reviews/index.html @@ -0,0 +1,311 @@ + + + + + + + + + + + + + Research Papers • ECEn 625: Compilation Strategies for High-Performance Systems + + + + + + + + + + + + + + + + + + + + +
+ + + + + +
+ + + +
+
+

+ + + + Research Papers +

+ +
+ + +

An important part of this course is reading research papers. High-level synthesis is an active research area and many of the most interesting developments are taking place in the research domain. In addition, reading and reviewing research papers is a good skill to practise, especially for those of you that go on to a research career.

+ +

Schedule

+ +

Paper reviews are due the day before we discuss the paper in class

+ + + + + + + + + + + + + + + + + + + + + + + + +
#Due DatePaper
1Mar 27, 11:59pmJason Cong, Jason Lau, Gai Liu, Stephen Neuendorffer, Peichen Pan, Kees Vissers, Zhiru Zhang, “FPGA HLS Today: Successes, Challenges, and Opportunities”, TRETS 2022.
2Apr 3, 11:59pmYi-Hsiang Lai, Yuze Chi, Yuwei Hu, Jie Wang, Cody Hao Yu, Yuan Zhou, Jason Cong, Zhiru Zhang, “HeteroCL: A Multi-Paradigm Programming Infrastructure for Software-Defined Reconfigurable Computing”, FPGA 2019.
3Apr 10, 11:59pmHanchen Ye, Cong Hao, Jianyi Cheng, Hyunmin Jeong, Jack Huang, Stephen Neuendorffer, Deming Chen, “ScaleHLS: A New Scalable High-Level Synthesis Framework on Multi-Level Intermediate Representation”, HPCA 2022.
+ +

Paper Review Contents

+ +

Include the following in your paper review (in marked sections):

+
    +
  1. A sentence or two giving an overview of the paper.
  2. +
  3. Describe the 2-3 Major Contributions and/or Novelty of the paper. This should be more than a re-statement of the abstract. What do you think are the important contributions of the paper?
  4. +
  5. Provide a critical review, discussing several positive and negative aspects of the paper. Try to provide non-trivial arguments, including some points not brought up by the authors. Do not summarize the paper (that’s what the abstract is for); rather, evaluate the merits of the work done by the authors as presented in the paper. You could comment on things like: (not all in one review): +
      +
    • importance of the problem being solved
    • +
    • soundness/correctness of approach
    • +
    • appropriateness of methodology
    • +
    • quality, completeness or repeatability of results
    • +
    • readability
    • +
    • perspective and/or comparison with previous work
    • +
    +
  6. +
  7. Identify at least one aspect of the paper that you didn’t understand, or want to better understand.
  8. +
+ +

Your review should be one page or less (normal fonts and margins). Quality is more important than quantity.

+ +

Grading Scheme

+ +

Submission Instructions & Late Policy

+

Send your review as a direct message on Slack. Because we discuss the paper reviews as a class, no late submissions will be accepted. Please make sure to get your paper reviews in on time!

+ + +
+
+
+
+ + +
+ + + + + + + + + + + + + + \ No newline at end of file diff --git a/schedule/index.html b/schedule/index.html new file mode 100644 index 0000000..f53b0b0 --- /dev/null +++ b/schedule/index.html @@ -0,0 +1,409 @@ + + + + + + + + + + + + + Schedule • ECEn 625: Compilation Strategies for High-Performance Systems + + + + + + + + + + + + + + + + + + + + +
+ + + + + +
+ + + +
+
+

+ + + + Schedule +

+ +
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
WeekMondayTuesdayWednesdayThursdayFriday
1 (Jan 9) Course Overview, Graphs Lab 1 Overview, Specialized Computing 
2 (Jan 16)HOLIDAYNO CLASSAsst 1 Due, 11:59pmNO CLASS 
3 (Jan 23) Compilers Guest Speaerk, Lab 2 
4 (Jan 30) LLVM Tutorial HLS Flow, Arch. Exploration 
5 (Feb 6)Asst 2 Due, 11:59pmScheduling Intro, ILP ILP Scheduling, Lab 3 
6 (Feb 13) NO CLASS Pipelining & Modulo Scheduling 
7 (Feb 20) NO CLASS, Asst 3 Due, 11:59pm Vitis HLS Tutorial 
8 (Feb 27) NO CLASS - Work on Student Lecture NO CLASS - Work on Student Lecture 
9 (Mar 6) Student Lectures Student Lectures 
10 (Mar 13) NO CLASSAsst 4 Due, 11:59pmInterfaces 
11 (Mar 20) Asst 5 Project Discussion & Midterm Q&A 
12 (Mar 27) Research Paper #1Asst 5 Due, 11:59pm, Midterm ExamProject Proposals & Midterm ExamMidterm Exam
13 (Apr 3) Research Paper #2 NO CLASS 
14 (Apr 10) Research Paper #3 Project Presentations 
14 (Apr 17) Project Presentations NO CLASS 
+ + + + + +
+
+
+
+ + +
+ + + + + + + + + + + + + + \ No newline at end of file diff --git a/vitis-tutorial/index.html b/vitis-tutorial/index.html new file mode 100644 index 0000000..f4c1bb9 --- /dev/null +++ b/vitis-tutorial/index.html @@ -0,0 +1,315 @@ + + + + + + + + + + + + + Vitis Tutorial • ECEn 625: Compilation Strategies for High-Performance Systems + + + + + + + + + + + + + + + + + + + + +
+ + + + + +
+ + + +
+
+

+ + Vitis Tutorial +

+ +
+ + +

Previous: Vivado Tutorial

+ +

Create Vitis Projects

+ +

Run Vitis (vitis), and choose a workspace location. I used lab_vitis/sw for my workspace location.

+ +

Create the platform project

+ +

The platform project generates the standalone software layer code, which provides a software layer to access hardware and processor features (timers, interrupts, etc) in a bare-metal environment.

+
    +
  1. File->New->Platform Project.
  2. +
  3. Chose a Platform Project name. I chose 625_hw.
  4. +
  5. Browse to your .xsa file name.
    +Wizard image of hardware platform selection
  6. +
  7. +

    Click Finish.

    +
  8. +
  9. Change the stdout output. By default, the output from your program will be sent over the physical UART pins present on the board. But instead of having to connect a UART to the board, we will use the option that allows us to send stdout over an virtual UART using the JTAG (USB) connection. +
      +
    • Expand your platform project, and double click on the platform.spr file. Select the standalone on ps7_cortexa9_0->Board Support Package, and click Modify BSP Settings.
      +Image of BSP menu
    • +
    • In the Board Support Package Settings popup, go to the standalone menu, and change stdout to use coresight_comp_0.
      +BSP stdout selection
    • +
    • Click OK to close the window and save the BSP settings.
    • +
    +
  10. +
  11. Build the BSP code. Right click on your platform project and choose Build Project.
  12. +
+ +

Create the application project

+
    +
  1. File->New->Application Project.
  2. +
  3. Chose your platform that you created in the last step.
    +Wizard menu for application selection
  4. +
  5. Choose an application name (ie. HelloWorld), and continue through the next screens.
  6. +
  7. On the Templates screen, choose Empty Application (C++), and then click Finish.
  8. +
  9. After you complete the wizard, find the src directory, and right click New->File, and create a main.cpp.
  10. +
  11. Create a simple application: +
    #include <stdio.h>  
    +int main() {
    +  printf("Hello World\n");
    +}
    +
    +
  12. +
  13. Build your application. Right click on your application project and choose Build Project.
  14. +
+ +

Run Your Applicaton on the Board

+
    +
  • +

    Right-click on your executable folder (down one level from the _system project created in the last step – see image below), choose Run As->Launch on Hardware (Single Application Debug.
    +Right click menu to run program on hardware

    +
  • +
  • +

    To view the program output, you will need to use the console selector button in the Console window to select the *TCF Debug Virtual Terminal - ARM Cortex-A9 MPCore #0 console. This is the JTAG console for core 0. +Menu to select proper console output

    +
  • +
  • +

    You should see the message Hello World.

    +
  • +
+ +

Next: Vitis HLS Integration Tutorial

+ +
+
+
+
+ + +
+ + + + + + + + + + + + + + \ No newline at end of file diff --git a/vivado-tutorial/index.html b/vivado-tutorial/index.html new file mode 100644 index 0000000..e2a20a9 --- /dev/null +++ b/vivado-tutorial/index.html @@ -0,0 +1,317 @@ + + + + + + + + + + + + + Vivado Tutorial • ECEn 625: Compilation Strategies for High-Performance Systems + + + + + + + + + + + + + + + + + + + + +
+ + + + + +
+ + + +
+
+

+ + Vivado Tutorial +

+ +
+ + +

Previous: Installing Vitis/Vivado

+ +

Setup

+ +

Installing Boards

+

If you are using a Digilent board, such as the Zedboard, you need to setup the board files in Vivado. See https://github.com/Xilinx/XilinxBoardStore.

+ +

Running Vivado

+

Before you can run the Vivado tools you should first run the configuration script:

+
source /tools/Xilinx/Vivado/2022.2/settings64.sh
+
+ +

This will add the tools to your PATH.

+ +

To run Vivado, simply run vivado.

+ +

Creating a Simple Hardware Project

+ +

Creating the Project

+

After launching Vivado, follow these steps to create a hardware project:

+
    +
  1. Create Project…, and choose a project name and location. You can name your project whatever you want, but make sure you place the project in it’s own directory. For example, my project was named 625_lab5 and located at lab_vitis/hw/vivado_proj. (Note that I chose to add a hw subdirectory and then created a project directory within this. You will see why this is useful when you get to the section on Committing to Git). Click Next. Choose an RTL project. Click Next.
  2. +
  3. You don’t need to add any sources or constraints yet, just click Next.
  4. +
  5. On the next you will be asked to choose an FPGA part. Click Boards at the top, and choose your board (ie. Zedboard). Click Finish to create your project.
  6. +
+ +

Creating a Base Design

+

In these steps we will create a basic system, containing only the Zynq processing system (PS).

+
    +
  1. Click Create Block Design, and click OK on the popup.
  2. +
  3. Add the ZYNQ7 Processing System IP to the design (right-click, Add IP).
  4. +
  5. A green banner should appear with a link to Run Block Automation. Run this. This will configure the ZYNQ for your board.
  6. +
  7. The FCLK_CLK0 output of the Zynq Processing System will serve as your system clock. It is set to 100MHz by default. Connect it to the M_AXI_GP0_ACLK input.
  8. +
  9. Generate a top-level module: In the Sources window, expand Design Sources and right-click on your block design (design_1.bd) and select Create HDL Wrapper. Use the option to Let Vivado manager wrapper and auto-update.
  10. +
+ +

Committing to Git

+

Want to commit your project to Git? Don’t try and commit your actual project files, as this won’t work. Instead, we will instruct Vivado to create a single Tcl script that can be used to re-create our project from scratch:

+
    +
  • Select File->Project->Write Tcl.
  • +
  • Make sure to check the box Recreate Block Designs using Tcl.
  • +
  • Those choose a file location. This should be outside your project directory, since your project directory is temporary and not committed to Git. My script is located at lab_vitis/hw/create_hw_proj.tcl. Commit this Tcl script to Git.
  • +
  • Now, feel free to delete your Vivado project folder, and then you can simply recreate it using vivado -source create_hw_proj.tcl. I typically create a simple Makefile such as this:
  • +
+ +
proj:
+	vivado -source create_hw_proj.tcl
+
+clean:
+	rm -rf 625_lab5
+
+ +

Synthesizing the hardware

+
    +
  1. Run Generate Bitstream.
  2. +
  3. Once the bitstream generation is complete, export the hardware: +
      +
    • File->Export Hardware.
    • +
    • Chose the Include Bitstream option, and choose a location to store the Xilinx Shell Archive (.xsa). Mine is placed at lab_vitis/hw/625_lab5_hw.xsa. This file will be provided to the software tools in the next section to tell the software tools all about our hardware system configuration.
    • +
    +
  4. +
  5. You should commit this .xsa file to Git.
  6. +
+ +

Next: Vitis Tutorial

+ +
+
+
+
+ + +
+ + + + + + + + + + + + + + \ No newline at end of file