Commit faa42107 authored by Andrey Filippov's avatar Andrey Filippov

adding InertialSense IMS-5 support

parent 2317d4fd
This diff is collapsed.
......@@ -2424,9 +2424,26 @@ simul_axi_hp_wr #(
assign x393_i.ps7_i.FCLKCLK= {4{CLK}};
assign x393_i.ps7_i.FCLKRESETN= {RST,~RST,RST,~RST};
`define TEST_IMX
`ifdef TEST_IMX
wire IMS_TXD; // SuppressThisWarning VEditor
wire IMS_ACTIVE; // SuppressThisWarning VEditor
wire ESCAPE; // SuppressThisWarning VEditor
simul_imx5#(
.DATA_FILE ("/input_data/imx5_did_ins_1.dat"), //
.BIT_DURATION ( 160), // ns
.RECORD_BYTES ( 80), // bytes per record
.RECORD_NUM ( 10), // number of records
.PAUSE_CLOCKS ( 100) // skip clocks between messages
) i_simul_imx5 (
.mrst (RST_SIM_AXI), // active low longer reset
.uart_out (IMS_TXD), // will just copy when not reset;
.sending (IMS_ACTIVE), // sending data (including start/stop bits)
.escape (ESCAPE)
);
`endif
`define TEST_IMU
`define TEST_EXT_INT
......@@ -2579,7 +2596,12 @@ assign #10 gpio_pins[7] = gpio_pins[8];
#(IMU_READY_PERIOD-IMU_NREADY_DURATION) IMU_DATA_READY=1'b0;
#(IMU_NREADY_DURATION) IMU_DATA_READY=1'b1;
end
assign gpio_pins[4]=SERIAL_BIT;
// for testing InertialSense IMX5 - switch only RS232, keep all other IMU-related
`ifdef TEST_IMX
assign gpio_pins[4]=IMS_TXD;
`else
assign gpio_pins[4]=SERIAL_BIT;
`endif
assign gpio_pins[5]=GPS1SEC;
`ifdef ODOMETER_PULSE_6
assign gpio_pins[6]=ODOMETER_PULSE;
......
#!/usr/bin/env python3
# -*- coding: utf-8 -*-
# Copyright (C) 2023, Elphel.inc.
# Helper module to generate IMX5 DID_INS_1
# This program is free software: you can redistribute it and/or modify
# it under the terms of the GNU General Public License as published by
# the Free Software Foundation, either version 3 of the License, or
# (at your option) any later version.
#
# This program is distributed in the hope that it will be useful,
# but WITHOUT ANY WARRANTY; without even the implied warranty of
# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
# GNU General Public License for more details.
#
# You should have received a copy of the GNU General Public License
# along with this program. If not, see <http://www.gnu.org/licenses/>.
#
__author__ = "Andrey Filippov"
__copyright__ = "Copyright 2023, Elphel, Inc."
__license__ = "GPL"
__version__ = "3.0+"
__maintainer__ = "Andrey Filippov"
__email__ = "andrey@elphel.com"
__status__ = "Development"
'''
Created on February 8, 2023
@author: Andrey Filippov
'''
import os
import sys
import struct
import datetime
import random
import math
import sys
try:
outname = sys.argv[1]
except IndexError:
outname = "../input_data/imx5_did_ins_1.dat"
abs_script = os.path.abspath(__file__)
SAMPLE_STEP = datetime.timedelta(microseconds = 16000)
NUM_STEPS = 10
DATETIME0 = datetime.datetime(1980, 1, 6,tzinfo=datetime.timezone.utc)
#page 89
#40.77730906709462, -111.9328777496785
#1288 m
VELOCITY = [20.0, 15.0, 1.0] #U,V,W m/s
#Bytes 0x0A , 0x24 , 0xB5 , 0xD3 , 0xFD , 0xFE and 0xFF are reserved bytes, with 0xFD being a reserved byte prefix.
INS_STAT = 0x12345678 # add escaped here
HDW_STAT = 0x0a2400fd # 0x0a, 0x24, 0xfd
LLA = [40.77730906709462, -111.9328777496785, 1288]
LLA_VAR = [0.1, 0.1, 20.0] # random LLA defiations
ENDIAN = "<" # "I" - unsigned int (4), "d" - double (8), "f" - float (4)
now = datetime.datetime.now(datetime.timezone.utc)
now_date = now.date()
now_time = now.time();
#b = a + datetime.timedelta(0,3) # days, seconds, then other fields.
#timedelta(days=0, seconds=0, microseconds=0, milliseconds=0, minutes=0, hours=0, weeks=0)
dt = now
ned = 3 * [0]
bin = []
for ns in range(NUM_STEPS):
rec = b''
theta = [math.pi * (2*random.random()-1),math.pi * (2*random.random()-1), math.pi * (2*random.random()-1)]
uvw = list(VELOCITY)
lla = list(LLA)
uvw = list(VELOCITY)
for i in range(len(LLA)):
lla[i] += LLA_VAR[i] * (2 *random.random() - 1)
ned[i] += SAMPLE_STEP.total_seconds() * VELOCITY[i]
dt += SAMPLE_STEP
#print(dt)
week = (dt-DATETIME0).days//7
#print (week)
diff = dt - (DATETIME0 + datetime.timedelta(days=7*week))
rec += struct.pack(ENDIAN+"I",week)
rec += struct.pack(ENDIAN+"d",diff.total_seconds())
rec += struct.pack(ENDIAN+"I",INS_STAT)
rec += struct.pack(ENDIAN+"I",HDW_STAT)
rec += struct.pack(ENDIAN+"fff",theta[0],theta[1],theta[2])
rec += struct.pack(ENDIAN+"fff",uvw[0],uvw[1],uvw[2])
rec += struct.pack(ENDIAN+"ddd",lla[0],lla[1],lla[2])
rec += struct.pack(ENDIAN+"fff",ned[0],ned[1],ned[2])
bin.append(rec)
'''
with open("../input_data/imx5_did_ins_1.bin", "wb") as f:
for rec in bin:
f.write(rec)
'''
with open(outname,"w") as outfile:
print("//",file=outfile)
print("// Simulated data for IMX5 INS DID_INS_1, %d (0x%x) bytes per record"%(len(bin[0]),len(bin[0])), file=outfile)
print("// GENERATOR = %s"%(abs_script),file=outfile)
print("//",file=outfile)
for rec in bin:
for b in rec:
print("%02x"%(b), file=outfile, end = " ")
print(file=outfile)
'''
0000000 08c8 0000 3461 ab2b f511 4113 5678 1234
0000010 5555 aaaa 1e32 3f8f d81f 4002 799f c000
0000020 0000 41a0 0000 4170 0000 3f80 ee61 dffa
0000030 5a87 4044 1d43 f155 f644 c05b a8d4 7b1e
0000040 1d5f 4094 d70a 3ea3 c28f 3e75 126f 3c83
0000050 08c8 0000 8234 bb8d f511 4113 5678 1234
0000060 5555 aaaa 19bd 3ddd f6de bedd 0151 c041
0000070 0000 41a0 0000 4170 0000 3f80 baf1 2fbd
0000080 6030 4044 fc7d 5253 fc0a c05b f24d 8001
0000090 28c0 4094 d70a 3f23 c28f 3ef5 126f 3d03
00000a0 08c8 0000 d007 cbef f511 4113 5678 1234
00000b0 5555 aaaa 4385 3f28 a5b0 3fb8 33dd bf9e
00000c0 0000 41a0 0000 4170 0000 3f80 c41b 1591
00000d0 5e90 4044 320b 9e4c fc86 c05b 3018 388b
00000e0 5d17 4094 c28f 3f75 51ec 3f38 9ba6 3d44
00000f0 08c8 0000 1dda dc52 f511 4113 5678 1234
0000100 5555 aaaa 0616 4012 7d64 bfa4 5448 be02
0000110 0000 41a0 0000 4170 0000 3f80 b248 319f
0000120 5bd9 4044 ce50 bfef fac4 c05b cc70 29cc
0000130 5d90 4094 d70a 3fa3 c28f 3f75 126f 3d83
0000140 08c8 0000 6bad ecb4 f511 4113 5678 1234
0000150 5555 aaaa 717a 3e02 265a c045 90a4 be60
0000160 0000 41a0 0000 4170 0000 3f80 4831 f678
0000170 6e35 4044 30f3 2825 f8bc c05b f395 33ac
0000180 2e15 4094 cccd 3fcc 999a 3f99 d70a 3da3
0000190 08c8 0000 b980 fd16 f511 4113 5678 1234
00001a0 5555 aaaa d917 3df5 f943 3f0f f515 bff0
00001b0 0000 41a0 0000 4170 0000 3f80 1a95 86b9
00001c0 5ccf 4044 4ce6 d0c7 ffa7 c05b ea59 6c85
00001d0 f49f 4093 c28f 3ff5 51ec 3fb8 9ba6 3dc4
00001e0 08c8 0000 0753 0d79 f512 4113 5678 1234
00001f0 5555 aaaa b958 bfcc 690e c02b 78f9 bed3
0000200 0000 41a0 0000 4170 0000 3f80 9d6c 2c01
0000210 5c47 4044 e8fc 2bcb fd18 c05b 03fa 1b29
0000220 5168 4094 5c29 400f 0a3d 3fd7 6042 3de5
0000230 08c8 0000 5526 1ddb f512 4113 5678 1234
0000240 5555 aaaa 05a9 bfa0 545f beb7 c5bb bf31
0000250 0000 41a0 0000 4170 0000 3f80 f31a ba91
0000260 5a25 4044 6bf5 6d82 fe15 c05b 0494 6c99
0000270 178a 4094 d70a 4023 c28f 3ff5 126f 3e03
0000280 08c8 0000 a2f9 2e3d f512 4113 5678 1234
0000290 5555 aaaa a667 3f57 4517 4002 8c73 3fc6
00002a0 0000 41a0 0000 4170 0000 3f80 46a2 2884
00002b0 6938 4044 cc2b 0350 00eb c05c 6be2 44c7
00002c0 08b1 4094 51ec 4038 3d71 400a 74bc 3e13
00002d0 08c8 0000 f0cc 3e9f f512 4113 5678 1234
00002e0 5555 aaaa f700 bec3 2170 403a a8ea c004
00002f0 0000 41a0 0000 4170 0000 3f80 4a33 cb7b
0000300 5e8d 4044 9060 1a1a 0213 c05c 54ac c45e
0000310 2191 4094 cccd 404c 999a 4019 d70a 3e23
0000320
'''
# print (week, diff.total_seconds())
# len(struct.pack("<d",1.0)) 8
......@@ -1076,12 +1076,12 @@
parameter LOGGER_CONF_GPS_BITS = 4,
parameter LOGGER_CONF_MSG = 13,
parameter LOGGER_CONF_MSG_BITS = 5,
parameter LOGGER_CONF_SYN = 18, // 15,
parameter LOGGER_CONF_SYN_BITS = 4, // 1,
parameter LOGGER_CONF_EN = 20, // 17,
parameter LOGGER_CONF_EN_BITS = 1,
parameter LOGGER_CONF_DBG = 25, // 22,
parameter LOGGER_CONF_DBG_BITS = 4,
parameter LOGGER_CONF_SYN = 19, // 18, // 15,
parameter LOGGER_CONF_SYN_BITS = 5, // 4, // 1,
parameter LOGGER_CONF_EN = 21, //20, // 17,
parameter LOGGER_CONF_EN_BITS = 1, // 1,
parameter LOGGER_CONF_DBG = 26, // 25, // 22,
parameter LOGGER_CONF_DBG_BITS = 4, // 4,
parameter MULT_SAXI_HALF_BRAM_IN = 1, // 0 - use full 36Kb BRAM for the buffer, 1 - use just half
parameter MULT_SAXI_WLOG = 4, // number of bits for the input data ( 3 - 8 bit, 4 - 16-bit, 5 - 32-bit
......
//
// Simulated data for IMX5 INS DID_INS_1, 80 (0x50) bytes per record
// GENERATOR = /home/elphel/git/x393/helpers/generate_imx.py
//
c8 08 00 00 28 d2 fd 1c 1d 51 14 41 78 56 34 12 fd 00 24 0a b6 b9 17 c0 ab cb 02 40 58 de e8 be 00 00 a0 41 00 00 70 41 00 00 80 3f 0f 6e 7d a5 a8 6e 44 40 63 f3 40 32 ae fc 5b c0 6d 4f 26 c9 94 58 94 40 0a d7 a3 3e 8f c2 75 3e 6f 12 83 3c
c8 08 00 00 fb 1f 60 2d 1d 51 14 41 78 56 34 12 fd 00 24 0a b0 24 c8 bf d1 b8 0a 40 8f ee 1b c0 00 00 a0 41 00 00 70 41 00 00 80 3f 4d f3 22 2e 37 59 44 40 dd 15 14 03 8f f5 5b c0 87 f0 af bb cd e2 93 40 0a d7 23 3f 8f c2 f5 3e 6f 12 03 3d
c8 08 00 00 ce 6d c2 3d 1d 51 14 41 78 56 34 12 fd 00 24 0a 87 95 fc 3f 75 da e6 3e e7 7a 30 40 00 00 a0 41 00 00 70 41 00 00 80 3f c8 37 ae 20 07 58 44 40 f2 e5 17 35 8e fe 5b c0 19 a1 08 74 fd 2b 94 40 8f c2 75 3f ec 51 38 3f a6 9b 44 3d
c8 08 00 00 a1 bb 24 4e 1d 51 14 41 78 56 34 12 fd 00 24 0a 68 56 58 bf 69 30 c9 be 2e af 5d bf 00 00 a0 41 00 00 70 41 00 00 80 3f 68 ae 91 d5 95 69 44 40 38 62 81 35 fa f5 5b c0 d9 71 84 62 81 0c 94 40 0a d7 a3 3f 8f c2 75 3f 6f 12 83 3d
c8 08 00 00 74 09 87 5e 1d 51 14 41 78 56 34 12 fd 00 24 0a 5a cd 3e 40 df f0 10 c0 56 92 b9 3f 00 00 a0 41 00 00 70 41 00 00 80 3f 66 46 4b 16 fc 62 44 40 bd 65 8d 50 07 f6 5b c0 55 b7 05 ec a0 f7 93 40 cd cc cc 3f 9a 99 99 3f 0a d7 a3 3d
c8 08 00 00 47 57 e9 6e 1d 51 14 41 78 56 34 12 fd 00 24 0a 82 49 3a 40 37 ea 9b be 86 38 1c 3f 00 00 a0 41 00 00 70 41 00 00 80 3f 89 91 77 9a 90 5e 44 40 ea 69 c8 ab 3d ff 5b c0 e5 08 e4 c5 c8 f5 93 40 8f c2 f5 3f ec 51 b8 3f a6 9b c4 3d
c8 08 00 00 1a a5 4b 7f 1d 51 14 41 78 56 34 12 fd 00 24 0a 9f 48 59 bf 6f b5 17 40 ee 65 3e c0 00 00 a0 41 00 00 70 41 00 00 80 3f de 16 e3 5b 36 69 44 40 68 f3 47 6f 2b f6 5b c0 4b b3 2f 28 fa dc 93 40 29 5c 0f 40 3d 0a d7 3f 42 60 e5 3d
c8 08 00 00 ed f2 ad 8f 1d 51 14 41 78 56 34 12 fd 00 24 0a c1 fe 28 40 45 ae ac be 02 6f 44 c0 00 00 a0 41 00 00 70 41 00 00 80 3f 12 5b a1 80 2e 5e 44 40 2a da 8d 17 c3 01 5c c0 d8 74 50 3a 70 3d 94 40 0a d7 23 40 8f c2 f5 3f 6f 12 03 3e
c8 08 00 00 c0 40 10 a0 1d 51 14 41 78 56 34 12 fd 00 24 0a ae 95 12 c0 a5 ed 1a 40 8e 48 6c bf 00 00 a0 41 00 00 70 41 00 00 80 3f 89 d3 89 20 a6 61 44 40 53 fb b2 7e 80 f6 5b c0 d3 72 38 a4 e8 14 94 40 ec 51 38 40 71 3d 0a 40 bc 74 13 3e
c8 08 00 00 93 8e 72 b0 1d 51 14 41 78 56 34 12 fd 00 24 0a ec 09 41 3e 89 a5 57 be 63 5a ea bf 00 00 a0 41 00 00 70 41 00 00 80 3f 22 ba 8e 99 8c 59 44 40 82 91 57 b9 64 ff 5b c0 a0 b7 2c 50 e3 e1 93 40 cd cc 4c 40 9a 99 19 40 0a d7 23 3e
This diff is collapsed.
This diff is collapsed.
......@@ -48,7 +48,6 @@ module imu_message393 (
input xclk, // half frequency (80 MHz nominal)
input we, // write enable for registers to log (@negedge mclk), with lower data half
input [3:0] wa, // write address for register (4 bits, @negedge mclk)
// input [15:0] di, // 16-bit data in multiplexed
input [31:0] din, // 32-bit data in, non-multiplexed
input en, // enable module operation, if 0 - reset
input trig, // leading edge - sample time, trailing set rdy
......
......@@ -46,6 +46,7 @@ module imu_timestamps393(
input [7:0] ts_data, // local timestamp data (s0,s1,s2,s3,u0,u1,u2,u3==0)
input [3:0] ts_rq,// requests to create timestamps (4 channels), @posedge xclk
input [15:0] timestamp_chnmod, // 4 bits per channel - return with 4 MSB of usec
output [3:0] ts_ackn, // timestamp for this channel is stored
input [3:0] ra, // read address (2 MSBs - channel number, 2 LSBs - usec_low, (usec_high ORed with channel <<24), sec_low, sec_high
output [15:0] dout);// output data
......@@ -53,6 +54,7 @@ module imu_timestamps393(
reg ts_busy;
reg ts_busy_d;
reg [1:0] chn; // channel for which timestamp is bein requested/received
reg [3:0] timestamp_mod;
wire [3:0] rq_pri; // 1-hot prioritized timestamp request
wire [1:0] rq_enc; // encoded request channel
reg [2:0] cntr; // ts rcv counter
......@@ -98,9 +100,12 @@ module imu_timestamps393(
if (!ts_rcv) cntr <= 0;
else cntr <= cntr + 1;
if (pre_snap) chn <= rq_enc;
if (pre_snap) begin
chn <= rq_enc;
timestamp_mod <= timestamp_chnmod[4*rq_enc +: 4]; // channel mux
end
// insert channel instead of the usec MSB, swap usec <-> sec
if (ts_rcv && cntr[0]) ts_ram[{chn, ~cntr[2], cntr[1]}] <= {rcv_last ? {6'b0,chn} : ts_data, ts_data_r};
if (ts_rcv && cntr[0]) ts_ram[{chn, ~cntr[2], cntr[1]}] <= {rcv_last ? {timestamp_mod, 2'b0, chn} : ts_data, ts_data_r};
if (rst) ts_ackn_r <= 4'hf;
else ts_ackn_r <= ts_rq & (ts_ackn_r | (chn1hot & {4{pre_ackn}}));
......
/*!
* <b>Module:</b>nmea_decoder393
* @file nmea_decoder393.v
* @date 2023-02-09
* @author Andrey Filippov
*
* @brief Decode some of the NMEA sentences (to compress them)
*
* @copyright Copyright (c) 2015 Elphel, Inc.
*
* <b>License:</b>
*
* imx5_decoder393.v is free software; you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
* the Free Software Foundation, either version 3 of the License, or
* (at your option) any later version.
*
* imx5_decoder393.v is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details.
*
* You should have received a copy of the GNU General Public License
* along with this program. If not, see <http://www.gnu.org/licenses/> .
*
* Additional permission under GNU GPL version 3 section 7:
* If you modify this Program, or any covered work, by linking or combining it
* with independent modules provided by the FPGA vendor only (this permission
* does not extend to any 3-rd party modules, "soft cores" or macros) under
* different license terms solely for the purpose of generating binary "bitstream"
* files and/or simulating the code, the copyright holders of this Program give
* you the right to distribute the covered work without those independent modules
* as long as the source code for them is available from the FPGA vendor free of
* charge, and there is no dependence on any encrypted modules for simulating of
* the combined code. This permission applies to you if the distributed code
* contains all the components and scripts required to completely simulate it
* with at least one of the Free Software programs.
*/
`timescale 1ns/1ps
module imx5_decoder393(
input xclk, // half frequency (80 MHz nominal)
// input start, // start of the serial message
// input rs232_wait_pause,// may be used as reset for decoder
input start_char, // serial character start (single pulse)
// output reg nmea_sent_start, // serial character start (single pulse)
input ser_di, // serial data in (LSB first)
input ser_stb,// serial data strobe, single-cycle, first cycle after ser_di valid
output rdy, // encoded nmea data ready
input rd_stb, // encoded nmea data read strobe (increment address)
output [15:0] rdata, // encoded data (16 bits)
input ser_rst,
output ts_rq,
output [3:0] ts_mode);
localparam CHR_START = 8'hff;
localparam CHR_STOP = 8'hfe;
localparam CHR_ESC = 8'hfd; // invert next byte
localparam PACKET_ID = 8'h04; // data packet
// output [23:0] debug);
reg [7:0] odbuf0_ram[0:63]; // byte-wide in, 16-bit output
reg [7:0] odbuf1_ram[0:63];
reg [5:0] raddr; // memory buffer read out address (16-bit words)
reg [6:0] waddr; // byte counter
reg pre_wr;
reg [1:0] buf_we;
reg [3:0] stb;
reg [7:0] byte_sr;
reg [7:0] byte_in;
reg [2:0] bit_cntr;
reg header_run;
reg did_start;
reg rec_run;
// reg footer_run;
reg got_start;
reg got_stop;
reg got_esc;
reg [2:0] got_char;
reg proc_escape;
reg nreset_r;
reg ser_stb_r;
reg [2:0] sr_byte_got;
// reg rec_done;
reg [3:0] rec_errs; // wrong record - abandon;
reg [7:0] byte_count;
reg [7:0] did_len;
// reg [7:0] did;
reg [5:0] out_cntr; // bytes left in packet (of 64)
wire got_special_w;
reg byte_count_zero;
reg [5:0] last_word_written; // number of the last word (4 nibbles) written - used to deassert rdy (garbage after)
reg [4:0] out_words;
reg rdy_r=1'b0;
// reg
wire packet_run_w;
reg ts_rq_r; // initial ts and all but last
// delaying ts request until prev. one packet is served
reg ts_rq_pend; // pending ts request, waiting packet to be sent out
reg ts_rq_next; // end of ts_rq_pend, issue timestamp request
// reg nxt_frag; // next packet fragment (request a new timestamp, output pack_frag to be included in usec of ts.
reg frag_start; // first one will start before ts request (packet will be aborted if wrong header)
reg frag_done; // next packet fragment (request a new timestamp, output pack_frag to be included in usec of ts.
reg [1:0] pack_frag; // fragment of a packet sent to the logger
assign ts_rq = ts_rq_r;
assign rdy = rdy_r;
assign ts_mode = {1'b1, 1'b0, pack_frag};
assign got_special_w = got_start || got_stop || got_esc;
assign packet_run_w = header_run || rec_run;
assign rdata[ 7: 0] = odbuf0_ram[raddr[5:0]];
assign rdata[15: 8] = odbuf1_ram[raddr[5:0]];
always @ (posedge xclk) begin
nreset_r <= !ser_rst;
stb[3:0] <= {stb[2:0], ser_stb};
ser_stb_r <= nreset_r && ser_stb;
if (!nreset_r || start_char) bit_cntr <= 0;
else if (ser_stb_r) bit_cntr <= bit_cntr+1;
if (ser_stb_r) byte_sr <= {ser_di, byte_sr[7:1]};
sr_byte_got <= {sr_byte_got[1:0], &bit_cntr & ser_stb_r};
got_start <= sr_byte_got[0] && (byte_sr == CHR_START);
got_stop <= sr_byte_got[0] && (byte_sr == CHR_STOP);
got_esc <= sr_byte_got[0] && (byte_sr == CHR_ESC);
got_char <= {got_char[1:0], sr_byte_got[1] & !got_special_w};
if (!nreset_r || got_char) proc_escape <= 0;
else if (got_esc) proc_escape <= 1;
if (got_char[0]) byte_in <= byte_sr ^ {8{proc_escape}};
if (!nreset_r || |rec_errs || got_stop || did_start) header_run <= 0;
else if (got_start) header_run <= 1;
// do not end on stop until written out
if (!nreset_r || (frag_done && byte_count_zero)) rec_run <= 0;
else if (did_start) rec_run <= 1;
// add footer?
if (got_start) byte_count <= 8'h0e;
else if (did_start) byte_count <= did_len - 1;
else if (got_char[2]) byte_count <= byte_count - 1;
// else if (pre_wr) byte_count <= byte_count - 1;
byte_count_zero <= packet_run_w && (byte_count == 0);
did_start <= header_run && got_char[1] && byte_count_zero;
rec_errs[0] <= header_run && got_char[1] && (byte_count[3:0] == 4'he) && (byte_in != PACKET_ID);
// if (header_run && got_char[1] && (byte_count[3:0] == 4'hb)) did <= byte_in;
if (header_run && got_char[1] && (byte_count[3:0] == 4'h7)) did_len <= byte_in;
if (!packet_run_w) waddr <= 0;
else if (|buf_we) waddr <= waddr + 1;
// some bytes from the header and all bytes from the data
pre_wr <= got_char[1] && ((header_run && ((byte_count[3:1] == 5) || (byte_count[3:1] == 3))) || rec_run);
buf_we <= {2{pre_wr}} & {waddr[0],~waddr[0]};
if (buf_we[0]) odbuf0_ram[waddr[6:1]] <= byte_in;
if (buf_we[1]) odbuf1_ram[waddr[6:1]] <= byte_in;
if (pre_wr) last_word_written[5:0] <= waddr[6:1];
if (!packet_run_w) pack_frag <= 0;
else if (frag_done) pack_frag <= pack_frag + 1;
frag_done <= pre_wr && rec_run && ((byte_count == 0) || (out_cntr == 0));
frag_start <= got_start || (frag_done && !byte_count_zero);
if (frag_start) out_cntr <= 6'h37;
else if (pre_wr) out_cntr <= out_cntr - 1;
if (!rec_run || ts_rq_next) ts_rq_pend <= 0;
else if (frag_done && !byte_count_zero) ts_rq_pend <= 1;
ts_rq_next <= ts_rq_pend && !rdy_r && !rd_stb;
// nxt_frag
// reg ts_rq_pend; // pending ts request, waiting packet to be sent out
// reg ts_rq_next; // end of ts_rq_pend, issue timestamp request
ts_rq_r <= did_start || ts_rq_next; // (frag_done && !byte_count_zero); //first start only after header processed OK;
if (!rdy_r) out_words <= 5'h1b;
else if (rd_stb) out_words <= out_words - 1;
if (!nreset_r || header_run) raddr <= 0;
else if (rd_stb) raddr <= raddr + 1;
if (!nreset_r || header_run || (out_words == 0) || (raddr == last_word_written)) rdy_r <= 0;
else if (frag_done) rdy_r <= 1;
end
endmodule
......@@ -51,39 +51,21 @@ module logger_arbiter393(
output ts_en, // 1 - use timestamp, 0 - channel data (or 16'h0 if !ready)
output reg dv, // output data valid (from registered mux - 2 stage - first selects data and ready, second ts/data/zero)
output [23:0] sample_counter);// number of 64-byte samples logged
/*
input xclk; // half frequency (80 MHz nominal)
input rst; // reset module
input [ 3:0] ts_rq_in; // in requests for timestamp (sinlgle-cycle)
output [ 3:0] ts_rq; // out request for timestamp, to timestmp module
input [ 3:0] ts_grant; // granted ts requests from timestamping module
input [ 3:0] rdy; // channels ready (leading edge - became ready, trailing - no more data, use zero)
output [ 3:0] nxt; // pulses to modules to output next word
output [ 1:0] channel; // decoded channel number (2 bits)
output [ 1:0] ts_sel; // select timestamp word to be output (0..3)
output ts_en; // 1 - use timestamp, 0 - channel data (or 16'h0 if !ready)
output dv; // output data valid (from registered mux - 2 stage - first selects data and ready, second ts/data/zero)
output [23:0] sample_counter;// number of 64-byte samples logged
*/
reg [3:0] ts_rq_in_d;
reg [3:0] ts_rq_r;
reg [3:0] ts_valid;
// reg [3:0] ts_rq_reset;
reg [3:0] channels_ready;// channels granted and ready
reg [3:1] chn1hot; // channels 1-hot - granted and ready, priority applied
reg rq_not_zero; // at least one channel is ready for processing (same time as chn1hot[3:0])
reg [1:0] channel_r;
// reg start; Not used!
reg busy;
wire wstart;
reg ts_en_r;
reg [4:0] seq_cntr;
reg seq_cntr_last;
reg [1:0] ts_sel_r;
// reg dv;
reg inc_sample_counter;
reg [23:0] sample_counter_r;// number of 64-byte samples logged
// reg [ 3:0] nxt;
reg pre_nxt;
reg [ 3:0] chn_servicing; //1-hot channel being service
wire [3:0] wts_rq;
......@@ -119,8 +101,6 @@ module logger_arbiter393(
channels_ready[2] & ~|channels_ready[1:0],
channels_ready[1] & ~channels_ready[0]};
// start <= wstart; Not used !
if ((seq_cntr[4:0]=='h1e) || rst) busy <= 1'b0;
else if (rq_not_zero) busy <= 1'b1;
......
......@@ -44,7 +44,7 @@ module nmea_decoder393(
input we, // registers write enable (@negedge mclk)
input [4:0] wa, // registers write address
input [7:0] wd, // write data
input start, // start of the serail message
input start, // start of the serial message
input rs232_wait_pause,// may be used as reset for decoder
input start_char, // serial character start (single pulse)
output reg nmea_sent_start, // serial character start (single pulse)
......@@ -100,7 +100,7 @@ module nmea_decoder393(
wire [3:0] gpxxx_w_one;
wire [7:0] format_data;
wire w_sentence_over;
reg [4:0] last_word_written; // number of the last word (4 nibbles) written - used ro deassert rdy (garbage after)
reg [4:0] last_word_written; // number of the last word (4 nibbles) written - used to deassert rdy (garbage after)
reg rdy_r=1'b0;
reg save_sent_number;
reg [ 7:0] debug0;
......@@ -281,10 +281,6 @@ module nmea_decoder393(
reg [3:0] odbuf1_ram[0:31];
reg [3:0] odbuf2_ram[0:31];
reg [3:0] odbuf3_ram[0:31];
/// always @ (posedge xclk) if (nibble_stb && (nibble_count[1:0] == 2'h0)) odbuf0_ram[nibble_count[6:2]] <= nibble[3:0];
/// always @ (posedge xclk) if (nibble_stb && (nibble_count[1:0] == 2'h1)) odbuf1_ram[nibble_count[6:2]] <= nibble[3:0];
/// always @ (posedge xclk) if (nibble_stb && (nibble_count[1:0] == 2'h2)) odbuf2_ram[nibble_count[6:2]] <= nibble[3:0];
/// always @ (posedge xclk) if (nibble_stb && (nibble_count[1:0] == 2'h3)) odbuf3_ram[nibble_count[6:2]] <= nibble[3:0];
wire nibble_0 = nibble_count[1:0] == 2'h0;
wire nibble_1 = nibble_count[1:0] == 2'h1;
......
......@@ -2669,7 +2669,7 @@ class X393ExportC(object):
def _enc_logger_conf(self):
dw=[]
dw.append(("imu_slot", vrlg.LOGGER_CONF_IMU - vrlg.LOGGER_CONF_IMU_BITS, vrlg.LOGGER_CONF_IMU_BITS, 0, "IMU slot"))
dw.append(("imu_slot", vrlg.LOGGER_CONF_IMU - vrlg.LOGGER_CONF_IMU_BITS, vrlg.LOGGER_CONF_IMU_BITS, 0, "IMU slot (3 - use IMX5 instead of GPS)"))
dw.append(("imu_set", vrlg.LOGGER_CONF_IMU, 1, 0, "Set 'imu_slot'"))
dw.append(("gps_slot", vrlg.LOGGER_CONF_GPS - vrlg.LOGGER_CONF_GPS_BITS, 2, 0, "GPS slot"))
dw.append(("gps_invert", vrlg.LOGGER_CONF_GPS - vrlg.LOGGER_CONF_GPS_BITS + 2, 1, 0, "GPS inpert 1pps signal"))
......
......@@ -60,8 +60,8 @@ class X393Logger(object):
ADDR_REG = 1
DATA_REG = 0
PCA9500_PP_ADDR = 0x40 #< PCA9500 i2c slave addr for the parallel port (read will be 0x41)
SLOW_SPI = 26 # just for the driver, not written to FPGA (was 23 for NC353)
I2C_SA3 = 28 #Low 3 bits of the SA7 of the PCA9500 slave address
SLOW_SPI = 27 # just for the driver, not written to FPGA (was 23 for NC353)
I2C_SA3 = 29 #Low 3 bits of the SA7 of the PCA9500 slave address
# X313_IMU_PERIOD_ADDR = 0x0 # request period for IMU (in SPI bit periods)
# X313_IMU_DIVISOR_ADDR = 0x1 # xclk (80MHz) clock divisor for half SPI bit period 393: clock is Now clock is logger_clk=100MHz (200 MHz?)
......@@ -355,9 +355,9 @@ int logger_init_fpga(int force) ///< if 0, only do if not already initialized
@param config - logger configuration word
"""
print("Writing logger configuration word: 0x%08x to register 0x%x"%(config & 0x3ffffff, vrlg.LOGGER_CONFIG))
print("Writing logger configuration word: 0x%08x to register 0x%x"%(config & 0x7ffffff, vrlg.LOGGER_CONFIG))
self.x393_axi_tasks.write_control_register(vrlg.LOGGER_ADDR + self.ADDR_REG, vrlg.LOGGER_CONFIG);
self.x393_axi_tasks.write_control_register(vrlg.LOGGER_ADDR + self.DATA_REG, config & 0x3ffffff);
self.x393_axi_tasks.write_control_register(vrlg.LOGGER_ADDR + self.DATA_REG, config & 0x7ffffff);
def logger_registers(self,registers):
"""
......@@ -382,7 +382,7 @@ int logger_init_fpga(int force) ///< if 0, only do if not already initialized
lmessage +=chr(0)*(56-len(lmessage))
lmessage = lmessage[:56]
print("Setting odometer message %56s"%(bytearray(self.zterm(lmessage)).decode()))
self.x393_axi_tasks.write_control_register(vrlg.LOGGER_ADDR + self.ADDR_REG, self.X313_IMU_REGISTERS_ADDR)
self.x393_axi_tasks.write_control_register(vrlg.LOGGER_ADDR + self.ADDR_REG, self.X313_IMU_MESSAGE_ADDR) # X313_IMU_REGISTERS_ADDR)
for i in range(0,56,4):
# d=ord(lmessage[i]) + (ord(lmessage[i+1]) << 8) + (ord(lmessage[i+1]) << 16) + (ord(lmessage[i+1]) << 24)
d=lmessage[i] + (lmessage[i+1] << 8) + (lmessage[i+1] << 16) + (lmessage[i+1] << 24)
......@@ -424,9 +424,14 @@ int logger_init_fpga(int force) ///< if 0, only do if not already initialized
period = struct.unpack_from("<I", wbuf, offset=self.X313_IMU_PERIOD_OFFS)[0]
divisor = struct.unpack_from("<I", wbuf, offset=self.X313_IMU_DIVISOR_OFFS)[0]
rs232_div = struct.unpack_from("<I", wbuf, offset=self.X313_IMU_RS232DIV_OFFS)[0]
print("period: 0x%08x"%(period))
print("divisor: 0x%08x"%(divisor))
print("rs232_div: 0x%08x"%(rs232_div))
if (self.DRY_MODE):
rs232_div = 8
config = struct.unpack_from("<I", wbuf, offset=self.X313_IMU_CONFIGURE_OFFS)[0]
print("config: 0x%08x"%(config))
message = wbuf[self.X313_IMU_MESSAGE_OFFS: self.X313_IMU_MESSAGE_OFFS+56]
nmea_format = wbuf[self.X313_IMU_NMEA_FORMAT_OFFS:self.X313_IMU_NMEA_FORMAT_OFFS+128]
registers = wbuf[self.X313_IMU_REGISTERS_OFFS: self.X313_IMU_NMEA_FORMAT_OFFS]
......@@ -590,11 +595,11 @@ which= 0x3f9
parameter LOGGER_CONF_GPS_BITS = 4,
parameter LOGGER_CONF_MSG = 13,
parameter LOGGER_CONF_MSG_BITS = 5,
parameter LOGGER_CONF_SYN = 18, // 15,
parameter LOGGER_CONF_SYN_BITS = 4, // 1,
parameter LOGGER_CONF_EN = 20, // 17,
parameter LOGGER_CONF_SYN = 19, // 18, // 15,
parameter LOGGER_CONF_SYN_BITS = 5, // 4, // 1,
parameter LOGGER_CONF_EN = 21, // 20, // 17,
parameter LOGGER_CONF_EN_BITS = 1,
parameter LOGGER_CONF_DBG = 25, // 22,
parameter LOGGER_CONF_DBG = 26, // 25, // 22,
parameter LOGGER_CONF_DBG_BITS = 4,
parameter GPIO_N = 10 // number of GPIO bits to control
......
/*!
* <b>Module:</b> simul_imx5
* @file simul_imx5.v
* @date 2022-02-08
* @author Andrey Filippov
*
* @brief Simulating Inertial Sense IMX5 binary protocol
*
* @copyright Copyright (c) 2022 <set up in Preferences-Verilog/VHDL Editor-Templates> .
*
* <b>License </b>
*
* simul_imx5.v is free software; you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
* the Free Software Foundation, either version 3 of the License, or
* (at your option) any later version.
*
* simul_imx5.v is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details.
*
* You should have received a copy of the GNU General Public License
* along with this program. If not, see <http://www.gnu.org/licenses/> .
*
* Additional permission under GNU GPL version 3 section 7:
* If you modify this Program, or any covered work, by linking or combining it
* with independent modules provided by the FPGA vendor only (this permission
* does not extend to any 3-rd party modules, "soft cores" or macros) under
* different license terms solely for the purpose of generating binary "bitstream"
* files and/or simulating the code, the copyright holders of this Program give
* you the right to distribute the covered work without those independent modules
* as long as the source code for them is available from the FPGA vendor free of
* charge, and there is no dependence on any encrypted modules for simulating of
* the combined code. This permission applies to you if the distributed code
* contains all the components and scripts required to completely simulate it
* with at least one of the Free Software programs.
*/
`timescale 1ns/1ps
module simul_imx5#(
parameter DATA_FILE = "/input_data/imx5_did_ins_1.dat", //
parameter BIT_DURATION = 160, // ns
parameter RECORD_BYTES = 80, // bytes per record
parameter RECORD_NUM = 10, // number of records
parameter PAUSE_CLOCKS = 100 // skip clocks between messages
)(
input mrst, // active low
output uart_out, // will just copy when not reset;
output sending, // sending data (excluding start/stop bits)
output escape
);
localparam PACKET_ID = 8'h4; // DATA packet
localparam PACKET_COUNTER = 8'h0;
localparam PACKET_FLAGS = 8'h13; // CM_PKT_FLAGS_LITTLE_ENDIAN = 0x01, CM_PKT_FLAGS_CHECKSUM_24_BIT = 0x10, CM_PKT_FLAGS_RX_VALID_DATA = 0x02
localparam DATA_SET_ID = 32'h4; // DID_INS_1
localparam DATA_OFFSET = 32'h0;
localparam DATA_SIZE = RECORD_BYTES * RECORD_NUM;
`ifndef ROOTPATH
`include "IVERILOG_INCLUDE.v"// SuppressThisWarning VEditor - maybe not used
`ifndef ROOTPATH
`define ROOTPATH "."
`endif
`endif
reg clk_r = 0;
reg [7:0] records[0 : DATA_SIZE - 1]; // SuppressThisWarning VEditor - Will be assigned by $readmem
reg IMX_SENDING = 0;
reg IMX_BIT = 1;
reg ESCAPE = 0;
reg [7:0] packet_counter;
reg [7:0] dbyte;
integer nrec = 0;
integer byte_pointer;
integer shifter;
integer num_byte;
reg [23:0] checkSumValue = 24'haaaaaa;
reg [95:0] header;
assign uart_out = IMX_BIT;
assign sending = IMX_SENDING;
assign escape = ESCAPE;
initial begin
$readmemh({`ROOTPATH,DATA_FILE},records);
header[31: 0] <= DATA_SET_ID;
header[63:32] <= RECORD_BYTES;
header[95:64] <= DATA_OFFSET;
packet_counter <= PACKET_COUNTER;
end
always #(BIT_DURATION/2) clk_r <= mrst ? 1'b0 : ~clk_r;
always @ (negedge mrst) begin
wait (clk_r); wait (~clk_r);
for (nrec = 0; nrec < RECORD_NUM; nrec = nrec + 1) begin
checkSumValue = 24'haaaaaa;
send_imx_byte('hff); // start (not escaped) // byte 0
dbyte = PACKET_ID;
send_imx_escaped_byte(dbyte); // pid // byte 1
checkSumValue[ 7: 0] = checkSumValue[ 7: 0] ^ dbyte;
dbyte = packet_counter;
send_imx_escaped_byte(dbyte); // counter // byte 2
checkSumValue[15: 8] = checkSumValue[15: 8] ^ dbyte;
dbyte = PACKET_FLAGS;
send_imx_escaped_byte(dbyte); // packet flags // byte 3
checkSumValue[23:16] = checkSumValue[23:16] ^ dbyte;
// send_imx_escaped_byte(PACKET_COUNTER); // counter
// send header
byte_pointer = 0;
shifter = 0;
for (byte_pointer = 0; byte_pointer < $bits(header); byte_pointer = byte_pointer + 8) begin
// for (byte_pointer = 0; byte_pointer < RECORD_BYTES; byte_pointer = byte_pointer + 1) begin
dbyte = header[byte_pointer +: 8];
send_imx_escaped_byte(dbyte); //
checkSumValue[shifter +: 8] = checkSumValue[shifter +: 8] ^ dbyte;
if (shifter > 8) shifter = 0;
else shifter = shifter + 8;
end
// send data
byte_pointer = RECORD_BYTES * nrec;
for (num_byte = 0; num_byte < RECORD_BYTES; num_byte = num_byte + 1) begin
dbyte = records[byte_pointer];
byte_pointer = byte_pointer + 1;
send_imx_escaped_byte(dbyte); //
checkSumValue[shifter +: 8] = checkSumValue[shifter +: 8] ^ dbyte;
if (shifter > 8) shifter = 0;
else shifter = shifter + 8;
end
// send checksum
send_imx_escaped_byte(checkSumValue[16 +: 8]);
send_imx_escaped_byte(checkSumValue[ 8 +: 8]);
send_imx_escaped_byte(checkSumValue[ 0 +: 8]);
send_imx_byte('hfe); // stop (not escaped)
repeat (PAUSE_CLOCKS) begin // make a pause between records
wait (clk_r); wait (~clk_r);
end
packet_counter = packet_counter + 1;
end
end
task send_imx_escaped_byte;
input [ 7:0] data_byte;
begin
if ((data_byte == 8'h0a) ||
(data_byte == 8'h24) ||
(data_byte == 8'hb5) ||
(data_byte == 8'hd3) ||
(data_byte == 8'hfd) ||
(data_byte == 8'hfe) ||
(data_byte == 8'hff)) begin
ESCAPE = 1;
send_imx_byte(8'hfd); // escape
send_imx_byte(~data_byte); // invertedbyte
ESCAPE = 0;
end else begin
send_imx_byte(data_byte);
end
end
endtask
// 0x0A , 0x24 , 0xB5 , 0xD3 , 0xFD , 0xFE and 0xFF
task send_imx_byte;
input [ 7:0] data_byte;
reg [ 9:0] d;
integer i;
begin
// IMX_SENDING = 1;
d = {1'b1, data_byte, 1'b0}; // includes start (0) and stop (1) bits
// SERIAL_BIT should be 1 here
// Send START (8), 8 data bits, LSB first, STOP(1)
// repeat (10) begin
for (i = 0; i < 10; i = i+1) begin
if (i == 1) IMX_SENDING = 1;
else if (i == 9) IMX_SENDING = 0;
IMX_BIT = d[0];
#1 d[9:0] = {1'b0,d[9:1]};
wait (clk_r); wait (~clk_r);
end
IMX_SENDING = 0;
end
endtask
endmodule
......@@ -153,6 +153,11 @@ module camsync393 #(
output ts_snap_mclk_chn3, // ts_snap_mclk make a timestamp pulse single @(posedge pclk)
input ts_snd_stb_chn3, // 1 clk before ts_snd_data is valid
input [7:0] ts_snd_data_chn3, // byte-wide serialized timestamp message
/// output ts_snap_mclk_chn4, // ts_snap_mclk make a timestamp pulse single @(posedge pclk)
/// input ts_snd_stb_chn4, // 1 clk before ts_snd_data is valid
/// input [7:0] ts_snd_data_chn4, // byte-wide serialized timestamp message
// Timestamps to be sent over the network (or provided internally)
output ts_master_snap, // ts_snap_mclk make a timestamp pulse single @(posedge pclk)
......@@ -176,7 +181,10 @@ module camsync393 #(
output [7:0] ts_rcv_data_chn2, // byte-wide serialized timestamp message received or local
output ts_rcv_stb_chn3, // 1 clock before ts_rcv_data is valid
output [7:0] ts_rcv_data_chn3 // byte-wide serialized timestamp message received or local
output [7:0] ts_rcv_data_chn3, // byte-wide serialized timestamp message received or local
output ts_rcv_stb_chn4, // 1 clock before ts_rcv_data is valid
output [7:0] ts_rcv_data_chn4 // byte-wide serialized timestamp message received or local
);
reg en = 0; // enable camsync module
// wire rst = mrst || !en;
......@@ -349,6 +357,7 @@ module camsync393 #(
reg rcv_done_rq; // request to copy time stamp (if it is not ready yet)
reg rcv_done_rq_d;
reg rcv_done; // rcv_run ended, copy timestamp if requested
wire rcv_done_mclk; // copy ts of received ts for the logger
// wire rcv_done_mclk; // rcv_done re-clocked @mclk
wire pre_rcv_error; // pre/post magic does not match, set ts to all ff-s
reg rcv_error;
......@@ -386,8 +395,14 @@ module camsync393 #(
reg ts_incoming; // expect incoming timestamps (ts_snd_en && !input_use_intern)
reg received_or_master; // either received timestamp or master
wire [31:0] ts_sec_received_or_master = ts_incoming? {sr_rcv_first[25:0], sr_rcv_second[31:26]} : ts_snd_sec[31:0];
wire [19:0] ts_usec_received_or_master = ts_incoming? {rcv_error?20'hfffff: sr_rcv_second[25:6]} : ts_snd_usec[19:0];
wire [31:0] ts_sec_received = {sr_rcv_first[25:0], sr_rcv_second[31:26]};
wire [19:0] ts_usec_received = {rcv_error?20'hfffff: sr_rcv_second[25:6]};
/// wire [31:0] ts_sec_received_or_master = ts_incoming? {sr_rcv_first[25:0], sr_rcv_second[31:26]} : ts_snd_sec[31:0];
/// wire [19:0] ts_usec_received_or_master = ts_incoming? {rcv_error?20'hfffff: sr_rcv_second[25:6]} : ts_snd_usec[19:0];
wire [31:0] ts_sec_received_or_master = ts_incoming? ts_sec_received : ts_snd_sec[31:0];
wire [19:0] ts_usec_received_or_master = ts_incoming? ts_usec_received : ts_snd_usec[19:0];
reg [3:0] frsync_pend; // from start_dly->start_early to frsync_pclk[i]; (start_dly too late in internal trigger mode)
reg received_or_master_pending; // from start_dly->start_early to received_or_master;
......@@ -406,7 +421,7 @@ module camsync393 #(
wire [3:0] frsync_pclk; // time to copy timestamps from master/received to channels (will always be after it is available)
wire [3:0] dly_cntr_start; // start delay counters (added non-triggered mode option)
// in triggered mode uses ts_master_stb, ts_master_data inputs (as was before), in free runnig - timestyamps from the master channel
// in triggered mode uses ts_master_stb, ts_master_data inputs (as was before), in free runnig - timestamps from the master channel
wire ts_master_stb_with_free; // 1 clk before ts_snd_data is valid
wire [7:0] ts_master_data_with_free; // byte-wide serialized timestamp message
......@@ -961,6 +976,14 @@ module camsync393 #(
.tdata (ts_rcv_data_chn3) // output[7:0] reg
);
timestamp_to_serial timestamp_to_serial4_i (
.clk (mclk), // input
.stb (rcv_done_mclk), // input
.sec (ts_sec_received), // input[31:0]
.usec (ts_usec_received), // input[19:0]
.tdata (ts_rcv_data_chn4) // output[7:0] reg
);
level_cross_clocks #(
......@@ -974,6 +997,7 @@ module camsync393 #(
assign {ts_rcv_stb_chn3, ts_rcv_stb_chn2, ts_rcv_stb_chn1, ts_rcv_stb_chn0}= ts_stb;
assign ts_rcv_stb_chn4 = rcv_done_mclk;
pulse_cross_clock i_start_to_pclk (.rst(mrst), .src_clk(mclk), .dst_clk(pclk), .in_pulse(start_d && start_en), .out_pulse(start_to_pclk),.busy());
pulse_cross_clock i_ts_snap_mclk0 (.rst(eprst), .src_clk(pclk), .dst_clk(mclk), .in_pulse(ts_snap_triggered[0]), .out_pulse(ts_snap_triggered_mclk[0]),.busy());
......@@ -1006,6 +1030,7 @@ module camsync393 #(
pulse_cross_clock i_ts_stb_mclk1 (.rst(eprst), .src_clk(pclk), .dst_clk(mclk), .in_pulse(ts_stb_pclk_r[1]), .out_pulse(ts_stb[1]),.busy());
pulse_cross_clock i_ts_stb_mclk2 (.rst(eprst), .src_clk(pclk), .dst_clk(mclk), .in_pulse(ts_stb_pclk_r[2]), .out_pulse(ts_stb[2]),.busy());
pulse_cross_clock i_ts_stb_mclk3 (.rst(eprst), .src_clk(pclk), .dst_clk(mclk), .in_pulse(ts_stb_pclk_r[3]), .out_pulse(ts_stb[3]),.busy());
pulse_cross_clock i_ts_stb_mclkx (.rst(eprst), .src_clk(pclk), .dst_clk(mclk), .in_pulse(rcv_done), .out_pulse(rcv_done_mclk),.busy());
pulse_cross_clock i_suppress_immediate_set_pclk(.rst(!en), .src_clk(mclk), .dst_clk(pclk), .in_pulse(suppress_immediate_set_mclk), .out_pulse(suppress_immediate_set_pclk),.busy());
......
......@@ -128,6 +128,9 @@ module timing393 #(
output ts_stb_chn3, // 1 clock before ts_rcv_data is valid
output [7:0] ts_data_chn3, // byte-wide serialized timestamp message received or local
output ts_stb_chn4, // 1 clock before ts_rcv_data is valid
output [7:0] ts_data_chn4, // byte-wide serialized timestamp message received or local
// timestamp for the event logger
input lclk, // clock used by the event logger
input lrst, // @ posedge lclk - sync reset
......@@ -149,15 +152,15 @@ module timing393 #(
wire [3:0] ts_stb; // 1 clk before ts_snd_data is valid
wire [31:0] ts_data; // byte-wide serialized timestamp message (channels concatenated)
wire [4:0] ts_stb; // 1 clk before ts_snd_data is valid
wire [39:0] ts_data; // byte-wide serialized timestamp message (channels concatenated)
wire [31:0] live_sec; // current time seconds, updated @ mclk
wire [19:0] live_usec; // current time microseconds, updated @ mclk
assign {ts_stb_chn3, ts_stb_chn2, ts_stb_chn1, ts_stb_chn0} = ts_stb;
assign {ts_data_chn3, ts_data_chn2, ts_data_chn1, ts_data_chn0} = ts_data;
assign {ts_stb_chn4, ts_stb_chn3, ts_stb_chn2, ts_stb_chn1, ts_stb_chn0} = ts_stb;
assign {ts_data_chn4, ts_data_chn3, ts_data_chn2, ts_data_chn1, ts_data_chn0} = ts_data;
assign {trig_chn3, trig_chn2, trig_chn1, trig_chn0} = trig;
assign frame_sync = {frsync_chn3, frsync_chn2, frsync_chn1, frsync_chn0};
......@@ -173,7 +176,6 @@ module timing393 #(
.RTC_SET_CORR (RTC_SET_CORR),
.RTC_SET_STATUS (RTC_SET_STATUS)
) rtc393_i (
// .rst (rst), // input
.mclk (mclk), // input
.mrst (mrst), // input
.refclk (refclk), // input
......@@ -185,12 +187,10 @@ module timing393 #(
.live_sec (live_sec), // output[31:0]
.live_usec (live_usec), // output[19:0]
.khz (khz) // output
);
timestamp_snapshot timestamp_snapshot_logger_i (
// .rst (rst), // input
.tclk (mclk), // input
.sec (live_sec), // input[31:0]
.usec (live_usec), // input[19:0]
......@@ -202,7 +202,6 @@ module timing393 #(
);
timestamp_snapshot timestamp_snapshot_chn0_i (
// .rst (rst), // input
.tclk (mclk), // input
.sec (live_sec), // input[31:0]
.usec (live_usec), // input[19:0]
......@@ -214,7 +213,6 @@ module timing393 #(
);
timestamp_snapshot timestamp_snapshot_chn1_i (
// .rst (rst), // input
.tclk (mclk), // input
.sec (live_sec), // input[31:0]
.usec (live_usec), // input[19:0]
......@@ -226,7 +224,6 @@ module timing393 #(
);
timestamp_snapshot timestamp_snapshot_chn2_i (
// .rst (rst), // input
.tclk (mclk), // input
.sec (live_sec), // input[31:0]
.usec (live_usec), // input[19:0]
......@@ -238,7 +235,6 @@ module timing393 #(
);
timestamp_snapshot timestamp_snapshot_chn3_i (
// .rst (rst), // input
.tclk (mclk), // input
.sec (live_sec), // input[31:0]
.usec (live_usec), // input[19:0]
......@@ -316,10 +312,10 @@ module timing393 #(
.ts_snd_data_chn1 (ts_local_data[1 * 8 +: 8]), // input[7:0]
.ts_snap_mclk_chn2 (ts_local_snap[2]), // output
.ts_snd_stb_chn2 (ts_local_stb[2]), // input
.ts_snd_data_chn2 (ts_local_data[2 * 8 +: 8]), // input[7:0]
.ts_snd_data_chn2 (ts_local_data[2 * 8 +: 8]), // input[7:0]
.ts_snap_mclk_chn3 (ts_local_snap[3]), // output
.ts_snd_stb_chn3 (ts_local_stb[3]), // input
.ts_snd_data_chn3 (ts_local_data[3 * 8 +: 8]), // input[7:0]
.ts_snd_data_chn3 (ts_local_data[3 * 8 +: 8]), // input[7:0]
.ts_master_snap (ts_master_snap), // output
.ts_master_stb (ts_master_stb), // input
.ts_master_data (ts_master_data), // input[7:0]
......@@ -330,7 +326,9 @@ module timing393 #(
.ts_rcv_stb_chn2 (ts_stb[2]), // output
.ts_rcv_data_chn2 (ts_data[2 * 8 +: 8]), // output[7:0]
.ts_rcv_stb_chn3 (ts_stb[3]), // output
.ts_rcv_data_chn3 (ts_data[3 * 8 +: 8]) // output[7:0]
.ts_rcv_data_chn3 (ts_data[3 * 8 +: 8]), // output[7:0]
.ts_rcv_stb_chn4 (ts_stb[4]), // output
.ts_rcv_data_chn4 (ts_data[4 * 8 +: 8]) // output[7:0]
);
endmodule
......
......@@ -661,8 +661,10 @@ module x393 #(
// Timestamp messages (@mclk) - combine to a single ts_data?
wire [3:0] ts_pre_stb; // input[ 3:0] 4 compressor channels
wire [31:0] ts_data; // input[31:0] 4 compressor channels
/// wire [3:0] ts_pre_stb; // input[ 3:0] 4 compressor channels
/// wire [31:0] ts_data; // input[31:0] 4 compressor channels
wire [4:0] ts_pre_stb; // input[ 3:0] 4 compressor channels
wire [39:0] ts_data; // input[31:0] 4 compressor channels
// Timestamp messages (@mclk) - combine to a single ts_data?
wire ts_pre_logger_stb; // input logger timestamp sync (@logger_clk)
......@@ -2420,8 +2422,8 @@ assign axi_grst = axi_rst_pre;
.frame_number_finished (cmprs_frame_number_finished),// output[63:0] frame numbers compressed
.ts_pre_stb (ts_pre_stb), // input[3:0]
.ts_data (ts_data), // input[31:0]
.ts_pre_stb (ts_pre_stb[3:0]), // input[3:0]
.ts_data (ts_data[31:0]), // input[31:0]
.eof_written_mclk (eof_written_mclk), // output[3:0]
.stuffer_done_mclk (stuffer_done_mclk), // output[3:0]
......@@ -2587,6 +2589,8 @@ assign axi_grst = axi_rst_pre;
.ts_data_chn2 (ts_data[2 * 8 +: 8]), // output[7:0]
.ts_stb_chn3 (ts_pre_stb[3]), // output
.ts_data_chn3 (ts_data[3 * 8 +: 8]), // output[7:0]
.ts_stb_chn4 (ts_pre_stb[4]), // output
.ts_data_chn4 (ts_data[4 * 8 +: 8]), // output[7:0]
.lclk (logger_clk), // input global clock, common with the logger (use 100 MHz?)
.lrst (lrst), // input
.ts_logger_snap (logger_snap), // input
......@@ -2651,6 +2655,8 @@ assign axi_grst = axi_rst_pre;
.ts_data_chn2 (ts_data[2 * 8 +: 8]), // input[7:0]
.ts_stb_chn3 (ts_pre_stb[3]), // input
.ts_data_chn3 (ts_data[3 * 8 +: 8]), // input[7:0]
.ts_stb_chn4 (ts_pre_stb[4]), // input
.ts_data_chn4 (ts_data[4 * 8 +: 8]), // input[7:0]
.data_out (logger_out), // output[15:0] @mclk
.data_out_stb (logger_stb), // output @mclk
......
No preview for this file type
Markdown is supported
0% or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment