]> rtime.felk.cvut.cz Git - fpga/lx-cpu1/lx-rocon.git/commitdiff
Multiple patches
authorMartin Meloun <meloumar@cmp.felk.cvut.cz>
Sun, 11 May 2014 21:43:17 +0000 (23:43 +0200)
committerMartin Meloun <meloumar@cmp.felk.cvut.cz>
Sun, 11 May 2014 21:46:37 +0000 (23:46 +0200)
1) USB sendhex forked due to changes (patch included)
2) Synthesis profiling for HW
3) Added LX master
4) Calbration -> Measuerement
5) Master CPU bus is 50 MHz and wired to Tumbl external bus,
   fixes in wiring
6) Cleanups
7) Other crap I forgot in the meantime :-)

Signed-off-by: Martin Meloun <meloumar@cmp.felk.cvut.cz>
40 files changed:
host/app/usb_sendhex [deleted symlink]
host/app/usb_sendhex/0001-Implement-USB_VENDOR_CALL-feature-in-usb_sendhex.patch [new file with mode: 0644]
host/app/usb_sendhex/Makefile [new file with mode: 0644]
host/app/usb_sendhex/Makefile.omk [new file with mode: 0644]
host/app/usb_sendhex/usb_sendhex.c [new file with mode: 0644]
hw/Makefile
hw/bus_calibration.vhd [deleted file]
hw/bus_irc.vhd
hw/bus_lxmaster.vhd [new file with mode: 0644]
hw/bus_measurement.vhd [new file with mode: 0644]
hw/bus_tumbl.vhd
hw/bus_tumbl_interconnect.vhd [deleted file]
hw/calibration_read_register.vhd [deleted file]
hw/calibration_write_register.vhd [deleted file]
hw/crc.vhd [new file with mode: 0644]
hw/dff.vhd [deleted file]
hw/dff2.vhd
hw/irc_proc_inc.vhd
hw/irc_proc_main.vhd
hw/irc_reader.vhd
hw/lx-rocon.ucf
hw/lx-rocon_firmware/firmware.c
hw/lx-rocon_firmware/start.S
hw/lx-rocon_tumbl/lx_rocon_dmem.vhd
hw/lx-rocon_tumbl/lx_rocon_gprf_abd.vhd
hw/lx-rocon_tumbl/lx_rocon_imem.vhd
hw/lx-rocon_tumbl/lx_rocon_tumbl.vhd
hw/lx_rocon_pkg.vhd
hw/lx_rocon_top.prj
hw/lx_rocon_top.vhd
hw/lxmaster.vhd [new file with mode: 0644]
hw/measurement_register.vhd [new file with mode: 0644]
hw/qcounter.vhd
hw/util_pkg.vhd [new file with mode: 0644]
hw/xilinx_dualport_bram_no_change.vhd
hw/xilinx_dualport_bram_write_first.vhd
submodule/ulan-app
sw/app/rocon/appl_fpga.c
sw/app/rocon/appl_fpga.h
sw/app/rocon/appl_usb.c

diff --git a/host/app/usb_sendhex b/host/app/usb_sendhex
deleted file mode 120000 (symlink)
index e5d04b2..0000000
+++ /dev/null
@@ -1 +0,0 @@
-../../submodule/ulan-app/app-host/usb_sendhex/
\ No newline at end of file
diff --git a/host/app/usb_sendhex/0001-Implement-USB_VENDOR_CALL-feature-in-usb_sendhex.patch b/host/app/usb_sendhex/0001-Implement-USB_VENDOR_CALL-feature-in-usb_sendhex.patch
new file mode 100644 (file)
index 0000000..2cb9db5
--- /dev/null
@@ -0,0 +1,150 @@
+From 225b899f1e904128ed4794041dc625751c08fc3f Mon Sep 17 00:00:00 2001
+From: Martin Meloun <meloumar@cmp.felk.cvut.cz>
+Date: Mon, 26 Aug 2013 11:23:24 +0200
+Subject: [PATCH] Implement USB_VENDOR_CALL feature in usb_sendhex
+
+USB_VENDOR_CALL feature sends a command with a argument
+(both 16bit) and expects 16bit return value. It is used
+for calling functions on the target. If mixed with other
+arguments, it is executed right before GOTO.
+
+Signed-off-by: Martin Meloun <meloumar@cmp.felk.cvut.cz>
+---
+ app-host/usb_sendhex/usb_sendhex.c | 57 ++++++++++++++++++++++++++++++++++----
+ 1 file changed, 52 insertions(+), 5 deletions(-)
+
+diff --git a/app-host/usb_sendhex/usb_sendhex.c b/app-host/usb_sendhex/usb_sendhex.c
+index 16f4907..c297822 100644
+--- a/app-host/usb_sendhex/usb_sendhex.c
++++ b/app-host/usb_sendhex/usb_sendhex.c
+@@ -3,7 +3,7 @@
+  *
+  * Based on 'ul_sendhex'
+  *
+- * Version 1.0 - 2004/02/03
++ * Version 1.1 - 2013/08/26
+  */
+ #define _GNU_SOURCE
+@@ -52,6 +52,9 @@ unsigned long mem_length = 0xff00;
+ unsigned long max_block  = 1024;
+ unsigned long go_addr    = 3;
+ int go_flg     = 0;
++int call       = 0xFFFF;
++int arg        = 0;
++int call_flg   = 0;
+ int reset_flg  = 0;
+ int prt_modules = 0;
+ int debugk     = 0;
+@@ -579,6 +582,33 @@ int download_file(char *file_name, char *format)
+   return ret;
+ }
++int send_cmd_call(int cmd, int val)
++{
++  int ret, resp_val;
++  usb_dev_handle *hdev;
++  char resp[10];
++
++  hdev = usb_open_device(vid, pid);
++
++  if (!hdev)
++  {
++    perror("send_cmd_call : USB open failed");
++    return -1;
++  }
++
++  ret = usb_control_msg(hdev, USB_TYPE_VENDOR | USB_RECIP_DEVICE | USB_ENDPOINT_IN,
++                        USB_VENDOR_CALL, val & 0xffff, cmd & 0xffff, resp, sizeof(resp), USB_TIMEOUT);
++  resp_val = usb_swab16(*((uint16_t *)(resp)));
++
++  if (ret < 0)
++    printf("Call %4X (%4X) ERROR %d: %s\n", (uint16_t)(cmd & 0xffff), (uint16_t)(val & 0xffff), ret, usb_strerror());
++  else
++    printf("Call %4X (%4X): %4X\n", (uint16_t)(cmd & 0xffff), (uint16_t)(val & 0xffff), resp_val);
++
++  usb_close_device(hdev);
++  return ret;
++}
++
+ int send_cmd_go(unsigned long addr)
+ {
+   int ret;
+@@ -893,6 +923,8 @@ usage(void)
+   printf("  -s, --start <addr>       start address of transfer\n");
+   printf("  -l, --length <num>       length of upload block\n");
+   printf("  -b, --block <num>        maximal block length\n");
++  printf("  -c, --call <num>         vendor custom call\n");
++  printf("  -a, --argument <num>     argument for vendor custom call\n");
+   printf("  -g, --go <addr>          start program from address\n");
+   printf("  -r, --reset              reset before download\n");
+   printf("  -E, --mass-erase <mode>  full device erase\n");
+@@ -917,6 +949,8 @@ int main(int argc, char *argv[])
+     { "start", 1, 0, 's' },
+     { "length", 1, 0, 'l' },
+     { "block", 1, 0, 'b' },
++    { "call", 1, 0, 'c' },
++    { "argument", 1, 0, 'a' },
+     { "go",    1, 0, 'g' },
+     { "reset", 0, 0, 'r' },
+     { "mass-erase", 1, 0, 'E' },
+@@ -934,9 +968,9 @@ int main(int argc, char *argv[])
+   int opt;
+ #ifndef HAS_GETOPT_LONG
+-  while ((opt = getopt(argc, argv, "d:i:t:s:l:b:g:rE:euwf:pvVhD:")) != EOF)
++  while ((opt = getopt(argc, argv, "d:i:t:s:l:b:c:a::g:rE:euwf:pvVhD:")) != EOF)
+ #else
+-  while ((opt = getopt_long(argc, argv, "d:i:t:s:l:b:g:rE:euwf:pvVh", &long_opts[0], NULL)) != EOF)
++  while ((opt = getopt_long(argc, argv, "d:i:t:s:l:b:c:a:g:rE:euwf:pvVh", &long_opts[0], NULL)) != EOF)
+ #endif
+     switch (opt)
+@@ -979,6 +1013,13 @@ int main(int argc, char *argv[])
+       case 'b':
+         max_block = strtoul(optarg, NULL, 0);
+         break;
++      case 'c':
++        call = strtoul(optarg, NULL, 0);
++        call_flg = 1;
++        break;
++      case 'a':
++        arg = strtoul(optarg, NULL, 0);
++        break;
+       case 'g':
+         go_addr = strtoul(optarg, NULL, 0);
+         go_flg = 1;
+@@ -1013,7 +1054,7 @@ int main(int argc, char *argv[])
+         verbose = 1;
+         break;
+       case 'V':
+-        fputs("USB sendhex v.1.0\n", stdout);
++        fputs("USB sendhex v.1.1\n", stdout);
+         exit(0);
+       case 'h':
+       default:
+@@ -1021,7 +1062,7 @@ int main(int argc, char *argv[])
+         exit(opt == 'h' ? 0 : 1);
+     }
+-  if ((optind >= argc) && !go_flg && !prt_modules && !debugk_flg
++  if ((optind >= argc) && !go_flg && !call_flg && !prt_modules && !debugk_flg
+       && !masserase_flg && !regerase_flg && !reset_flg)
+   {
+     usage();
+@@ -1062,6 +1103,12 @@ int main(int argc, char *argv[])
+       exit(2);
+   }
++  if (call_flg)
++  {
++    if (send_cmd_call(call, arg) < 0)
++      exit(2);
++  }
++
+   if (go_flg)
+   {
+     if (send_cmd_go(go_addr) < 0)
+-- 
+1.8.4.5
+
diff --git a/host/app/usb_sendhex/Makefile b/host/app/usb_sendhex/Makefile
new file mode 100644 (file)
index 0000000..b22a357
--- /dev/null
@@ -0,0 +1,14 @@
+# Generic directory or leaf node makefile for OCERA make framework
+
+ifndef MAKERULES_DIR
+MAKERULES_DIR := $(shell ( old_pwd="" ;  while [ ! -e Makefile.rules ] ; do if [ "$$old_pwd" = `pwd`  ] ; then exit 1 ; else old_pwd=`pwd` ; cd -L .. 2>/dev/null ; fi ; done ; pwd ) )
+endif
+
+ifeq ($(MAKERULES_DIR),)
+all : default
+.DEFAULT::
+       @echo -e "\nThe Makefile.rules has not been found in this or partent directory\n"
+else
+include $(MAKERULES_DIR)/Makefile.rules
+endif
+
diff --git a/host/app/usb_sendhex/Makefile.omk b/host/app/usb_sendhex/Makefile.omk
new file mode 100644 (file)
index 0000000..7bd55e2
--- /dev/null
@@ -0,0 +1,11 @@
+default_CONFIG = CONFIG_APP_USB_SENDHEX=x
+
+ifeq ($(CONFIG_APP_USB_SENDHEX),y)
+
+bin_PROGRAMS = usb_sendhex
+
+usb_sendhex_SOURCES = usb_sendhex.c
+
+lib_LOADLIBES = usb
+
+endif #CONFIG_APP_USB_SENDHEX
diff --git a/host/app/usb_sendhex/usb_sendhex.c b/host/app/usb_sendhex/usb_sendhex.c
new file mode 100644 (file)
index 0000000..c297822
--- /dev/null
@@ -0,0 +1,1119 @@
+/* usb_sendhex - program for manage device firmware by USB
+ * R.Bartosinski <bartosr@centrum.cz> (C)2004
+ *
+ * Based on 'ul_sendhex'
+ *
+ * Version 1.1 - 2013/08/26
+ */
+#define _GNU_SOURCE
+
+#include <stdio.h>
+#include <stdlib.h>
+#include <string.h>
+#include <getopt.h>
+#include <usb.h>
+#include <sys/time.h>
+#include <stdint.h>
+#include <endian.h>
+
+#if !defined(_WIN32) && !defined(__DJGPP__) && !defined(HAS_GETDELIM)
+#define HAS_GETDELIM
+#endif
+#define HAS_GETOPT_LONG
+
+#define USB_DEV_VID 0xDEAD
+#define USB_DEV_PID 0x1000
+
+#define USB_TIMEOUT 500
+
+// USB vendor defines
+
+#define USB_VENDOR_GET_CAPABILITIES  0x00 // get capabilities
+#define USB_VENDOR_RESET_DEVICE      0x08
+// #define USB_VENDOR_SET_BYTE          0x10
+// #define USB_VENDOR_SET_WORD          0x20
+#define USB_VENDOR_GET_SET_MEMORY    0x30
+#define USB_VENDOR_ERASE_MEMORY      0x40 // erase memory for 1 Byte
+#define USB_VENDOR_ERASE_1KB_MEMORY  0x48 // erase memory for 1 KB
+#define USB_VENDOR_MASS_ERASE        0x50 // erase all device memory
+#define USB_VENDOR_GOTO              0x60
+#define USB_VENDOR_CALL              0x70
+#define USB_VENDOR_GET_STATUS        0xF0
+#define USB_VENDOR_MASK              0xF8 // mask for vendor commands
+
+#define USB_VENDOR_MEMORY_BY_BULK    0x80
+
+int vid = USB_DEV_VID;
+int pid = USB_DEV_PID;
+int upload_flg = 0;
+int mem_type   = 2;
+unsigned long mem_start  = 0;
+unsigned long mem_length = 0xff00;
+unsigned long max_block  = 1024;
+unsigned long go_addr    = 3;
+int go_flg     = 0;
+int call       = 0xFFFF;
+int arg        = 0;
+int call_flg   = 0;
+int reset_flg  = 0;
+int prt_modules = 0;
+int debugk     = 0;
+int debugk_flg = 0;
+int verbose    = 0;
+int wait_for_device_flg = 0;
+char *file_format = NULL;
+int regerase_flg = 0;
+int masserase_flg = 0;
+unsigned long masserase_mode = 0;
+
+/*****************************************************************************/
+
+typedef struct tform_file
+{
+  unsigned char *buf;
+  int   buf_len;
+  int   buf_addr;
+  int   buf_bytes;
+  FILE *file;
+  char *line_buf;
+  int  line_addr;
+  int  line_bytes;
+  int  line_offs;
+  int  start_addr;
+  int (*read)(struct tform_file *tform);
+  int (*done)(struct tform_file *tform);
+} tform_file;
+
+/*****************************************************************************/
+
+#if __BYTE_ORDER == __BIG_ENDIAN
+uint16_t usb_swab16(uint16_t x)
+{
+  return x << 8 | x >> 8;
+}
+#else
+uint16_t usb_swab16(uint16_t x)
+{
+  return x;
+}
+#endif
+
+#ifndef HAS_GETDELIM
+int getdelim(char **line, size_t *linelen, char delim, FILE *F)
+{
+  char c;
+  size_t l = 0;
+
+  do
+  {
+    if (l + 1 >= *linelen)
+    {
+      *linelen = l + 20;
+
+      if (!*line)
+        *line = (char *)malloc(*linelen);
+      else
+        *line = (char *)realloc(*line, *linelen);
+    }
+
+    c = fgetc(F);
+
+    if (feof(F))
+    {
+      if (l)
+        break;
+      else
+        return -1;
+    }
+
+    if (c != '\r')
+      (*line)[l++] = c;
+  }
+  while (c != delim);
+
+  (*line)[l] = 0;
+  return l;
+}
+#endif
+
+int get_hex(char **p, unsigned *v, int chars)
+{
+  unsigned u = 0;
+  char c;
+  *v = 0;
+
+  while (**p == ' ')
+    (*p)++;
+
+  while (chars--)
+  {
+    u <<= 4;
+    c = **p;
+
+    if ((c >= '0') && (c <= '9'))
+      u += c - '0';
+    else if ((c >= 'A') && (c <= 'F'))
+      u += c - 'A' + 10;
+    else
+      return -1;
+
+    (*p)++;
+  };
+
+  *v = u;
+
+  return 0;
+}
+
+int tform_init(tform_file *tform, int buf_len)
+{
+  if (!buf_len) buf_len = 1024;
+
+  tform->file = NULL;
+  tform->buf_len = buf_len;
+  tform->buf = malloc(tform->buf_len);
+  tform->buf_addr = 0;
+  tform->line_buf = NULL;
+  tform->line_offs = 0;
+  tform->line_bytes = 0;
+  tform->start_addr = -1;
+  tform->buf_bytes = 0;
+  tform->read = NULL;
+  tform->done = NULL;
+  return 0;
+}
+
+int tform_done(tform_file *tform)
+{
+  if (tform->done)
+    return tform->done(tform);
+
+  fclose(tform->file);
+
+  if (tform->buf)
+    free(tform->buf);
+
+  if (tform->line_buf)
+    free(tform->line_buf);
+
+  return 0;
+};
+
+int tform_read(tform_file *tform)
+{
+  return tform->read(tform);
+}
+
+int tform_read_ihex(tform_file *tform)
+{
+  int cn, len = 0;
+  int addr = 0;
+  unsigned u, v;
+  char *p, *r;
+  char *line = NULL;
+  size_t line_len = 0;
+
+  while (len < tform->buf_len)
+  {
+    if (!tform->line_bytes)
+    {
+      int checksum = 0;
+      int ihex_type = 0;
+
+      tform->line_offs = 0;
+
+      if (getdelim(&line, &line_len, '\n', tform->file) == -1)
+        break;
+
+      p = line;
+
+      if (*p++ != ':')
+        printf("tform_read : strange line %s\n", line);
+      else
+      {
+        if (get_hex(&p, &u, 2) < 0)
+        {
+          printf("tform_read_ihex : bad ihex cnt\n");
+          return -1;
+        }
+
+        checksum += cn = tform->line_bytes = u;
+
+        if (!tform->line_buf)
+          tform->line_buf = malloc(cn);
+        else
+          tform->line_buf = realloc(tform->line_buf, cn);
+
+        if (get_hex(&p, &u, 2) < 0)
+        {
+          printf("tform_read_ihex : bad ihex addr\n");
+          return -1;
+        }
+
+        if (get_hex(&p, &v, 2) < 0)
+        {
+          printf("tform_read_ihex : bad ihex addr\n");
+          return -1;
+        }
+
+        checksum += u + v;
+        tform->line_addr = (u << 8) + v;
+
+        if (get_hex(&p, &u, 2) < 0)
+        {
+          printf("tform_read_ihex : bad ihex type\n");
+          return -1;
+        }
+
+        checksum += ihex_type = u;
+
+        if (ihex_type == 0 || ihex_type == 1)
+        {
+          r = tform->line_buf;
+
+          while (cn--)
+          {
+            if (get_hex(&p, &u, 2) < 0)
+            {
+              printf("tform_read_ihex : bad ihex data\n");
+              return -1;
+            }
+
+            checksum += *r++ = u;
+          }
+
+          if (get_hex(&p, &u, 2) < 0)
+          {
+            printf("tform_read_ihex : bad ihex csum\n");
+            return -1;
+          }
+
+          checksum += u;
+
+          if (checksum & 0xff)
+          {
+            printf("tform_read_ihex : error ihex csum %d\n",
+                   checksum);
+            return -1;
+          }
+
+          while ((u = *p++)) if (u != ' ' && u != '\n' && u != '\r')
+          {
+            printf("tform_read_ihex : residual chars on line\n");
+            return -1;
+          }
+        }
+
+        if (ihex_type == 1)
+        {
+          tform->line_bytes = 0;
+          tform->start_addr = tform->line_addr;
+        }
+      }
+    }
+
+    if (tform->line_bytes)
+    {
+      if (!len)
+        addr = tform->buf_addr = tform->line_addr + tform->line_offs;
+      else if (addr != tform->line_addr + tform->line_offs)
+        break;
+
+      cn = tform->line_bytes - tform->line_offs;
+
+      if (cn + len > tform->buf_len) cn = tform->buf_len - len;
+
+      memcpy(tform->buf + len, tform->line_buf + tform->line_offs, cn);
+      len += cn;
+      addr += cn;
+      tform->line_offs += cn;
+
+      if (tform->line_bytes == tform->line_offs)
+        tform->line_bytes = 0;
+    }
+  }
+
+  tform->buf_bytes = len;
+
+  return len;
+}
+
+int tform_read_binary(tform_file *tform)
+{
+  int len = 0;
+
+  tform->buf_addr += tform->buf_bytes;
+  len = fread(tform->buf, 1, tform->buf_len, tform->file);
+
+  if (len < 0)
+  {
+    perror("tform_read_binary : read error");
+    return -1;
+  }
+
+  tform->buf_bytes = len;
+  return len;
+}
+
+int tform_open(tform_file *tform, char *file_name,
+               char *format, int buf_len, int wr_fl)
+{
+  FILE *file;
+
+  if (!format || !strcmp("ihex", format))
+  {
+    if ((file = fopen(file_name, "r")) == NULL)
+    {
+      perror("download_file : hex file open");
+      return -1;
+    }
+
+    tform_init(tform, buf_len);
+    tform->file = file;
+    tform->read = tform_read_ihex;
+  }
+  else if (!strcmp("binary", format))
+  {
+    if ((file = fopen(file_name, "rb")) == NULL)
+    {
+      perror("download_file : binary file open");
+      return -1;
+    };
+
+    tform_init(tform, buf_len);
+    tform->file = file;
+    tform->read = tform_read_binary;
+  }
+  else
+  {
+    fprintf(stderr, "requested unknown format %s\n", format);
+    return -1;
+  }
+
+  return 1;
+}
+
+
+/*****************************************************************************/
+/*****************************************************************************/
+/*****************************************************************************/
+/* USB functions */
+void print_devices(void)
+{
+  struct usb_bus *bus;
+  struct usb_device *dev;
+  int i = 0;
+
+  usb_init(); // NO for more devices
+  usb_find_busses();
+  usb_find_devices();
+
+  printf("All connected usb devices\n");
+  printf("  bus/device    idVendor/idProduct\n");
+
+  for (bus = usb_busses; bus; bus = bus->next)
+  {
+    for (dev = bus->devices; dev; dev = dev->next)
+    {
+      i++;
+      printf("    %s/%s     0x%04X/0x%04X\n", bus->dirname, dev->filename, dev->descriptor.idVendor, dev->descriptor.idProduct);
+    }
+  }
+
+  if (!i)
+    printf(" -- no device.\n");
+}
+
+struct usb_device *find_usb_device(int vendor, int product)
+{
+  struct usb_bus *bus;
+  struct usb_device *dev;
+
+  for (bus = usb_busses; bus; bus = bus->next)
+  {
+    for (dev = bus->devices; dev; dev = dev->next)
+    {
+      if ((dev->descriptor.idVendor == vendor) &&
+          (dev->descriptor.idProduct) == product)
+        return dev;
+    }
+  }
+
+  return NULL;
+}
+
+usb_dev_handle *usb_open_device(int uvid, int upid)
+{
+  struct usb_device *dev;
+  usb_dev_handle *hdev;
+
+  usb_init(); // NO for more devices
+  usb_find_busses();
+  usb_find_devices();
+
+  dev = find_usb_device(uvid, upid);
+
+  if (!dev)
+  {
+    if (verbose)
+      printf("!!! Cannot find device 0x%04X:0x%04X\n", uvid, upid);
+
+    return NULL;
+  }
+
+  if ((hdev = usb_open(dev)) == NULL)
+  {
+    if (verbose)
+      printf("!!! USB device wasn't opened !!!\n");
+
+    return NULL;
+  }
+
+  usb_claim_interface(hdev, 0);
+
+  if (verbose)
+    printf(" USB Device 0x%04X:0x%04X '%s' is open.\n", uvid, upid, dev->filename);
+
+  return hdev;
+}
+
+int usb_close_device(usb_dev_handle *hdev)
+{
+  int bRes = 1;
+  usb_release_interface(hdev, 0);
+  bRes = usb_close(hdev);
+
+  if (bRes && verbose)
+    printf("!!! USB Device wasn't closed !!!\n");
+
+  return bRes;
+}
+
+/*****************************************************************************/
+/*****************************************************************************/
+/*****************************************************************************/
+
+int download_file(char *file_name, char *format)
+{
+  usb_dev_handle *hdev;
+  tform_file tform;
+  int len;
+  int i;
+  int ret = 0;
+//  int stamp;
+  unsigned long shift_addr = 0;
+
+  struct timeval time1, time2;
+  struct timezone tz;
+
+  shift_addr = mem_start;
+
+  hdev = usb_open_device(vid, pid);
+
+  if (!hdev)
+  {
+    perror("download_file : usb device open failed");
+    return -1;
+  }
+
+  /* ul_drv_debflg(ul_fd,0x11); */ /* 0x9 0x11 */
+
+  if (tform_open(&tform, file_name, format, max_block, 0) < 0)
+  {
+    usb_close_device(hdev);
+    return -1;
+  }
+
+  gettimeofday(&time1, &tz);
+
+  do
+  {
+    len = tform_read(&tform);
+
+    if (!len) break;
+
+    if (len < 0)
+    {
+      perror("download_file : ihex");
+      ret = -1;
+      break;
+    }
+
+    printf("addr %4lX len %4X\n", tform.buf_addr + shift_addr, len);
+
+    /* send data */
+
+    //  if((stamp=ul_new_memrq_write(ul_fd,module,mem_type,
+    //     tform.buf_addr+shift_addr,len,tform.buf))<0)
+    //  { printf("download_file : send message error\n");
+    //    ret=-1; break;
+    //  };
+    i = 3;
+
+    do
+    {
+      ret = usb_control_msg(hdev, USB_TYPE_VENDOR | USB_RECIP_DEVICE | USB_ENDPOINT_OUT, USB_VENDOR_GET_SET_MEMORY | mem_type /*USB_VENDOR_TARGET_XDATA*/,
+                            (unsigned long)(tform.buf_addr + shift_addr) & 0xffff, (((unsigned long)(tform.buf_addr + shift_addr)) >> 16) & 0xffff, (void *)tform.buf, len, 150 + len); //USB_TIMEOUT);
+//      ret = usb_bulk_write( hdev, USB_ENDPOINT_IN | 0x02, buf, len, 1000);
+
+      if (verbose && ret < 0)  printf("Mem read error %d - again\n", ret);
+
+      i--;
+    }
+    while (ret < 0 && i);
+
+  }
+  while (1);
+
+  gettimeofday(&time2, &tz);
+
+  if (verbose)
+  {
+    long dus = (time2.tv_sec * 1000000 + time2.tv_usec) - (time1.tv_sec * 1000000 + time1.tv_usec);
+    printf("Upload time %lu.%lu s\n", dus / 1000000, dus % 1000000);
+  }
+
+
+  if (tform.start_addr != -1)
+    printf("Found start address %4X\n", tform.start_addr);
+
+  tform_done(&tform);
+  usb_close_device(hdev);
+  return ret;
+}
+
+int send_cmd_call(int cmd, int val)
+{
+  int ret, resp_val;
+  usb_dev_handle *hdev;
+  char resp[10];
+
+  hdev = usb_open_device(vid, pid);
+
+  if (!hdev)
+  {
+    perror("send_cmd_call : USB open failed");
+    return -1;
+  }
+
+  ret = usb_control_msg(hdev, USB_TYPE_VENDOR | USB_RECIP_DEVICE | USB_ENDPOINT_IN,
+                        USB_VENDOR_CALL, val & 0xffff, cmd & 0xffff, resp, sizeof(resp), USB_TIMEOUT);
+  resp_val = usb_swab16(*((uint16_t *)(resp)));
+
+  if (ret < 0)
+    printf("Call %4X (%4X) ERROR %d: %s\n", (uint16_t)(cmd & 0xffff), (uint16_t)(val & 0xffff), ret, usb_strerror());
+  else
+    printf("Call %4X (%4X): %4X\n", (uint16_t)(cmd & 0xffff), (uint16_t)(val & 0xffff), resp_val);
+
+  usb_close_device(hdev);
+  return ret;
+}
+
+int send_cmd_go(unsigned long addr)
+{
+  int ret;
+  usb_dev_handle *hdev;
+
+  hdev = usb_open_device(vid, pid);
+
+  if (!hdev)
+  {
+    perror("send_cmd_go : USB open failed");
+    return -1;
+  }
+
+  ret = usb_control_msg(hdev, USB_TYPE_VENDOR | USB_RECIP_DEVICE | USB_ENDPOINT_IN,
+                        USB_VENDOR_GOTO, addr & 0xffff, (addr >> 16) & 0xffff, NULL, 0, USB_TIMEOUT);
+
+  if (ret < 0) printf("Goto to %4lX ERROR %d: %s\n", addr, ret, usb_strerror());
+  else printf("Goto to %4lX OK\n", addr);
+
+  usb_close_device(hdev);
+  return ret;
+}
+
+int send_cmd_reset()
+{
+  int ret;
+  usb_dev_handle *hdev;
+
+  hdev = usb_open_device(vid, pid);
+
+  if (!hdev)
+  {
+    perror("send_cmd_reset : USB open failed");
+    return -1;
+  }
+
+  ret = usb_control_msg(hdev, USB_TYPE_VENDOR | USB_RECIP_DEVICE | USB_ENDPOINT_IN,
+                        USB_VENDOR_RESET_DEVICE, 0, 0, NULL, 0, USB_TIMEOUT);
+
+  if (ret < 0)
+    printf("Reset device ERROR %d: %s\n", ret, usb_strerror());
+  else
+    printf("Reset OK\n");
+
+  usb_close_device(hdev);
+  return ret;
+};
+
+
+int send_cmd_regerase(unsigned long addr, unsigned long len)
+{
+  int ret;
+  usb_dev_handle *hdev;
+
+  hdev = usb_open_device(vid, pid);
+
+  if (!hdev)
+  {
+    perror("send_cmd_regerase : USB open failed");
+    return -1;
+  }
+
+  if (addr + len < 0x10000)
+  {
+    ret = usb_control_msg(hdev, USB_TYPE_VENDOR | USB_RECIP_DEVICE | USB_ENDPOINT_IN,
+                          USB_VENDOR_ERASE_MEMORY, addr, len, NULL, 0, USB_TIMEOUT * 5);
+  }
+  else
+  {
+    len += addr & 0x3ff;
+    ret = usb_control_msg(hdev, USB_TYPE_VENDOR | USB_RECIP_DEVICE | USB_ENDPOINT_IN,
+                          USB_VENDOR_ERASE_1KB_MEMORY, addr >> 10, len >> 10, NULL, 0, USB_TIMEOUT * 10);
+  }
+
+  if (ret < 0)
+    printf("Region Erase from %4lX ERROR %d: %s\n", addr, ret, usb_strerror());
+  else
+    printf("Region Erase from %4lX OK\n", addr);
+
+  usb_close_device(hdev);
+  return ret;
+};
+
+
+
+int send_cmd_masserase(unsigned long mode)
+{
+  int ret;
+  usb_dev_handle *hdev;
+
+  hdev = usb_open_device(vid, pid);
+
+  if (!hdev)
+  {
+    perror("send_cmd_masserase : USB open failed");
+    return -1;
+  };
+
+  ret = usb_control_msg(hdev, USB_TYPE_VENDOR | USB_RECIP_DEVICE | USB_ENDPOINT_IN,
+                        USB_VENDOR_MASS_ERASE, mode & 0xffff, (mode >> 16) & 0xffff, NULL, 0, USB_TIMEOUT * 20);
+
+  if (ret < 0)
+    printf("Mass Erase to %4lX ERROR %d: %s\n", mode, ret, usb_strerror());
+  else printf("Mass Erase to %4lX OK\n", mode);
+
+  usb_close_device(hdev);
+  return ret;
+};
+
+
+int upload_file(char *file_name, char *format)
+{
+  usb_dev_handle *hdev;
+  FILE *file;
+  int ret = 0;
+  unsigned char buf[0x400];
+  unsigned char *p;
+  char *mode = "w";
+  enum {fmt_ihex, fmt_binary, fmt_dump} fmt;
+  int i, l, csum;
+  unsigned long mem_adr = mem_start;
+  unsigned long mem_len = mem_length;
+  unsigned long len;
+
+  struct timeval time1, time2;
+  struct timezone tz;
+
+  if (max_block > 0x400)
+    max_block = 0x400;
+
+  if (!format || !strcmp("ihex", format))
+    fmt = fmt_ihex;
+  else if (!strcmp("binary", format))
+  {
+    mode = "wb";
+    fmt = fmt_binary;
+  }
+  else if (!strcmp("dump", format))
+    fmt = fmt_dump;
+  else
+  {
+    fprintf(stderr, "requested unknown format %s\n", format);
+    return -1;
+  }
+
+  if (!strcmp(file_name, "-"))
+    file_name = NULL;
+
+  hdev = usb_open_device(vid, pid);
+
+  if (!hdev)
+  {
+    perror("upload_file : open failed");
+    return -1;
+  };
+
+  /* ul_drv_debflg(ul_fd,0x11); */ /* 0x9 0x11 */
+
+  if (file_name)
+  {
+    if ((file = fopen(file_name, mode)) == NULL)
+    {
+      perror("upload_file : file open");
+      usb_close_device(hdev);
+      return -1;
+    }
+  }
+  else file = stdout;
+
+  gettimeofday(&time1, &tz);
+
+//  ret = usb_control_msg( hdev, USB_TYPE_VENDOR | USB_RECIP_DEVICE | USB_ENDPOINT_IN, USB_VENDOR_MEMORY_BY_BULK | USB_VENDOR_TARGET_XDATA,
+//                            mem_adr & 0xffff, mem_len, NULL, 0, 2000); //USB_TIMEOUT);
+
+  if (ret < 0)
+  {
+    printf("ERR ctrl msg\n");
+    mem_len = 0;
+  }
+
+  while (mem_len)
+  {
+    len = mem_len < max_block ? mem_len : max_block;
+    /* read data */
+    i = 3;
+
+    do
+    {
+      ret = usb_control_msg(hdev, USB_TYPE_VENDOR | USB_RECIP_DEVICE | USB_ENDPOINT_IN, USB_VENDOR_GET_SET_MEMORY | mem_type /*USB_VENDOR_TARGET_XDATA*/,
+                            mem_adr & 0xffff, (mem_adr >> 16) & 0xffff, (void *)buf, len, 100 + len); //USB_TIMEOUT);
+//      ret = usb_bulk_read( hdev, USB_ENDPOINT_IN | 0x02, buf, len, 1000);
+
+      if (verbose && ret < 0)
+        printf("Mem read error - again\n");
+
+      i--;
+    }
+    while (ret < 0 && i);
+
+    if (ret < 0)
+    {
+      printf("Mem read returns %d: %s\n", ret, usb_strerror());
+      break;
+    }
+
+    if (file_name) printf("%04lX\n", mem_adr);
+
+    switch (fmt)
+    {
+      case fmt_ihex:
+        p = buf;
+        i = 0;
+
+        while (i < len)
+        {
+          l = len - i;
+
+          if (l > 16) l = 16;
+
+          csum = l + (mem_adr + i) + ((mem_adr + i) >> 8);
+          fprintf(file, ":%02X%04lX00", l, (mem_adr + i) & 0xffff);
+
+          while (l--)
+          {
+            fprintf(file, "%02X", buf[i]);
+            csum += buf[i++];
+          };
+
+          fprintf(file, "%02X\n", (-csum) & 0xFF);
+        }
+
+        break;
+
+      case fmt_binary:
+        if (fwrite(buf, len, 1, file) != 1)
+        {
+          perror("upload_file : file write");
+          return -1;
+        }
+
+        break;
+
+      case fmt_dump:
+        i = 0;
+        p = buf;
+
+        while (i < len)
+        {
+          if (i & 0xf) printf(" %02X", *(p++));
+          else printf(i ? "\n%04lX:%02X" : "%04lX:%02X", mem_adr + i, *(p++));
+
+          i++;
+        }
+
+        printf("\n");
+        break;
+    }
+
+    mem_adr += len;
+    mem_len -= len;
+  }
+
+  gettimeofday(&time2, &tz);
+
+  if (verbose)
+  {
+    long dus = (time2.tv_sec * 1000000 + time2.tv_usec) - (time1.tv_sec * 1000000 + time1.tv_usec);
+    printf("Upload time %lu.%lu s\n", dus / 1000000, dus % 1000000);
+  }
+
+  if (file_name)
+    fclose(file);
+
+  usb_close_device(hdev);
+
+  return 0;
+};
+
+static int wait_for_device(int timeout)
+{
+  usb_dev_handle *hdev;
+
+  while (timeout)
+  {
+    hdev = usb_open_device(vid, pid);
+
+    if (hdev)
+      break;
+
+#ifdef _WIN32
+    Sleep(1000);
+#else
+    sleep(1);
+#endif
+    timeout--;
+  }
+
+  return timeout ? 0 : -1;
+}
+
+/*****************************************************************************/
+/*****************************************************************************/
+/*****************************************************************************/
+
+static void
+usage(void)
+{
+  printf("Usage: usb_sendhex <parameters> <hex_file>\n");
+  printf("  -d, --vid <num>          device vendor id (VID) [0x%04X]\n", USB_DEV_VID);
+  printf("  -i, --pid <num>          product id (PID) [0x%04X]\n", USB_DEV_PID);
+  printf("  -t, --type <num>         target module memory space\n");
+  printf("  -s, --start <addr>       start address of transfer\n");
+  printf("  -l, --length <num>       length of upload block\n");
+  printf("  -b, --block <num>        maximal block length\n");
+  printf("  -c, --call <num>         vendor custom call\n");
+  printf("  -a, --argument <num>     argument for vendor custom call\n");
+  printf("  -g, --go <addr>          start program from address\n");
+  printf("  -r, --reset              reset before download\n");
+  printf("  -E, --mass-erase <mode>  full device erase\n");
+  printf("  -e, --erase                     erase region defined by -s -l\n");
+  printf("  -u, --upload             upload memory block [download]\n");
+  printf("  -w, --wait               wait for device to be on\n");
+  printf("  -f, --format <format>    format of data file [ihex]\n");
+  printf("  -p, --print              print devices\n");
+  printf("      --debug-kernel <m>   flags to debug kernel\n");
+  printf("  -v, --verbose            verbose program\n");
+  printf("  -V, --version            show version\n");
+  printf("  -h, --help               this usage screen\n");
+}
+
+int main(int argc, char *argv[])
+{
+  static struct option long_opts[] =
+  {
+    { "vid", 1, 0, 'd' },
+    { "pid", 1, 0, 'i' },
+    { "type",  1, 0, 't' },
+    { "start", 1, 0, 's' },
+    { "length", 1, 0, 'l' },
+    { "block", 1, 0, 'b' },
+    { "call", 1, 0, 'c' },
+    { "argument", 1, 0, 'a' },
+    { "go",    1, 0, 'g' },
+    { "reset", 0, 0, 'r' },
+    { "mass-erase", 1, 0, 'E' },
+    { "erase", 0, 0, 'e' },
+    { "upload", 0, 0, 'u' },
+    { "wait", 0, 0, 'w' },
+    { "format", 1, 0, 'f' },
+    { "print", 0, 0, 'p' },
+    { "verbose", 0, 0, 'v' },
+    { "version", 0, 0, 'V' },
+    { "help",  0, 0, 'h' },
+    { "debug-kernel", 1, 0, 'D' },
+    { 0, 0, 0, 0}
+  };
+  int opt;
+
+#ifndef HAS_GETOPT_LONG
+  while ((opt = getopt(argc, argv, "d:i:t:s:l:b:c:a::g:rE:euwf:pvVhD:")) != EOF)
+#else
+  while ((opt = getopt_long(argc, argv, "d:i:t:s:l:b:c:a:g:rE:euwf:pvVh", &long_opts[0], NULL)) != EOF)
+#endif
+
+    switch (opt)
+    {
+      char *p;
+      case 'd':
+        vid = strtol(optarg, &p, 16);
+
+        if (!p || (p == optarg))
+        {
+          printf("usb_sendhex : vendor ID is not hexadecimal number\n");
+          exit(1);
+        }
+
+        if (*p == ':')
+        {
+          char *r = p + 1;
+          pid = strtol(r, &p, 16);
+
+          if (!p || (p == r))
+          {
+            printf("usb_sendhex : product ID is not hexadecimal number\n");
+            exit(1);
+          }
+        }
+
+        break;
+      case 'i':
+        pid = strtol(optarg, &p, 16);
+        break;
+      case 't':
+        mem_type = strtol(optarg, NULL, 0);
+        break;
+      case 's':
+        mem_start = strtoul(optarg, NULL, 0);
+        break;
+      case 'l':
+        mem_length = strtoul(optarg, NULL, 0);
+        break;
+      case 'b':
+        max_block = strtoul(optarg, NULL, 0);
+        break;
+      case 'c':
+        call = strtoul(optarg, NULL, 0);
+        call_flg = 1;
+        break;
+      case 'a':
+        arg = strtoul(optarg, NULL, 0);
+        break;
+      case 'g':
+        go_addr = strtoul(optarg, NULL, 0);
+        go_flg = 1;
+        break;
+      case 'r':
+        reset_flg = 1;
+        break;
+      case 'E':
+        masserase_mode = strtoul(optarg, NULL, 0);
+        masserase_flg = 1;
+        break;
+      case 'e':
+        regerase_flg = 1;
+        break;
+      case 'u':
+        upload_flg = 1;
+        break;
+      case 'w':
+        wait_for_device_flg = 1;
+        break;
+      case 'f':
+        file_format = optarg;
+        break;
+      case 'p':
+        prt_modules = 1;
+        break;
+      case 'D':
+        debugk = strtol(optarg, NULL, 0);
+        debugk_flg = 1;
+        break;
+      case 'v':
+        verbose = 1;
+        break;
+      case 'V':
+        fputs("USB sendhex v.1.1\n", stdout);
+        exit(0);
+      case 'h':
+      default:
+        usage();
+        exit(opt == 'h' ? 0 : 1);
+    }
+
+  if ((optind >= argc) && !go_flg && !call_flg && !prt_modules && !debugk_flg
+      && !masserase_flg && !regerase_flg && !reset_flg)
+  {
+    usage();
+    exit(1);
+  }
+
+  if (prt_modules)
+    print_devices();
+
+  if (wait_for_device_flg)
+    if (wait_for_device(100) < 0)
+      exit(2);
+
+  if (reset_flg)
+    send_cmd_reset();
+
+  if (regerase_flg)
+    send_cmd_regerase(mem_start, mem_length);
+
+  if (masserase_flg)
+    send_cmd_masserase(masserase_mode);
+
+  if (!upload_flg)
+  {
+    while (optind < argc)
+      if (download_file(argv[optind++], file_format) < 0)
+        exit(2);
+  }
+  else
+  {
+    if (optind + 1 != argc)
+    {
+      printf("upload_file : needs exactly one filename\n");
+      exit(1);
+    }
+
+    if (upload_file(argv[optind], file_format) < 0)
+      exit(2);
+  }
+
+  if (call_flg)
+  {
+    if (send_cmd_call(call, arg) < 0)
+      exit(2);
+  }
+
+  if (go_flg)
+  {
+    if (send_cmd_go(go_addr) < 0)
+      exit(2);
+  }
+
+  return 0;
+}
index cfdb561c7337da33bc2ddf0177a008e616b0c613..f67a1c04b07fd2adfbdc0747b9eb1cf79e497774 100644 (file)
@@ -60,11 +60,13 @@ REQ_SRC            := .
 REQ_FIRMWARE       := $(OUT)/imem.bin $(OUT)/imem.asm $(OUT)/dmem.bin $(OUT)/firmware.lst
 
 #===============================================================================
-# Sythesis settings
+# Sythesis settings (SmartXplorer)
 
 XST_GLOB_OPT := AllClockNets
 XST_OPT_LEVEL := 2
+XST_OPT_MODE := Speed
 XST_IOB_PACKING := False
+XST_POWER := NO
 XST_KEEP_HIEARCHY := No
 XST_NETLIST_HIEARCHY := As_Optimized
 XST_READ_CORES := YES
@@ -72,7 +74,7 @@ XST_WRITE_TIMING_CONSTRAINTS := NO
 XST_CROSS_CLOCK_ANALYSIS := NO
 XST_CASE := Maintain
 XST_REDUCE_CONTROL_SETS := Auto
-XST_REGISTER_DUPLICATION := Yes
+XST_REGISTER_DUPLICATION := YES
 XST_REGISTER_BALANCING := Yes
 XST_MOVE_FIRST_STAGE := YES
 XST_MOVE_LAST_STAGE := YES
@@ -83,7 +85,15 @@ XST_IOBUF := YES
 XST_MAX_FANOUT := 100000
 XST_RESOURCE_SHARING := YES
 XST_SLICE_UTILIZATION_RATIO_MARGIN := 5
-
+XST_SLICE_UTILIZATION_RATIO := 100
+XST_BRAM_UTILIZATION_RATIO := 100
+XST_DSP_UTILIZATION_RATIO := 100
+XST_USE_DSP48 := Auto
+XST_USE_SYNC_SET := Auto
+XST_USE_SYNC_RESET := Auto
+XST_SAFE_IMPLEMENTATION := No
+
+MAP_PLACER_COST_TABLE := 2
 MAP_LOGIC_OPT := on
 MAP_GLOBAL_OPT := off
 MAP_EQUIVALENT_REGISTER_REMOVAL := off
@@ -100,9 +110,9 @@ TARGET_OBJDUMP := $(MB_CROSS_COMPILE)objdump
 
 C_OBJS := $(OUT)/firmware.o
 A_OBJS :=
-CFLAGS := -mxl-soft-div -msoft-float -mno-xl-soft-mul -mxl-barrel-shift -Wno-main -Wl,-no-check-sections -fno-zero-initialized-in-bss -g -O2 -Wall
+CFLAGS := -mxl-soft-div -msoft-float -Wno-main -Wl,-no-check-sections -ffunction-sections -fno-zero-initialized-in-bss -g -O2 -Wall
 AFLAGS := -D__ASSEMBLY__ $(CFLAGS)
-LDFLAGS := -static -nostdlib -defsym _STACK_SIZE=0x0200
+LDFLAGS := -static -nostdlib -relax -defsym _STACK_SIZE=0x0200 --gc-sections
 
 OBJS := $(OUT)/start.o $(C_OBJS) $(A_OBJS)
 
@@ -133,10 +143,11 @@ re-synthesize $(REQ_NGC): $(addprefix $(REQ_SRC)/,$(PRJ))
          -ofmt NGC \
          -top $(TOP) \
          -p $(DEVICE) \
-         -opt_mode Speed \
          -keep_hierarchy $(XST_KEEP_HIEARCHY) \
          -glob_opt $(XST_GLOB_OPT) \
+         -opt_mode $(XST_OPT_MODE) \
          -opt_level $(XST_OPT_LEVEL) \
+         -power $(XST_POWER) \
          -iob $(XST_IOB_PACKING) \
          -read_cores $(XST_READ_CORES) \
          -write_timing_constraints $(XST_WRITE_TIMING_CONSTRAINTS) \
@@ -153,7 +164,10 @@ re-synthesize $(REQ_NGC): $(addprefix $(REQ_SRC)/,$(PRJ))
          -optimize_primitives $(XST_OPTIMIZE_PRIMITIVES) \
          -use_clock_enable $(XST_USE_CLOCK_ENABLE) \
          -equivalent_register_removal $(XST_EQUIVALENT_REGISTER_REMOVAL) \
-         -slice_utilization_ratio_maxmargin $(XST_SLICE_UTILIZATION_RATIO_MARGIN)" | xst | tee xst.log
+         -slice_utilization_ratio_maxmargin $(XST_SLICE_UTILIZATION_RATIO_MARGIN) \
+         -slice_utilization_ratio $(XST_SLICE_UTILIZATION_RATIO) \
+         -bram_utilization_ratio $(XST_BRAM_UTILIZATION_RATIO) \
+         -dsp_utilization_ratio $(XST_DSP_UTILIZATION_RATIO)" | xst | tee xst.log
 
 .PHONY: re-translate
 re-translate $(REQ_NGD): $(REQ_NGC) $(REQ_UCF)
@@ -166,7 +180,7 @@ re-translate $(REQ_NGD): $(REQ_NGC) $(REQ_UCF)
 .PHONY: re-map
 re-map $(REQ_NCD_MAP) $(REQ_PCF): $(REQ_NGD)
        cd $(OUT); \
-       map -w -intstyle $(INTSTYLE) -p $(DEVICE) -logic_opt $(MAP_LOGIC_OPT) -ol high -t 1 -xt 0 \
+       map -w -intstyle $(INTSTYLE) -p $(DEVICE) -logic_opt $(MAP_LOGIC_OPT) -ol high -t $(MAP_PLACER_COST_TABLE) -xt 0 \
          -r 4 -global_opt $(MAP_GLOBAL_OPT) -mt off -ir off -pr off -lc $(MAP_LUT_COMBINING) \
          -power off -equivalent_register_removal $(MAP_EQUIVALENT_REGISTER_REMOVAL) \
          -o $(NCD_MAP) $(NGD) $(PCF) | tee map.log
@@ -174,7 +188,7 @@ re-map $(REQ_NCD_MAP) $(REQ_PCF): $(REQ_NGD)
 .PHONY: re-par
 re-par $(REQ_NCD): $(REQ_NCD_MAP) $(REQ_PCF)
        cd $(OUT); \
-       par -w -intstyle $(INTSTYLE) -ol high -mt off $(NCD_MAP) $(NCD) $(PCF) | tee par.log
+       par -w -intstyle $(INTSTYLE) -ol high -xe n -mt off $(NCD_MAP) $(NCD) $(PCF) | tee par.log
 
 .PHONY: re-gen
 re-gen $(REQ_BIN): $(REQ_NCD)
diff --git a/hw/bus_calibration.vhd b/hw/bus_calibration.vhd
deleted file mode 100644 (file)
index 2c63a6a..0000000
+++ /dev/null
@@ -1,146 +0,0 @@
-library ieee;
-use ieee.std_logic_1164.all;
-use ieee.std_logic_arith.all;
-use ieee.std_logic_unsigned.all;
-use ieee.numeric_std.all;
-use work.lx_rocon_pkg.all;
-
--- Memory bus calibration
--- Holds the signal for one clock to simulate longest route
-
-entity bus_calibration is
-       port
-       (
-               -- Clock
-               clk_i     : in std_logic;
-               -- Reset
-               reset_i   : in std_logic;
-               -- Chip enable
-               ce_i      : in std_logic;
-               -- Address
-               address_i : in std_logic_vector(1 downto 0);
-               -- Data bus
-               data_i    : in std_logic_vector(31 downto 0);
-               data_o    : out std_logic_vector(31 downto 0);
-               -- Bus signals
-               rd_i      : in std_logic;
-               bls_i     : in std_logic_vector(3 downto 0);
-               ta_o      : out std_logic
-       );
-end bus_calibration;
-
-architecture Behavioral of bus_calibration is
-
-       -- Wiring
-       signal read1_out_s  : std_logic_vector(31 downto 0);
-       signal read1_ta_s   : std_logic;
-
-       signal read2_out_s  : std_logic_vector(31 downto 0);
-       signal read2_ta_s   : std_logic;
-
-       signal write1_out_s : std_logic_vector(31 downto 0);
-       signal write1_ta_s  : std_logic;
-       signal write1_ce_s  : std_logic;
-
-       signal write2_out_s : std_logic_vector(31 downto 0);
-       signal write2_ta_s  : std_logic;
-       signal write2_ce_s  : std_logic;
-
-begin
-
-       -- First read calibration register (0xAAAAAAAA)
-       memory_bus_calib_read1: calibration_read_register
-       generic map
-       (
-               id_g   => "10101010101010101010101010101010"
-       )
-       port map
-       (
-               rd_i   => rd_i,
-               ta_o   => read1_ta_s,
-               data_o => read1_out_s
-       );
-
-       -- Second read calibration register (=0x55555555)
-       memory_bus_calib_read2: calibration_read_register
-       generic map
-       (
-               id_g   => "01010101010101010101010101010101"
-       )
-       port map
-       (
-               rd_i   => rd_i,
-               ta_o   => read2_ta_s,
-               data_o => read2_out_s
-       );
-
-       -- First write calibration register
-       memory_bus_calib_write1: calibration_write_register
-       port map
-       (
-               clk_i   => clk_i,
-               ce_i    => write1_ce_s,
-               reset_i => reset_i,
-               rd_i    => rd_i,
-               bls_i   => bls_i,
-               ta_o    => write1_ta_s,
-               data_i  => data_i,
-               data_o  => write1_out_s
-       );
-
-       -- Second write calibration register
-       memory_bus_calib_write2: calibration_write_register
-       port map
-       (
-               clk_i   => clk_i,
-               ce_i    => write2_ce_s,
-               reset_i => reset_i,
-               rd_i    => rd_i,
-               bls_i   => bls_i,
-               ta_o    => write2_ta_s,
-               data_i  => data_i,
-               data_o  => write2_out_s
-       );
-
-       -- Processes
-update:
-       process (clk_i)
-       begin
-
-               if clk_i = '1' and clk_i'event then
-
-                       -- Defaults
-                       write1_ce_s <= '0';
-                       write2_ce_s <= '0';
-                       ta_o        <= '0';
-                       data_o      <= (others => 'X');
-
-                       -- Chip Enable
-                       -- This will delay the register read / write
-                       if ce_i = '1' then
-                               case address_i is
-                                       when "00" =>  -- Read1
-                                               ta_o        <= read1_ta_s;
-                                               data_o      <= read1_out_s;
-                                       when "01" =>  -- Read2
-                                               ta_o        <= read2_ta_s;
-                                               data_o      <= read2_out_s;
-                                       when "10" => -- Write1
-                                               write1_ce_s <= '1';
-                                               ta_o        <= write1_ta_s;
-                                               data_o      <= write1_out_s;
-                                       when "11" =>  -- Write2
-                                               write2_ce_s <= '1';
-                                               ta_o        <= write2_ta_s;
-                                               data_o      <= write2_out_s;
-                                       when others =>
-                                               null;
-                               end case;
-                       end if;
-
-               end if;
-
-       end process;
-
-end Behavioral;
-
index 8ca630abddc930dc26bc6a8af7f278801022dc6c..6eb65fc4329c5c044d82d699bab5d3d330719d79 100644 (file)
@@ -2,7 +2,7 @@ library ieee;
 use ieee.std_logic_1164.all;
 use ieee.std_logic_unsigned.all;
 use ieee.numeric_std.all;
-use work.mbl_Pkg.all;
+use work.mbl_pkg.all;
 use work.lx_rocon_pkg.all;
 
 -- IRC bus interconnect
@@ -11,199 +11,206 @@ entity bus_irc is
        (
                clk_i        : in std_logic;
                reset_i      : in std_logic;
-               -- Address (needs just last 4 bits, rest is wired to CE)
-               address_i    : in std_logic_vector(3 downto 0);
-               ce_i         : in std_logic;
                -- Data bus
+               address_i    : in std_logic_vector(3 downto 0);
+               next_ce_i    : in std_logic;
                data_i       : in std_logic_vector(31 downto 0);
                data_o       : out std_logic_vector(31 downto 0);
-               -- Bus signals
-               rd_i         : in std_logic;
+               --
                bls_i        : in std_logic_vector(3 downto 0);
-               ta_o         : out std_logic;
                -- Signals for IRC
-               irc1_i       : in IRC_INPUT_Type;
-               irc2_i       : in IRC_INPUT_Type;
-               irc3_i       : in IRC_INPUT_Type;
-               irc4_i       : in IRC_INPUT_Type;
-               -- Secondary data bus (slave)
-               address_2_i  : in std_logic_vector(3 downto 0);
-               ce_2_i       : in std_logic;
-               --
-               rd_2_i       : in std_logic;
-               bls_2_i      : in std_logic_vector(3 downto 0);
-               ta_2_o       : out std_logic
+               irc_i        : in IRC_INPUT_Array_Type(3 downto 0)
        );
 end bus_irc;
 
 architecture Behavioral of bus_irc is
 
-       signal irc1_s, irc2_s, irc3_s, irc4_s : IRC_OUTPUT_Type;
-       signal reset_index_event_s            : std_logic_vector(3 downto 0);
-       signal reset_ab_error_s               : std_logic_vector(3 downto 0);
-       signal irc_en_s                       : std_logic;
-       signal irc_bls_s                      : std_logic_vector(3 downto 0);
-       signal irc_addr_s                     : std_logic_vector(2 downto 0);
-       signal irc_data_s                     : std_logic_vector(31 downto 0);
-
+       signal irc_o_s             : IRC_OUTPUT_Array_Type(3 downto 0);
+       signal reset_index_event_s : std_logic_vector(3 downto 0);
+       signal reset_ab_error_s    : std_logic_vector(3 downto 0);
+       signal state_o_s           : std_logic_vector(1 downto 0);
+       signal state_o_r           : std_logic_vector(1 downto 0);
+       --
+       signal irc_en_s            : std_logic;
+       signal irc_bls_s           : std_logic_vector(3 downto 0);
+       signal irc_addr_s          : std_logic_vector(2 downto 0);
+       signal irc_data_s          : std_logic_vector(31 downto 0);
+       signal irc_out_s           : std_logic;
+       signal irc_out_r           : std_logic;
+       --
+       signal reset_reg_s         : std_logic;
+       signal reset_reg_r         : std_logic;
+       signal reset_reg_wr_s      : std_logic;
+       signal reset_s             : std_logic;
+       signal ce_s                : std_logic;
 begin
 
-       irc1 : irc_reader
+irc1 : irc_reader
        port map
        (
                clk_i               => clk_i,
-               reset_i             => reset_i,
-               irc_i               => irc1_i,
+               reset_i             => reset_s,
+               irc_i               => irc_i(0),
                reset_index_event_i => reset_index_event_s(0),
                reset_ab_error_i    => reset_ab_error_s(0),
-               irc_o               => irc1_s
+               irc_o               => irc_o_s(0)
        );
 
-       irc2 : irc_reader
+irc2 : irc_reader
        port map
        (
                clk_i               => clk_i,
-               reset_i             => reset_i,
-               irc_i               => irc2_i,
+               reset_i             => reset_s,
+               irc_i               => irc_i(1),
                reset_index_event_i => reset_index_event_s(1),
                reset_ab_error_i    => reset_ab_error_s(1),
-               irc_o               => irc2_s
+               irc_o               => irc_o_s(1)
        );
 
-       irc3 : irc_reader
+irc3 : irc_reader
        port map
        (
                clk_i               => clk_i,
-               reset_i             => reset_i,
-               irc_i               => irc3_i,
+               reset_i             => reset_s,
+               irc_i               => irc_i(2),
                reset_index_event_i => reset_index_event_s(2),
                reset_ab_error_i    => reset_ab_error_s(2),
-               irc_o               => irc3_s
+               irc_o               => irc_o_s(2)
        );
 
-       irc4 : irc_reader
+irc4 : irc_reader
        port map
        (
                clk_i               => clk_i,
-               reset_i             => reset_i,
-               irc_i               => irc4_i,
+               reset_i             => reset_s,
+               irc_i               => irc_i(3),
                reset_index_event_i => reset_index_event_s(3),
                reset_ab_error_i    => reset_ab_error_s(3),
-               irc_o               => irc4_s
+               irc_o               => irc_o_s(3)
        );
 
-       irc_proc : irc_proc_main
+irc_proc : irc_proc_main
        port map
        (
-               clk_i              => clk_i,
-               reset_i            => reset_i,
-               irc1_i.qcount      => irc1_s.qcount,
-               irc1_i.index       => irc1_s.index,
-               irc1_i.index_event => irc1_s.index_event,
-               irc2_i.qcount      => irc2_s.qcount,
-               irc2_i.index       => irc2_s.index,
-               irc2_i.index_event => irc2_s.index_event,
-               irc3_i.qcount      => irc3_s.qcount,
-               irc3_i.index       => irc3_s.index,
-               irc3_i.index_event => irc3_s.index_event,
-               irc4_i.qcount      => irc4_s.qcount,
-               irc4_i.index       => irc4_s.index,
-               irc4_i.index_event => irc4_s.index_event,
-               irc_index_reset_o  => reset_index_event_s,
-               -- BRAM access (the other port)
-               mem_clk_i          => clk_i,
-    mem_en_i           => irc_en_s,
-    mem_we_i           => irc_bls_s,
-    mem_addr_i         => irc_addr_s,
-    mem_data_i         => data_i,
-    mem_data_o         => irc_data_s
+               clk_i                => clk_i,
+               reset_i              => reset_s,
+               -- IRC
+               irc_i(0)             => irc_o_s(0).count,
+               irc_i(1)             => irc_o_s(1).count,
+               irc_i(2)             => irc_o_s(2).count,
+               irc_i(3)             => irc_o_s(3).count,
+               irc_index_reset_o    => reset_index_event_s,
+               -- BRAM
+               mem_clk_i            => clk_i,
+               mem_en_i             => irc_en_s,
+               mem_we_i             => irc_bls_s,
+               mem_addr_i           => irc_addr_s,
+               mem_data_i           => data_i,
+               mem_data_o           => irc_data_s
        );
 
-wire:
-       process(ce_i, ce_2_i, rd_i, rd_2_i, bls_i, bls_2_i, address_i, address_2_i, irc_data_s, irc1_s, irc2_s, irc3_s, irc4_s, data_i)
-               variable ce_v      : std_logic;
-               variable rd_v      : std_logic;
-               variable bls_v     : std_logic_vector(3 downto 0);
-               variable address_v : std_logic_vector(3 downto 0);
+       reset_s <= reset_reg_r or reset_i;
+
+wire_in:
+       process(next_ce_i, ce_s, reset_reg_s, bls_i, address_i, irc_data_s, data_i, irc_o_s)
        begin
 
                -- init values
-               data_o           <= (others => 'X');
                irc_en_s         <= '0';
+               irc_out_s        <= '0';
                irc_bls_s        <= (others => '0');
-               irc_addr_s       <= (others => 'X');
+               irc_addr_s       <= (others => '0');
                reset_ab_error_s <= (others => '0');
+               state_o_s        <= (others => 'X');
+               reset_reg_s      <= '0';
+               reset_reg_wr_s   <= '0';
 
-               -- init variables
-               ce_v        := ce_i or ce_2_i;
-
-               if ce_i = '1' then
-                       rd_v      := rd_i;
-                       bls_v     := bls_i;
-                       address_v := address_i;
-               elsif ce_2_i = '1' then
-                       rd_v      := rd_2_i;
-                       bls_v     := bls_2_i;
-                       address_v := address_2_i;
-               else
-                       rd_v      := '0';
-                       bls_v     := (others => '0');
-                       address_v := (others => '0');
-               end if;
-
-               -- Bus request
-               if ce_v = '1' then
+               -- Incoming bus request
+               if next_ce_i = '1' then
                        -- Mapping:
-                       -- 0 & axis & irc / index - (all read from bram) (R/w)
+                       -- 0 & axis & irc / index - (all read from bram) (R/W)
                        -- 1 & axis & 0           - status register (R/W)
-                       if address_v(3) = '0' then
-                               irc_addr_s  <= address_i(2 downto 0);
-                               irc_en_s    <= '1';
-                               irc_bls_s   <= bls_i;
-                               data_o      <= irc_data_s;
-                       elsif address_v(0) = '0' then
-                               if rd_v = '1' then
-
-                                       case address_v(2 downto 1) is
-                                               when "00" =>
-                                                       data_o(0)       <= irc1_s.mark;
-                                                       data_o(1)       <= irc1_s.ab_error;
-                                               when "01" =>
-                                                       data_o(0)       <= irc2_s.mark;
-                                                       data_o(1)       <= irc2_s.ab_error;
-                                               when "10" =>
-                                                       data_o(0)       <= irc3_s.mark;
-                                                       data_o(1)       <= irc3_s.ab_error;
-                                               when "11" =>
-                                                       data_o(0)       <= irc4_s.mark;
-                                                       data_o(1)       <= irc4_s.ab_error;
-                                               when others =>
-                                                       null;
-                                       end case;
-
-                                       data_o(31 downto 2) <= (others => '0');
-
-                               elsif bls_v(0) = '1' and data_i(0) = '1' then
-                                       reset_ab_error_s(to_integer(unsigned(address_v(2 downto 1)))) <= '1';
+                       -- 1 &  00  & 1           - reset
+                       if address_i(3) = '0' then
+
+                               irc_addr_s    <= address_i(2 downto 0);
+                               irc_en_s      <= '1';
+                               irc_bls_s     <= bls_i;
+                               irc_out_s     <= '1';
+
+                       -- Maybe these would be better to latch in next_ce_i cycle,
+                       -- and then just pass them
+                       elsif address_i(0) = '0' then
+
+                               case address_i(2 downto 1) is
+                                       when "00" =>
+                                               state_o_s(0) <= irc_o_s(0).state.mark;
+                                               state_o_s(1) <= irc_o_s(0).state.ab_error;
+                                       when "01" =>
+                                               state_o_s(0) <= irc_o_s(1).state.mark;
+                                               state_o_s(1) <= irc_o_s(1).state.ab_error;
+                                       when "10" =>
+                                               state_o_s(0) <= irc_o_s(2).state.mark;
+                                               state_o_s(1) <= irc_o_s(2).state.ab_error;
+                                       when "11" =>
+                                               state_o_s(0) <= irc_o_s(3).state.mark;
+                                               state_o_s(1) <= irc_o_s(3).state.ab_error;
+                                       when others =>
+                                               null;
+                               end case;
+
+                               if bls_i(0) = '1' and data_i(1) = '1' then
+                                       reset_ab_error_s(to_integer(unsigned(address_i(2 downto 1)))) <= '1';
                                end if;
+                       elsif address_i = "1001" then
+
+                               if bls_i(0) = '1' then
+                                       reset_reg_s    <= data_i(0);
+                                       reset_reg_wr_s <= '1';
+                               else
+                                       -- Ugh, hack :-)
+                                       state_o_s(0)   <= reset_reg_s;
+                                       state_o_s(1)   <= '0';
+                               end if;
+
                        end if;
 
                end if;
        end process;
 
-ta:
-       process(clk_i)
+wire_out:
+       process(ce_s, irc_data_s, irc_out_r, state_o_r)
        begin
-               if clk_i = '1' and clk_i'event then
-                       ta_o <= rd_i;
 
-                       if rd_i = '0' and rd_2_i = '1' then
-                               ta_2_o <= rd_2_i;
-                       else
-                               ta_2_o <= '0';
-                       end if;
+       data_o <= (others => 'X');
+
+       if ce_s = '1' then
 
+               if irc_out_r = '1' then
+                       data_o <= irc_data_s;
+               else
+                       data_o(1 downto 0) <= state_o_r;
                end if;
+
+       end if;
+
+
+       end process;
+
+update:
+       process
+       begin
+               wait until clk_i'event and clk_i= '1';
+               ce_s      <= next_ce_i;
+               irc_out_r <= irc_out_s;
+               state_o_r <= state_o_s;
+
+               if reset_i = '1' then
+                       reset_reg_r <= '1';
+               elsif reset_reg_wr_s = '1' then
+                       reset_reg_r <= reset_reg_s;
+               end if;
+
        end process;
 
 end Behavioral;
diff --git a/hw/bus_lxmaster.vhd b/hw/bus_lxmaster.vhd
new file mode 100644 (file)
index 0000000..948d0a2
--- /dev/null
@@ -0,0 +1,49 @@
+library ieee;
+use ieee.std_logic_1164.all;
+use ieee.std_logic_unsigned.all;
+use ieee.numeric_std.all;
+use work.lx_rocon_pkg.all;
+
+-- LX Master bus interconnect
+entity bus_lxmaster is
+       port
+       (
+               clk_i        : in std_logic;
+               reset_i      : in std_logic;
+               -- Data bus
+               address_i    : in std_logic_vector(8 downto 0);
+               next_ce_i    : in std_logic;
+               data_i       : in std_logic_vector(15 downto 0);
+               data_o       : out std_logic_vector(15 downto 0);
+               --
+               bls_i        : in std_logic_vector(1 downto 0);
+               -- Signals for LX Master
+               mosi_o       : out std_logic;
+               clock_o      : out std_logic;
+               sync_o       : out std_logic
+       );
+end bus_lxmaster;
+
+architecture Behavioral of bus_lxmaster is
+begin
+
+master: lxmaster
+       port map
+       (
+               clk_i            => clk_i,
+               reset_i          => reset_i,
+               --
+               mosi_o           => mosi_o,
+               clock_o          => clock_o,
+               sync_o           => sync_o,
+               -- BRAM
+               mem_clk_i        => clk_i,
+               mem_en_i         => next_ce_i,
+               mem_we_i         => bls_i,
+               mem_addr_i       => address_i,
+               mem_data_i       => data_i,
+               mem_data_o       => data_o
+       );
+
+
+end Behavioral;
diff --git a/hw/bus_measurement.vhd b/hw/bus_measurement.vhd
new file mode 100644 (file)
index 0000000..e681c9f
--- /dev/null
@@ -0,0 +1,99 @@
+library ieee;
+use ieee.std_logic_1164.all;
+use ieee.std_logic_arith.all;
+use ieee.std_logic_unsigned.all;
+use ieee.numeric_std.all;
+use work.lx_rocon_pkg.all;
+
+-- Memory bus measurement
+-- Holds the signal for one clock to simulate longest route
+
+entity bus_measurement is
+       port
+       (
+               -- Clock
+               clk_i     : in std_logic;
+               -- Reset
+               reset_i   : in std_logic;
+               -- Chip enable
+               ce_i      : in std_logic;
+               -- Address
+               address_i : in std_logic_vector(1 downto 0);
+               -- Data bus
+               data_i    : in std_logic_vector(31 downto 0);
+               data_o    : out std_logic_vector(31 downto 0);
+               -- Bus signals
+               bls_i     : in std_logic_vector(3 downto 0)
+       );
+end bus_measurement;
+
+architecture Behavioral of bus_measurement is
+
+       -- Wiring
+       signal meas1_out_s    : std_logic_vector(31 downto 0);
+       signal meas1_ce_s     : std_logic;
+       --
+       signal meas2_out_s    : std_logic_vector(31 downto 0);
+       signal meas2_ce_s     : std_logic;
+
+begin
+
+       -- First measurement register (0xAAAAAAAA)
+measurement1: measurement_register
+       generic map
+       (
+               id_g   => "10101010101010101010101010101010"
+       )
+       port map
+       (
+               clk_i    => clk_i,
+               ce_i     => meas1_ce_s,
+               switch_i => address_i(0),
+               reset_i  => reset_i,
+               bls_i    => bls_i,
+               data_i   => data_i,
+               data_o   => meas1_out_s
+       );
+
+       -- Second measurement register (=0x55555555)
+measurement2: measurement_register
+       generic map
+       (
+               id_g   => "01010101010101010101010101010101"
+       )
+       port map
+       (
+               clk_i    => clk_i,
+               ce_i     => meas2_ce_s,
+               switch_i => address_i(0),
+               reset_i  => reset_i,
+               bls_i    => bls_i,
+               data_i   => data_i,
+               data_o   => meas2_out_s
+       );
+
+-- Bus process
+update:
+       process (ce_i, address_i, meas1_out_s, meas2_out_s)
+       begin
+
+               -- Defaults
+               meas1_ce_s <= '0';
+               meas2_ce_s <= '0';
+               data_o     <= (others => 'X');
+
+               -- Chip Enable
+               if ce_i = '1' then
+                       if address_i(1) = '0' then
+                               meas1_ce_s  <= '1';
+                               data_o      <= meas1_out_s;
+                       else
+                               meas2_ce_s  <= '1';
+                               data_o      <= meas2_out_s;
+                       end if;
+               end if;
+
+       end process;
+
+end Behavioral;
+
index 712cc744e2f5aec246f894c29561cc78e2c44797..2496570c1edda5b1c6ccdc0c42199d504401c9a8 100644 (file)
@@ -4,7 +4,7 @@ use ieee.std_logic_1164.all;
 use ieee.std_logic_arith.all;
 use ieee.std_logic_unsigned.all;
 use ieee.numeric_std.all;
-use work.mbl_Pkg.all;
+use work.mbl_pkg.all;
 use work.lx_rocon_pkg.all;
 
 -- Connects tumbl to the Master CPU
@@ -13,76 +13,53 @@ entity bus_tumbl is
        port
        (
                -- Clock
-               clk_100m_i       : in std_logic;
-               clk_50m_i        : in std_logic;
+               clk_i        : in std_logic;
                -- Chip enable
-               ce_100m_i        : in std_logic;
+               ce_        : in std_logic;
                -- Global Reset
-               reset_100m_i     : in std_logic;
+               reset_     : in std_logic;
                -- Master CPU bus for the memory
-    rd_100m_i        : in std_logic;
-    bls_100m_i       : in std_logic_vector(3 downto 0);
-    address_100m_i   : in std_logic_vector(11 downto 0);
-    data_100m_i      : in std_logic_vector(31 downto 0);
-    data_100m_o      : out std_logic_vector(31 downto 0);
-               ta_100m_o        : out std_logic;
+    bls_i        : in std_logic_vector(3 downto 0);
+    address_i    : in std_logic_vector(11 downto 0);
+    data_i       : in std_logic_vector(31 downto 0);
+    data_o       : out std_logic_vector(31 downto 0);
                -- Tumbl extrenal memory bus
-               xmemb_sel_100m_o : out std_logic;
-               xmemb_100m_i     : in DMEMB2CORE_Type;
-               xmemb_100m_o     : out CORE2DMEMB_Type
+               xmemb_sel_ : out std_logic;
+               xmemb_     : in DMEMB2CORE_Type;
+               xmemb_     : out CORE2DMEMB_Type
   );
 end bus_tumbl;
 
 architecture Behavioral of bus_tumbl is
-
-       -- Internal state
-       -- The following signals are driven by 100M clock
-       signal tumbl_reset_100m_s : std_logic;
-       signal tumbl_halt_100m_s  : std_logic;
-       signal tumbl_int_100m_s   : std_logic;
-       signal tumbl_trace_100m_s : std_logic;
-
-       -- The following signals kick in at 50M clock
-       signal tumbl_reset_50m_s  : std_logic;
-       signal tumbl_halt_50m_s   : std_logic;
-       signal tumbl_int_50m_s    : std_logic;
-       signal tumbl_trace_50m_s  : std_logic;
-
-       -- Trace kick (since this is "one cycle command", it needs req / ack)
-       signal tumbl_trace_kick_50m_s      : std_logic;
-       signal tumbl_trace_kick_ack_50m_s  : std_logic;
-       signal tumbl_trace_kick_req_100m_s : std_logic;
-
-       -- Tumbl PC (copy it with cpu clock and then wire further)
-       signal tumbl_pc_50m_s         : std_logic_vector(31 downto 0);
-
-       -- Halting using halt instruction
-       -- Driven by 50M clock
-       signal tumbl_halted_50m_s     : std_logic;
-       signal tumbl_halt_code_50m_s  : std_logic_vector(4 downto 0);
-
-       -- Tumbl signals under 100M domain
-       -- Driven by 100M clock
-       signal tumbl_pc_100m_s        : std_logic_vector(31 downto 0);
-       signal tumbl_halted_100m_s    : std_logic;
-       signal tumbl_halt_code_100m_s : std_logic_vector(4 downto 0);
+       -- Types
+       type TUMBL_Input_Type is record
+               halt       : std_logic;
+               int        : std_logic;
+               trace      : std_logic;
+               trace_kick : std_logic;
+       end record;
+
+       type TUMBL_State_Type is record
+               pc         : std_logic_vector(31 downto 0);
+               halted     : std_logic;
+               halt_code  : std_logic_vector(4 downto 0);
+       end record;
+
+       -- Reset
+       signal tumbl_reset_s : std_logic;
+       -- Internals
+       signal tumbl_input_s : TUMBL_Input_Type;
+       signal tumbl_state_s : TUMBL_State_Type;
 
        -- Internal memory signals
-       -- Driven by 100M clock
-       signal imem_en_100m_s     : std_logic;
-       signal dmem_en_100m_s     : std_logic;
-
-       signal imem_we_100m_s     : std_logic_vector(3 downto 0);
-       signal dmem_we_100m_s     : std_logic_vector(3 downto 0);
+       signal imem_en_s     : std_logic;
+       signal dmem_en_s     : std_logic;
 
-       signal imem_data_o_100m_s : std_logic_vector(31 downto 0);
-       signal dmem_data_o_100m_s : std_logic_vector(31 downto 0);
+       signal imem_we_s     : std_logic_vector(3 downto 0);
+       signal dmem_we_s     : std_logic_vector(3 downto 0);
 
-       -- Tumbl external memory
-       -- Driven by 50M clock
-       signal xmemb_sel_50m_s    : std_logic;
-       signal xmemb_50m_i_s      : DMEMB2CORE_Type;
-       signal xmemb_50m_o_s      : CORE2DMEMB_Type;
+       signal imem_data_o_s : std_logic_vector(31 downto 0);
+       signal dmem_data_o_s : std_logic_vector(31 downto 0);
 
        -- Internal bus structure
        -- 12 address bits: 2 bits for selection, 10 bits for address
@@ -117,198 +94,142 @@ begin
        I_TUMBL: lx_rocon_tumbl
        generic map
        (
-               IMEM_ABITS_g => 11,
-               DMEM_ABITS_g => 12,
+               IMEM_ABITS_g         => 9,
+               DMEM_ABITS_g         => 10,
                --
-               USE_HW_MUL_g => true,
-               USE_BARREL_g => true,
+               USE_HW_MUL_g         => true,
+               USE_BARREL_g         => true,
                COMPATIBILITY_MODE_g => false
        )
        port map
        (
-               clk_i        => clk_50m_i,
-               rst_i        => tumbl_reset_50m_s,
-               halt_i       => tumbl_halt_50m_s,
-               int_i        => tumbl_int_50m_s,
-               trace_i      => tumbl_trace_50m_s,
-               trace_kick_i => tumbl_trace_kick_50m_s,
+               clk_i        => clk_i,
+               rst_i        => tumbl_reset_s,
+               halt_i       => tumbl_input_s.halt,
+               int_i        => tumbl_input_s.int,
+               trace_i      => tumbl_input_s.trace,
+               trace_kick_i => tumbl_input_s.trace_kick,
 
-               pc_o         => tumbl_pc_50m_s,
-               halted_o     => tumbl_halted_50m_s,
-               halt_code_o  => tumbl_halt_code_50m_s,
+               pc_o         => tumbl_state_s.pc,
+               halted_o     => tumbl_state_s.halted,
+               halt_code_o  => tumbl_state_s.halt_code,
 
                -- Internal memory (instruction)
-               imem_clk_i   => clk_100m_i,
-    imem_en_i    => imem_en_100m_s,
-    imem_we_i    => imem_we_100m_s,
-    imem_addr_i  => address_100m_i(8 downto 0),
-    imem_data_i  => data_100m_i,
-    imem_data_o  => imem_data_o_100m_s,
+               imem_clk_i   => clk_i,
+    imem_en_i    => imem_en_s,
+    imem_we_i    => imem_we_s,
+    imem_addr_i  => address_i(8 downto 0),
+    imem_data_i  => data_i,
+    imem_data_o  => imem_data_o_s,
 
                -- Internal memory (data)
-               dmem_clk_i   => clk_100m_i,
-    dmem_en_i    => dmem_en_100m_s,
-    dmem_we_i    => dmem_we_100m_s,
-    dmem_addr_i  => address_100m_i(9 downto 0),
-    dmem_data_i  => data_100m_i,
-    dmem_data_o  => dmem_data_o_100m_s,
+               dmem_clk_i   => clk_i,
+    dmem_en_i    => dmem_en_s,
+    dmem_we_i    => dmem_we_s,
+    dmem_addr_i  => address_i(9 downto 0),
+    dmem_data_i  => data_i,
+    dmem_data_o  => dmem_data_o_s,
 
                -- External memory bus
-               xmemb_sel_o  => xmemb_sel_50m_s,
-               xmemb_i      => xmemb_50m_i_s,
-               xmemb_o      => xmemb_50m_o_s
+               xmemb_sel_o  => xmemb_sel_o,
+               xmemb_i      => xmemb_i,
+               xmemb_o      => xmemb_o
        );
 
-       -- Enabling
-       enabling: process(ce_100m_i, address_100m_i)
+-- Enabling
+enabling: process(ce_i, address_i)
        begin
 
-               if ce_100m_i = '1' and address_100m_i(11 downto 10) = "00" then
-                       imem_en_100m_s <= '1';
+               if ce_i = '1' and address_i(11 downto 10) = "00" then
+                       imem_en_s <= '1';
                else
-                       imem_en_100m_s <= '0';
+                       imem_en_s <= '0';
                end if;
 
-               if ce_100m_i = '1' and address_100m_i(11 downto 10) = "01" then
-                       dmem_en_100m_s <= '1';
+               if ce_i = '1' and address_i(11 downto 10) = "01" then
+                       dmem_en_s <= '1';
                else
-                       dmem_en_100m_s <= '0';
+                       dmem_en_s <= '0';
                end if;
 
        end process;
 
-       -- Wiring
-       -- NOTE: This is only modifying signals inside 100m domain
-       wiring: process(ce_100m_i, rd_100m_i, bls_100m_i, address_100m_i, imem_en_100m_s, imem_data_o_100m_s, dmem_en_100m_s,
-                                                                       dmem_data_o_100m_s, tumbl_reset_100m_s, tumbl_int_100m_s, tumbl_halt_100m_s, tumbl_trace_100m_s,
-                                                                       tumbl_halted_100m_s, tumbl_halt_code_100m_s, tumbl_pc_100m_s)
+-- Wiring
+wiring:
+       process(ce_i, bls_i, address_i, imem_en_s, imem_data_o_s, dmem_en_s,
+                                                               dmem_data_o_s, tumbl_reset_s, tumbl_input_s, tumbl_state_s)
        begin
 
-               if imem_en_100m_s = '1' then
-                       imem_we_100m_s <= bls_100m_i;
+               if imem_en_s = '1' then
+                       imem_we_s <= bls_i;
                else
-                       imem_we_100m_s <= "0000";
+                       imem_we_s <= "0000";
                end if;
 
-               if dmem_en_100m_s = '1' then
-                       dmem_we_100m_s <= bls_100m_i;
+               if dmem_en_s = '1' then
+                       dmem_we_s <= bls_i;
                else
-                       dmem_we_100m_s <= "0000";
+                       dmem_we_s <= "0000";
                end if;
 
-               if imem_en_100m_s = '1' then
-                       data_100m_o <= imem_data_o_100m_s;
-               elsif dmem_en_100m_s = '1' then
-                       data_100m_o <= dmem_data_o_100m_s;
-               elsif ce_100m_i = '1' and rd_100m_i = '1' and address_100m_i(11 downto 10) = "11" then
-                       if address_100m_i(9 downto 0) = "0000000000" then
-                               data_100m_o(0) <= tumbl_reset_100m_s;
-                               data_100m_o(1) <= tumbl_int_100m_s;
-                               data_100m_o(2) <= tumbl_halt_100m_s;
-                               data_100m_o(3) <= tumbl_trace_100m_s;
-                               data_100m_o(4) <= tumbl_halted_100m_s;
-                               data_100m_o(31 downto 5) <= (others => '0');
-                       elsif address_100m_i(9 downto 0) = "0000000010" then
-                               data_100m_o <= tumbl_pc_100m_s;
-                       elsif address_100m_i(9 downto 0) = "0000000011" then
-                               data_100m_o(4 downto 0)  <= tumbl_halt_code_100m_s;
-                               data_100m_o(31 downto 5) <= (others => '0');
+               if imem_en_s = '1' then
+                       data_o <= imem_data_o_s;
+               elsif dmem_en_s = '1' then
+                       data_o <= dmem_data_o_s;
+               elsif ce_i = '1' and address_i(11 downto 10) = "11" then
+                       if address_i(9 downto 0) = "0000000000" then
+                               data_o(0) <= tumbl_reset_s;
+                               data_o(1) <= tumbl_input_s.int;
+                               data_o(2) <= tumbl_input_s.halt;
+                               data_o(3) <= tumbl_input_s.trace;
+                               data_o(4) <= tumbl_state_s.halted;
+                               data_o(31 downto 5) <= (others => '0');
+                       elsif address_i(9 downto 0) = "0000000010" then
+                               data_o <= tumbl_state_s.pc;
+                       elsif address_i(9 downto 0) = "0000000011" then
+                               data_o(4 downto 0)  <= tumbl_state_s.halt_code;
+                               data_o(31 downto 5) <= (others => '0');
                        else
-                               data_100m_o <= (others => 'X');
+                               data_o <= (others => 'X');
                        end if;
                else
-                       data_100m_o <= (others => 'X');
+                       data_o <= (others => 'X');
                end if;
 
        end process;
 
-       -- Transaction acknowledge and writing to registers
-       -- The clocks are synchronous!
-       update: process(clk_100m_i)
+-- Transaction acknowledge and writing to registers
+update:
+       process
        begin
 
-               -- Update on the 100 MHz clock
-               if clk_100m_i = '1' and clk_100m_i'event then
-                       ta_100m_o <= '0';
+               -- Update
+               wait until clk_i'event and clk_i = '1';
 
-                       -- Copy the 50M driven signals to 100M domain
-                       tumbl_pc_100m_s        <= tumbl_pc_50m_s;
-                       tumbl_halted_100m_s    <= tumbl_halted_50m_s;
-                       tumbl_halt_code_100m_s <= tumbl_halt_code_50m_s;
-                       --
-                       xmemb_sel_100m_o       <= xmemb_sel_50m_s;
-                       xmemb_100m_o           <= xmemb_50m_o_s;
+               tumbl_input_s.trace_kick <= '0';
 
-                       if imem_en_100m_s = '1' or dmem_en_100m_s = '1' then
-                               ta_100m_o <= '1';
-                       end if;
+               if reset_i = '1' then
+                       tumbl_reset_s            <= '1';
+                       tumbl_input_s.int        <= '0';
+                       tumbl_input_s.halt       <= '0';
+                       tumbl_input_s.trace      <= '0';
 
-                       if reset_100m_i = '1' then
-                               tumbl_reset_100m_s            <= '1';
-                               tumbl_int_100m_s              <= '0';
-                               tumbl_halt_100m_s             <= '0';
-                               tumbl_trace_100m_s            <= '0';
-                               tumbl_trace_kick_req_100m_s   <= '0';
-                       else
-                               if tumbl_trace_kick_ack_50m_s = '1' then
-                                       tumbl_trace_kick_req_100m_s <= '0';
-                               end if;
+               else
 
-                               if ce_100m_i = '1' and address_100m_i(11 downto 10) = "11" then
-                                       if bls_100m_i(0) = '1' then
-                                               if address_100m_i(9 downto 0) = "0000000000" then
-                                                       tumbl_reset_100m_s      <= data_100m_i(0);
-                                                       tumbl_int_100m_s        <= data_100m_i(1);
-                                                       tumbl_halt_100m_s       <= data_100m_i(2);
-                                                       tumbl_trace_100m_s      <= data_100m_i(3);
-                                               elsif address_100m_i(9 downto 0) = "0000000001" then
-                                                       if data_100m_i(0) = '1' then
-                                                               tumbl_trace_kick_req_100m_s <= '1';
-                                                       end if;
+                       if ce_i = '1' and address_i(11 downto 10) = "11" then
+                               if bls_i(0) = '1' then
+                                       if address_i(9 downto 0) = "0000000000" then
+                                               tumbl_reset_s              <= data_i(0);
+                                               tumbl_input_s.int          <= data_i(1);
+                                               tumbl_input_s.halt         <= data_i(2);
+                                               tumbl_input_s.trace        <= data_i(3);
+                                       elsif address_i(9 downto 0) = "0000000001" then
+                                               if data_i(0) = '1' then
+                                                       tumbl_input_s.trace_kick <= '1';
                                                end if;
                                        end if;
-
-                                       if rd_100m_i = '1' then
-                                               ta_100m_o <= '1';
-                                       end if;
-                               end if;
-                       end if;
-
-               end if;
-       end process;
-
-       -- Update tracing
-       tumbl: process(clk_50m_i)
-       begin
-
-               -- Update on the 50 MHz clock
-               if clk_50m_i = '1' and clk_50m_i'event then
-
-                       -- Copy the 100M driven signals to their 50M domain
-                       -- and then route them further
-                       tumbl_reset_50m_s <= tumbl_reset_100m_s;
-                       tumbl_int_50m_s   <= tumbl_int_100m_s;
-                       tumbl_halt_50m_s  <= tumbl_halt_100m_s;
-                       tumbl_trace_50m_s <= tumbl_trace_100m_s;
-                       --
-                       xmemb_50m_i_s     <= xmemb_100m_i;
-
-                       if reset_100m_i = '1' then
-                               tumbl_trace_kick_50m_s       <= '0';
-                               tumbl_trace_kick_ack_50m_s   <= '0';
-                       else
-                               if tumbl_trace_kick_50m_s = '0' and tumbl_trace_kick_req_100m_s = '1' then
-                                       tumbl_trace_kick_50m_s     <= '1';
-                                       tumbl_trace_kick_ack_50m_s <= '1';
-                               else
-                                       tumbl_trace_kick_50m_s     <= '0';
                                end if;
                        end if;
-
-                       if tumbl_trace_kick_req_100m_s = '0' then
-                               tumbl_trace_kick_ack_50m_s   <= '0';
-                       end if;
-
                end if;
 
        end process;
diff --git a/hw/bus_tumbl_interconnect.vhd b/hw/bus_tumbl_interconnect.vhd
deleted file mode 100644 (file)
index 30b3e99..0000000
+++ /dev/null
@@ -1,48 +0,0 @@
-library ieee;
-use ieee.std_logic_1164.all;
-use ieee.std_logic_arith.all;
-use ieee.std_logic_unsigned.all;
-use ieee.numeric_std.all;
-use work.lx_rocon_pkg.all;
-
--- Memory bus interconnect between tumbl and master cpu
-
-entity bus_tumbl_interconnect is
-       generic
-       (
-       )
-       port
-       (
-               -- Clock
-               clk_100m_i      : in std_logic;
-               clk_50m_i       : in std_logic;
-               -- Global Reset
-               reset_100m_i    : in std_logic;
-               -- Master CPU memory bus
-    rd_100m_i       : in std_logic;
-    bls_100m_i      : in std_logic_vector(3 downto 0);
-    address_100m_i  : in std_logic_vector(11 downto 0);
-    data_100m_i     : in std_logic_vector(31 downto 0);
-    data_100m_o     : out std_logic_vector(31 downto 0);
-               ta_100m_o       : out std_logic;
-               -- Tumbl memory bus
-               XMEMB_sel_50m_i : in std_logic;
-               XMEMB_50m_i     : in CORE2DMEMB_Type
-               XMEMB_50m_o     : out DMEMB2CORE_Type;
-               -- BRAM port (has to be 100 MHz clocked)
-    mem_en_o        : out std_logic;
-    mem_we_o        : out std_logic_vector(3 downto 0);
-    mem_addr_o      : out std_logic_vector(8 downto 0);
-    mem_data_i      : in std_logic_vector(31 downto 0);
-    mem_data_o      : out std_logic_vector(31 downto 0);
-
-       );
-end bus_tumbl_interconnect;
-
-architecture Behavioral of bus_tumbl_interconnect is
-
-begin
-
-
-end Behavioral;
-
diff --git a/hw/calibration_read_register.vhd b/hw/calibration_read_register.vhd
deleted file mode 100644 (file)
index 09f07f2..0000000
+++ /dev/null
@@ -1,35 +0,0 @@
-library ieee;
-use ieee.std_logic_1164.all;
-use ieee.std_logic_arith.all;
-use ieee.std_logic_unsigned.all;
-use ieee.numeric_std.all;
-
--- Calibration read register - returns fixed value
--- Uses clock for writing the ID to the bus
-
-entity calibration_read_register is
-  generic
-       (
-               id_g   : std_logic_vector(31 downto 0) := (others => '0')
-       );
-       port
-       (
-               -- Data bus (read only)
-               data_o : out std_logic_vector(31 downto 0);
-               -- Bus signals
-               rd_i   : in std_logic;
-               ta_o   : out std_logic
-       );
-end calibration_read_register;
-
-architecture Behavioral of calibration_read_register is
-begin
-
-memory_bus:
-       process(rd_i)
-       begin
-               ta_o     <= rd_i;
-               data_o   <= id_g;
-       end process;
-
-end Behavioral;
diff --git a/hw/calibration_write_register.vhd b/hw/calibration_write_register.vhd
deleted file mode 100644 (file)
index 33922fb..0000000
+++ /dev/null
@@ -1,72 +0,0 @@
-library ieee;
-use ieee.std_logic_1164.all;
-use ieee.std_logic_arith.all;
-use ieee.std_logic_unsigned.all;
-use ieee.numeric_std.all;
-
--- Calibration write register
--- Used to calibrate writing timing
-
-entity calibration_write_register is
-       port
-       (
-               -- Clock
-               clk_i   : in std_logic;
-               -- Reset
-               reset_i : in std_logic;
-               -- Chip enable
-               ce_i    : in std_logic;
-               -- Data bus
-               data_i  : in std_logic_vector(31 downto 0);
-               data_o  : out std_logic_vector(31 downto 0);
-               -- Bus signals
-               rd_i    : in std_logic;
-               bls_i   : in std_logic_vector(3 downto 0);
-               ta_o    : out std_logic
-       );
-end calibration_write_register;
-
-architecture Behavioral of calibration_write_register is
-       signal value_s : std_logic_vector(31 downto 0);
-begin
-
-       -- Read is immideate
-       memory_bus_read: process(rd_i, value_s)
-       begin
-               ta_o   <= rd_i;
-               data_o <= value_s;
-       end process;
-
-       -- Write waits for clock
-       memory_bus_write: process(clk_i)
-       begin
-
-               if clk_i = '1' and clk_i'event then
-
-                       if reset_i = '1' then
-                               value_s <= (others => '0');
-                       else
-
-                               if ce_i = '1' and bls_i /= "0000" then
-
-                                       if bls_i(0) = '1' then
-                                               value_s(7 downto 0)   <= data_i(7 downto 0);
-                                       end if;
-                                       if bls_i(1) = '1' then
-                                               value_s(15 downto 8)  <= data_i(15 downto 8);
-                                       end if;
-                                       if bls_i(2) = '1' then
-                                               value_s(23 downto 16) <= data_i(23 downto 16);
-                                       end if;
-                                       if bls_i(3) = '1' then
-                                               value_s(31 downto 24) <= data_i(31 downto 24);
-                                       end if;
-
-                               end if;
-                       end if;
-               end if;
-
-       end process;
-
-end Behavioral;
-
diff --git a/hw/crc.vhd b/hw/crc.vhd
new file mode 100644 (file)
index 0000000..55d6781
--- /dev/null
@@ -0,0 +1,49 @@
+--
+-- * CRC-8 generator *
+--
+-- part of LXPWR motion control board (c) PiKRON Ltd
+-- idea by Pavel Pisa PiKRON Ltd <pisa@cmp.felk.cvut.cz>
+-- code by Marek Peca <mp@duch.cz>
+-- 01/2013
+--
+-- license: GNU GPLv3
+--
+
+library ieee;
+use ieee.std_logic_1164.all;
+use ieee.numeric_std.all;
+
+entity crc is
+       port
+       (
+               clk_i   : in std_logic;
+               reset_i : in std_logic;
+               input_i : in std_logic;
+               crc_o   : out std_logic_vector(7 downto 0)
+       );
+end crc;
+
+architecture behavioral of crc is
+       signal reg_s, next_reg_s : std_logic_vector(7 downto 0);
+begin
+       crc_o <= next_reg_s;
+
+comb: process (reset_i, input_i, reg_s)
+       begin
+               if reset_i = '1' then
+                       next_reg_s <= (others => '1');
+               else
+                       next_reg_s(4 downto 0) <= reg_s(5 downto 1);
+                       next_reg_s(5) <= reg_s(0) xor reg_s(6);
+                       next_reg_s(6) <= reg_s(0) xor reg_s(7);
+                       next_reg_s(7) <= reg_s(0) xor input_i;
+               end if;
+       end process;
+
+seq: process
+  begin
+               wait until clk_i'event and clk_i = '1';
+               reg_s <= next_reg_s;
+       end process;
+
+end behavioral;
diff --git a/hw/dff.vhd b/hw/dff.vhd
deleted file mode 100644 (file)
index 10da173..0000000
+++ /dev/null
@@ -1,34 +0,0 @@
-library ieee;
-use ieee.std_logic_1164.all;
-use ieee.std_logic_arith.all;
-use ieee.std_logic_unsigned.all;
-use ieee.numeric_std.all;
-
--- D circuit
-
-entity dff is
-  port
-       (
-    clk_i   : in std_logic;
-               reset_i : in std_logic;
-    d_i     : in std_logic;
-    q_o     : out std_logic
-  );
-end dff2;
-
-architecture behavioral of dff is
-begin
-
-seq:
-       process(clk_i)
-       begin
-    if clk_i = '1' and clk_i'event then
-                       if reset_i = '1' then
-                               q_o <= '0';
-                       else
-                               q_o <= d_i;
-                       end if;
-               end if;
-  end process;
-
-end behavioral;
index c0d62dde99e4eb1a35505e2467bd77d1a805480d..be894d6afae09b0efbe274ab424b8b78349fb290 100644 (file)
@@ -3,6 +3,7 @@ use ieee.std_logic_1164.all;
 use ieee.std_logic_arith.all;
 use ieee.std_logic_unsigned.all;
 use ieee.numeric_std.all;
+use work.lx_rocon_pkg.all;
 
 -- D circuit (filtered)
 
@@ -23,20 +24,19 @@ begin
   q_o <= data_s;
 
 seq:
-       process(clk_i)
+       process
        begin
-    if clk_i = '1' and clk_i'event then
-                       if reset_i = '1' then
-                               last_d_s <= '0';
-                               data_s <= '0';
-                       else
-                               if d_i = last_d_s then
-                                       data_s <= d_i;
-                               end if;
+    wait until clk_i'event and clk_i = '1';
+               if reset_i = '1' then
+                       last_d_s <= '0';
+                       data_s <= '0';
+               else
+                       if d_i = last_d_s then
+                               data_s <= d_i;
                        end if;
-
-                       last_d_s <= d_i;
                end if;
+
+               last_d_s <= d_i;
   end process;
 
 end behavioral;
index 8c9875b407776ea60833171494d33d87cbe1dfb7..f4159847440c0f19baeba34b6d22edee84c563ec 100644 (file)
@@ -31,15 +31,15 @@ begin
        op_o <= num_s(1 downto 0);
 
 inc:
-       process (clk_i)
+       process
        begin
 
-               if clk_i = '1' and clk_i'event then
-                       if reset_i = '1' then
-                               num_s <= (others => '0');
-                       else
-                               num_s <= std_logic_vector(num_s + 1);
-                       end if;
+               wait until clk_i'event and clk_i = '1';
+
+               if reset_i = '1' then
+                       num_s <= (others => '0');
+               else
+                       num_s <= std_logic_vector(num_s + 1);
                end if;
 
        end process;
index ad4a7e801266368b5e53eb273ae002b6da025860..45f898a255f28f5695b12f019179cfa05b1cbcdc 100644 (file)
@@ -2,10 +2,12 @@ library ieee;
 use ieee.std_logic_1164.all;
 use ieee.std_logic_unsigned.all;
 use ieee.numeric_std.all;
-use work.mbl_Pkg.all;
+use work.mbl_pkg.all;
 use work.lx_rocon_pkg.all;
 
 -- Main unit in the IRC cooprocessor
+-- This could be written as generic (n IRC axes)
+-- >100 MHz
 entity irc_proc_main is
        port
        (
@@ -13,13 +15,10 @@ entity irc_proc_main is
                clk_i             : in std_logic;
                reset_i           : in std_logic;
                -- Signals from IRC
-               irc1_i            : in IRC_SLIM_OUTPUT_Type;
-               irc2_i            : in IRC_SLIM_OUTPUT_Type;
-               irc3_i            : in IRC_SLIM_OUTPUT_Type;
-               irc4_i            : in IRC_SLIM_OUTPUT_Type;
+               irc_i             : in IRC_COUNT_OUTPUT_Array_Type(3 downto 0);
                -- Index resetting
                irc_index_reset_o : out std_logic_vector(3 downto 0);
-               -- BRAM access (the other port)
+               -- BRAM access
                mem_clk_i         : in std_logic;
     mem_en_i          : in std_logic;
     mem_we_i          : in std_logic_vector(3 downto 0);
@@ -31,22 +30,17 @@ end irc_proc_main;
 
 architecture Behavioral of irc_proc_main is
 
-       -- IRC Output array
-       type IRC_OUTPUT_Array_Type is array (0 to 3) of IRC_SLIM_OUTPUT_Type;
+       signal op_s         : std_logic_vector(1 downto 0);
+       signal axis_s       : std_logic_vector(1 downto 0);
        --
-       signal op_s                : std_logic_vector(1 downto 0);
-       signal axis_s              : std_logic_vector(1 downto 0);
+       signal op_r         : std_logic_vector(1 downto 0);
+       signal axis_r       : std_logic_vector(1 downto 0);
        --
-       signal op_r                : std_logic_vector(1 downto 0);
-       signal axis_r              : std_logic_vector(1 downto 0);
-       --
-       signal irc_array_s         : IRC_OUTPUT_Array_Type;
-       --
-       signal ram_en_s            : std_logic;
-       signal ram_addr_s          : std_logic_vector(2 downto 0);
-       signal ram_write_s         : std_logic_vector(3 downto 0);
-       signal ram_data_i_s        : std_logic_vector(31 downto 0);
-       signal ram_data_o_s        : std_logic_vector(31 downto 0);
+       signal ram_en_s     : std_logic;
+       signal ram_addr_s   : std_logic_vector(2 downto 0);
+       signal ram_write_s  : std_logic_vector(3 downto 0);
+       signal ram_data_i_s : std_logic_vector(31 downto 0);
+       signal ram_data_o_s : std_logic_vector(31 downto 0);
 
 begin
 
@@ -88,101 +82,97 @@ begin
 
        -- RAM address (delayed by a cycle when writing)
        ram_addr_s     <= (axis_r & op_r(1)) when ram_write_s = "1111" else (axis_s & op_s(1));
-       -- IRC packing
-       irc_array_s(0) <= irc1_i;
-       irc_array_s(1) <= irc2_i;
-       irc_array_s(2) <= irc3_i;
-       irc_array_s(3) <= irc4_i;
 
 seq:
-       process (clk_i)
+       process
 
                variable skip_v            : std_logic;
-               variable irc_v             : IRC_SLIM_OUTPUT_Type;
+               variable irc_v             : IRC_COUNT_OUTPUT_Type;
                variable res_v             : std_logic_vector(31 downto 0);
                variable count_v           : std_logic_vector(31 downto 0);
 
        begin
 
-               if clk_i = '1' and clk_i'event then
-
-                       -- Init (reset the index reset events)
-                       irc_index_reset_o <= (others => '0');
-
-                       if reset_i = '1' then
-                               -- Reset
-                               ram_en_s     <= '1';
-                               ram_write_s  <= "0000";
-                               ram_data_i_s <= (others => '0');
-                               --
-                               op_r         <= (others => '0');
-                               axis_r       <= (others => '0');
-
-                       else
-                               -- Defaults
-                               skip_v      := '1';
-                               ram_en_s    <= '0';
-                               ram_write_s <= "0000";
-
-                               -- Caluclating step
-                               if op_r(1) = '0' then
-                                       -- get source
-                                       irc_v := irc_array_s(to_integer(unsigned(axis_s)));
-
-                                       if op_r(0) = '0' then
-                                               count_v(7 downto 0) := irc_v.qcount;
+               wait until clk_i'event and clk_i = '1';
+
+               -- Init (reset the index reset events)
+               irc_index_reset_o <= (others => '0');
+
+               if reset_i = '1' then
+                       -- Reset
+                       ram_en_s     <= '1';
+                       ram_write_s  <= "0000";
+                       ram_data_i_s <= (others => '0');
+                       --
+                       op_r         <= (others => '0');
+                       axis_r       <= (others => '0');
+
+               else
+                       -- Defaults
+                       skip_v      := '1';
+                       ram_en_s    <= '0';
+                       ram_write_s <= "0000";
+
+                       -- Caluclating step
+                       if op_r(1) = '0' then
+                               -- get source
+                               irc_v := irc_i(to_integer(unsigned(axis_s)));
+
+                               if op_r(0) = '0' then
+                                       count_v(7 downto 0) := irc_v.qcount;
+                                       skip_v := '0';
+                               else
+                                       if irc_v.index_event = '1' then
+                                               irc_index_reset_o(to_integer(unsigned(axis_s))) <= '1';
+                                               count_v(7 downto 0) := irc_v.index;
                                                skip_v := '0';
+                                       end if;
+                               end if;
+
+                               if skip_v = '0' then
+                                       -- signed extension
+                                       if count_v(7) = '1' then
+                                               count_v(31 downto 8) := (others => '1');
                                        else
-                                               if irc_v.index_event = '1' then
-                                                       irc_index_reset_o(to_integer(unsigned(axis_s))) <= '1';
-                                                       count_v(7 downto 0) := irc_v.index;
-                                                       skip_v := '0';
-                                               end if;
+                                               count_v(31 downto 8) := (others => '0');
                                        end if;
 
-                                       if skip_v = '0' then
-                                               -- signed extension
-                                               if count_v(7) = '1' then
-                                                       count_v(31 downto 8) := (others => '1');
-                                               else
-                                                       count_v(31 downto 8) := (others => '0');
-                                               end if;
-
-                                               -- calculate qs8
-                                               ep_add32nc(count_v, not ram_data_o_s, '1', res_v);
-
-                                               -- extend it
-                                               count_v(7 downto 0) := res_v(7 downto 0);
-
-                                               if res_v(7) = '1' then
-                                                       count_v(31 downto 8) := (others => '1');
-                                               else
-                                                       count_v(31 downto 8) := (others => '0');
-                                               end if;
-
-                                               -- add it back
-                                               ep_add32nc(ram_data_o_s, count_v, '0', res_v);
-
-                                               -- store it
-                                               ram_en_s     <= '1';
-                                               ram_write_s  <= "1111";
-                                               ram_data_i_s <= res_v;
+                                       -- calculate qs8
+                                       ep_add32nc(count_v, not ram_data_o_s, '1', res_v);
+
+                                       -- extend it
+                                       count_v(7 downto 0) := res_v(7 downto 0);
+
+                                       if res_v(7) = '1' then
+                                               count_v(31 downto 8) := (others => '1');
+                                       else
+                                               count_v(31 downto 8) := (others => '0');
                                        end if;
 
-                               end if;
+                                       -- add it back
+                                       ep_add32nc(ram_data_o_s, count_v, '0', res_v);
 
-                               -- Read next stored IRC
-                               if op_r = "10" then
-                                       ram_en_s <= '1';
+                                       -- store it
+                                       ram_en_s     <= '1';
+                                       ram_write_s  <= "1111";
+                                       ram_data_i_s <= res_v;
                                end if;
 
                        end if;
 
-                       op_r     <= op_s;
-                       axis_r   <= axis_s;
+                       -- Read next stored IRC
+                       -- FIXME: Wire the enabling directly so it takes one cycle less,
+                       -- although op_r = "11" is reserved for potential extesion for 2nd index,
+                       -- so not very important
+                       if op_r = "10" then
+                               ram_en_s <= '1';
+                       end if;
 
                end if;
 
+               op_r     <= op_s;
+               axis_r   <= axis_s;
+
        end process;
 
 end Behavioral;
index 36897875e11a0618e789ac1f5d275b44587f80fb..e5cf207e25d7b7aeff33ea733237782cca370bcf 100644 (file)
@@ -23,19 +23,18 @@ entity irc_reader is
 end irc_reader;
 
 architecture rtl of irc_reader is
-
        begin
 
-       dff_mark: dff2
+dff_mark: dff2
        port map
        (
                clk_i   => clk_i,
                reset_i => '0',
                d_i     => irc_i.mark,
-               q_o     => irc_o.mark
+               q_o     => irc_o.state.mark
        );
 
-       qctr: qcounter
+qctr: qcounter
        port map
        (
                clk_i               => clk_i,
@@ -45,11 +44,11 @@ architecture rtl of irc_reader is
                index0_i            => irc_i.index,
                reset_index_event_i => reset_index_event_i,
                reset_ab_error_i    => reset_ab_error_i,
-               qcount_o            => irc_o.qcount,
-               qcount_index_o      => irc_o.index,
-               ab_error_o          => irc_o.ab_error,
+               qcount_o            => irc_o.count.qcount,
+               qcount_index_o      => irc_o.count.index,
+               ab_error_o          => irc_o.state.ab_error,
                ab_event_o          => open,
-               index_event_o       => irc_o.index_event,
+               index_event_o       => irc_o.count.index_event,
                a_rise_o            => open,
                a_fall_o            => open,
                b_rise_o            => open,
index 73ed939e907012f1b47912aeef73739f9a493247..95a4d013860bcfc8871d790c03ade15f1c41985e 100644 (file)
@@ -6,13 +6,13 @@ CONFIG VCCAUX  = 3.3;
 # ====================================================================
 
 # Clock
-#NET CLK_CPU             PERIOD = 13.8ns HIGH 50%;
-#NET CLK_CPU             LOC = P15  | IOSTANDARD = LVCMOS33;
-NET CLK_50M             PERIOD = 20.0ns HIGH 50%;
-NET CLK_50M             LOC = P14  | IOSTANDARD = LVCMOS33;
+#NET CLK_CPU             PERIOD = 13.88ns HIGH 50%;
+#NET CLK_CPU             LOC = P15  | IOSTANDARD = LVCMOS33 | SLEW = FAST;
+NET CLK_50M             PERIOD = 20.00ns HIGH 50%;
+NET CLK_50M             LOC = P14  | IOSTANDARD = LVCMOS33 | SLEW = FAST;
 
 # Reset (active LOW)
-NET INIT                LOC = P39  | IOSTANDARD = LVCMOS33;
+NET INIT                LOC = P39  | IOSTANDARD = LVCMOS33 | SLEW = SLOW;
 
 # Memory peripheral
 NET CS0_XC              LOC = P64  | IOSTANDARD = LVCMOS33 | SLEW = SLOW;
@@ -75,53 +75,30 @@ NET DATA<30>            LOC = P138 | IOSTANDARD = LVCMOS33 | SLEW = SLOW;
 NET DATA<31>            LOC = P137 | IOSTANDARD = LVCMOS33 | SLEW = SLOW;
 
 # IRC
-NET IRC1_A              LOC = P2   | IOSTANDARD = LVCMOS33;
-NET IRC1_B              LOC = P6   | IOSTANDARD = LVCMOS33;
-NET IRC1_INDEX          LOC = P7   | IOSTANDARD = LVCMOS33;
-NET IRC1_MARK           LOC = P5   | IOSTANDARD = LVCMOS33;
+NET IRC1_A              LOC = P2   | IOSTANDARD = LVCMOS33 | SLEW = FAST;
+NET IRC1_B              LOC = P6   | IOSTANDARD = LVCMOS33 | SLEW = FAST;
+NET IRC1_INDEX          LOC = P7   | IOSTANDARD = LVCMOS33 | SLEW = FAST;
+NET IRC1_MARK           LOC = P5   | IOSTANDARD = LVCMOS33 | SLEW = FAST;
 
-NET IRC2_A              LOC = P8   | IOSTANDARD = LVCMOS33;
-NET IRC2_B              LOC = P10  | IOSTANDARD = LVCMOS33;
-NET IRC2_INDEX          LOC = P11  | IOSTANDARD = LVCMOS33;
-NET IRC2_MARK           LOC = P9   | IOSTANDARD = LVCMOS33;
+NET IRC2_A              LOC = P8   | IOSTANDARD = LVCMOS33 | SLEW = FAST;
+NET IRC2_B              LOC = P10  | IOSTANDARD = LVCMOS33 | SLEW = FAST;
+NET IRC2_INDEX          LOC = P11  | IOSTANDARD = LVCMOS33 | SLEW = FAST;
+NET IRC2_MARK           LOC = P9   | IOSTANDARD = LVCMOS33 | SLEW = FAST;
 
-NET IRC3_A              LOC = P12  | IOSTANDARD = LVCMOS33;
-NET IRC3_B              LOC = P17  | IOSTANDARD = LVCMOS33;
-NET IRC3_INDEX          LOC = P21  | IOSTANDARD = LVCMOS33;
-NET IRC3_MARK           LOC = P16  | IOSTANDARD = LVCMOS33;
+NET IRC3_A              LOC = P12  | IOSTANDARD = LVCMOS33 | SLEW = FAST;
+NET IRC3_B              LOC = P17  | IOSTANDARD = LVCMOS33 | SLEW = FAST;
+NET IRC3_INDEX          LOC = P21  | IOSTANDARD = LVCMOS33 | SLEW = FAST;
+NET IRC3_MARK           LOC = P16  | IOSTANDARD = LVCMOS33 | SLEW = FAST;
 
-NET IRC4_A              LOC = P22  | IOSTANDARD = LVCMOS33;
-NET IRC4_B              LOC = P24  | IOSTANDARD = LVCMOS33;
-NET IRC4_INDEX          LOC = P26  | IOSTANDARD = LVCMOS33;
-NET IRC4_MARK           LOC = P23  | IOSTANDARD = LVCMOS33;
+NET IRC4_A              LOC = P22  | IOSTANDARD = LVCMOS33 | SLEW = FAST;
+NET IRC4_B              LOC = P24  | IOSTANDARD = LVCMOS33 | SLEW = FAST;
+NET IRC4_INDEX          LOC = P26  | IOSTANDARD = LVCMOS33 | SLEW = FAST;
+NET IRC4_MARK           LOC = P23  | IOSTANDARD = LVCMOS33 | SLEW = FAST;
 
 # ====================================================================
-# OUTPUTS
+# S1 Interface
 # ====================================================================
 
-#NET OUTPUT<47>          LOC = P112 | IOSTANDARD = LVCMOS33;
-#NET OUTPUT<48>          LOC = P111 | IOSTANDARD = LVCMOS33;
-#NET OUTPUT<49>          LOC = P105 | IOSTANDARD = LVCMOS33;
-#NET OUTPUT<50>          LOC = P104 | IOSTANDARD = LVCMOS33;
-#NET OUTPUT<51>          LOC = P102 | IOSTANDARD = LVCMOS33;
-#NET OUTPUT<52>          LOC = P101 | IOSTANDARD = LVCMOS33;
-#NET OUTPUT<53>          LOC = P100 | IOSTANDARD = LVCMOS33;
-#NET OUTPUT<54>          LOC = P99  | IOSTANDARD = LVCMOS33;
-#NET OUTPUT<55>          LOC = P98  | IOSTANDARD = LVCMOS33;
-#NET OUTPUT<56>          LOC = P97  | IOSTANDARD = LVCMOS33;
-#NET OUTPUT<57>          LOC = P95  | IOSTANDARD = LVCMOS33;
-#NET OUTPUT<58>          LOC = P94  | IOSTANDARD = LVCMOS33;
-#NET OUTPUT<59>          LOC = P93  | IOSTANDARD = LVCMOS33;
-#NET OUTPUT<60>          LOC = P92  | IOSTANDARD = LVCMOS33;
-#NET OUTPUT<61>          LOC = P88  | IOSTANDARD = LVCMOS33;
-#NET OUTPUT<62>          LOC = P87  | IOSTANDARD = LVCMOS33;
-#NET OUTPUT<63>          LOC = P85  | IOSTANDARD = LVCMOS33;
-#NET OUTPUT<64>          LOC = P84  | IOSTANDARD = LVCMOS33;
-#NET OUTPUT<65>          LOC = P83  | IOSTANDARD = LVCMOS33;
-#NET OUTPUT<66>          LOC = P82  | IOSTANDARD = LVCMOS33;
-#NET OUTPUT<67>          LOC = P81  | IOSTANDARD = LVCMOS33;
-#NET OUTPUT<68>          LOC = P80  | IOSTANDARD = LVCMOS33;
-#NET OUTPUT<69>          LOC = P79  | IOSTANDARD = LVCMOS33;
-#NET OUTPUT<70>          LOC = P78  | IOSTANDARD = LVCMOS33;
-#NET OUTPUT<71>          LOC = P75  | IOSTANDARD = LVCMOS33;
-#NET OUTPUT<72>          LOC = P74  | IOSTANDARD = LVCMOS33;
+NET S1_CLK_OUT           LOC = P94  | IOSTANDARD = LVCMOS33 | SLEW = FAST;
+NET S1_SYNC_OUT          LOC = P101 | IOSTANDARD = LVCMOS33 | SLEW = FAST;
+NET S1_MOSI              LOC = P97  | IOSTANDARD = LVCMOS33 | SLEW = FAST;
index e12a76ab88bdb8c680691815c9e2cbda07dc496b..655fa6f5bea1f4e32af9fe64352682ca4c60c3ff 100644 (file)
@@ -41,6 +41,12 @@ void init_defvals()
        a_settings.acc_dev = 0;
 }
 
+void read_input(axis_io* io)
+{
+       io->irc_last = io->irc;
+       io->irc = *((int32_t*)0x8000);
+}
+
 void update_axis(axis_settings *settings, axis_io* io)
 {
        int i;
@@ -74,10 +80,10 @@ void main()
 {
        while (1)
        {
+               read_input(&a_io);
                update_axis(&a_settings, &a_io);
                a_io.irc = irc_a_reg;
                a_io.current = current_a_reg;
                count++;
        }
 }
-
index 136809fd647ff907d26737242a24b38b1073995b..3f7a81baf8785c71b3f951d9a22c0a7e11ac3c96 100644 (file)
@@ -44,12 +44,12 @@ _main:
        addi     r6, r0, _sdata
        addi     r7, r0, _edata
        rsub     r18, r6, r7
-       blei     r18, .Lenddata
+       brci     le, r18, .Lenddata
 .Lloopdata:
        swi      r0, r6, 0
        addi     r6, r6, 4
        rsub     r18, r6, r7
-       bgti     r18, .Lloopdata
+       brci     gt, r18, .Lloopdata
 .Lenddata:
        /* Init default values */
        brli     r15, init_defvals
index 2315529a49b49deb0adeb7d97f834cb31c3cd20a..cccc34e4d71ba26bc56f8ecd5080970bdbdd1a30 100644 (file)
@@ -4,7 +4,7 @@ use ieee.std_logic_1164.all;
 use ieee.std_logic_arith.all;
 use ieee.std_logic_unsigned.all;
 use ieee.numeric_std.all;
-use work.mbl_Pkg.all;
+use work.mbl_pkg.all;
 use work.lx_rocon_pkg.all;
 
 -- 4 kB data memory for Thumbl core
@@ -16,9 +16,8 @@ entity lx_rocon_dmem is
                -- Memory wiring for Tumbl
                clk_i  : in std_logic;
                ce_i   : in std_logic;
-               adr_i  : in std_logic_vector(11 downto 2);
-               wre_i  : in std_logic;
-               bsel_i : in std_logic_vector(3 downto 0);
+               adr_i  : in std_logic_vector(9 downto 0);
+               bls_i  : in std_logic_vector(3 downto 0);
                dat_i  : in std_logic_vector(31 downto 0);
                dat_o  : out std_logic_vector(31 downto 0);
                -- Memory wiring for Master CPU
@@ -32,14 +31,9 @@ entity lx_rocon_dmem is
 end lx_rocon_dmem;
 
 architecture rtl of lx_rocon_dmem is
-
-       signal wre_i_s : std_logic_vector(3 downto 0);
-
 begin
 
-       wre_i_s <= bsel_i when (wre_i = '1') else "0000";
-
-       I_RAMB: xilinx_dualport_bram_write_first
+I_RAMB: xilinx_dualport_bram_write_first
        generic map
        (
                we_width => 4,
@@ -52,8 +46,8 @@ begin
                clka => clk_i,
                rsta => '0',
                ena => ce_i,
-               wea => wre_i_s,
-               addra => adr_i(11 downto 2),
+               wea => bls_i,
+               addra => adr_i,
                dina => dat_i,
                douta => dat_o,
 
index 7c1613a3033d08df0c71a5e7302485c1d430fd8e..550655c231e26d56a88b081597b00b6b4102fa13 100644 (file)
@@ -4,7 +4,7 @@ use ieee.std_logic_1164.all;
 use ieee.std_logic_arith.all;
 use ieee.std_logic_unsigned.all;
 use ieee.numeric_std.all;
-use work.mbl_Pkg.all;
+use work.mbl_pkg.all;
 use work.lx_rocon_pkg.all;
 
 -- 32x32b General Puprose Registers for Tumbl Core
@@ -72,89 +72,89 @@ begin
        I_rA: xilinx_dualport_bram_write_first
        generic map
        (
-               byte_width => 32,
-               we_width => 1,
+               byte_width    => 32,
+               we_width      => 1,
                address_width => 5
        )
        port map
        (
-               clka => clk_i,
-               rsta => rst_i,
-               ena => ena_rA_s,
+               clka   => clk_i,
+               rsta   => rst_i,
+               ena    => ena_rA_s,
                wea(0) => rst_i,
-               addra => rdix_rA_s,
-               dina => C_32_ZEROS,
-               douta => rA_DOA_s,
+               addra  => rdix_rA_s,
+               dina   => C_32_ZEROS,
+               douta  => rA_DOA_s,
                -- Write-back
-               clkb => clk_i,
-               rstb => rst_i,
-               enb => clken_s,
+               clkb   => clk_i,
+               rstb   => rst_i,
+               enb    => clken_s,
                web(0) => wre_rD_s,
-               addrb => MEM_WRB_i.wrix_rD,
-               dinb => MEM_WRB_i.data_rD,
-               doutb => rA_DOB_s
+               addrb  => MEM_WRB_i.wrix_rD,
+               dinb   => MEM_WRB_i.data_rD,
+               doutb  => rA_DOB_s
        );
 
        I_rB: xilinx_dualport_bram_write_first
        generic map
        (
-               byte_width => 32,
-               we_width => 1,
+               byte_width    => 32,
+               we_width      => 1,
                address_width => 5
        )
        port map
        (
-               clka => clk_i,
-               rsta => rst_i,
-               ena => ena_rB_s,
+               clka   => clk_i,
+               rsta   => rst_i,
+               ena    => ena_rB_s,
                wea(0) => rst_i,
-               addra => rdix_rB_s,
-               dina => C_32_ZEROS,
-               douta => rB_DOA_s,
+               addra  => rdix_rB_s,
+               dina   => C_32_ZEROS,
+               douta  => rB_DOA_s,
                -- Write-back
-               clkb => clk_i,
-               rstb => rst_i,
-               enb => clken_s,
+               clkb   => clk_i,
+               rstb   => rst_i,
+               enb    => clken_s,
                web(0) => wre_rD_s,
-               addrb => MEM_WRB_i.wrix_rD,
-               dinb => MEM_WRB_i.data_rD,
-               doutb => rB_DOB_s
+               addrb  => MEM_WRB_i.wrix_rD,
+               dinb   => MEM_WRB_i.data_rD,
+               doutb  => rB_DOB_s
        );
 
        I_rD: xilinx_dualport_bram_write_first
        generic map
        (
-               byte_width => 32,
-               we_width => 1,
+               byte_width    => 32,
+               we_width      => 1,
                address_width => 5
        )
        port map
        (
-               clka => clk_i,
-               rsta => rst_i,
-               ena => ena_rD_s,
+               clka   => clk_i,
+               rsta   => rst_i,
+               ena    => ena_rD_s,
                wea(0) => rst_i,
-               addra => rdix_rD_s,
-               dina => C_32_ZEROS,
-               douta => rD_DOA_s,
+               addra  => rdix_rD_s,
+               dina   => C_32_ZEROS,
+               douta  => rD_DOA_s,
                -- Write-back
-               clkb => clk_i,
-               rstb => rst_i,
-               enb => clken_s,
+               clkb   => clk_i,
+               rstb   => rst_i,
+               enb    => clken_s,
                web(0) => wre_rD_s,
-               addrb => MEM_WRB_i.wrix_rD,
-               dinb => MEM_WRB_i.data_rD,
-               doutb => rD_DOB_s
+               addrb  => MEM_WRB_i.wrix_rD,
+               dinb   => MEM_WRB_i.data_rD,
+               doutb  => rD_DOB_s
        );
 
-       p_regd: process(clk_i)
+p_regd:
+       process
        begin
-               if clk_i = '1' and clk_i'event then
-                       if (clken_i = '1') then
-                               wthru_rA_r <= not ena_rA_s;
-                               wthru_rB_r <= not ena_rB_s;
-                               wthru_rD_r <= not ena_rD_s;
-                       end if;
+               wait until clk_i'event and clk_i = '1';
+               if (clken_i = '1') then
+                       wthru_rA_r <= not ena_rA_s;
+                       wthru_rB_r <= not ena_rB_s;
+                       wthru_rD_r <= not ena_rD_s;
                end if;
        end process;
 
index 6d3135b989d0d73cdbc718aa6f446e91ea67ef2b..69f97729290ca1f8f5f14264f7d610cd1d10b738 100644 (file)
@@ -4,7 +4,7 @@ use ieee.std_logic_1164.all;
 use ieee.std_logic_arith.all;
 use ieee.std_logic_unsigned.all;
 use ieee.numeric_std.all;
-use work.mbl_Pkg.all;
+use work.mbl_pkg.all;
 use work.lx_rocon_pkg.all;
 
 -- 2 kB instruction memory for Thumbl core
@@ -16,7 +16,7 @@ entity lx_rocon_imem is
                -- Memory wiring for Tumbl
                clk_i  : in std_logic;
                cs_i   : in std_logic;
-               adr_i  : in std_logic_vector(10 downto 2);
+               adr_i  : in std_logic_vector(8 downto 0);
                dat_o  : out std_logic_vector(31 downto 0);
                -- Memory wiring for Master CPU
                clk_m  : in std_logic;
@@ -31,7 +31,7 @@ end lx_rocon_imem;
 architecture rtl of lx_rocon_imem is
 begin
 
-       I_RAMB: xilinx_dualport_bram_write_first
+I_RAMB: xilinx_dualport_bram_write_first
        generic map
        (
                we_width => 4,
@@ -45,7 +45,7 @@ begin
                rsta => '0',
                ena => cs_i,
                wea => "0000",
-               addra => adr_i(10 downto 2),
+               addra => adr_i,
                dina => C_32_ZEROS,
                douta => dat_o,
 
index 49ed8cd344f07581abc2e629b487f5c27c45c077..122e1b3f0f6e474e94279fc834ca0e45d048dde4 100644 (file)
@@ -4,17 +4,18 @@ use ieee.std_logic_1164.all;
 use ieee.std_logic_arith.all;
 use ieee.std_logic_unsigned.all;
 use ieee.numeric_std.all;
-use work.mbl_Pkg.all;
+use work.mbl_pkg.all;
 use work.lx_rocon_pkg.all;
 
 -- Tumbl configured as a coprocessor for lx_rocon
--- Uses 10 bits width address bus with HW barrel and multiplier
+-- Uses 12 bits width address bus with HW barrel and multiplier
 
 entity lx_rocon_tumbl is
        generic
        (
-               IMEM_ABITS_g         : positive := 11;
-               DMEM_ABITS_g         : positive := 12;
+               -- This is for 32-bit addressing
+               IMEM_ABITS_g         : positive := 9;
+               DMEM_ABITS_g         : positive := 10;
                --
                USE_HW_MUL_g         : boolean := true;
                USE_BARREL_g         : boolean := true;
@@ -56,10 +57,10 @@ end entity lx_rocon_tumbl;
 
 architecture rtl of lx_rocon_tumbl is
 
-       constant DMEM_TEST_c : std_logic_vector((31-DMEM_ABITS_g) downto 0) := (others => '0');
+       constant DMEM_TEST_c : std_logic_vector((14-DMEM_ABITS_g) downto 0) := (others => '0');
 
        signal imem_clken_s  : std_logic;
-       signal imem_addr_s   : std_logic_vector(31 downto 0);
+       signal imem_addr_s   : std_logic_vector((IMEM_ABITS_g-1) downto 0);
        signal imem_data_s   : std_logic_vector(31 downto 0);
        signal gprf_clken_s  : std_logic;
        signal core_clken_s  : std_logic;
@@ -95,10 +96,11 @@ architecture rtl of lx_rocon_tumbl is
        signal dmem_really_sel_s          : std_logic;
        signal gprf_really_clken_s        : std_logic;
 
+
 begin
 
        -- select internal data memory when all address bits above DMEM_ABITS_g are zero
-       dmem_sel_s  <= '1' when (c2dmemb_s.addr(31 downto DMEM_ABITS_g) = DMEM_TEST_c)
+       dmem_sel_s  <= '1' when (c2dmemb_s.addr(14 downto DMEM_ABITS_g) = DMEM_TEST_c)
                                                                        else '0';
        XMEMB_sel_o <= (not dmem_sel_s) and core_clken_s;
        XMEMB_o     <= c2dmemb_s;
@@ -111,12 +113,12 @@ begin
        dmem_really_sel_s   <= dmem_sel_s and core_clken_s;
        gprf_really_clken_s <= gprf_clken_s and core_clken_s;
 
-       I_IMEM: lx_rocon_imem
+I_IMEM: lx_rocon_imem
        port map
        (
                clk_i  => clk_i,
                cs_i   => imem_really_clken_s,
-               adr_i  => imem_addr_s((IMEM_ABITS_g-1) downto 2),
+               adr_i  => imem_addr_s((IMEM_ABITS_g-1) downto 0),
                dat_o  => imem_data_s,
 
                clk_m  => imem_clk_i,
@@ -127,14 +129,13 @@ begin
                dout_m => imem_data_o
        );
 
-       I_DMEM: lx_rocon_dmem
+I_DMEM: lx_rocon_dmem
        port map
        (
                clk_i  => clk_i,
                ce_i   => dmem_really_sel_s,
-               adr_i  => c2dmemb_s.addr((DMEM_ABITS_g-1) downto 2),
-               wre_i  => c2dmemb_s.wre,
-               bsel_i => c2dmemb_s.bSel,
+               adr_i  => c2dmemb_s.addr((DMEM_ABITS_g-1) downto 0),
+               bls_i  => c2dmemb_s.bls,
                dat_i  => c2dmemb_s.data,
                dat_o  => dmem_data_s,
 
@@ -146,7 +147,7 @@ begin
                dout_m => dmem_data_o
        );
 
-       I_FETCH: fetch
+I_FETCH: fetch
        port map
        (
                prog_cntr_i => IF2ID_r.program_counter,
@@ -155,7 +156,7 @@ begin
                IF2ID_o     => IF2ID_s
        );
 
-       I_DECODE: decode
+I_DECODE: decode
        generic map(USE_HW_MUL_g, USE_BARREL_g, COMPATIBILITY_MODE_g)
        port map
        (
@@ -169,7 +170,7 @@ begin
                ID2CTRL_o   => ID2CTRL_s
        );
 
-       I_GPRF: lx_rocon_gprf_abd
+I_GPRF: lx_rocon_gprf_abd
        port map
        (
                clk_i        => clk_i,
@@ -181,7 +182,7 @@ begin
                GPRF2EX_o    => GPRF2EX_s
        );
 
-       I_EXEQ: exeq
+I_EXEQ: exeq
        generic map(USE_HW_MUL_g, USE_BARREL_g, COMPATIBILITY_MODE_g)
        port map
        (
@@ -212,11 +213,11 @@ begin
 
        -- this is a very simple address block decoder, just "internal" dmem or "external"
        -- clken and int hardwired for fast internal data-memory
-       DMEMB_i_s.clken <= '1'          when (dmem_sel_s = '1') else XMEMB_i.clken;
-       DMEMB_i_s.data  <=  dmem_data_s when (dmem_sel_r = '1') else XMEMB_i.data;
+       DMEMB_i_s.clken <= '1'         when (dmem_sel_s = '1') else XMEMB_i.clken;
+       DMEMB_i_s.data  <= dmem_data_s when (dmem_sel_r = '1') else XMEMB_i.data;
        DMEMB_i_s.int   <= XMEMB_i.int;
 
-       I_MEM: mem
+I_MEM: mem
        port map
        (
                EX2MEM_i    => EX2MEM_r,
@@ -231,8 +232,8 @@ begin
                MEM2CTRL_o => MEM2CTRL_s
        );
 
-       I_CTRL: core_ctrl
-       generic map (COMPATIBILITY_MODE_g)
+I_CTRL: core_ctrl
+       generic map (IMEM_ABITS_g, COMPATIBILITY_MODE_g)
        port map
        (
                clk_i           => clk_i,
@@ -286,15 +287,15 @@ begin
                MEM2CTRL_i      => MEM2CTRL_s
        );
 
-       regd_proc: process(clk_i, rst_i)
+regd_proc:
+       process
        begin
-               if clk_i = '1' and clk_i'event then
-                       if (rst_i = '1') then           -- synchronous reset ...
-                               dmem_sel_r <= '1';
-                       else                            -- delay select_external_mem (needed for reading ...)
-                               if (DMEMB_i_s.clken = '1') then
-                                       dmem_sel_r <= dmem_sel_s;   -- OR c2dmemb_s.wre; ??
-                               end if;
+               wait until clk_i'event and clk_i = '1';
+               if (rst_i = '1') then           -- synchronous reset ...
+                       dmem_sel_r   <= '1';
+               else                            -- delay select_external_mem (needed for reading ...)
+                       if (DMEMB_i_s.clken = '1') then
+                               dmem_sel_r <= dmem_sel_s;   -- OR c2dmemb_s.wre; ??
                        end if;
                end if;
        end process regd_proc;
index 547349b79689ec31f6e682f28b3502ae15c0c662..deea82647bbec63ba74180e0d8b5f839cee7827d 100644 (file)
@@ -16,20 +16,28 @@ package lx_rocon_pkg is
                mark  : std_logic;
        end record;
        --
-       type IRC_OUTPUT_Type is record
+       type IRC_COUNT_OUTPUT_Type is record
                qcount      : std_logic_vector(7 downto 0);
                index       : std_logic_vector(7 downto 0);
                index_event : std_logic;
+       end record;
+       --
+       type IRC_STATE_OUTPUT_Type is record
                ab_error    : std_logic;
                mark        : std_logic;
        end record;
        --
-       type IRC_SLIM_OUTPUT_Type is record
-               qcount      : std_logic_vector(7 downto 0);
-               index       : std_logic_vector(7 downto 0);
-               index_event : std_logic;
+       type IRC_OUTPUT_Type is record
+               count       : IRC_COUNT_OUTPUT_Type;
+               state       : IRC_STATE_OUTPUT_Type;
        end record;
 
+       -- Arrays
+       type IRC_INPUT_Array_Type         is array (natural range <>) of IRC_INPUT_Type;
+       type IRC_OUTPUT_Array_Type        is array (natural range <>) of IRC_OUTPUT_Type;
+       type IRC_COUNT_OUTPUT_Array_Type  is array (natural range <>) of IRC_COUNT_OUTPUT_Type;
+       type IRC_STATE_OUTPUT_Array_Type  is array (natural range <>) of IRC_STATE_OUTPUT_Type;
+
        -- IRC coprocessor MAIN
        component irc_proc_main
        port
@@ -38,13 +46,10 @@ package lx_rocon_pkg is
                clk_i             : in std_logic;
                reset_i           : in std_logic;
                -- Signals from IRC
-               irc1_i            : in IRC_SLIM_OUTPUT_Type;
-               irc2_i            : in IRC_SLIM_OUTPUT_Type;
-               irc3_i            : in IRC_SLIM_OUTPUT_Type;
-               irc4_i            : in IRC_SLIM_OUTPUT_Type;
+               irc_i             : in IRC_COUNT_OUTPUT_Array_Type(3 downto 0);
                -- Index resetting
                irc_index_reset_o : out std_logic_vector(3 downto 0);
-               -- BRAM access (the other port)
+               -- BRAM access
                mem_clk_i         : in std_logic;
     mem_en_i          : in std_logic;
     mem_we_i          : in std_logic_vector(3 downto 0);
@@ -96,8 +101,8 @@ package lx_rocon_pkg is
                reset_index_event_i : in std_logic;
                reset_ab_error_i    : in std_logic;
                -- Outputs
-    qcount_o            : out std_logic_vector (7 downto 0);
-               qcount_index_o      : out std_logic_vector (7 downto 0);
+    qcount_o            : out std_logic_vector(7 downto 0);
+               qcount_index_o      : out std_logic_vector(7 downto 0);
                index_event_o       : out std_logic;
     a_rise_o, a_fall_o  : out std_logic;
                b_rise_o, b_fall_o  : out std_logic;
@@ -128,6 +133,36 @@ package lx_rocon_pkg is
   );
   end component;
 
+       component crc
+  port
+       (
+               clk_i   : in std_logic;
+    reset_i : in std_logic;
+    input_i : in std_logic;
+    crc_o   : out std_logic_vector(7 downto 0)
+  );
+       end component;
+
+       -- LX Master
+       component lxmaster
+       port
+       (
+               clk_i             : in std_logic;
+               reset_i           : in std_logic;
+               --
+               mosi_o            : out std_logic;
+               clock_o           : out std_logic;
+               sync_o            : out std_logic;
+               -- BRAM access
+               mem_clk_i         : in std_logic;
+    mem_en_i          : in std_logic;
+    mem_we_i          : in std_logic_vector(1 downto 0);
+    mem_addr_i        : in std_logic_vector(8 downto 0);
+    mem_data_i        : in std_logic_vector(15 downto 0);
+    mem_data_o        : out std_logic_vector(15 downto 0)
+       );
+       end component;
+
        --------------------------------------------------------------------------------
        -- TUMBL
        --------------------------------------------------------------------------------
@@ -201,8 +236,7 @@ package lx_rocon_pkg is
                clk_i  : in std_logic;
                ce_i   : in std_logic;
                adr_i  : in std_logic_vector(11 downto 2);
-               wre_i  : in std_logic;
-               bsel_i : in std_logic_vector(3 downto 0);
+               bls_i  : in std_logic_vector(3 downto 0);
                dat_i  : in std_logic_vector(31 downto 0);
                dat_o  : out std_logic_vector(31 downto 0);
                -- Memory wiring for Master CPU
@@ -232,19 +266,27 @@ package lx_rocon_pkg is
        -- MEMORY BUS
        --------------------------------------------------------------------------------
 
-       -- Calibration read register
-       component calibration_read_register
+       -- Measurement register
+       component measurement_register
        generic
        (
                id_g   : std_logic_vector(31 downto 0) := (others => '0')
        );
        port
        (
-               -- Data bus (read only)
-               data_o : out std_logic_vector(31 downto 0);
+               -- Clock
+               clk_i    : in std_logic;
+               -- Reset
+               reset_i  : in std_logic;
+               -- Chip enable
+               ce_i     : in std_logic;
+               -- Switch
+               switch_i : in std_logic;
+               -- Data bus
+               data_i   : in std_logic_vector(31 downto 0);
+               data_o   : out std_logic_vector(31 downto 0);
                -- Bus signals
-               rd_i   : in std_logic;
-               ta_o   : out std_logic
+               bls_i    : in std_logic_vector(3 downto 0)
        );
        end component;
 
@@ -254,53 +296,20 @@ package lx_rocon_pkg is
        (
                clk_i        : in std_logic;
                reset_i      : in std_logic;
-               -- Address (needs just last 4 bits, rest is wired to CE)
-               address_i    : in std_logic_vector(3 downto 0);
-               ce_i         : in std_logic;
                -- Data bus
+               address_i    : in std_logic_vector(3 downto 0);
+               next_ce_i    : in std_logic;
                data_i       : in std_logic_vector(31 downto 0);
                data_o       : out std_logic_vector(31 downto 0);
-               -- Bus signals
-               rd_i         : in std_logic;
+               --
                bls_i        : in std_logic_vector(3 downto 0);
-               ta_o         : out std_logic;
                -- Signals for IRC
-               irc1_i       : in IRC_INPUT_Type;
-               irc2_i       : in IRC_INPUT_Type;
-               irc3_i       : in IRC_INPUT_Type;
-               irc4_i       : in IRC_INPUT_Type;
-               -- Secondary data bus (slave)
-               address_2_i  : in std_logic_vector(3 downto 0);
-               ce_2_i       : in std_logic;
-               --
-               rd_2_i       : in std_logic;
-               bls_2_i      : in std_logic_vector(3 downto 0);
-               ta_2_o       : out std_logic
+               irc_i        : in IRC_INPUT_Array_Type(3 downto 0)
        );
        end component;
 
-       -- Calibration write register
-       component calibration_write_register
-       port
-       (
-               -- Clock
-               clk_i   : in std_logic;
-               -- Reset
-               reset_i : in std_logic;
-               -- Chip enable
-               ce_i    : in std_logic;
-               -- Data bus
-               data_i  : in std_logic_vector(31 downto 0);
-               data_o  : out std_logic_vector(31 downto 0);
-               -- Bus signals
-               rd_i    : in std_logic;
-               bls_i   : in std_logic_vector(3 downto 0);
-               ta_o    : out std_logic
-       );
-       end component;
-
-       -- Calibration interconnect
-       component bus_calibration
+       -- Measurement interconnect
+       component bus_measurement
        port
        (
                -- Clock
@@ -315,9 +324,7 @@ package lx_rocon_pkg is
                data_i    : in std_logic_vector(31 downto 0);
                data_o    : out std_logic_vector(31 downto 0);
                -- Bus signals
-               rd_i      : in std_logic;
-               bls_i     : in std_logic_vector(3 downto 0);
-               ta_o      : out std_logic
+               bls_i     : in std_logic_vector(3 downto 0)
        );
        end component;
 
@@ -326,26 +333,71 @@ package lx_rocon_pkg is
        port
        (
                -- Clock
-               clk_100m_i       : in std_logic;
-               clk_50m_i        : in std_logic;
+               clk_i        : in std_logic;
                -- Chip enable
-               ce_100m_i        : in std_logic;
+               ce_        : in std_logic;
                -- Global Reset
-               reset_100m_i     : in std_logic;
+               reset_     : in std_logic;
                -- Master CPU bus for the memory
-    rd_100m_i        : in std_logic;
-    bls_100m_i       : in std_logic_vector(3 downto 0);
-    address_100m_i   : in std_logic_vector(11 downto 0);
-    data_100m_i      : in std_logic_vector(31 downto 0);
-    data_100m_o      : out std_logic_vector(31 downto 0);
-               ta_100m_o        : out std_logic;
+    bls_i        : in std_logic_vector(3 downto 0);
+    address_i    : in std_logic_vector(11 downto 0);
+    data_i       : in std_logic_vector(31 downto 0);
+    data_o       : out std_logic_vector(31 downto 0);
                -- Tumbl extrenal memory bus
-               xmemb_sel_100m_o : out std_logic;
-               xmemb_100m_i     : in DMEMB2CORE_Type;
-               xmemb_100m_o     : out CORE2DMEMB_Type
+               xmemb_sel_ : out std_logic;
+               xmemb_     : in DMEMB2CORE_Type;
+               xmemb_     : out CORE2DMEMB_Type
   );
        end component;
 
+       -- Register on the bus
+       component bus_register is
+       generic
+       (
+               -- Reset value
+               reset_value_g : std_logic_vector(31 downto 0) := (others => '0');
+               -- Width
+               b0_g          : natural := 8;
+               b1_g          : natural := 8;
+               b2_g          : natural := 8;
+               b3_g          : natural := 8
+       );
+       port
+       (
+               -- Clock
+               clk_i         : in std_logic;
+               -- Reset
+               reset_i       : in std_logic;
+               -- Chip enable
+               ce_i          : in std_logic;
+               -- Data bus
+               data_i        : in std_logic_vector((b0_g+b1_g+b2_g+b3_g-1) downto 0);
+               data_o        : out std_logic_vector((b0_g+b1_g+b2_g+b3_g-1) downto 0);
+               -- Bus signals
+               bls_i         : in std_logic_vector(3 downto 0)
+       );
+       end component;
+
+       -- LX Master bus interconnect
+       component bus_lxmaster
+       port
+       (
+               clk_i        : in std_logic;
+               reset_i      : in std_logic;
+               -- Data bus
+               address_i    : in std_logic_vector(8 downto 0);
+               next_ce_i    : in std_logic;
+               data_i       : in std_logic_vector(15 downto 0);
+               data_o       : out std_logic_vector(15 downto 0);
+               --
+               bls_i        : in std_logic_vector(1 downto 0);
+               -- Signals for LX Master
+               mosi_o       : out std_logic;
+               clock_o      : out std_logic;
+               sync_o       : out std_logic
+       );
+       end component;
+
        --------------------------------------------------------------------------------
        -- BRAM
        --------------------------------------------------------------------------------
index 1d260dfbe018a0056c50c8786256f0b5ff7df4a5..8ed8bbe7e98a6e887839802968740fc8bb4f5834 100644 (file)
@@ -1,8 +1,9 @@
-vhdl work "tumbl/mbl_Pkg.vhd"
+vhdl work "tumbl/mbl_pkg.vhd"
 vhdl work "lx_rocon_pkg.vhd"
 vhdl work "xilinx_dualport_bram_write_first.vhd"
 vhdl work "dff2.vhd"
 vhdl work "xilinx_dualport_bram_no_change.vhd"
+vhdl work "util_pkg.vhd"
 vhdl work "tumbl/mem.vhd"
 vhdl work "tumbl/fetch.vhd"
 vhdl work "tumbl/exeq.vhd"
@@ -13,12 +14,14 @@ vhdl work "lx-rocon_tumbl/lx_rocon_imem.vhd"
 vhdl work "lx-rocon_tumbl/lx_rocon_gprf_abd.vhd"
 vhdl work "lx-rocon_tumbl/lx_rocon_dmem.vhd"
 vhdl work "irc_proc_inc.vhd"
+vhdl work "crc.vhd"
+vhdl work "measurement_register.vhd"
+vhdl work "lxmaster.vhd"
 vhdl work "lx-rocon_tumbl/lx_rocon_tumbl.vhd"
 vhdl work "irc_reader.vhd"
 vhdl work "irc_proc_main.vhd"
-vhdl work "calibration_write_register.vhd"
-vhdl work "calibration_read_register.vhd"
 vhdl work "bus_tumbl.vhd"
+vhdl work "bus_measurement.vhd"
+vhdl work "bus_lxmaster.vhd"
 vhdl work "bus_irc.vhd"
-vhdl work "bus_calibration.vhd"
 vhdl work "lx_rocon_top.vhd"
index 987e40249cf517785487aca1b7b1369017a8eb4f..4e27660805180bdb42052d9a8bbc3dbc7ee7c692 100644 (file)
@@ -7,7 +7,7 @@ use ieee.numeric_std.all;
 library unisim;
 use unisim.vcomponents.all;
 
-use work.mbl_Pkg.all;
+use work.mbl_pkg.all;
 use work.lx_rocon_pkg.all;
 
 -- lx_rocon_top - wires the modules with the outside world
@@ -18,97 +18,102 @@ use work.lx_rocon_pkg.all;
 --
 -- Master cpu memory bus has the following wires:
 --
--- - address[15..0]          The address
+-- - address[15..0]          The address, used to mark chip enable
 -- - data_in[31..0]          The data coming to bus
 -- - data_out[31..0]         The data coming from bus, multiplexed
--- - rd                      Read enable, active LOW
--- - bls[3..0]               Write enable for respective bytes, active LOW
---                           In some cases, only WR is used
--- - ta                      Transaction acknowledge (latches data out), active LOW, multiplexed
+-- - bls[3..0]               Write enable for respective bytes
 
 entity lx_rocon_top is
        port
        (
                -- External
-               --clk_cpu    : in std_logic;
-               clk_50m    : in std_logic;
+               --clk_cpu     : in std_logic;
+               clk_50m     : in std_logic;
                --
-               cs0_xc     : in std_logic;
+               cs0_xc      : in std_logic;
                --
-               rd         : in std_logic;
-               bls        : in std_logic_vector(3 downto 0);
-               address    : in std_logic_vector(15 downto 0);
-               data       : inout std_logic_vector(31 downto 0);
+               rd          : in std_logic;
+               bls         : in std_logic_vector(3 downto 0);
+               address     : in std_logic_vector(15 downto 0);
+               data        : inout std_logic_vector(31 downto 0);
                --
-               irc1_a     : in std_logic;
-               irc1_b     : in std_logic;
-               irc1_index : in std_logic;
-               irc1_mark  : in std_logic;
+               irc1_a      : in std_logic;
+               irc1_b      : in std_logic;
+               irc1_index  : in std_logic;
+               irc1_mark   : in std_logic;
                --
-               irc2_a     : in std_logic;
-               irc2_b     : in std_logic;
-               irc2_index : in std_logic;
-               irc2_mark  : in std_logic;
+               irc2_a      : in std_logic;
+               irc2_b      : in std_logic;
+               irc2_index  : in std_logic;
+               irc2_mark   : in std_logic;
                --
-               irc3_a     : in std_logic;
-               irc3_b     : in std_logic;
-               irc3_index : in std_logic;
-               irc3_mark  : in std_logic;
+               irc3_a      : in std_logic;
+               irc3_b      : in std_logic;
+               irc3_index  : in std_logic;
+               irc3_mark   : in std_logic;
                --
-               irc4_a     : in std_logic;
-               irc4_b     : in std_logic;
-               irc4_index : in std_logic;
-               irc4_mark  : in std_logic;
+               irc4_a      : in std_logic;
+               irc4_b      : in std_logic;
+               irc4_index  : in std_logic;
+               irc4_mark   : in std_logic;
                --
-               init       : in std_logic
+               init        : in std_logic;
+               --
+               s1_clk_out  : out std_logic;
+               s1_sync_out : out std_logic;
+               s1_mosi     : out std_logic
        );
 end lx_rocon_top;
 
 architecture Behavioral of lx_rocon_top is
 
        -- Reset signal
-       signal reset_s             : std_logic;
-       signal neg_init_s          : std_logic;
-       -- 100 MHz clock
-       signal clk_100m_s          : std_logic;
-       signal clk_100m_fb_s       : std_logic;
-       signal clk_100m_locked_s   : std_logic;
-       -- Peripherals on the memory bus
-       signal tumbl_out_s         : std_logic_vector(31 downto 0);
-       signal tumbl_ta_s          : std_logic;
-       signal tumbl_ce_s          : std_logic;
-       --
-       signal irc_reg_out_s       : std_logic_vector(31 downto 0);
-       signal irc_reg_ta_s        : std_logic;
-       signal irc_reg_ce_s        : std_logic;
-       --
-       signal calib_out_s         : std_logic_vector(31 downto 0);
-       signal calib_ta_s          : std_logic;
-       signal calib_ce_s          : std_logic;
+       signal reset_s                 : std_logic;
+       signal init_f_s                : std_logic;
+       signal init_f_r                : std_logic;
+       -- Peripherals on the memory buses
+       -- Master to Tumbl DMEM / IMEM (Master)
+       signal tumbl_out_s              : std_logic_vector(31 downto 0);
+       signal tumbl_ce_s               : std_logic;
+       -- Measurement (Master)
+       signal meas_out_s               : std_logic_vector(31 downto 0);
+       signal meas_ce_s                : std_logic;
+       -- Master to Tumbl XMEM
+       signal master_tumbl_xmem_out_s  : std_logic_vector(31 downto 0);
+       signal master_tumbl_xmem_ce_s   : std_logic;
+       signal master_tumbl_xmem_lock_s : std_logic;
+       -- IRC (Tumbl)
+       signal irc_proc_out_s            : std_logic_vector(31 downto 0);
+       signal irc_proc_ce_s             : std_logic;
+       signal irc_proc_next_ce_s        : std_logic;
+       -- LX Master (Tumbl)
+       signal lxmaster_out_s           : std_logic_vector(15 downto 0);
+       signal lxmaster_ce_s            : std_logic;
+       signal lxmaster_next_ce_s       : std_logic;
        -- Signals for external bus transmission
-       signal data_i_s            : std_logic_vector(31 downto 0);
-       signal data_o_s            : std_logic_vector(31 downto 0);
+       signal data_i_s                 : std_logic_vector(31 downto 0);
+       signal data_o_s                 : std_logic_vector(31 downto 0);
        -- Signals for internal transaction
-       signal last_address_s      : std_logic_vector(15 downto 0);
-       signal last_rd_s           : std_logic;
-       signal last_bls_s          : std_logic_vector(3 downto 0);
+       signal last_address_s           : std_logic_vector(15 downto 0);
+       signal last_rd_s                : std_logic;
+       signal last_bls_s               : std_logic_vector(3 downto 0);
 
-       -- Reading logic:
+       -- Reading logic for Master CPU:
        -- Broadcast rd only till ta (transaction acknowledge)
        -- is received, then latch the data till the state of
        -- rd or address changes
        --
        -- Data latching is synchronous - it's purpose is to
-       -- provide stable data for CPU on the bus on high rise
-       -- of trans. ack signal
+       -- provide stable data for CPU on the bus
        signal rd_f_s              : std_logic; -- Filtered RD
        signal rd_d_s              : std_logic; -- D over RD
-       signal i_ta_s              : std_logic; -- Internal bus TA (active 1)
        signal i_rd_s              : std_logic; -- Internal bus RD (active 1)
+       signal last_i_rd_s         : std_logic; -- Delayed RD bus, used for latching
        --
-       signal data_read_s         : std_logic_vector(31 downto 0); -- Latched read data
+       signal address_f_s         : std_logic_vector(15 downto 0); -- Filtered address
+       signal address_d_s         : std_logic_vector(15 downto 0); -- D over address
        --
-       signal acked_s             : std_logic;
+       signal data_read_s         : std_logic_vector(31 downto 0); -- Latched read data
 
        -- Writing logic:
        signal bls_f_s             : std_logic_vector(3 downto 0); -- Filtered BLS
@@ -118,261 +123,253 @@ architecture Behavioral of lx_rocon_top is
        signal data_write_s        : std_logic_vector(31 downto 0); -- Data broadcasted to write
 
        -- Tumbl:
-       signal tumbl_rd_s          : std_logic;
        signal tumbl_bls_s         : std_logic_vector(3 downto 0);
+       signal tumbl_address_s     : std_logic_vector(14 downto 0);
+       signal tumbl_data_i_s      : std_logic_vector(31 downto 0);
+       --
        signal tumbl_xmemb_o_s     : CORE2DMEMB_Type;
        signal tumbl_xmemb_i_s     : DMEMB2CORE_Type;
-       signal tumbl_sel_s         : std_logic;
-       --
-       signal tumbl_irc_reg_ta_s  : std_logic;
-       signal tumbl_irc_reg_ce_s  : std_logic;
+       signal tumbl_xmemb_sel_s   : std_logic;
 
 begin
 
-       -- Clocking
-       clk_100m_dcm_sp : DCM_SP
-       generic map
+-- Tumbl coprocessor
+memory_bus_tumbl: bus_tumbl
+       port map
        (
-               clkdv_divide          => 2.0,
-               clkfx_divide          => 1,
-               clkfx_multiply        => 2,
-               clkin_divide_by_2     => false,
-               clkin_period          => 20.0, -- 50 MHz
-               clkout_phase_shift    => "NONE",
-               clk_feedback          => "1X",
-               deskew_adjust         => "SYSTEM_SYNCHRONOUS",
-               dfs_frequency_mode    => "LOW",
-               dll_frequency_mode    => "LOW",
-               dss_mode              => "NONE",
-               duty_cycle_correction => true,
-               factory_jf            => X"c080",
-               phase_shift           => 0,
-               startup_wait          => false
-       )
+               clk_i          => clk_50m,
+               reset_i        => reset_s,
+               ce_i           => tumbl_ce_s,
+               bls_i          => i_bls_s,
+               address_i      => address_f_s(11 downto 0),
+               data_i         => data_i_s,
+               data_o         => tumbl_out_s,
+               --
+               xmemb_o        => tumbl_xmemb_o_s,
+               xmemb_i        => tumbl_xmemb_i_s,
+               xmemb_sel_o    => tumbl_xmemb_sel_s
+       );
+
+-- Measurement
+memory_bus_measurement: bus_measurement
        port map
        (
-               clk0                  => clk_100m_fb_s,
-               clk180                => open,
-               clk270                => open,
-               clk2x                 => clk_100m_s,
-               clk2x180              => open,
-               clk90                 => open,
-               clkdv                 => open,
-               clkfx                 => open,
-               clkfx180              => open,
-               locked                => clk_100m_locked_s,
-               psdone                => open,
-               status                => open,
-               clkfb                 => clk_100m_fb_s,
-               clkin                 => clk_50m,
-               dssen                 => '0',
-               psclk                 => '0',
-               psen                  => '0',
-               psincdec              => '0',
-               rst                   => neg_init_s
+               clk_i     => clk_50m,
+               reset_i   => reset_s,
+               ce_i      => meas_ce_s,
+               address_i => address_f_s(1 downto 0),
+               bls_i     => i_bls_s,
+               data_i    => data_i_s,
+               data_o    => meas_out_s
        );
 
-       -- IRC interconnect
-       memory_bus_irc: bus_irc
+-- IRC interconnect
+memory_bus_irc: bus_irc
        port map
        (
-               clk_i        => clk_100m_s,
-               reset_i      => reset_s,
-               address_i    => address(3 downto 0),
-               ce_i         => irc_reg_ce_s,
-               data_i       => data_i_s,
-               data_o       => irc_reg_out_s,
-               rd_i         => i_rd_s,
-               bls_i        => i_bls_s,
-               ta_o         => irc_reg_ta_s,
+               reset_i        => reset_s,
                --
-               address_2_i  => tumbl_xmemb_o_s.addr(3 downto 0),
-               ce_2_i       => tumbl_irc_reg_ce_s,
-               rd_2_i       => tumbl_rd_s,
-               bls_2_i      => tumbl_bls_s,
-               ta_2_o       => tumbl_irc_reg_ta_s,
+               clk_i          => clk_50m,
+               address_i      => tumbl_address_s(3 downto 0),
+               next_ce_i      => irc_proc_next_ce_s,
+               data_i         => tumbl_data_i_s,
+               data_o         => irc_proc_out_s,
+               bls_i          => tumbl_bls_s,
                --
-               irc1_i.a     => irc1_a,
-               irc1_i.b     => irc1_b,
-               irc1_i.index => irc1_index,
-               irc1_i.mark  => irc1_mark,
+               irc_i(0).a     => irc1_a,
+               irc_i(0).b     => irc1_b,
+               irc_i(0).index => irc1_index,
+               irc_i(0).mark  => irc1_mark,
                --
-               irc2_i.a     => irc2_a,
-               irc2_i.b     => irc2_b,
-               irc2_i.index => irc2_index,
-               irc2_i.mark  => irc2_mark,
+               irc_i(1).a     => irc2_a,
+               irc_i(1).b     => irc2_b,
+               irc_i(1).index => irc2_index,
+               irc_i(1).mark  => irc2_mark,
                --
-               irc3_i.a     => irc3_a,
-               irc3_i.b     => irc3_b,
-               irc3_i.index => irc3_index,
-               irc3_i.mark  => irc3_mark,
+               irc_i(2).a     => irc3_a,
+               irc_i(2).b     => irc3_b,
+               irc_i(2).index => irc3_index,
+               irc_i(2).mark  => irc3_mark,
                --
-               irc4_i.a     => irc4_a,
-               irc4_i.b     => irc4_b,
-               irc4_i.index => irc4_index,
-               irc4_i.mark  => irc4_mark
+               irc_i(3).a     => irc4_a,
+               irc_i(3).b     => irc4_b,
+               irc_i(3).index => irc4_index,
+               irc_i(3).mark  => irc4_mark
        );
 
-       -- Tumbl coprocessor
-       memory_bus_tumbl: bus_tumbl
+-- LX Master
+memory_bus_lxmaster: bus_lxmaster
        port map
        (
-               clk_100m_i        => clk_100m_s,
-               clk_50m_i         => clk_50m,
-               reset_100m_i      => reset_s,
-               ce_100m_i         => tumbl_ce_s,
-               ta_100m_o         => tumbl_ta_s,
-               rd_100m_i         => i_rd_s,
-               bls_100m_i        => i_bls_s,
-               address_100m_i    => address(11 downto 0),
-               data_100m_i       => data_i_s,
-               data_100m_o       => tumbl_out_s,
+               reset_i        => reset_s,
                --
-               xmemb_100m_o      => tumbl_xmemb_o_s,
-               xmemb_100m_i      => tumbl_xmemb_i_s,
-               xmemb_sel_100m_o  => tumbl_sel_s
-       );
-
-       -- Calibration
-       memory_bus_calibration: bus_calibration
-       port map
-       (
-               clk_i     => clk_100m_s,
-               reset_i   => reset_s,
-               ce_i      => calib_ce_s,
-               address_i => address(1 downto 0),
-               rd_i      => i_rd_s,
-               bls_i     => i_bls_s,
-               ta_o      => calib_ta_s,
-               data_i    => data_i_s,
-               data_o    => calib_out_s
+               clk_i          => clk_50m,
+               address_i      => tumbl_address_s(8 downto 0),
+               next_ce_i      => lxmaster_next_ce_s,
+               data_i         => tumbl_data_i_s(15 downto 0),
+               data_o         => lxmaster_out_s,
+               bls_i          => tumbl_bls_s(1 downto 0),
+               --
+               mosi_o         => s1_mosi,
+               clock_o        => s1_clk_out,
+               sync_o         => s1_sync_out
        );
 
        -- Filters
        --bls_f <= bls when bls = bls_d else "1111";
-       bls_f_s(0) <= bls(0) when bls(0) = bls_d_s(0) else '1';
-       bls_f_s(1) <= bls(2) when bls(2) = bls_d_s(2) else '1';
-       bls_f_s(2) <= bls(2) when bls(2) = bls_d_s(2) else '1';
-       bls_f_s(3) <= bls(3) when bls(3) = bls_d_s(3) else '1';
-       rd_f_s     <= rd when rd = rd_d_s else '1';
+       bls_f_s(0)  <= bls(0) when bls(0) = bls_d_s(0) else '1';
+       bls_f_s(1)  <= bls(2) when bls(2) = bls_d_s(2) else '1'; -- FIXME: BLS(1) not soldered properly on my board
+       bls_f_s(2)  <= bls(2) when bls(2) = bls_d_s(2) else '1';
+       bls_f_s(3)  <= bls(3) when bls(3) = bls_d_s(3) else '1';
+       rd_f_s      <= rd when rd = rd_d_s else '1';
+       address_f_s <= address when address = address_d_s else last_address_s; -- Use last address on mismatch!
+
+       -- Signalling
+       data_i_s   <= data_write_s when i_bls_s /= "0000" else (others => '0');
 
        -- Tumbl
-       tumbl_rd_s  <= tumbl_xmemb_o_s.ena when (tumbl_sel_s = '1') else '0';
-       tumbl_bls_s <= tumbl_xmemb_o_s.bSel when (tumbl_sel_s = '1' and tumbl_xmemb_o_s.wre = '1') else "0000";
+       tumbl_bls_s     <= i_bls_s when (master_tumbl_xmem_lock_s = '1')
+                          else tumbl_xmemb_o_s.bls when (tumbl_xmemb_sel_s = '1')
+                          else "0000";
+       tumbl_address_s <= address_f_s(14 downto 0) when (master_tumbl_xmem_lock_s = '1')
+                          else tumbl_xmemb_o_s.addr when (tumbl_xmemb_sel_s = '1')
+                          else (others => '0');
+       tumbl_data_i_s  <= data_i_s when (master_tumbl_xmem_lock_s = '1')
+                          else tumbl_xmemb_o_s.data when (tumbl_xmemb_sel_s = '1')
+                          else (others => '0');
        --
        tumbl_xmemb_i_s.int <= '0'; -- No interrupt
-       -- Bus update
+       -- Enable clken only when available for Tumbl
+       tumbl_xmemb_i_s.clken <= not master_tumbl_xmem_lock_s;
+
+-- Bus update
 memory_bus_update:
-       process(clk_100m_s)
+       process
        begin
 
-               if clk_100m_s = '1' and clk_100m_s'event then
-
-                       -- ======================================================
-                       --  MASTER CPU
-                       -- ======================================================
-
-                       -- Set every signal to inactive state here
-                       irc_reg_ce_s  <= '0';
-                       tumbl_ce_s    <= '0';
-                       calib_ce_s    <= '0';
-                       i_rd_s        <= '0';
-                       i_bls_s       <= (others => '0');
-
-                       -- Check if we have chip select
-                       if reset_s = '1' then
-                               acked_s     <= '1';
-                               i_ta_s      <= '0';
-                               data_read_s <= (others => '0');
-                       elsif cs0_xc = '0' then
-
-                               -- Memory Map (16-bit address @ 32-bit each)
-
-                               -- Each address is seen as 32-bit entry now
-                               -- 0x0000 - 0x0FFF: Tumbl
-                               -- 0x8000 - 0x800F: IRC registers
-                               -- 0xFFFC - 0xFFFF: Calibration
-
-                               if address < "0001000000000000" then               -- Tumbl
-                                       tumbl_ce_s   <= '1';
-                                       i_ta_s       <= tumbl_ta_s;
-                                       data_o_s     <= tumbl_out_s;
-                               elsif address(15 downto 4) = "100000000000" then   -- IRC
-                                       irc_reg_ce_s <= '1';
-                                       i_ta_s       <= irc_reg_ta_s;
-                                       data_o_s     <= irc_reg_out_s;
-                               elsif address(15 downto 2) = "11111111111111" then -- Calibration
-                                       calib_ce_s   <= '1';
-                                       i_ta_s       <= calib_ta_s;
-                                       data_o_s     <= calib_out_s;
+               wait until clk_50m = '1' and clk_50m'event;
+
+               -- Defaults
+               i_bls_s <= "0000";
+               i_rd_s  <= '0';
+
+               -- Check if we have chip select
+               if cs0_xc = '0' then
+
+                       -- Reading
+                       if rd_f_s = '0' then
+
+                               -- Internal read
+                               if (last_rd_s = '1' or last_address_s /= address_f_s) then
+                                       i_rd_s <= '1';
                                end if;
 
-                               -- Reading
-                               if rd_f_s = '0' then
-                                       if last_rd_s = '1' or last_address_s /= address then
-                                               -- Getting something new
-                                               -- Set internal RD to active and reset ack and latched data
-                                               acked_s      <= '0';
-                                               i_rd_s       <= '1';
-                                               -- Data latching - synchronous
-                                               data_read_s  <= (others => 'X');
-                                       elsif i_rd_s = '1' and acked_s = '0' and i_ta_s = '1' then
-                                               -- Got acknowledge, latch data
-                                               acked_s      <= '1';
-                                               data_read_s  <= data_o_s;
-                                       elsif acked_s = '0' then
-                                               -- Ongoing read, keep the signal active
-                                               i_rd_s       <= '1';
-                                               data_read_s  <= (others => 'X');
-                                       end if;
-
-                                       last_address_s <= address;
-                               else
-                                       -- Not reading, anything goes
-                                       data_read_s    <= (others => 'X');
+                               if i_rd_s = '0' and last_i_rd_s = '1' then
+                                       -- Latch data we just read - they are valid in this cycle
+                                       data_read_s  <= data_o_s;
                                end if;
 
-                               last_rd_s        <= rd_f_s;
+                               last_address_s <= address_f_s;
+                       else
+                               -- Not reading, anything goes
+                               data_read_s    <= (others => 'X');
+                       end if;
 
-                               -- Writing
-                               if bls_f_s /= "1111" then
+                       last_rd_s        <= rd_f_s;
 
-                                       if last_bls_s /= bls_f_s or last_address_s /= address then
-                                               -- Broadcast BLS for once cycle to write the data
-                                               i_bls_s      <= not bls_f_s;
-                                               -- Data broadcasting is in a separate process
-                                       end if;
+                       -- Writing
+                       if bls_f_s /= "1111" then
 
-                                       last_address_s <= address;
+                               -- Internal write
+                               if (last_bls_s /= bls_f_s or last_address_s /= address_f_s) then
+                                       i_bls_s      <= not bls_f_s;
                                end if;
 
-                               last_bls_s       <= bls_f_s;
+                               last_address_s <= address_f_s;
+                       end if;
 
-                       else
+                       last_bls_s       <= bls_f_s;
 
-                               -- Set last read / bls to '1' if CS0 is not asserted
-                               last_rd_s        <= '1';
-                               last_bls_s       <= (others => '1');
+               else
 
-                       end if;
+                       -- Set last read / bls to '1' if CS0 is not asserted
+                       last_rd_s        <= '1';
+                       last_bls_s       <= (others => '1');
+                       last_address_s   <= address_d_s;
+
+               end if;
+
+               -- Filters
+               bls_d_s     <= bls;
+               rd_d_s      <= rd;
+               address_d_s <= address;
+               --
+               last_i_rd_s <= i_rd_s;
 
-                       -- Filters
-                       bls_d_s <= bls;
-                       rd_d_s  <= rd;
+               -- ======================================================
+               --  TUMBL BUS
+               -- ======================================================
+
+               -- Just copy these to their desired next state
+               irc_proc_ce_s <= irc_proc_next_ce_s;
+               lxmaster_ce_s <= lxmaster_next_ce_s;
+
+               -- Other
+               init_f_s <= init;
+               init_f_r <= init_f_s;
+
+       end process;
+
+-- Do the actual wiring here
+memory_bus_wiring:
+       process(cs0_xc, address_f_s, tumbl_out_s, meas_out_s, master_tumbl_xmem_out_s)
+       begin
+
+               -- Inactive by default
+               tumbl_ce_s             <= '0';
+               meas_ce_s              <= '0';
+               master_tumbl_xmem_ce_s <= '0';
+               data_o_s               <= (others => '0');
+
+               if cs0_xc = '0' then
+
+                       -- Memory Map (16-bit address @ 32-bit each)
+
+                       -- Each address is seen as 32-bit entry now
+                       -- 0x0000 - 0x0FFF: Tumbl IMEM / DMEM
+                       -- 0x1FFC - 0x1FFF: Measurement
+                       -- 0x8000 - 0x8FFF: Tumbl BUS
+
+                       if address_f_s < "0001000000000000" then                  -- Tumbl
+                               tumbl_ce_s             <= '1';
+                               data_o_s               <= tumbl_out_s;
+                       elsif address_f_s(15 downto 2) = "00011111111111" then    -- Measurement
+                               meas_ce_s              <= '1';
+                               data_o_s               <= meas_out_s;
+                       elsif address_f_s(15) = '1' then                          -- Tumbl External BUS
+                               master_tumbl_xmem_ce_s <= '1';
+                               data_o_s               <= master_tumbl_xmem_out_s;
+                       end if;
 
                end if;
 
        end process;
 
-       -- If RD and BLS is not high, we must keep DATA at high impedance
-       -- or the FPGA collides with SDRAM (damaging each other)
+-- If RD and BLS is not high, we must keep DATA at high impedance
+-- or the FPGA collides with SDRAM (damaging each other)
 memory_bus_out:
        process(cs0_xc, rd, data, data_read_s)
        begin
 
                -- CS0 / RD / BLS are active LOW
                if cs0_xc = '0' and rd = '0' then
+                       -- Don't risk flipping (between data_o_s and latched data_read_s, it's better to wait)
+                       -- Maybe check this later.
+                       -- if last_i_rd_s = '1' then
+                       --   data <= data_o_s;
+                       -- else
                        data <= data_read_s;
+                       -- end if;
                else
                        -- IMPORTANT!!!
                        data <= (others => 'Z');
@@ -382,57 +379,71 @@ memory_bus_out:
 
        end process;
 
-tumbl_bus:
-       process(tumbl_sel_s, tumbl_xmemb_o_s, tumbl_irc_reg_ta_s, irc_reg_out_s, cs0_xc)
+-- Outputs from Tumbl (enabling and address muxing) and Master CPU
+tumbl_bus_o:
+       process(tumbl_xmemb_sel_s, tumbl_xmemb_o_s, master_tumbl_xmem_ce_s, address_f_s, i_rd_s, i_bls_s)
+               variable addr_v : std_logic_vector(14 downto 0); -- This space is visible by both (32-bit)
+               variable sel_v  : std_logic;
        begin
 
-               -- ======================================================
-               --  TUMBL
-               -- ======================================================
-
-               -- This is purely internal slave bus
-
                -- Defaults
-               tumbl_xmemb_i_s.clken <= '1'; -- No haltfire :-)
-               tumbl_xmemb_i_s.data  <= (others => 'X');
-               tumbl_irc_reg_ce_s    <= '0';
-
-               if tumbl_sel_s = '1' then
-                       -- IRC 0x1000 - 0x100F
-                       if tumbl_xmemb_o_s.addr(12) = '1' then
-                               tumbl_irc_reg_ce_s    <= '1';
-                               tumbl_xmemb_i_s.clken <= tumbl_irc_reg_ta_s;
-                               -- Cannot latch here (too cost, abort if bad timing)
-                               tumbl_xmemb_i_s.data  <= irc_reg_out_s;
-                               -- Data writing and signal is done elsewhere
+               irc_proc_next_ce_s        <= '0';
+               lxmaster_next_ce_s        <= '0';
+               master_tumbl_xmem_lock_s  <= '0';
+               --
+               addr_v                    := (others => '0');
+               sel_v                     := '0';
+
+               -- Check who is accessing
+               if master_tumbl_xmem_ce_s = '1' and (i_rd_s = '1' or i_bls_s /= "0000") then
+                       -- Master blocks Tumbl
+                       master_tumbl_xmem_lock_s <= '1';
+                       addr_v                   := address_f_s(14 downto 0);
+                       sel_v                    := '1';
+               else
+                       addr_v                   := tumbl_xmemb_o_s.addr;
+                       sel_v                    := '1';
+               end if;
+
+               if sel_v = '1' then
+                       -- IRC:       0x0800 - 0x080F (32-bit address)
+                       -- LX MASTER: 0x0A00 - 0x0BFF (32-bit address)
+                       if addr_v(14 downto 4) = "00010000000" then
+                               irc_proc_next_ce_s     <= '1';
+                       elsif addr_v(14 downto 9) = "000101" then
+                               lxmaster_next_ce_s     <= '1';
                        end if;
                end if;
 
        end process;
 
-       -- Data broadcast
-data_i_write:
-       process(cs0_xc, bls_f_s, data_write_s, tumbl_sel_s, tumbl_bls_s, tumbl_xmemb_o_s)
+-- Inputs to Tumbl (enabling and address muxing)
+tumbl_bus_i:
+       process(irc_proc_ce_s, irc_proc_out_s, lxmaster_ce_s, lxmaster_out_s, tumbl_xmemb_i_s)
        begin
 
-               if cs0_xc = '0' and bls_f_s /= "1111" then -- External, log. 0 active
-                       data_i_s <= data_write_s;
-               elsif tumbl_sel_s = '1' and tumbl_bls_s /= "0000" then -- Internal, log. 1 active
-                       data_i_s <= tumbl_xmemb_o_s.data;
-               else
-                       data_i_s <= (others => 'X');
+               tumbl_xmemb_i_s.data  <= (others => 'X');
+
+               -- NOTE: This is input to Tumbl EXEQ - with MUL instruction for input > 18-bit,
+               -- (i.e. more DSPs in a sequence), this already has tough timing constraints
+               -- and SmartXplorer has to be used with XiSE or use Synplify.
+               if irc_proc_ce_s = '1' then
+                       tumbl_xmemb_i_s.data <= irc_proc_out_s;
+               elsif lxmaster_ce_s = '1' then
+                       tumbl_xmemb_i_s.data(15 downto 0)  <= lxmaster_out_s;
+                       tumbl_xmemb_i_s.data(31 downto 16) <= (others => '0');
                end if;
 
+               master_tumbl_xmem_out_s <= tumbl_xmemb_i_s.data;
+
        end process;
 
-       -- Reset
+-- Reset
 initialization:
-       process(init, clk_100m_locked_s)
+       process(init_f_s, init_f_r)
        begin
 
-               -- TODO: Proper reset (lacks filter and propagation with ack as we use PLL)
-               neg_init_s <= not init;
-               reset_s <= (not init) or (not clk_100m_locked_s);
+               reset_s <= (not init_f_s) and (not init_f_r);
 
        end process;
 
diff --git a/hw/lxmaster.vhd b/hw/lxmaster.vhd
new file mode 100644 (file)
index 0000000..262a4e6
--- /dev/null
@@ -0,0 +1,260 @@
+library ieee;
+use ieee.std_logic_1164.all;
+use ieee.std_logic_unsigned.all;
+use ieee.numeric_std.all;
+use work.util_pkg.all;
+use work.lx_rocon_pkg.all;
+
+-- LX Master
+entity lxmaster is
+       port
+       (
+               clk_i             : in std_logic;
+               reset_i           : in std_logic;
+               --
+               mosi_o            : out std_logic;
+               clock_o           : out std_logic;
+               sync_o            : out std_logic;
+               -- BRAM access
+               mem_clk_i         : in std_logic;
+    mem_en_i          : in std_logic;
+    mem_we_i          : in std_logic_vector(1 downto 0);
+    mem_addr_i        : in std_logic_vector(8 downto 0);
+    mem_data_i        : in std_logic_vector(15 downto 0);
+    mem_data_o        : out std_logic_vector(15 downto 0)
+       );
+end lxmaster;
+
+architecture Behavioral of lxmaster is
+
+       -- Types
+       type state_t is (ST_BEGIN, ST_DECIDE, ST_PREINIT, ST_INIT, ST_READY, ST_XFER, ST_CRC, ST_END);
+       constant frame_length_c         : positive := 2500; -- 50 MHz -> 20 kHz
+       -- RAM Access (both ARM and Tumbl)
+       signal ram_en_s                 : std_logic;
+       signal ram_rst_s                : std_logic;
+       --
+       signal ram_addr_s               : std_logic_vector(8 downto 0);
+       signal ram_data_o_s             : std_logic_vector(15 downto 0);
+       -- State
+       signal lxmaster_state_s         : state_t;
+       signal lxmaster_not_last_word_s : std_logic;
+       -- Data
+       signal lxmaster_num_data_s      : std_logic_vector(7 downto 0); -- If 0 then the peripheral is not active this cycle
+       signal lxmaster_loaded_data_s   : std_logic_vector(15 downto 0);
+       signal lxmaster_data_counter_s  : std_logic_vector(3 downto 0); -- Shift: 0 - 15
+       -- Transmission
+       signal lxmaster_sync_s          : std_logic;
+       -- Frame counter
+       signal lxmaster_frame_counter_s : natural range 0 to (frame_length_c-1);
+       -- CRC
+       signal lxmaster_crc_data_s      : std_logic;
+       signal lxmaster_crc_reset_s     : std_logic;
+       signal lxmaster_crc_out_s       : std_logic_vector(7 downto 0);
+       -- RAM reset
+       signal lxmaster_ram_reset_s     : std_logic;
+
+begin
+
+       -- Directly route out some signals
+       clock_o              <= clk_i; -- Cannot mix with logic
+       sync_o               <= not lxmaster_sync_s; -- Active in log. 0
+       mosi_o               <= '1' when lxmaster_sync_s = '0'
+                                else lxmaster_crc_out_s(0) when lxmaster_state_s = ST_CRC
+                                else lxmaster_loaded_data_s(0);
+       -- CRC
+       lxmaster_crc_data_s  <= '1' when lxmaster_state_s = ST_CRC else lxmaster_loaded_data_s(0);
+       lxmaster_crc_reset_s <= '1' when lxmaster_state_s = ST_READY or reset_i = '1' else '0';
+
+ram: xilinx_dualport_bram_write_first
+       generic map
+       (
+               we_width      => 2,
+               byte_width    => 8,
+               address_width => 9
+       )
+       port map
+       (
+               -- Internal
+               clka  => clk_i,
+               rsta  => ram_rst_s,
+               ena   => ram_en_s,
+               wea   => (others => '0'),
+               addra => ram_addr_s,
+               dina  => (others => '0'),
+               douta => ram_data_o_s,
+               -- External
+               clkb  => mem_clk_i,
+               rstb  => '0',
+               enb   => mem_en_i,
+               web   => mem_we_i,
+               addrb => mem_addr_i,
+               dinb  => mem_data_i,
+               doutb => mem_data_o
+       );
+
+crc_out: crc
+       port map
+       (
+               clk_i   => clk_i,
+               reset_i => lxmaster_crc_reset_s,
+               input_i => lxmaster_crc_data_s,
+               crc_o   => lxmaster_crc_out_s
+       );
+
+       ram_rst_s <= reset_i or lxmaster_ram_reset_s;
+
+-- This function toggles outputs directly, make sure the outputs
+-- are updated with clock.
+-- TODO: When finalized, all RAM enabling to happen immediatelly, not with next cycle!
+-- TODO: Maybe some exception handling (overflows etc.)
+update:
+       process
+               variable ram_addr_v : std_logic_vector(8 downto 0);
+       begin
+
+               wait until clk_i'event and clk_i = '1';
+
+               lxmaster_ram_reset_s       <= '0';
+
+               if reset_i = '1' then
+                       lxmaster_frame_counter_s <= 0;
+                       lxmaster_num_data_s      <= x"00";
+                       lxmaster_loaded_data_s   <= x"0000";
+                       lxmaster_state_s         <= ST_BEGIN;
+                       lxmaster_sync_s          <= '0';
+
+                       ram_addr_s               <= '0' & x"00";
+                       ram_en_s                 <= '1';
+               else
+                       -- OK, we are enabled, default values
+                       lxmaster_sync_s          <= '0'; -- Not transferring
+                       ram_en_s                 <= '0'; -- Not reading
+
+                       case lxmaster_state_s is
+                               when ST_BEGIN =>
+                                       -- We're reading address 0x000 now
+                                       lxmaster_state_s         <= ST_DECIDE;
+
+                               when ST_DECIDE =>
+                                       -- We just read address 0, check which buffer we should use
+                                       if ram_data_o_s(15) = '0' then
+                                               ram_addr_s             <= '0' & x"00"; -- First buffer
+                                       else
+                                               ram_addr_s             <= '1' & x"00"; -- Second buffer
+                                       end if;
+
+                                       ram_en_s                 <= '1'; -- Read
+                                       lxmaster_state_s         <= ST_PREINIT; -- Go to second decide
+
+                               when ST_PREINIT =>
+                                       -- Advance reading
+                                       ram_addr_s               <= ram_addr_s + 1; -- Update address
+                                       ram_en_s                 <= '1'; -- Read
+                                       lxmaster_state_s         <= ST_INIT; -- Go to init
+
+                               when ST_INIT =>
+                                       -- We just read number of commands
+                                       if ram_data_o_s(7 downto 0) = x"00" then
+                                               lxmaster_state_s       <= ST_END; --Nothing
+                                       else
+                                               lxmaster_state_s       <= ST_READY; -- Make next read init the transfer
+                                       end if;
+
+                                       -- Regardless, write the number of data
+                                       lxmaster_num_data_s      <= ram_data_o_s(7 downto 0);
+
+                               -- No need to forward it here
+                               when ST_READY =>
+                                       -- We have first word on data and start transfer
+                                       lxmaster_loaded_data_s       <= ram_data_o_s;
+                                       lxmaster_sync_s              <= '1'; -- Transferring data next cycle
+                                       lxmaster_data_counter_s      <= x"0"; -- Reset counter
+                                       lxmaster_state_s             <= ST_XFER; --Go to transfer loop
+                                       lxmaster_not_last_word_s     <= '0'; -- Not last word
+
+                               when ST_XFER =>
+                                       lxmaster_loaded_data_s       <= '0' & lxmaster_loaded_data_s(15 downto 1); -- Shift it
+                                       lxmaster_sync_s              <= '1'; -- Transferring data next cycle
+
+                                       if lxmaster_data_counter_s = x"D" and ram_addr_s(7 downto 0) /= lxmaster_num_data_s then
+                                               -- At 13th bit, we need to read from RAM if more words are to come (RAM address starts with 1 for data!)
+                                               ram_addr_s                 <= ram_addr_s + 1; -- Update address
+                                               lxmaster_data_counter_s    <= lxmaster_data_counter_s + 1; -- Increment
+                                               ram_en_s                   <= '1'; -- Read
+                                               lxmaster_not_last_word_s   <= '1';
+                                       elsif lxmaster_data_counter_s = x"F" then
+                                               -- At 15th bit, we either stop if ram_addr_s equals lxmaster_num_data_s (wasn't updated so it would not overflow)
+                                               if ram_addr_s(7 downto 0) = lxmaster_num_data_s and lxmaster_not_last_word_s = '0' then
+                                                       lxmaster_state_s         <= ST_CRC;
+                                                       lxmaster_data_counter_s  <= x"0";
+                                               else
+                                                       lxmaster_loaded_data_s   <= ram_data_o_s;
+                                                       lxmaster_data_counter_s  <= x"0";
+                                                       lxmaster_not_last_word_s <= '0';
+                                               end if;
+                                       else
+                                               -- Increment
+                                               lxmaster_data_counter_s    <= lxmaster_data_counter_s + 1;
+                                       end if;
+
+                               when ST_CRC =>
+
+                                       -- Check if this is last command, first read one more
+                                       if lxmaster_data_counter_s = x"0" then
+                                               if (ram_addr_s(7 downto 0) = x"FF") then
+                                                       lxmaster_ram_reset_s     <= '1'; -- Make sure we read 0 in this case
+                                               end if;
+
+                                               ram_addr_s                 <= ram_addr_s + 1; -- Update address
+                                               ram_en_s                   <= '1'; -- Read
+                                       elsif lxmaster_data_counter_s = x"2" then
+
+                                               if ram_data_o_s(7 downto 0) /= x"00" then -- Need to read first command
+                                                       ram_addr_v               := ram_addr_s(8) & ram_data_o_s(15 downto 8); -- Update address
+                                                       ram_addr_s               <= ram_addr_v;
+                                                       lxmaster_num_data_s      <= std_logic_vector(unsigned(ram_addr_v(7 downto 0)) + unsigned(ram_data_o_s(7 downto 0)));
+                                                       ram_en_s                 <= '1'; -- Read
+                                               else
+                                                       lxmaster_num_data_s      <= x"00"; -- Signalize termination
+                                               end if;
+
+                                       end if;
+
+                                       if lxmaster_data_counter_s = x"7" then -- Ending
+                                               lxmaster_data_counter_s    <= x"0";
+
+                                               if lxmaster_num_data_s(7 downto 0) = x"00" then
+                                                       lxmaster_state_s         <= ST_END; -- Last command
+                                               else
+                                                       -- We are at init at the moment
+                                                       lxmaster_state_s         <= ST_READY; -- Sync goes inactive for a cycle
+                                               end if;
+
+                                       else
+                                               lxmaster_sync_s            <= '1'; -- Transferring data next cycle
+                                               lxmaster_data_counter_s    <= lxmaster_data_counter_s + 1; -- Increment
+                                       end if;
+
+                               when ST_END =>
+                                       if lxmaster_frame_counter_s = (frame_length_c - 1) then
+                                               -- Initialize first step
+                                               lxmaster_state_s           <= ST_BEGIN;
+                                               ram_addr_s                 <= '0' & x"00";
+                                               ram_en_s                   <= '1';
+                                       end if;
+
+                       end case;
+
+                       -- Increment counter
+                       if lxmaster_frame_counter_s = (frame_length_c - 1) then
+                               lxmaster_frame_counter_s <= 0;
+                       else
+                               lxmaster_frame_counter_s <= lxmaster_frame_counter_s + 1;
+                       end if;
+
+               end if;
+
+       end process;
+
+end Behavioral;
diff --git a/hw/measurement_register.vhd b/hw/measurement_register.vhd
new file mode 100644 (file)
index 0000000..5192694
--- /dev/null
@@ -0,0 +1,71 @@
+library ieee;
+use ieee.std_logic_1164.all;
+use ieee.std_logic_arith.all;
+use ieee.std_logic_unsigned.all;
+use ieee.numeric_std.all;
+use work.lx_rocon_pkg.all;
+
+-- Transaction measurement register
+
+entity measurement_register is
+       generic
+       (
+               id_g   : std_logic_vector(31 downto 0) := (others => '0')
+       );
+       port
+       (
+               -- Clock
+               clk_i    : in std_logic;
+               -- Reset
+               reset_i  : in std_logic;
+               -- Chip enable
+               ce_i     : in std_logic;
+               -- Switch
+               switch_i : in std_logic;
+               -- Data bus
+               data_i   : in std_logic_vector(31 downto 0);
+               data_o   : out std_logic_vector(31 downto 0);
+               -- Bus signals
+               bls_i    : in std_logic_vector(3 downto 0)
+       );
+end measurement_register;
+
+architecture Behavioral of measurement_register is
+       signal value_s : std_logic_vector(31 downto 0);
+begin
+
+       data_o <= value_s when switch_i = '1' else id_g;
+
+-- Write waits for clock
+memory_bus_write:
+       process
+       begin
+
+               wait until clk_i'event and clk_i = '1';
+
+               if reset_i = '1' then
+                       value_s <= (others => '0');
+               else
+
+                       if ce_i = '1' and bls_i /= "0000" then
+
+                               if bls_i(0) = '1' then
+                                       value_s(7 downto 0)   <= data_i(7 downto 0);
+                               end if;
+                               if bls_i(1) = '1' then
+                                       value_s(15 downto 8)  <= data_i(15 downto 8);
+                               end if;
+                               if bls_i(2) = '1' then
+                                       value_s(23 downto 16) <= data_i(23 downto 16);
+                               end if;
+                               if bls_i(3) = '1' then
+                                       value_s(31 downto 24) <= data_i(31 downto 24);
+                               end if;
+
+                       end if;
+               end if;
+
+       end process;
+
+end Behavioral;
+
index 8eef2f054d17902ec91957c008deaa916b28a378..8dcbe5cc3eedf09a640f6c33056338aa0926c94d 100644 (file)
@@ -45,7 +45,7 @@ architecture behavioral of qcounter is
   signal count_index_s      : std_logic_vector (7 downto 0);
 
 begin
-       dff_a: dff2
+dff_a: dff2
        port map
        (
                clk_i   => clk_i,
@@ -54,7 +54,7 @@ begin
                q_o     => a_s
        );
 
 dff_b: dff2
+ dff_b: dff2
        port map
        (
                clk_i   => clk_i,
@@ -63,7 +63,7 @@ begin
                q_o     => b_s
        );
 
-       dff_index: dff2
+dff_index: dff2
        port map
        (
                clk_i   => clk_i,
@@ -153,36 +153,36 @@ comb_count:
   end process;
 
 seq:
-       process (clk_i)
+       process
        begin
                -- Reset for qcounter is synchronous and lasts at least one more cycle
                -- to prevent hazardous states after releasing it
-               if clk_i = '1' and clk_i'event then
-                       if reset_i = '1' then
-                               count_prev_s        <= (others => '0');
-                               count_index_prev_s  <= (others => '0');
-                               index_event_int_s   <= '0';
-                               ab_error_int_s      <= '0';
+               wait until clk_i'event and clk_i = '1';
+
+               if reset_i = '1' then
+                       count_prev_s        <= (others => '0');
+                       count_index_prev_s  <= (others => '0');
+                       index_event_int_s   <= '0';
+                       ab_error_int_s      <= '0';
+               else
+                       count_prev_s        <= count_s;
+                       count_index_prev_s  <= count_index_s;
+                       --
+                       if reset_index_event_i = '1' then
+                               index_event_int_s <= '0';
                        else
-                               count_prev_s        <= count_s;
-                               count_index_prev_s  <= count_index_s;
-                               --
-                               if reset_index_event_i = '1' then
-                                       index_event_int_s <= '0';
-                               else
-                                       index_event_int_s <= index_event_int_s or index_event_s;
-                               end if;
-                               --
-                               if reset_ab_error_i = '1' then
-                                       ab_error_int_s    <= '0';
-                               else
-                                       ab_error_int_s    <= ab_error_int_s or ab_error_s;
-                               end if;
+                               index_event_int_s <= index_event_int_s or index_event_s;
+                       end if;
+                       --
+                       if reset_ab_error_i = '1' then
+                               ab_error_int_s    <= '0';
+                       else
+                               ab_error_int_s    <= ab_error_int_s or ab_error_s;
                        end if;
-                       a_prev_s              <= a_s;
-                       b_prev_s              <= b_s;
-                       last_reset_s          <= reset_i;
                end if;
+               a_prev_s              <= a_s;
+               b_prev_s              <= b_s;
+               last_reset_s          <= reset_i;
   end process;
 
 end behavioral;
diff --git a/hw/util_pkg.vhd b/hw/util_pkg.vhd
new file mode 100644 (file)
index 0000000..a9b7048
--- /dev/null
@@ -0,0 +1,51 @@
+library ieee;
+use ieee.std_logic_1164.all;
+use ieee.numeric_std.all;
+
+package util_pkg is
+  -- ceil(log2(n))
+  function ceil_log2(n: natural) return natural;
+  -- ceil(a/b)
+  function ceil_div(a: integer; b: integer) return integer;
+  --
+  function max(left, right: integer) return integer;
+  function min(left, right: integer) return integer;
+end;
+
+---
+
+package body util_pkg is
+
+  function ceil_log2(n: natural) return natural is
+  begin
+    if n <= 1 then
+      return 0;
+    else
+      if n mod 2 = 0 then
+        return 1 + ceil_log2(n/2);
+      else
+        return 1 + ceil_log2((n+1)/2);
+      end if;
+    end if;
+  end function ceil_log2;
+
+  function ceil_div(a: integer; b: integer) return integer is
+  begin
+    return (a+b-1)/b;
+  end function ceil_div;
+
+  function max(left, right: integer) return integer is
+  begin
+    if left > right then return left;
+    else return right;
+    end if;
+  end;
+
+  function min(left, right: integer) return integer is
+  begin
+    if left < right then return left;
+    else return right;
+    end if;
+  end;
+
+end util_pkg;
index 55cdfb9ca0ecb0e1e1552156bd4f6d15b4ac01a7..10a9d95fbf112e1987512842a4d06361ab381696 100644 (file)
@@ -39,58 +39,56 @@ architecture Behavioral of xilinx_dualport_bram_no_change is
 
 begin
 
-       -- CLKA process
-       ram_process_a : process(clka)
+-- CLKA process
+ram_process_a:
+       process
        begin
 
-               if clka = '1' and clka'event then
+               wait until clka'event and clka = '1';
 
-                       if ena = '1' then
+               if ena = '1' then
 
-                               for i in 0 to (we_width-1) loop
-                                       if wea(i) = '1' then
-                                               ram_block(to_integer(unsigned(addra)))(((i+1)*byte_width-1) downto (i*byte_width))
-                                                       := dina(((i+1)*byte_width-1) downto (i*byte_width));
-                                       end if;
-                               end loop;
-
-                               if to_integer(unsigned(wea)) = 0 then
-                                       if rsta = '1' then
-                                               douta <= (others => '0');
-                                       else
-                                               douta <= ram_block(to_integer(unsigned(addra)));
-                                       end if;
+                       for i in 0 to (we_width-1) loop
+                               if wea(i) = '1' then
+                                       ram_block(to_integer(unsigned(addra)))(((i+1)*byte_width-1) downto (i*byte_width))
+                                               := dina(((i+1)*byte_width-1) downto (i*byte_width));
                                end if;
+                       end loop;
 
+                       if to_integer(unsigned(wea)) = 0 then
+                               if rsta = '1' then
+                                       douta <= (others => '0');
+                               else
+                                       douta <= ram_block(to_integer(unsigned(addra)));
+                               end if;
                        end if;
 
                end if;
 
        end process;
 
-       -- CLKB process
-       ram_process_b : process(clkb)
+-- CLKB process
+ram_process_b:
+       process
        begin
 
-               if clkb = '1' and clkb'event then
+               wait until clkb'event and clkb = '1';
 
-                       if enb = '1' then
+               if enb = '1' then
 
-                               for i in 0 to (we_width-1) loop
-                                       if web(i) = '1' then
-                                               ram_block(to_integer(unsigned(addrb)))(((i+1)*byte_width-1) downto (i*byte_width))
-                                                       := dinb(((i+1)*byte_width-1) downto (i*byte_width));
-                                       end if;
-                               end loop;
-
-                               if to_integer(unsigned(web)) = 0 then
-                                       if rstb = '1' then
-                                               doutb <= (others => '0');
-                                       else
-                                               doutb <= ram_block(to_integer(unsigned(addrb)));
-                                       end if;
+                       for i in 0 to (we_width-1) loop
+                               if web(i) = '1' then
+                                       ram_block(to_integer(unsigned(addrb)))(((i+1)*byte_width-1) downto (i*byte_width))
+                                               := dinb(((i+1)*byte_width-1) downto (i*byte_width));
                                end if;
+                       end loop;
 
+                       if to_integer(unsigned(web)) = 0 then
+                               if rstb = '1' then
+                                       doutb <= (others => '0');
+                               else
+                                       doutb <= ram_block(to_integer(unsigned(addrb)));
+                               end if;
                        end if;
 
                end if;
index 50e05ec62a20343881d5739805d427c3020a6a12..7e0e6180e16f1d19ed553ff10662be010c4d34ec 100644 (file)
@@ -39,54 +39,50 @@ architecture Behavioral of xilinx_dualport_bram_write_first is
 
 begin
 
-       -- CLKA process
-       ram_process_a : process(clka)
+-- CLKA process
+ram_process_a:
+       process
        begin
 
-               if clka = '1' and clka'event then
+               wait until clka'event and clka = '1';
+               if ena = '1' then
 
-                       if ena = '1' then
-
-                               for i in 0 to (we_width-1) loop
-                                       if wea(i) = '1' then
-                                               ram_block(to_integer(unsigned(addra)))(((i+1)*byte_width-1) downto (i*byte_width))
-                                                       := dina(((i+1)*byte_width-1) downto (i*byte_width));
-                                       end if;
-                               end loop;
-
-                               if rsta = '1' then
-                                       douta <= (others => '0');
-                               else
-                                       douta <= ram_block(to_integer(unsigned(addra)));
+                       for i in 0 to (we_width-1) loop
+                               if wea(i) = '1' then
+                                       ram_block(to_integer(unsigned(addra)))(((i+1)*byte_width-1) downto (i*byte_width))
+                                               := dina(((i+1)*byte_width-1) downto (i*byte_width));
                                end if;
+                       end loop;
 
+                       if rsta = '1' then
+                               douta <= (others => '0');
+                       else
+                               douta <= ram_block(to_integer(unsigned(addra)));
                        end if;
 
                end if;
 
        end process;
 
-       -- CLKB process
-       ram_process_b : process(clkb)
+-- CLKB process
+ram_process_b:
+       process
        begin
 
-               if clkb = '1' and clkb'event then
-
-                       if enb = '1' then
-
-                               for i in 0 to (we_width-1) loop
-                                       if web(i) = '1' then
-                                               ram_block(to_integer(unsigned(addrb)))(((i+1)*byte_width-1) downto (i*byte_width))
-                                                       := dinb(((i+1)*byte_width-1) downto (i*byte_width));
-                                       end if;
-                               end loop;
+               wait until clkb'event and clkb = '1';
+               if enb = '1' then
 
-                               if rstb = '1' then
-                                       doutb <= (others => '0');
-                               else
-                                       doutb <= ram_block(to_integer(unsigned(addrb)));
+                       for i in 0 to (we_width-1) loop
+                               if web(i) = '1' then
+                                       ram_block(to_integer(unsigned(addrb)))(((i+1)*byte_width-1) downto (i*byte_width))
+                                               := dinb(((i+1)*byte_width-1) downto (i*byte_width));
                                end if;
+                       end loop;
 
+                       if rstb = '1' then
+                               doutb <= (others => '0');
+                       else
+                               doutb <= ram_block(to_integer(unsigned(addrb)));
                        end if;
 
                end if;
index 225b899f1e904128ed4794041dc625751c08fc3f..a3fc9411ccca6a85ea488c51699523610369ff53 160000 (submodule)
@@ -1 +1 @@
-Subproject commit 225b899f1e904128ed4794041dc625751c08fc3f
+Subproject commit a3fc9411ccca6a85ea488c51699523610369ff53
index 67ed35bdf87350edf877925f73bb0850ad9c6484..1d4d92d2d6cde439818e028d441a21635e678305 100644 (file)
@@ -25,21 +25,26 @@ volatile struct irc_register *irc2 = (volatile struct irc_register *)FPGA_IRC2_B
 volatile struct irc_register *irc3 = (volatile struct irc_register *)FPGA_IRC3_BASE;
 volatile struct irc_register *irc4 = (volatile struct irc_register *)FPGA_IRC4_BASE;
 
+volatile uint8_t *irc1_state = (volatile uint8_t *)(FPGA_IRC1_BASE + 0x20);
+volatile uint8_t *irc2_state = (volatile uint8_t *)(FPGA_IRC2_BASE + 0x20);
+volatile uint8_t *irc3_state = (volatile uint8_t *)(FPGA_IRC3_BASE + 0x20);
+volatile uint8_t *irc4_state = (volatile uint8_t *)(FPGA_IRC4_BASE + 0x20);
+
 /* Variables for configuration */
-volatile uint16_t *fpga_configure_line = (volatile uint16_t *)0x8003FFFC;
+volatile uint16_t *fpga_configure_line = (volatile uint16_t *)0x80007FF0;
 int fpga_configured = 0;
 int fpga_reconfiguration_locked = 1;
 
-/* BUS calibration - registers to measure the delay necessary for reading and writing */
-volatile uint32_t *fpga_bus_calib_read1 = (volatile uint32_t *)0x8003FFF0;
-volatile uint32_t *fpga_bus_calib_read2 = (volatile uint32_t *)0x8003FFF4;
+/* BUS measurement - registers to measure the delay necessary for reading and writing */
+volatile uint32_t *fpga_bus_meas_read1  = (volatile uint32_t *)0x80007FF0;
+volatile uint32_t *fpga_bus_meas_write1 = (volatile uint32_t *)0x80007FF4;
 
-volatile uint32_t *fpga_bus_calib_write1 = (volatile uint32_t *)0x8003FFF8;
-volatile uint32_t *fpga_bus_calib_write2 = (volatile uint32_t *)0x8003FFFC;
+volatile uint32_t *fpga_bus_meas_read2  = (volatile uint32_t *)0x80007FF8;
+volatile uint32_t *fpga_bus_meas_write2 = (volatile uint32_t *)0x80007FFC;
 
-/* BUS calibration - values (shifting all bits) */
-#define CALIB_VAL1 0xAAAAAAAA
-#define CALIB_VAL2 0x55555555
+/* BUS measurement - values (shifting all bits) */
+#define MEAS_VAL1 0xAAAAAAAA
+#define MEAS_VAL2 0x55555555
 
 void appl_fpga_init()
 {
@@ -55,7 +60,7 @@ void appl_fpga_init()
    */
   LPC_EMC->StaticConfig0 = 0x00000002;
 
-  /* Delays - not calibrated at this point
+  /* Delays - not measured at this point
    * We're running on 72 MHz, FPGA bus is running on 100 MHz async.
    * Read: 32 cycles
    * Write: 33 cycles
@@ -72,9 +77,7 @@ void appl_fpga_init()
 }
 
 int appl_fpga_tumbl_set_reset(int reset)
-{ 
-  int i;
-  
+{   
   if (reset)
     *tumbl_control |= FPGA_TUMBL_CONTROL_REG_RESET_BIT;
   else
@@ -128,10 +131,10 @@ void appl_fpga_tumbl_write(unsigned int offset, unsigned char *ptr, int len)
 }
 
 /* 
- * Bus calibration - functions can be called via USB interface
+ * Bus measurement - functions can be called via USB interface
  * Proper usage:
- * 1) Calibrate read
- * 2) Calibrate write
+ * 1) Measurement read
+ * 2) Measurement write
  * 3) Set turnaround
  *      bus is not pipelined, therefore
  *      just necessary delay for I/O to enter
@@ -141,7 +144,7 @@ void appl_fpga_tumbl_write(unsigned int offset, unsigned char *ptr, int len)
 /* Cannot be on stack due to memory barrier for gcc */
 static uint32_t a, b;
 
-int appl_fpga_calibrate_bus_read()
+int appl_fpga_measure_bus_read()
 {
   int i;
   
@@ -160,18 +163,18 @@ int appl_fpga_calibrate_bus_read()
       /* Read the values several times - so there are two flips at least
        * NOTE: SDRAM reads / writes may occur in between!
        */
-      a = *fpga_bus_calib_read1;
-      b = *fpga_bus_calib_read2;
-      a = *fpga_bus_calib_read1;
-      b = *fpga_bus_calib_read2;
-      a = *fpga_bus_calib_read1;
-      b = *fpga_bus_calib_read2;
-      a = *fpga_bus_calib_read1;
-      b = *fpga_bus_calib_read2;
+      a = *fpga_bus_meas_read1;
+      b = *fpga_bus_meas_read2;
+      a = *fpga_bus_meas_read1;
+      b = *fpga_bus_meas_read2;
+      a = *fpga_bus_meas_read1;
+      b = *fpga_bus_meas_read2;
+      a = *fpga_bus_meas_read1;
+      b = *fpga_bus_meas_read2;
       __memory_barrier();
       
       /* Verify */
-      if (a != CALIB_VAL1 || b != CALIB_VAL2)
+      if (a != MEAS_VAL1 || b != MEAS_VAL2)
       {
         if (LPC_EMC->StaticWaitRd0 == 0x1F)
         {
@@ -200,7 +203,7 @@ int appl_fpga_calibrate_bus_read()
   return 0;
 }
 
-int appl_fpga_calibrate_bus_write()
+int appl_fpga_measure_bus_write()
 {
   int i;
   
@@ -213,8 +216,8 @@ int appl_fpga_calibrate_bus_write()
     {
       /* Make sure there is nothing other going on */
       __memory_barrier();
-      *fpga_bus_calib_write1 = 0x00000000;
-      *fpga_bus_calib_write2 = 0x00000000;
+      *fpga_bus_meas_write1 = 0x00000000;
+      *fpga_bus_meas_write2 = 0x00000000;
       __memory_barrier();
       a = 0xFFFFFFFF;
       b = 0xFFFFFFFF;
@@ -222,25 +225,25 @@ int appl_fpga_calibrate_bus_write()
       /* Write the values several times - so there are two flips at least
        * NOTE: SDRAM reads / writes may occur in between!
        */
-      *fpga_bus_calib_write1 = CALIB_VAL1;
-      *fpga_bus_calib_write2 = CALIB_VAL2;
-      *fpga_bus_calib_write1 = CALIB_VAL1;
-      *fpga_bus_calib_write2 = CALIB_VAL2;
-      *fpga_bus_calib_write1 = CALIB_VAL1;
-      *fpga_bus_calib_write2 = CALIB_VAL2;
-      *fpga_bus_calib_write1 = CALIB_VAL1;
-      *fpga_bus_calib_write2 = CALIB_VAL2;
+      *fpga_bus_meas_write1 = MEAS_VAL1;
+      *fpga_bus_meas_write2 = MEAS_VAL2;
+      *fpga_bus_meas_write1 = MEAS_VAL1;
+      *fpga_bus_meas_write2 = MEAS_VAL2;
+      *fpga_bus_meas_write1 = MEAS_VAL1;
+      *fpga_bus_meas_write2 = MEAS_VAL2;
+      *fpga_bus_meas_write1 = MEAS_VAL1;
+      *fpga_bus_meas_write2 = MEAS_VAL2;
       /* 
        * Strongly ordered memory
        * GCC is blocked by volatilness
        */
       __memory_barrier();
-      a = *fpga_bus_calib_write1;
-      b = *fpga_bus_calib_write2;
+      a = *fpga_bus_meas_write1;
+      b = *fpga_bus_meas_write2;
       __memory_barrier();
       
       /* Verify */
-      if (a != CALIB_VAL1 || b != CALIB_VAL2)
+      if (a != MEAS_VAL1 || b != MEAS_VAL2)
       {
         if (LPC_EMC->StaticWaitWr0 == 0x1F)
         {
@@ -406,9 +409,9 @@ int appl_fpga_configure()
   for (i = 0; i < 128; i++)
     {}
     
-  /* Use EMC delays obtained through calibration */
-  LPC_EMC->StaticWaitRd0 = 0x04;
-  LPC_EMC->StaticWaitWr0 = 0x01;
+  /* Use EMC delays obtained through measurement */
+  LPC_EMC->StaticWaitRd0 = 0x07;
+  LPC_EMC->StaticWaitWr0 = 0x03;
 
   /* Lift the reset */
   hal_gpio_direction_output(XC_INIT_PIN, 1);
index 738c5777b066a13c8032ea452478a049669255ac..e98bc0a7ea5f6ada3b3bbb72f22ad599836d6dfe 100644 (file)
 
 extern volatile uint32_t *tumbl_control;
 extern volatile uint32_t *tumbl_trace_kick;
+extern volatile uint32_t *tumbl_pc;
 extern volatile uint32_t *tumbl_imem;
 extern volatile uint32_t *tumbl_dmem;
 
 /* IRC */
 
-#define FPGA_IRC1_BASE    0x80020000
-#define FPGA_IRC2_BASE    0x80020010
-#define FPGA_IRC3_BASE    0x80020020
-#define FPGA_IRC4_BASE    0x80020030
+#define FPGA_IRC1_BASE    0x80022000
+#define FPGA_IRC2_BASE    0x80022008
+#define FPGA_IRC3_BASE    0x80022010
+#define FPGA_IRC4_BASE    0x80022018
 
 struct irc_register
 {
   uint32_t count;
   uint32_t count_index;
-  uint32_t state;
 };
 
 extern volatile struct irc_register *irc1;
@@ -42,7 +42,11 @@ extern volatile struct irc_register *irc2;
 extern volatile struct irc_register *irc3;
 extern volatile struct irc_register *irc4;
 
-extern volatile uint32_t *fpga_bcd;
+extern volatile uint8_t *irc1_state;
+extern volatile uint8_t *irc2_state;
+extern volatile uint8_t *irc3_state;
+extern volatile uint8_t *irc4_state;
+
 
 /* Configuration defines */
 
@@ -63,8 +67,8 @@ void appl_fpga_tumbl_write(unsigned int offset, unsigned char *ptr, int len);
 
 void appl_fpga_init();
 int appl_fpga_configure();
-int appl_fpga_calibrate_bus_read();
-int appl_fpga_calibrate_bus_write();
+int appl_fpga_measure_bus_read();
+int appl_fpga_measure_bus_write();
 void appl_fpga_set_reconfiguration_lock(int lock);
 int appl_fpga_get_reconfiguration_lock();
 
index b3bb8a0234ef1824f3b2bb3997f091923da5b0ae..76af96043621374b64027d74a17fb1a11c7364a9 100644 (file)
 #define SWAP(x) (x)
 #endif
 
-#define USB_VENDOR_TARGET_TUMBL       0x03
+#define USB_VENDOR_TARGET_TUMBL        0x03
 
-#define USB_CMD_FPGA_CONFIGURE        0xF000
-#define USB_CMD_FPGA_CALIBRATE_READ   0xF001
-#define USB_CMD_FPGA_CALIBRATE_WRITE  0xF002
-#define USB_CMD_FPGA_TEST_IRC         0xF004
-#define USB_CMD_FPGA_TEST_BCD         0xF005
+#define USB_CMD_FPGA_CONFIGURE         0xF000
+#define USB_CMD_FPGA_MEASURE_READ      0xF001
+#define USB_CMD_FPGA_MEASURE_WRITE     0xF002
+#define USB_CMD_FPGA_TEST_IRC          0xF004
 
-#define USB_CMD_FPGA_TUMBL_SET_RESET  0xF100
-#define USB_CMD_FPGA_TUMBL_SET_HALT   0xF101
-#define USB_CMD_FPGA_TUMBL_SET_TRACE  0xF102
-#define USB_CMD_FPGA_TUMBL_KICK_TRACE 0xF103
+#define USB_CMD_FPGA_TUMBL_SET_RESET   0xF100
+#define USB_CMD_FPGA_TUMBL_SET_HALT    0xF101
+#define USB_CMD_FPGA_TUMBL_SET_TRACE   0xF102
+#define USB_CMD_FPGA_TUMBL_KICK_TRACE  0xF103
+#define USB_CMD_FPGA_TUMBL_GET_PC      0xF104
 
-#define USB_CMD_FPGA_TUMBL_DUMP_IMEM  0xF200
-#define USB_CMD_FPGA_TUMBL_DUMP_DMEM  0xF201
+#define USB_CMD_FPGA_TUMBL_DUMP_IMEM   0xF200
+#define USB_CMD_FPGA_TUMBL_DUMP_DMEM   0xF201
 
-#define USB_CMD_FPGA_RESET            0xFFFF
+#define USB_CMD_FPGA_RESET             0xFFFF
 
 usb_device_t usb_device;
 usb_ep_t eps[NUM_ENDPOINTS];
@@ -178,11 +178,11 @@ uint16_t appl_usb_vendor_call(uint16_t command, uint16_t argument)
     case USB_CMD_FPGA_CONFIGURE:
       return appl_fpga_configure();
 
-    case USB_CMD_FPGA_CALIBRATE_READ:
-      return appl_fpga_calibrate_bus_read();
+    case USB_CMD_FPGA_MEASURE_READ:
+      return appl_fpga_measure_bus_read();
 
-    case USB_CMD_FPGA_CALIBRATE_WRITE:
-      return appl_fpga_calibrate_bus_write();
+    case USB_CMD_FPGA_MEASURE_WRITE:
+      return appl_fpga_measure_bus_write();
 
     case USB_CMD_FPGA_TEST_IRC:
       printf("IRC1: count = %d, count index = %d\n", (unsigned int) irc1->count, (unsigned int) irc1->count_index);
@@ -202,6 +202,10 @@ uint16_t appl_usb_vendor_call(uint16_t command, uint16_t argument)
       
     case USB_CMD_FPGA_TUMBL_KICK_TRACE:
       return appl_fpga_tumbl_kick_trace();
+      
+    case USB_CMD_FPGA_TUMBL_GET_PC:
+      printf("Tubml PC: 0x%08X\n", (unsigned int) *tumbl_pc);
+      return 0;
     
     case USB_CMD_FPGA_TUMBL_DUMP_IMEM:
       printf("TUMBL IMEM:\n");