├── LICENSE
├── Makefile
├── README.md
├── component.xml
├── design_modules.svg
├── hdl
├── axi_csi.v
├── axilite_control.v
├── ecc_block.v
├── pckthandler.v
├── pckthandler_fsm.v
├── ph_finder.v
├── raw10_decoder.v
└── wordalign.v
├── unit_tests
├── Makefile
├── csirx_tb.v
├── ecc_block_tb.v
├── ecc_block_testvec.txt
├── image4.bin
├── image4_out.bin
├── pckthandler_fsm_tb.v
├── pckthandler_fsm_testvec.txt
├── pckthandler_tb.v
├── pckthandler_tb2.v
├── pckthandler_testvec.txt
├── ph_finder_tb.v
├── ph_finder_testvec.txt
├── raw10_decoder_tb.v
├── raw10_decoder_testvec.txt
└── viewdump.py
└── xgui
├── axi_csi_v1_1.tcl
└── axi_csi_v1_1_v1_0.tcl
/LICENSE:
--------------------------------------------------------------------------------
1 | GNU LESSER GENERAL PUBLIC LICENSE
2 | Version 3, 29 June 2007
3 |
4 | Copyright (C) 2007 Free Software Foundation, Inc.
5 | Everyone is permitted to copy and distribute verbatim copies
6 | of this license document, but changing it is not allowed.
7 |
8 |
9 | This version of the GNU Lesser General Public License incorporates
10 | the terms and conditions of version 3 of the GNU General Public
11 | License, supplemented by the additional permissions listed below.
12 |
13 | 0. Additional Definitions.
14 |
15 | As used herein, "this License" refers to version 3 of the GNU Lesser
16 | General Public License, and the "GNU GPL" refers to version 3 of the GNU
17 | General Public License.
18 |
19 | "The Library" refers to a covered work governed by this License,
20 | other than an Application or a Combined Work as defined below.
21 |
22 | An "Application" is any work that makes use of an interface provided
23 | by the Library, but which is not otherwise based on the Library.
24 | Defining a subclass of a class defined by the Library is deemed a mode
25 | of using an interface provided by the Library.
26 |
27 | A "Combined Work" is a work produced by combining or linking an
28 | Application with the Library. The particular version of the Library
29 | with which the Combined Work was made is also called the "Linked
30 | Version".
31 |
32 | The "Minimal Corresponding Source" for a Combined Work means the
33 | Corresponding Source for the Combined Work, excluding any source code
34 | for portions of the Combined Work that, considered in isolation, are
35 | based on the Application, and not on the Linked Version.
36 |
37 | The "Corresponding Application Code" for a Combined Work means the
38 | object code and/or source code for the Application, including any data
39 | and utility programs needed for reproducing the Combined Work from the
40 | Application, but excluding the System Libraries of the Combined Work.
41 |
42 | 1. Exception to Section 3 of the GNU GPL.
43 |
44 | You may convey a covered work under sections 3 and 4 of this License
45 | without being bound by section 3 of the GNU GPL.
46 |
47 | 2. Conveying Modified Versions.
48 |
49 | If you modify a copy of the Library, and, in your modifications, a
50 | facility refers to a function or data to be supplied by an Application
51 | that uses the facility (other than as an argument passed when the
52 | facility is invoked), then you may convey a copy of the modified
53 | version:
54 |
55 | a) under this License, provided that you make a good faith effort to
56 | ensure that, in the event an Application does not supply the
57 | function or data, the facility still operates, and performs
58 | whatever part of its purpose remains meaningful, or
59 |
60 | b) under the GNU GPL, with none of the additional permissions of
61 | this License applicable to that copy.
62 |
63 | 3. Object Code Incorporating Material from Library Header Files.
64 |
65 | The object code form of an Application may incorporate material from
66 | a header file that is part of the Library. You may convey such object
67 | code under terms of your choice, provided that, if the incorporated
68 | material is not limited to numerical parameters, data structure
69 | layouts and accessors, or small macros, inline functions and templates
70 | (ten or fewer lines in length), you do both of the following:
71 |
72 | a) Give prominent notice with each copy of the object code that the
73 | Library is used in it and that the Library and its use are
74 | covered by this License.
75 |
76 | b) Accompany the object code with a copy of the GNU GPL and this license
77 | document.
78 |
79 | 4. Combined Works.
80 |
81 | You may convey a Combined Work under terms of your choice that,
82 | taken together, effectively do not restrict modification of the
83 | portions of the Library contained in the Combined Work and reverse
84 | engineering for debugging such modifications, if you also do each of
85 | the following:
86 |
87 | a) Give prominent notice with each copy of the Combined Work that
88 | the Library is used in it and that the Library and its use are
89 | covered by this License.
90 |
91 | b) Accompany the Combined Work with a copy of the GNU GPL and this license
92 | document.
93 |
94 | c) For a Combined Work that displays copyright notices during
95 | execution, include the copyright notice for the Library among
96 | these notices, as well as a reference directing the user to the
97 | copies of the GNU GPL and this license document.
98 |
99 | d) Do one of the following:
100 |
101 | 0) Convey the Minimal Corresponding Source under the terms of this
102 | License, and the Corresponding Application Code in a form
103 | suitable for, and under terms that permit, the user to
104 | recombine or relink the Application with a modified version of
105 | the Linked Version to produce a modified Combined Work, in the
106 | manner specified by section 6 of the GNU GPL for conveying
107 | Corresponding Source.
108 |
109 | 1) Use a suitable shared library mechanism for linking with the
110 | Library. A suitable mechanism is one that (a) uses at run time
111 | a copy of the Library already present on the user's computer
112 | system, and (b) will operate properly with a modified version
113 | of the Library that is interface-compatible with the Linked
114 | Version.
115 |
116 | e) Provide Installation Information, but only if you would otherwise
117 | be required to provide such information under section 6 of the
118 | GNU GPL, and only to the extent that such information is
119 | necessary to install and execute a modified version of the
120 | Combined Work produced by recombining or relinking the
121 | Application with a modified version of the Linked Version. (If
122 | you use option 4d0, the Installation Information must accompany
123 | the Minimal Corresponding Source and Corresponding Application
124 | Code. If you use option 4d1, you must provide the Installation
125 | Information in the manner specified by section 6 of the GNU GPL
126 | for conveying Corresponding Source.)
127 |
128 | 5. Combined Libraries.
129 |
130 | You may place library facilities that are a work based on the
131 | Library side by side in a single library together with other library
132 | facilities that are not Applications and are not covered by this
133 | License, and convey such a combined library under terms of your
134 | choice, if you do both of the following:
135 |
136 | a) Accompany the combined library with a copy of the same work based
137 | on the Library, uncombined with any other library facilities,
138 | conveyed under the terms of this License.
139 |
140 | b) Give prominent notice with the combined library that part of it
141 | is a work based on the Library, and explaining where to find the
142 | accompanying uncombined form of the same work.
143 |
144 | 6. Revised Versions of the GNU Lesser General Public License.
145 |
146 | The Free Software Foundation may publish revised and/or new versions
147 | of the GNU Lesser General Public License from time to time. Such new
148 | versions will be similar in spirit to the present version, but may
149 | differ in detail to address new problems or concerns.
150 |
151 | Each version is given a distinguishing version number. If the
152 | Library as you received it specifies that a certain numbered version
153 | of the GNU Lesser General Public License "or any later version"
154 | applies to it, you have the option of following the terms and
155 | conditions either of that published version or of any later version
156 | published by the Free Software Foundation. If the Library as you
157 | received it does not specify a version number of the GNU Lesser
158 | General Public License, you may choose any version of the GNU Lesser
159 | General Public License ever published by the Free Software Foundation.
160 |
161 | If the Library as you received it specifies that a proxy can decide
162 | whether future versions of the GNU Lesser General Public License shall
163 | apply, that proxy's public statement of acceptance of any version is
164 | permanent authorization for you to choose that version for the
165 | Library.
166 |
--------------------------------------------------------------------------------
/Makefile:
--------------------------------------------------------------------------------
1 |
2 | IVERILOG := iverilog -g2005
3 | BUILDDIR := build
4 |
5 | .PHONY: all clean
6 |
7 | all: ecc_block pckthandler pckthandler_fsm ph_finder raw10_decoder
8 |
9 |
10 | pckthandler2 : unit_tests/pckthandler_tb2.v
11 | $(IVERILOG) *.v unit_tests/pckthandler_tb2.v -o $(BUILDDIR)/$@
12 | cd unit_tests; vvp ../$(BUILDDIR)/$@
13 |
14 | # All the unit tests
15 | # Run them from the unit_tests dir since they depend on files
16 | % : %.v
17 | $(IVERILOG) *.v unit_tests/$*_tb.v -o $(BUILDDIR)/$@
18 | cd unit_tests; vvp ../$(BUILDDIR)/$@
19 |
20 | clean:
21 | rm -rf build/*
22 |
23 |
24 |
--------------------------------------------------------------------------------
/README.md:
--------------------------------------------------------------------------------
1 | # csirx
2 | Open-source CSI-2 receiver for Xilinx UltraScale parts
3 |
4 |
5 | # Supported cameras
6 | Right now, this only supports the Sony IMX219 (aka the Raspberry Pi camera). In the Raspberry Pi configuration, it supports 2 data lanes and 10-bit RAW output.
7 |
8 | # License
9 | This code is released under the GNU LGPL 3.0. That means you're welcome to use it however you want, but if you publish/sell a design based on a modified version of the code, then you need to share your changes to this code (but not the rest of your system).
10 |
11 | # Links
12 | Several others have created similar CSI-2 receivers:
13 |
14 | * https://github.com/daveshah1/CSI2Rx
15 |
16 |
--------------------------------------------------------------------------------
/component.xml:
--------------------------------------------------------------------------------
1 |
2 |
3 | stanford.edu
4 | user
5 | axi_csi
6 | 1.1
7 |
8 |
9 | output_m_axis
10 |
11 |
12 |
13 |
14 |
15 |
16 | TDATA
17 |
18 |
19 | output_m_axis_tdata
20 |
21 |
22 |
23 |
24 | TSTRB
25 |
26 |
27 | output_m_axis_tstrb
28 |
29 |
30 |
31 |
32 | TLAST
33 |
34 |
35 | output_m_axis_tlast
36 |
37 |
38 |
39 |
40 | TVALID
41 |
42 |
43 | output_m_axis_tvalid
44 |
45 |
46 |
47 |
48 | TREADY
49 |
50 |
51 | output_m_axis_tready
52 |
53 |
54 |
55 |
56 |
57 | regspace_s_axi
58 |
59 |
60 |
61 |
62 |
63 |
64 |
65 |
66 | AWADDR
67 |
68 |
69 | regspace_s_axi_awaddr
70 |
71 |
72 |
73 |
74 | AWPROT
75 |
76 |
77 | regspace_s_axi_awprot
78 |
79 |
80 |
81 |
82 | AWVALID
83 |
84 |
85 | regspace_s_axi_awvalid
86 |
87 |
88 |
89 |
90 | AWREADY
91 |
92 |
93 | regspace_s_axi_awready
94 |
95 |
96 |
97 |
98 | WDATA
99 |
100 |
101 | regspace_s_axi_wdata
102 |
103 |
104 |
105 |
106 | WSTRB
107 |
108 |
109 | regspace_s_axi_wstrb
110 |
111 |
112 |
113 |
114 | WVALID
115 |
116 |
117 | regspace_s_axi_wvalid
118 |
119 |
120 |
121 |
122 | WREADY
123 |
124 |
125 | regspace_s_axi_wready
126 |
127 |
128 |
129 |
130 | BRESP
131 |
132 |
133 | regspace_s_axi_bresp
134 |
135 |
136 |
137 |
138 | BVALID
139 |
140 |
141 | regspace_s_axi_bvalid
142 |
143 |
144 |
145 |
146 | BREADY
147 |
148 |
149 | regspace_s_axi_bready
150 |
151 |
152 |
153 |
154 | ARADDR
155 |
156 |
157 | regspace_s_axi_araddr
158 |
159 |
160 |
161 |
162 | ARPROT
163 |
164 |
165 | regspace_s_axi_arprot
166 |
167 |
168 |
169 |
170 | ARVALID
171 |
172 |
173 | regspace_s_axi_arvalid
174 |
175 |
176 |
177 |
178 | ARREADY
179 |
180 |
181 | regspace_s_axi_arready
182 |
183 |
184 |
185 |
186 | RDATA
187 |
188 |
189 | regspace_s_axi_rdata
190 |
191 |
192 |
193 |
194 | RRESP
195 |
196 |
197 | regspace_s_axi_rresp
198 |
199 |
200 |
201 |
202 | RVALID
203 |
204 |
205 | regspace_s_axi_rvalid
206 |
207 |
208 |
209 |
210 | RREADY
211 |
212 |
213 | regspace_s_axi_rready
214 |
215 |
216 |
217 |
218 |
219 | regspace_s_axi_aresetn
220 |
221 |
222 |
223 |
224 |
225 |
226 | RST
227 |
228 |
229 | regspace_s_axi_aresetn
230 |
231 |
232 |
233 |
234 |
235 | POLARITY
236 | ACTIVE_LOW
237 |
238 |
239 |
240 |
241 | regspace_s_axi_aclk
242 |
243 |
244 |
245 |
246 |
247 |
248 | CLK
249 |
250 |
251 | regspace_s_axi_aclk
252 |
253 |
254 |
255 |
256 |
257 | ASSOCIATED_BUSIF
258 | regspace_s_axi
259 |
260 |
261 | ASSOCIATED_RESET
262 | regspace_s_axi_aresetn
263 |
264 |
265 |
266 |
267 | csi_intr
268 |
269 |
270 |
271 |
272 |
273 |
274 | INTERRUPT
275 |
276 |
277 | csi_intr
278 |
279 |
280 |
281 |
282 |
283 | SENSITIVITY
284 | LEVEL_HIGH
285 |
286 |
287 |
288 |
289 | rxbyteclkhs_resetn
290 |
291 |
292 |
293 |
294 |
295 |
296 | RST
297 |
298 |
299 | rxbyteclkhs_resetn
300 |
301 |
302 |
303 |
304 |
305 | POLARITY
306 | ACTIVE_LOW
307 |
308 |
309 |
310 |
311 | ppi_rxbyteclkhs_clk
312 |
313 |
314 |
315 |
316 |
317 |
318 | CLK
319 |
320 |
321 | ppi_rxbyteclkhs_clk
322 |
323 |
324 |
325 |
326 |
327 | ASSOCIATED_BUSIF
328 | input_mipi_ppi:output_m_axis
329 |
330 |
331 |
332 |
333 | input_mipi_ppi
334 |
335 |
336 |
337 |
338 |
339 |
340 | DL1_RXACTIVEHS
341 |
342 |
343 | ppi_dl1_rxactivehs
344 |
345 |
346 |
347 |
348 | CL_ENABLE
349 |
350 |
351 | ppi_cl_enable
352 |
353 |
354 |
355 |
356 | DL1_RXDATAHS
357 |
358 |
359 | ppi_dl1_rxdatahs
360 |
361 |
362 |
363 |
364 | CL_STOPSTATE
365 |
366 |
367 | ppi_cl_stopstate
368 |
369 |
370 |
371 |
372 | DL0_RXSYNCHS
373 |
374 |
375 | ppi_dl0_rxsynchs
376 |
377 |
378 |
379 |
380 | DL1_RXVALIDHS
381 |
382 |
383 | ppi_dl1_rxvalidhs
384 |
385 |
386 |
387 |
388 | DL0_RXACTIVEHS
389 |
390 |
391 | ppi_dl0_rxactivehs
392 |
393 |
394 |
395 |
396 | DL1_RXSYNCHS
397 |
398 |
399 | ppi_dl1_rxsynchs
400 |
401 |
402 |
403 |
404 | DL0_ENABLE
405 |
406 |
407 | ppi_dl0_enable
408 |
409 |
410 |
411 |
412 | DL0_RXDATAHS
413 |
414 |
415 | ppi_dl0_rxdatahs
416 |
417 |
418 |
419 |
420 | DL1_FORCERXMODE
421 |
422 |
423 | ppi_dl1_forcerxmode
424 |
425 |
426 |
427 |
428 | DL1_ENABLE
429 |
430 |
431 | ppi_dl1_enable
432 |
433 |
434 |
435 |
436 | DL0_RXVALIDHS
437 |
438 |
439 | ppi_dl0_rxvalidhs
440 |
441 |
442 |
443 |
444 | DL0_FORCERXMODE
445 |
446 |
447 | ppi_dl0_forcerxmode
448 |
449 |
450 |
451 |
452 |
453 |
454 |
455 | regspace_s_axi
456 |
457 | reg0
458 | 0
459 | 4096
460 | 32
461 | register
462 |
463 |
464 |
465 |
466 |
467 |
468 | xilinx_anylanguagesynthesis
469 | Synthesis
470 | :vivado.xilinx.com:synthesis
471 | Verilog
472 | axi_csi
473 |
474 | xilinx_anylanguagesynthesis_view_fileset
475 |
476 |
477 |
478 | viewChecksum
479 | b6a6cb14
480 |
481 |
482 |
483 |
484 | xilinx_anylanguagebehavioralsimulation
485 | Simulation
486 | :vivado.xilinx.com:simulation
487 | Verilog
488 | axi_csi
489 |
490 | xilinx_anylanguagebehavioralsimulation_view_fileset
491 |
492 |
493 |
494 | viewChecksum
495 | b6a6cb14
496 |
497 |
498 |
499 |
500 | xilinx_xpgui
501 | UI Layout
502 | :vivado.xilinx.com:xgui.ui
503 |
504 | xilinx_xpgui_view_fileset
505 |
506 |
507 |
508 | viewChecksum
509 | f92e9879
510 |
511 |
512 |
513 |
514 |
515 |
516 | csi_intr
517 |
518 | out
519 |
520 |
521 | wire
522 | xilinx_anylanguagesynthesis
523 | xilinx_anylanguagebehavioralsimulation
524 |
525 |
526 |
527 |
528 |
529 | rxbyteclkhs_resetn
530 |
531 | in
532 |
533 |
534 | wire
535 | xilinx_anylanguagesynthesis
536 | xilinx_anylanguagebehavioralsimulation
537 |
538 |
539 |
540 |
541 |
542 | ppi_cl_stopstate
543 |
544 | in
545 |
546 |
547 | wire
548 | xilinx_anylanguagesynthesis
549 | xilinx_anylanguagebehavioralsimulation
550 |
551 |
552 |
553 |
554 |
555 | ppi_cl_enable
556 |
557 | out
558 |
559 |
560 | wire
561 | xilinx_anylanguagesynthesis
562 | xilinx_anylanguagebehavioralsimulation
563 |
564 |
565 |
566 |
567 |
568 | ppi_rxbyteclkhs_clk
569 |
570 | in
571 |
572 |
573 | wire
574 | xilinx_anylanguagesynthesis
575 | xilinx_anylanguagebehavioralsimulation
576 |
577 |
578 |
579 |
580 |
581 | ppi_dl0_rxactivehs
582 |
583 | in
584 |
585 |
586 | wire
587 | xilinx_anylanguagesynthesis
588 | xilinx_anylanguagebehavioralsimulation
589 |
590 |
591 |
592 |
593 |
594 | ppi_dl0_rxsynchs
595 |
596 | in
597 |
598 |
599 | wire
600 | xilinx_anylanguagesynthesis
601 | xilinx_anylanguagebehavioralsimulation
602 |
603 |
604 |
605 |
606 |
607 | ppi_dl0_enable
608 |
609 | out
610 |
611 |
612 | wire
613 | xilinx_anylanguagesynthesis
614 | xilinx_anylanguagebehavioralsimulation
615 |
616 |
617 |
618 |
619 |
620 | ppi_dl0_forcerxmode
621 |
622 | out
623 |
624 |
625 | wire
626 | xilinx_anylanguagesynthesis
627 | xilinx_anylanguagebehavioralsimulation
628 |
629 |
630 |
631 |
632 |
633 | ppi_dl0_rxvalidhs
634 |
635 | in
636 |
637 |
638 | wire
639 | xilinx_anylanguagesynthesis
640 | xilinx_anylanguagebehavioralsimulation
641 |
642 |
643 |
644 |
645 |
646 | ppi_dl0_rxdatahs
647 |
648 | in
649 |
650 | 7
651 | 0
652 |
653 |
654 |
655 | wire
656 | xilinx_anylanguagesynthesis
657 | xilinx_anylanguagebehavioralsimulation
658 |
659 |
660 |
661 |
662 |
663 | ppi_dl1_rxactivehs
664 |
665 | in
666 |
667 |
668 | wire
669 | xilinx_anylanguagesynthesis
670 | xilinx_anylanguagebehavioralsimulation
671 |
672 |
673 |
674 |
675 |
676 | ppi_dl1_rxsynchs
677 |
678 | in
679 |
680 |
681 | wire
682 | xilinx_anylanguagesynthesis
683 | xilinx_anylanguagebehavioralsimulation
684 |
685 |
686 |
687 |
688 |
689 | ppi_dl1_enable
690 |
691 | out
692 |
693 |
694 | wire
695 | xilinx_anylanguagesynthesis
696 | xilinx_anylanguagebehavioralsimulation
697 |
698 |
699 |
700 |
701 |
702 | ppi_dl1_forcerxmode
703 |
704 | out
705 |
706 |
707 | wire
708 | xilinx_anylanguagesynthesis
709 | xilinx_anylanguagebehavioralsimulation
710 |
711 |
712 |
713 |
714 |
715 | ppi_dl1_rxvalidhs
716 |
717 | in
718 |
719 |
720 | wire
721 | xilinx_anylanguagesynthesis
722 | xilinx_anylanguagebehavioralsimulation
723 |
724 |
725 |
726 |
727 |
728 | ppi_dl1_rxdatahs
729 |
730 | in
731 |
732 | 7
733 | 0
734 |
735 |
736 |
737 | wire
738 | xilinx_anylanguagesynthesis
739 | xilinx_anylanguagebehavioralsimulation
740 |
741 |
742 |
743 |
744 |
745 | regspace_s_axi_aclk
746 |
747 | in
748 |
749 |
750 | wire
751 | xilinx_anylanguagesynthesis
752 | xilinx_anylanguagebehavioralsimulation
753 |
754 |
755 |
756 |
757 |
758 | regspace_s_axi_aresetn
759 |
760 | in
761 |
762 |
763 | wire
764 | xilinx_anylanguagesynthesis
765 | xilinx_anylanguagebehavioralsimulation
766 |
767 |
768 |
769 |
770 |
771 | regspace_s_axi_awaddr
772 |
773 | in
774 |
775 | 4
776 | 0
777 |
778 |
779 |
780 | wire
781 | xilinx_anylanguagesynthesis
782 | xilinx_anylanguagebehavioralsimulation
783 |
784 |
785 |
786 | 0
787 |
788 |
789 |
790 |
791 | regspace_s_axi_awprot
792 |
793 | in
794 |
795 | 2
796 | 0
797 |
798 |
799 |
800 | wire
801 | xilinx_anylanguagesynthesis
802 | xilinx_anylanguagebehavioralsimulation
803 |
804 |
805 |
806 | 0
807 |
808 |
809 |
810 |
811 | regspace_s_axi_awvalid
812 |
813 | in
814 |
815 |
816 | wire
817 | xilinx_anylanguagesynthesis
818 | xilinx_anylanguagebehavioralsimulation
819 |
820 |
821 |
822 | 0
823 |
824 |
825 |
826 |
827 | regspace_s_axi_awready
828 |
829 | out
830 |
831 |
832 | wire
833 | xilinx_anylanguagesynthesis
834 | xilinx_anylanguagebehavioralsimulation
835 |
836 |
837 |
838 |
839 |
840 | regspace_s_axi_wdata
841 |
842 | in
843 |
844 | 31
845 | 0
846 |
847 |
848 |
849 | wire
850 | xilinx_anylanguagesynthesis
851 | xilinx_anylanguagebehavioralsimulation
852 |
853 |
854 |
855 | 0
856 |
857 |
858 |
859 |
860 | regspace_s_axi_wstrb
861 |
862 | in
863 |
864 | 3
865 | 0
866 |
867 |
868 |
869 | wire
870 | xilinx_anylanguagesynthesis
871 | xilinx_anylanguagebehavioralsimulation
872 |
873 |
874 |
875 | 1
876 |
877 |
878 |
879 |
880 | regspace_s_axi_wvalid
881 |
882 | in
883 |
884 |
885 | wire
886 | xilinx_anylanguagesynthesis
887 | xilinx_anylanguagebehavioralsimulation
888 |
889 |
890 |
891 | 0
892 |
893 |
894 |
895 |
896 | regspace_s_axi_wready
897 |
898 | out
899 |
900 |
901 | wire
902 | xilinx_anylanguagesynthesis
903 | xilinx_anylanguagebehavioralsimulation
904 |
905 |
906 |
907 |
908 |
909 | regspace_s_axi_bresp
910 |
911 | out
912 |
913 | 1
914 | 0
915 |
916 |
917 |
918 | wire
919 | xilinx_anylanguagesynthesis
920 | xilinx_anylanguagebehavioralsimulation
921 |
922 |
923 |
924 |
925 |
926 | regspace_s_axi_bvalid
927 |
928 | out
929 |
930 |
931 | wire
932 | xilinx_anylanguagesynthesis
933 | xilinx_anylanguagebehavioralsimulation
934 |
935 |
936 |
937 |
938 |
939 | regspace_s_axi_bready
940 |
941 | in
942 |
943 |
944 | wire
945 | xilinx_anylanguagesynthesis
946 | xilinx_anylanguagebehavioralsimulation
947 |
948 |
949 |
950 | 0
951 |
952 |
953 |
954 |
955 | regspace_s_axi_araddr
956 |
957 | in
958 |
959 | 4
960 | 0
961 |
962 |
963 |
964 | wire
965 | xilinx_anylanguagesynthesis
966 | xilinx_anylanguagebehavioralsimulation
967 |
968 |
969 |
970 | 0
971 |
972 |
973 |
974 |
975 | regspace_s_axi_arprot
976 |
977 | in
978 |
979 | 2
980 | 0
981 |
982 |
983 |
984 | wire
985 | xilinx_anylanguagesynthesis
986 | xilinx_anylanguagebehavioralsimulation
987 |
988 |
989 |
990 | 0
991 |
992 |
993 |
994 |
995 | regspace_s_axi_arvalid
996 |
997 | in
998 |
999 |
1000 | wire
1001 | xilinx_anylanguagesynthesis
1002 | xilinx_anylanguagebehavioralsimulation
1003 |
1004 |
1005 |
1006 | 0
1007 |
1008 |
1009 |
1010 |
1011 | regspace_s_axi_arready
1012 |
1013 | out
1014 |
1015 |
1016 | wire
1017 | xilinx_anylanguagesynthesis
1018 | xilinx_anylanguagebehavioralsimulation
1019 |
1020 |
1021 |
1022 |
1023 |
1024 | regspace_s_axi_rdata
1025 |
1026 | out
1027 |
1028 | 31
1029 | 0
1030 |
1031 |
1032 |
1033 | wire
1034 | xilinx_anylanguagesynthesis
1035 | xilinx_anylanguagebehavioralsimulation
1036 |
1037 |
1038 |
1039 | 0
1040 |
1041 |
1042 |
1043 |
1044 | regspace_s_axi_rresp
1045 |
1046 | out
1047 |
1048 | 1
1049 | 0
1050 |
1051 |
1052 |
1053 | wire
1054 | xilinx_anylanguagesynthesis
1055 | xilinx_anylanguagebehavioralsimulation
1056 |
1057 |
1058 |
1059 |
1060 |
1061 | regspace_s_axi_rvalid
1062 |
1063 | out
1064 |
1065 |
1066 | wire
1067 | xilinx_anylanguagesynthesis
1068 | xilinx_anylanguagebehavioralsimulation
1069 |
1070 |
1071 |
1072 |
1073 |
1074 | regspace_s_axi_rready
1075 |
1076 | in
1077 |
1078 |
1079 | wire
1080 | xilinx_anylanguagesynthesis
1081 | xilinx_anylanguagebehavioralsimulation
1082 |
1083 |
1084 |
1085 | 0
1086 |
1087 |
1088 |
1089 |
1090 | output_m_axis_tvalid
1091 |
1092 | out
1093 |
1094 |
1095 | wire
1096 | xilinx_anylanguagesynthesis
1097 | xilinx_anylanguagebehavioralsimulation
1098 |
1099 |
1100 |
1101 |
1102 |
1103 | output_m_axis_tdata
1104 |
1105 | out
1106 |
1107 | 63
1108 | 0
1109 |
1110 |
1111 |
1112 | wire
1113 | xilinx_anylanguagesynthesis
1114 | xilinx_anylanguagebehavioralsimulation
1115 |
1116 |
1117 |
1118 |
1119 |
1120 | output_m_axis_tstrb
1121 |
1122 | out
1123 |
1124 | 7
1125 | 0
1126 |
1127 |
1128 |
1129 | wire
1130 | xilinx_anylanguagesynthesis
1131 | xilinx_anylanguagebehavioralsimulation
1132 |
1133 |
1134 |
1135 |
1136 |
1137 | output_m_axis_tlast
1138 |
1139 | out
1140 |
1141 |
1142 | wire
1143 | xilinx_anylanguagesynthesis
1144 | xilinx_anylanguagebehavioralsimulation
1145 |
1146 |
1147 |
1148 |
1149 |
1150 | output_m_axis_tready
1151 |
1152 | in
1153 |
1154 |
1155 | wire
1156 | xilinx_anylanguagesynthesis
1157 | xilinx_anylanguagebehavioralsimulation
1158 |
1159 |
1160 |
1161 |
1162 |
1163 |
1164 |
1165 |
1166 | choice_list_99a1d2b9
1167 | LEVEL_HIGH
1168 | LEVEL_LOW
1169 | EDGE_RISING
1170 | EDGE_FALLING
1171 |
1172 |
1173 | choice_list_9d8b0d81
1174 | ACTIVE_HIGH
1175 | ACTIVE_LOW
1176 |
1177 |
1178 |
1179 |
1180 | xilinx_anylanguagesynthesis_view_fileset
1181 |
1182 | hdl/axilite_control.v
1183 | verilogSource
1184 |
1185 |
1186 | hdl/ecc_block.v
1187 | verilogSource
1188 |
1189 |
1190 | hdl/pckthandler.v
1191 | verilogSource
1192 |
1193 |
1194 | hdl/pckthandler_fsm.v
1195 | verilogSource
1196 |
1197 |
1198 | hdl/ph_finder.v
1199 | verilogSource
1200 |
1201 |
1202 | hdl/raw10_decoder.v
1203 | verilogSource
1204 |
1205 |
1206 | hdl/axi_csi.v
1207 | verilogSource
1208 |
1209 |
1210 | hdl/wordalign.v
1211 | verilogSource
1212 | CHECKSUM_d54e92fb
1213 |
1214 |
1215 |
1216 | xilinx_anylanguagebehavioralsimulation_view_fileset
1217 |
1218 | hdl/axilite_control.v
1219 | verilogSource
1220 |
1221 |
1222 | hdl/ecc_block.v
1223 | verilogSource
1224 |
1225 |
1226 | hdl/pckthandler.v
1227 | verilogSource
1228 |
1229 |
1230 | hdl/pckthandler_fsm.v
1231 | verilogSource
1232 |
1233 |
1234 | hdl/ph_finder.v
1235 | verilogSource
1236 |
1237 |
1238 | hdl/raw10_decoder.v
1239 | verilogSource
1240 |
1241 |
1242 | hdl/axi_csi.v
1243 | verilogSource
1244 |
1245 |
1246 | hdl/wordalign.v
1247 | verilogSource
1248 |
1249 |
1250 |
1251 | xilinx_xpgui_view_fileset
1252 |
1253 | xgui/axi_csi_v1_1.tcl
1254 | tclSource
1255 | CHECKSUM_f92e9879
1256 | XGUI_VERSION_2
1257 |
1258 |
1259 |
1260 | CSI decoder for 2-lane, 10-bpp camera
1261 |
1262 |
1263 | Component_Name
1264 | axi_csi_v1_1_v1_0
1265 |
1266 |
1267 |
1268 |
1269 |
1270 | zynq
1271 | qzynq
1272 | azynq
1273 | zynquplus
1274 |
1275 |
1276 | /UserIP
1277 | /Video_&_Image_Processing
1278 |
1279 | axi_csi
1280 | package_project
1281 | 3
1282 |
1283 | user.org:user:axi_csi_v1_1:1.0
1284 |
1285 | 2018-06-14T06:14:13Z
1286 |
1287 |
1288 | /mnt/data/Documents/research/fcam5/mipi_csi/csirx
1289 | /mnt/data/Documents/research/fcam5/mipi_csi/csirx
1290 | /mnt/data/Documents/research/fcam5/mipi_csi/csirx
1291 | /nobackup/sebell/work/ultrazed/ip_repo/csirx
1292 |
1293 |
1294 |
1295 | 2017.2
1296 |
1297 |
1298 |
1299 |
1300 |
1301 |
1302 |
1303 |
1304 |
--------------------------------------------------------------------------------
/design_modules.svg:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 |
532 |
--------------------------------------------------------------------------------
/hdl/axi_csi.v:
--------------------------------------------------------------------------------
1 | /* axi_csi Top-level wrapper for the CSI receiver with AXI-Lite control
2 | * interface.
3 | */
4 |
5 | `timescale 1 ns / 1 ps
6 |
7 | module axi_csi #
8 | (
9 | localparam CONTROL_DATA_WIDTH = 32,
10 | localparam CONTROL_ADDR_WIDTH = 5
11 | )
12 | (
13 | // interrupt line
14 | output wire csi_intr,
15 |
16 | // reset signal, synchronized to ppi_rxbyteclkhs_clk
17 | input wire rxbyteclkhs_resetn,
18 |
19 | // PPI interface
20 | input wire ppi_cl_stopstate,
21 | output wire ppi_cl_enable, // clock enable
22 | input wire ppi_rxbyteclkhs_clk, // receive byte clock
23 |
24 | input wire ppi_dl0_rxactivehs, // whether high-speed receive is active on this lane
25 | input wire ppi_dl0_rxsynchs, // pulse at beginning of high-speed transmission
26 | output wire ppi_dl0_enable, // enable this lane
27 | output wire ppi_dl0_forcerxmode,
28 | input wire ppi_dl0_rxvalidhs, // this lane is valid
29 | input wire [7:0] ppi_dl0_rxdatahs,// data for this lane
30 |
31 | input wire ppi_dl1_rxactivehs, // whether high-speed receive is active on this lane
32 | input wire ppi_dl1_rxsynchs, // pulse at beginning of high-speed transmission
33 | output wire ppi_dl1_enable, // enable this lane
34 | output wire ppi_dl1_forcerxmode,
35 | input wire ppi_dl1_rxvalidhs, // this lane is valid
36 | input wire [7:0] ppi_dl1_rxdatahs,// data for this lane
37 |
38 | // AXI-Lite control bus
39 | input wire regspace_s_axi_aclk,
40 | input wire regspace_s_axi_aresetn,
41 | input wire [CONTROL_ADDR_WIDTH-1 : 0] regspace_s_axi_awaddr,
42 | input wire [2 : 0] regspace_s_axi_awprot,
43 | input wire regspace_s_axi_awvalid,
44 | output wire regspace_s_axi_awready,
45 | input wire [CONTROL_DATA_WIDTH-1 : 0] regspace_s_axi_wdata,
46 | input wire [(CONTROL_DATA_WIDTH/8)-1 : 0] regspace_s_axi_wstrb,
47 | input wire regspace_s_axi_wvalid,
48 | output wire regspace_s_axi_wready,
49 | output wire [1 : 0] regspace_s_axi_bresp,
50 | output wire regspace_s_axi_bvalid,
51 | input wire regspace_s_axi_bready,
52 | input wire [CONTROL_ADDR_WIDTH-1 : 0] regspace_s_axi_araddr,
53 | input wire [2 : 0] regspace_s_axi_arprot,
54 | input wire regspace_s_axi_arvalid,
55 | output wire regspace_s_axi_arready,
56 | output wire [CONTROL_DATA_WIDTH-1 : 0] regspace_s_axi_rdata,
57 | output wire [1 : 0] regspace_s_axi_rresp,
58 | output wire regspace_s_axi_rvalid,
59 | input wire regspace_s_axi_rready,
60 |
61 |
62 | // AXI-Stream master output
63 | // synchronized to the ppi_rxbyteclkhs_clk clock signal
64 | output wire output_m_axis_tvalid,
65 | output wire [63: 0] output_m_axis_tdata,
66 | output wire [7: 0] output_m_axis_tstrb,
67 | output wire output_m_axis_tlast,
68 | input wire output_m_axis_tready
69 | );
70 |
71 | // Instantiation of Axi Bus Interface RegSpace_S_AXI
72 | // All logic is embedded inside RegSpace_S_AXI
73 | axilite_control # (
74 | .N_DATA_LANES(2),
75 | .C_S_AXI_DATA_WIDTH(32),
76 | .C_S_AXI_ADDR_WIDTH(5)
77 | ) axilite_control_inst (
78 | // interrupt line
79 | .csi_intr(csi_intr),
80 |
81 | // reset signal
82 | .rxbyteclkhs_resetn(rxbyteclkhs_resetn),
83 |
84 | // PPI interface
85 | .cl_stopstate(ppi_cl_stopstate),
86 | .cl_enable(ppi_cl_enable),
87 | .rxbyteclkhs(ppi_rxbyteclkhs_clk),
88 |
89 | .dl0_rxactivehs(ppi_dl0_rxactivehs),
90 | .dl0_rxsynchs(ppi_dl0_rxsynchs),
91 | .dl0_enable(ppi_dl0_enable),
92 | .dl0_forcerxmode(ppi_dl0_forcerxmode),
93 | .dl0_rxvalidhs(ppi_dl0_rxvalidhs),
94 | .dl0_rxdatahs(ppi_dl0_rxdatahs),
95 |
96 | .dl1_rxactivehs(ppi_dl1_rxactivehs),
97 | .dl1_rxsynchs(ppi_dl1_rxsynchs),
98 | .dl1_enable(ppi_dl1_enable),
99 | .dl1_forcerxmode(ppi_dl1_forcerxmode),
100 | .dl1_rxvalidhs(ppi_dl1_rxvalidhs),
101 | .dl1_rxdatahs(ppi_dl1_rxdatahs),
102 |
103 | // AXI Stream Interface Outpout
104 | .m_axis_tvalid(output_m_axis_tvalid),
105 | .m_axis_tdata(output_m_axis_tdata),
106 | .m_axis_tstrb(output_m_axis_tstrb),
107 | .m_axis_tlast(output_m_axis_tlast),
108 | .m_axis_tready(output_m_axis_tready),
109 |
110 | // AXI Lite Interface RegSpace
111 | .S_AXI_ACLK(regspace_s_axi_aclk),
112 | .S_AXI_ARESETN(regspace_s_axi_aresetn),
113 | .S_AXI_AWADDR(regspace_s_axi_awaddr),
114 | .S_AXI_AWPROT(regspace_s_axi_awprot),
115 | .S_AXI_AWVALID(regspace_s_axi_awvalid),
116 | .S_AXI_AWREADY(regspace_s_axi_awready),
117 | .S_AXI_WDATA(regspace_s_axi_wdata),
118 | .S_AXI_WSTRB(regspace_s_axi_wstrb),
119 | .S_AXI_WVALID(regspace_s_axi_wvalid),
120 | .S_AXI_WREADY(regspace_s_axi_wready),
121 | .S_AXI_BRESP(regspace_s_axi_bresp),
122 | .S_AXI_BVALID(regspace_s_axi_bvalid),
123 | .S_AXI_BREADY(regspace_s_axi_bready),
124 | .S_AXI_ARADDR(regspace_s_axi_araddr),
125 | .S_AXI_ARPROT(regspace_s_axi_arprot),
126 | .S_AXI_ARVALID(regspace_s_axi_arvalid),
127 | .S_AXI_ARREADY(regspace_s_axi_arready),
128 | .S_AXI_RDATA(regspace_s_axi_rdata),
129 | .S_AXI_RRESP(regspace_s_axi_rresp),
130 | .S_AXI_RVALID(regspace_s_axi_rvalid),
131 | .S_AXI_RREADY(regspace_s_axi_rready)
132 | );
133 |
134 | endmodule
135 |
--------------------------------------------------------------------------------
/hdl/axilite_control.v:
--------------------------------------------------------------------------------
1 | /* axilite_control Implementation of an AXI-Lite control bus and register
2 | * space for the CSI receiver. */
3 |
4 | `timescale 1 ns / 1 ps
5 |
6 | module axilite_control #
7 | (
8 | // Lots of things are hard-coded for 2 data lanes, so this isn't configurable
9 | parameter integer N_DATA_LANES = 2,
10 |
11 | // Width of S_AXI data bus
12 | parameter integer C_S_AXI_DATA_WIDTH = 32,
13 | // Width of S_AXI address bus
14 | parameter integer C_S_AXI_ADDR_WIDTH = 5
15 | )
16 | (
17 | // interrupt line
18 | output wire csi_intr,
19 |
20 | // reset signal synchronized to rxbyteclkhs clock
21 | input wire rxbyteclkhs_resetn,
22 |
23 | // PPI interface
24 | input wire cl_stopstate,
25 | output wire cl_enable,
26 | input wire rxbyteclkhs,
27 |
28 | input wire dl0_rxactivehs,
29 | input wire dl0_rxsynchs,
30 | output wire dl0_enable,
31 | output wire dl0_forcerxmode,
32 | input wire dl0_rxvalidhs,
33 | input wire [7:0] dl0_rxdatahs,
34 |
35 | input wire dl1_rxactivehs,
36 | input wire dl1_rxsynchs,
37 | output wire dl1_enable,
38 | output wire dl1_forcerxmode,
39 | input wire dl1_rxvalidhs,
40 | input wire [7:0] dl1_rxdatahs,
41 |
42 | // AXI Stream Interface Output
43 | // Uses the rxbyteclkhs clock
44 | // and rxbyteclkhs_resetn reset signals
45 | output wire m_axis_tvalid,
46 | output wire [63:0] m_axis_tdata,
47 | output wire [7:0] m_axis_tstrb,
48 | output wire m_axis_tlast,
49 | input wire m_axis_tready,
50 |
51 | // User ports ends
52 | // Do not modify the ports beyond this line
53 |
54 | // Global Clock Signal
55 | input wire S_AXI_ACLK,
56 | // Global Reset Signal. This Signal is Active LOW
57 | input wire S_AXI_ARESETN,
58 | // Write address (issued by master, acceped by Slave)
59 | input wire [C_S_AXI_ADDR_WIDTH-1 : 0] S_AXI_AWADDR,
60 | // Write channel Protection type. This signal indicates the
61 | // privilege and security level of the transaction, and whether
62 | // the transaction is a data access or an instruction access.
63 | input wire [2 : 0] S_AXI_AWPROT,
64 | // Write address valid. This signal indicates that the master signaling
65 | // valid write address and control information.
66 | input wire S_AXI_AWVALID,
67 | // Write address ready. This signal indicates that the slave is ready
68 | // to accept an address and associated control signals.
69 | output wire S_AXI_AWREADY,
70 | // Write data (issued by master, acceped by Slave)
71 | input wire [C_S_AXI_DATA_WIDTH-1 : 0] S_AXI_WDATA,
72 | // Write strobes. This signal indicates which byte lanes hold
73 | // valid data. There is one write strobe bit for each eight
74 | // bits of the write data bus.
75 | input wire [(C_S_AXI_DATA_WIDTH/8)-1 : 0] S_AXI_WSTRB,
76 | // Write valid. This signal indicates that valid write
77 | // data and strobes are available.
78 | input wire S_AXI_WVALID,
79 | // Write ready. This signal indicates that the slave
80 | // can accept the write data.
81 | output wire S_AXI_WREADY,
82 | // Write response. This signal indicates the status
83 | // of the write transaction.
84 | output wire [1 : 0] S_AXI_BRESP,
85 | // Write response valid. This signal indicates that the channel
86 | // is signaling a valid write response.
87 | output wire S_AXI_BVALID,
88 | // Response ready. This signal indicates that the master
89 | // can accept a write response.
90 | input wire S_AXI_BREADY,
91 | // Read address (issued by master, acceped by Slave)
92 | input wire [C_S_AXI_ADDR_WIDTH-1 : 0] S_AXI_ARADDR,
93 | // Protection type. This signal indicates the privilege
94 | // and security level of the transaction, and whether the
95 | // transaction is a data access or an instruction access.
96 | input wire [2 : 0] S_AXI_ARPROT,
97 | // Read address valid. This signal indicates that the channel
98 | // is signaling valid read address and control information.
99 | input wire S_AXI_ARVALID,
100 | // Read address ready. This signal indicates that the slave is
101 | // ready to accept an address and associated control signals.
102 | output wire S_AXI_ARREADY,
103 | // Read data (issued by slave)
104 | output wire [C_S_AXI_DATA_WIDTH-1 : 0] S_AXI_RDATA,
105 | // Read response. This signal indicates the status of the
106 | // read transfer.
107 | output wire [1 : 0] S_AXI_RRESP,
108 | // Read valid. This signal indicates that the channel is
109 | // signaling the required read data.
110 | output wire S_AXI_RVALID,
111 | // Read ready. This signal indicates that the master can
112 | // accept the read data and response information.
113 | input wire S_AXI_RREADY
114 | );
115 |
116 | // used for interrupts and run/stop
117 | localparam NUM_INTRS = 2; // number of interrupts
118 | localparam SOF_REG_BIT = 2; // bit position for SOF interrupts in CONFIG, CTRL, and STATUS registers
119 | localparam SOF_INTR_BIT = 0; // bit position for SOF interrupts in irqs_posted
120 | localparam EOF_REG_BIT = 3; // bit position for EOF interrupts in CONFIG, CTRL, and STATUS registers
121 | localparam OUTPUT_EN_BIT = 4; // bit position for Output Enable. When zero, core runs but output isn't produced
122 | localparam EOF_INTR_BIT = 1; // bit position for EOF interrupts in irqs_posted
123 | localparam GLOBALINT_BIT= 1; // bit position for global interrupts in CONFIG, CTRL, and STATUS registers
124 | localparam RS_REG_BIT = 0; // bit position for Run/Stop in CONFIG, CTRL, and STATUS registers
125 |
126 | reg [(NUM_INTRS-1):0] irqs_posted, irqs_acked;
127 | reg frame_active_new, frame_active_last;
128 | reg RS_flag;
129 | reg RS_new, RS_last;
130 | reg enable_output; // Output enable flag latched in at SOF
131 |
132 | // other user signals
133 | wire reset;
134 | wire [(N_DATA_LANES*8)-1:0] aligned_word_out;
135 | wire aligned_word_valid;
136 | wire frame_active; // whether we're in the process of receiving a frame
137 | wire frame_valid; // whether the output frame data is actually valid
138 | wire [(N_DATA_LANES*8)-1:0] frame_out;
139 | wire [63:0] unpacked_out;
140 | wire unpacked_out_valid;
141 | wire unpacked_last;
142 | wire last_packet;
143 |
144 |
145 | // AXI4LITE signals
146 | reg [C_S_AXI_ADDR_WIDTH-1 : 0] axi_awaddr;
147 | reg axi_awready;
148 | reg axi_wready;
149 | reg [1 : 0] axi_bresp;
150 | reg axi_bvalid;
151 | reg [C_S_AXI_ADDR_WIDTH-1 : 0] axi_araddr;
152 | reg axi_arready;
153 | reg [C_S_AXI_DATA_WIDTH-1 : 0] axi_rdata;
154 | reg [1 : 0] axi_rresp;
155 | reg axi_rvalid;
156 |
157 | // Example-specific design signals
158 | // local parameter for addressing 32 bit / 64 bit C_S_AXI_DATA_WIDTH
159 | // ADDR_LSB is used for addressing 32/64 bit registers/memories
160 | // ADDR_LSB = 2 for 32 bits (n downto 2)
161 | // ADDR_LSB = 3 for 64 bits (n downto 3)
162 | localparam integer ADDR_LSB = (C_S_AXI_DATA_WIDTH/32) + 1;
163 | localparam integer OPT_MEM_ADDR_BITS = 2;
164 | //----------------------------------------------
165 | //-- Signals for user logic register space example
166 | //------------------------------------------------
167 | //-- Number of Slave Registers 8
168 | reg [C_S_AXI_DATA_WIDTH-1:0] CSI_CONFIG_REG; // configuration register (R/W)
169 | reg [C_S_AXI_DATA_WIDTH-1:0] CSI_CTRL_SET_REG; // "SET" register for CSI_CTRL (write-only, read all 0's)
170 | reg [C_S_AXI_DATA_WIDTH-1:0] CSI_CTRL_CLEAR_REG; // "CLEAR" register for CSI_CTRL (write-only, read all 0's)
171 | reg [C_S_AXI_DATA_WIDTH-1:0] CSI_STATUS_REG; // status register (read-only)
172 | reg [C_S_AXI_DATA_WIDTH-1:0] CSI_FR_LINES_REG; // expected number of image lines per frame
173 | reg [C_S_AXI_DATA_WIDTH-1:0] slv_reg5; // unimplemented (always read 0xDEADBEEF
174 | reg [C_S_AXI_DATA_WIDTH-1:0] slv_reg6; // unimplemented (always read 0xDEADBEEF
175 | reg [C_S_AXI_DATA_WIDTH-1:0] slv_reg7; // unimplemented (always read 0xDEADBEEF
176 | wire slv_reg_rden;
177 | wire slv_reg_wren;
178 | reg [C_S_AXI_DATA_WIDTH-1:0] reg_data_out;
179 | integer byte_index;
180 | reg aw_en;
181 |
182 | // I/O Connections assignments
183 |
184 | assign S_AXI_AWREADY = axi_awready;
185 | assign S_AXI_WREADY = axi_wready;
186 | assign S_AXI_BRESP = axi_bresp;
187 | assign S_AXI_BVALID = axi_bvalid;
188 | assign S_AXI_ARREADY = axi_arready;
189 | assign S_AXI_RDATA = axi_rdata;
190 | assign S_AXI_RRESP = axi_rresp;
191 | assign S_AXI_RVALID = axi_rvalid;
192 | // Implement axi_awready generation
193 | // axi_awready is asserted for one S_AXI_ACLK clock cycle when both
194 | // S_AXI_AWVALID and S_AXI_WVALID are asserted. axi_awready is
195 | // de-asserted when reset is low.
196 |
197 | always @( posedge S_AXI_ACLK )
198 | begin
199 | if ( S_AXI_ARESETN == 1'b0 )
200 | begin
201 | axi_awready <= 1'b0;
202 | aw_en <= 1'b1;
203 | end
204 | else
205 | begin
206 | if (~axi_awready && S_AXI_AWVALID && S_AXI_WVALID && aw_en)
207 | begin
208 | // slave is ready to accept write address when
209 | // there is a valid write address and write data
210 | // on the write address and data bus. This design
211 | // expects no outstanding transactions.
212 | axi_awready <= 1'b1;
213 | aw_en <= 1'b0;
214 | end
215 | else if (S_AXI_BREADY && axi_bvalid)
216 | begin
217 | aw_en <= 1'b1;
218 | axi_awready <= 1'b0;
219 | end
220 | else
221 | begin
222 | axi_awready <= 1'b0;
223 | end
224 | end
225 | end
226 |
227 | // Implement axi_awaddr latching
228 | // This process is used to latch the address when both
229 | // S_AXI_AWVALID and S_AXI_WVALID are valid.
230 |
231 | always @( posedge S_AXI_ACLK )
232 | begin
233 | if ( S_AXI_ARESETN == 1'b0 )
234 | begin
235 | axi_awaddr <= 0;
236 | end
237 | else
238 | begin
239 | if (~axi_awready && S_AXI_AWVALID && S_AXI_WVALID && aw_en)
240 | begin
241 | // Write Address latching
242 | axi_awaddr <= S_AXI_AWADDR;
243 | end
244 | end
245 | end
246 |
247 | // Implement axi_wready generation
248 | // axi_wready is asserted for one S_AXI_ACLK clock cycle when both
249 | // S_AXI_AWVALID and S_AXI_WVALID are asserted. axi_wready is
250 | // de-asserted when reset is low.
251 |
252 | always @( posedge S_AXI_ACLK )
253 | begin
254 | if ( S_AXI_ARESETN == 1'b0 )
255 | begin
256 | axi_wready <= 1'b0;
257 | end
258 | else
259 | begin
260 | if (~axi_wready && S_AXI_WVALID && S_AXI_AWVALID && aw_en )
261 | begin
262 | // slave is ready to accept write data when
263 | // there is a valid write address and write data
264 | // on the write address and data bus. This design
265 | // expects no outstanding transactions.
266 | axi_wready <= 1'b1;
267 | end
268 | else
269 | begin
270 | axi_wready <= 1'b0;
271 | end
272 | end
273 | end
274 |
275 | // Implement memory mapped register select and write logic generation
276 | // The write data is accepted and written to memory mapped registers when
277 | // axi_awready, S_AXI_WVALID, axi_wready and S_AXI_WVALID are asserted. Write strobes are used to
278 | // select byte enables of slave registers while writing.
279 | // These registers are cleared when reset (active low) is applied.
280 | // Slave register write enable is asserted when valid address and data are available
281 | // and the slave is ready to accept the write address and write data.
282 | assign slv_reg_wren = axi_wready && S_AXI_WVALID && axi_awready && S_AXI_AWVALID;
283 |
284 | always @( posedge S_AXI_ACLK )
285 | begin
286 | if ( S_AXI_ARESETN == 1'b0 )
287 | begin
288 | CSI_CONFIG_REG <= 0;
289 | CSI_CTRL_SET_REG <= 0;
290 | CSI_CTRL_CLEAR_REG <= 0;
291 | CSI_STATUS_REG <= 0;
292 | CSI_FR_LINES_REG <= 0;
293 | slv_reg5 <= 0;
294 | slv_reg6 <= 0;
295 | slv_reg7 <= 0;
296 |
297 | irqs_acked <= 0;
298 | RS_new <= 0;
299 | RS_last <= 0;
300 | end
301 | else begin
302 | irqs_acked <= 0;
303 | RS_last <= RS_new;
304 |
305 | if (slv_reg_wren)
306 | begin
307 | case ( axi_awaddr[ADDR_LSB+OPT_MEM_ADDR_BITS:ADDR_LSB] )
308 | 3'h0: begin
309 | CSI_CONFIG_REG <= S_AXI_WDATA;
310 | end
311 | 3'h1: begin
312 | // handle interrupts acknowledgements
313 | irqs_acked <= {2{S_AXI_WDATA[GLOBALINT_BIT]}} | {S_AXI_WDATA[EOF_REG_BIT], S_AXI_WDATA[SOF_REG_BIT]};
314 |
315 | // handle R/S
316 | if(S_AXI_WDATA[0] & ~RS_flag) begin
317 | RS_new <= 1'b1;
318 | RS_last <= 1'b0;
319 | end
320 | end
321 | 3'h2: begin
322 | if(S_AXI_WDATA[0] == 1'b1) begin
323 | RS_new <= 1'b0;
324 | end
325 | end
326 | 3'h3: begin
327 | // status register is read-only
328 | // writes are ignored
329 | CSI_STATUS_REG <= CSI_STATUS_REG;
330 | end
331 | 3'h4: begin
332 | CSI_FR_LINES_REG <= S_AXI_WDATA;
333 | end
334 | 3'h5:
335 | for ( byte_index = 0; byte_index <= (C_S_AXI_DATA_WIDTH/8)-1; byte_index = byte_index+1 )
336 | if ( S_AXI_WSTRB[byte_index] == 1 ) begin
337 | // Respective byte enables are asserted as per write strobes
338 | // Slave register 5
339 | slv_reg5[(byte_index*8) +: 8] <= S_AXI_WDATA[(byte_index*8) +: 8];
340 | end
341 | 3'h6:
342 | for ( byte_index = 0; byte_index <= (C_S_AXI_DATA_WIDTH/8)-1; byte_index = byte_index+1 )
343 | if ( S_AXI_WSTRB[byte_index] == 1 ) begin
344 | // Respective byte enables are asserted as per write strobes
345 | // Slave register 6
346 | slv_reg6[(byte_index*8) +: 8] <= S_AXI_WDATA[(byte_index*8) +: 8];
347 | end
348 | 3'h7:
349 | for ( byte_index = 0; byte_index <= (C_S_AXI_DATA_WIDTH/8)-1; byte_index = byte_index+1 )
350 | if ( S_AXI_WSTRB[byte_index] == 1 ) begin
351 | // Respective byte enables are asserted as per write strobes
352 | // Slave register 7
353 | slv_reg7[(byte_index*8) +: 8] <= S_AXI_WDATA[(byte_index*8) +: 8];
354 | end
355 | default : begin
356 | CSI_CONFIG_REG <= CSI_CONFIG_REG;
357 | CSI_CTRL_SET_REG <= CSI_CTRL_SET_REG;
358 | CSI_CTRL_CLEAR_REG <= CSI_CTRL_CLEAR_REG;
359 | CSI_STATUS_REG <= CSI_STATUS_REG;
360 | CSI_FR_LINES_REG <= CSI_FR_LINES_REG;
361 | slv_reg5 <= slv_reg5;
362 | slv_reg6 <= slv_reg6;
363 | slv_reg7 <= slv_reg7;
364 | end
365 | endcase
366 | end
367 | end
368 | end
369 |
370 | // Implement write response logic generation
371 | // The write response and response valid signals are asserted by the slave
372 | // when axi_wready, S_AXI_WVALID, axi_wready and S_AXI_WVALID are asserted.
373 | // This marks the acceptance of address and indicates the status of
374 | // write transaction.
375 |
376 | always @( posedge S_AXI_ACLK )
377 | begin
378 | if ( S_AXI_ARESETN == 1'b0 )
379 | begin
380 | axi_bvalid <= 0;
381 | axi_bresp <= 2'b0;
382 | end
383 | else
384 | begin
385 | if (axi_awready && S_AXI_AWVALID && ~axi_bvalid && axi_wready && S_AXI_WVALID)
386 | begin
387 | // indicates a valid write response is available
388 | axi_bvalid <= 1'b1;
389 | axi_bresp <= 2'b0; // 'OKAY' response
390 | end // work error responses in future
391 | else
392 | begin
393 | if (S_AXI_BREADY && axi_bvalid)
394 | //check if bready is asserted while bvalid is high)
395 | //(there is a possibility that bready is always asserted high)
396 | begin
397 | axi_bvalid <= 1'b0;
398 | end
399 | end
400 | end
401 | end
402 |
403 | // Implement axi_arready generation
404 | // axi_arready is asserted for one S_AXI_ACLK clock cycle when
405 | // S_AXI_ARVALID is asserted. axi_awready is
406 | // de-asserted when reset (active low) is asserted.
407 | // The read address is also latched when S_AXI_ARVALID is
408 | // asserted. axi_araddr is reset to zero on reset assertion.
409 |
410 | always @( posedge S_AXI_ACLK )
411 | begin
412 | if ( S_AXI_ARESETN == 1'b0 )
413 | begin
414 | axi_arready <= 1'b0;
415 | axi_araddr <= 32'b0;
416 | end
417 | else
418 | begin
419 | if (~axi_arready && S_AXI_ARVALID)
420 | begin
421 | // indicates that the slave has acceped the valid read address
422 | axi_arready <= 1'b1;
423 | // Read address latching
424 | axi_araddr <= S_AXI_ARADDR;
425 | end
426 | else
427 | begin
428 | axi_arready <= 1'b0;
429 | end
430 | end
431 | end
432 |
433 | // Implement axi_arvalid generation
434 | // axi_rvalid is asserted for one S_AXI_ACLK clock cycle when both
435 | // S_AXI_ARVALID and axi_arready are asserted. The slave registers
436 | // data are available on the axi_rdata bus at this instance. The
437 | // assertion of axi_rvalid marks the validity of read data on the
438 | // bus and axi_rresp indicates the status of read transaction.axi_rvalid
439 | // is deasserted on reset (active low). axi_rresp and axi_rdata are
440 | // cleared to zero on reset (active low).
441 | always @( posedge S_AXI_ACLK )
442 | begin
443 | if ( S_AXI_ARESETN == 1'b0 )
444 | begin
445 | axi_rvalid <= 0;
446 | axi_rresp <= 0;
447 | end
448 | else
449 | begin
450 | if (axi_arready && S_AXI_ARVALID && ~axi_rvalid)
451 | begin
452 | // Valid read data is available at the read data bus
453 | axi_rvalid <= 1'b1;
454 | axi_rresp <= 2'b0; // 'OKAY' response
455 | end
456 | else if (axi_rvalid && S_AXI_RREADY)
457 | begin
458 | // Read data is accepted by the master
459 | axi_rvalid <= 1'b0;
460 | end
461 | end
462 | end
463 |
464 | // Implement memory mapped register select and read logic generation
465 | // Slave register read enable is asserted when valid address is available
466 | // and the slave is ready to accept the read address.
467 | assign slv_reg_rden = axi_arready & S_AXI_ARVALID & ~axi_rvalid;
468 | always @(*)
469 | begin
470 | // Address decoding for reading registers
471 | case ( axi_araddr[ADDR_LSB+OPT_MEM_ADDR_BITS:ADDR_LSB] )
472 | 3'h0 : reg_data_out <= CSI_CONFIG_REG;
473 | 3'h1 : reg_data_out <= 0; // CSI_CTRL_SET_REG always returns 0's when read
474 | 3'h2 : reg_data_out <= 0; // CSI_CTRL_CLEAR_REG always returns 0's when read
475 | 3'h3 : begin // Reading status register CSI_STATUS_REG
476 | // interrupts
477 | reg_data_out[31:4] <= 0;
478 | reg_data_out[3] <= irqs_posted[EOF_INTR_BIT];
479 | reg_data_out[2] <= irqs_posted[SOF_INTR_BIT];
480 | reg_data_out[1] <= (| irqs_posted);
481 | reg_data_out[0] <= RS_flag;
482 | end
483 | 3'h4 : reg_data_out <= CSI_FR_LINES_REG;
484 | 3'h5 : reg_data_out <= 32'hDEADBEEF; //slv_reg5 is un-implemented and returns 0xDEADBEEF when read
485 | 3'h6 : reg_data_out <= 32'hDEADBEEF; //slv_reg6 is un-implemented and returns 0xDEADBEEF when read
486 | 3'h7 : reg_data_out <= 32'hDEADBEEF; //slv_reg7 is un-implemented and returns 0xDEADBEEF when read
487 | default : reg_data_out <= 0;
488 | endcase
489 | end
490 |
491 | // Output register or memory read data
492 | always @( posedge S_AXI_ACLK )
493 | begin
494 | if ( S_AXI_ARESETN == 1'b0 )
495 | begin
496 | axi_rdata <= 0;
497 | end
498 | else
499 | begin
500 | // When there is a valid read address (S_AXI_ARVALID) with
501 | // acceptance of read address by the slave (axi_arready),
502 | // output the read dada
503 | if (slv_reg_rden)
504 | begin
505 | axi_rdata <= reg_data_out; // register read data
506 | end
507 | end
508 | end
509 |
510 | // Add user logic here
511 |
512 | // Make active-high reset
513 | assign reset = ~rxbyteclkhs_resetn | ~RS_flag;
514 |
515 | // interrupt-related
516 | assign csi_intr = CSI_CONFIG_REG[GLOBALINT_BIT] & (| (irqs_posted & CSI_CONFIG_REG[EOF_REG_BIT:SOF_REG_BIT]));
517 |
518 | // interrupt generation logic
519 | always @(posedge S_AXI_ACLK)
520 | begin
521 | if ( S_AXI_ARESETN == 1'b0 )
522 | begin
523 | irqs_posted <= 0;
524 | frame_active_new <= 0;
525 | frame_active_last <= 0;
526 | end
527 | else begin
528 | frame_active_new <= frame_active;
529 | frame_active_last <= frame_active_new;
530 |
531 | if(~frame_active_last & frame_active_new) irqs_posted[SOF_INTR_BIT] <= 1'b1;
532 | else if(frame_active_last & ~frame_active_new) irqs_posted[EOF_INTR_BIT] <= 1'b1;
533 | else begin
534 | irqs_posted[SOF_INTR_BIT] <= irqs_posted[SOF_INTR_BIT] & ~irqs_acked[SOF_INTR_BIT];
535 | irqs_posted[EOF_INTR_BIT] <= irqs_posted[EOF_INTR_BIT] & ~irqs_acked[EOF_INTR_BIT];
536 | end
537 | end
538 | end
539 |
540 |
541 | // generating the RS signal
542 | always @(posedge S_AXI_ACLK)
543 | begin
544 | if ( S_AXI_ARESETN == 1'b0 ) RS_flag <= 0;
545 | else begin
546 | if(RS_last & ~RS_new) RS_flag <= 1'b0;
547 | else if(~RS_last & RS_new) RS_flag <= 1'b1;
548 | else if(~CSI_CONFIG_REG[RS_REG_BIT] & ~frame_active_new & frame_active_last) RS_flag <= 1'b0;
549 | else RS_flag <= RS_flag;
550 | end
551 | end
552 |
553 | // CSI modules
554 | wordalign align(
555 | .clk(rxbyteclkhs),
556 | .resetn(rxbyteclkhs_resetn),
557 | .dl0_rxvalidhs(dl0_rxvalidhs),
558 | .dl0_rxdatahs(dl0_rxdatahs),
559 | .dl1_rxvalidhs(dl1_rxvalidhs),
560 | .dl1_rxdatahs(dl1_rxdatahs),
561 | .word_out(aligned_word_out),
562 | .word_valid(aligned_word_valid)
563 | );
564 |
565 | pckthandler depacket(
566 | .rxbyteclkhs(rxbyteclkhs),
567 | .reset(reset),
568 | .in_stream_valid(aligned_word_valid),
569 | .in_stream(aligned_word_out),
570 | .frame_active(frame_active),
571 | .frame_valid(frame_valid),
572 | .out_stream(frame_out),
573 | .lines_per_frame(CSI_FR_LINES_REG),
574 | .last_packet(last_packet)
575 | );
576 |
577 | raw10_decoder unpack(
578 | .rxbyteclkhs(rxbyteclkhs),
579 | .reset(reset),
580 | .frame_active(frame_active),
581 | .frame_valid(frame_valid),
582 | .data_in(frame_out),
583 | .out_valid(unpacked_out_valid),
584 | .data_out(unpacked_out),
585 | .last_packet_in(last_packet),
586 | .last_packet_out(unpacked_last)
587 | );
588 |
589 |
590 | // Latch in the output enable signal on SOF
591 | // The frame_active signal goes high just before the first data goes out
592 | always @(posedge S_AXI_ACLK)
593 | begin
594 | if ( S_AXI_ARESETN == 1'b0 )
595 | enable_output <= 0;
596 | else if(~frame_active_last & frame_active_new)
597 | enable_output <= CSI_CONFIG_REG[OUTPUT_EN_BIT];
598 | else
599 | enable_output <= enable_output;
600 | end
601 |
602 | // Stream Interface
603 | assign m_axis_tdata = enable_output ? unpacked_out : 0;
604 | assign m_axis_tvalid = enable_output ? unpacked_out_valid : 0;
605 | assign m_axis_tstrb = enable_output ? 8'b11111111 : 0;
606 | assign m_axis_tlast = enable_output ? unpacked_last : 0;
607 |
608 | // always enable the D-PHY
609 | assign cl_enable = 1'b1;
610 | assign dl0_enable = 1'b1;
611 | assign dl1_enable = 1'b1;
612 |
613 | // don't force the lanes into reset
614 | assign dl0_forcerxmode = 1'b1;
615 | assign dl1_forcerxmode = 1'b1;
616 |
617 | // User logic ends
618 |
619 | endmodule
620 |
--------------------------------------------------------------------------------
/hdl/ecc_block.v:
--------------------------------------------------------------------------------
1 | /* ECC check block (combinational block): validates the packet header info based on received ECC
2 | * Gedeon Nyengele
3 | * 08 January 2018
4 | */
5 |
6 | /*
7 | * @param PH_in input packet header (input)
8 | * @param PH_out possibly corrected PH without the ECC field (output)
9 | * @param no_error signals whether the PH has no errors (output)
10 | * @param corrected_error signals whether a single bit error was corrected (output)
11 | * @param error signals whether the PH has an error that cannot be corrected (output)
12 | */
13 |
14 | module ecc_block(PH_in, PH_out, no_error, corrected_error, error);
15 |
16 | parameter PH_SIZE = 32;
17 | parameter ECC_SIZE = 8;
18 |
19 | input [(PH_SIZE-1):0] PH_in;
20 | output reg [(PH_SIZE-ECC_SIZE-1):0] PH_out;
21 | output reg no_error, corrected_error, error;
22 |
23 | wire [(PH_SIZE-ECC_SIZE-1):0] data = PH_in[(PH_SIZE-ECC_SIZE-1):0];
24 | reg [(ECC_SIZE-1):0] calc_ecc;
25 | reg [(ECC_SIZE-1):0] syndrome;
26 |
27 | always @(*) begin
28 | // compute ECC
29 | calc_ecc = {2'b00,
30 | (^ {data[10], data[11], data[12], data[13], data[14], data[15], data[16], data[17], data[18], data[19], data[21], data[22], data[23]}),
31 | (^ {data[4], data[5], data[6], data[7], data[8], data[9], data[16], data[17], data[18], data[19], data[20], data[22], data[23]}),
32 | (^ {data[1], data[2], data[3], data[7], data[8], data[9], data[13], data[14], data[15], data[19], data[20], data[21], data[23]}),
33 | (^ {data[0], data[2], data[3], data[5], data[6], data[9], data[11], data[12], data[15], data[18], data[20], data[21], data[22]}),
34 | (^ {data[0], data[1], data[3], data[4], data[6], data[8], data[10], data[12], data[14], data[17], data[20], data[21], data[22], data[23]}),
35 | (^ {data[0], data[1], data[2], data[4], data[5], data[7], data[10], data[11], data[13], data[16], data[20], data[21], data[22], data[23]})
36 | };
37 |
38 | // compute syndrome
39 | syndrome = PH_in[(PH_SIZE-1):(PH_SIZE-ECC_SIZE)] ^ calc_ecc;
40 |
41 | // correct data
42 | case(syndrome)
43 | 8'h07 : begin {no_error, corrected_error, error} = 3'b010; PH_out = PH_in[(PH_SIZE-ECC_SIZE-1):0] ^ (1<<0); end
44 | 8'h0B : begin {no_error, corrected_error, error} = 3'b010; PH_out = PH_in[(PH_SIZE-ECC_SIZE-1):0] ^ (1<<1); end
45 | 8'h0D : begin {no_error, corrected_error, error} = 3'b010; PH_out = PH_in[(PH_SIZE-ECC_SIZE-1):0] ^ (1<<2); end
46 | 8'h0E : begin {no_error, corrected_error, error} = 3'b010; PH_out = PH_in[(PH_SIZE-ECC_SIZE-1):0] ^ (1<<3); end
47 | 8'h13 : begin {no_error, corrected_error, error} = 3'b010; PH_out = PH_in[(PH_SIZE-ECC_SIZE-1):0] ^ (1<<4); end
48 | 8'h15 : begin {no_error, corrected_error, error} = 3'b010; PH_out = PH_in[(PH_SIZE-ECC_SIZE-1):0] ^ (1<<5); end
49 | 8'h16 : begin {no_error, corrected_error, error} = 3'b010; PH_out = PH_in[(PH_SIZE-ECC_SIZE-1):0] ^ (1<<6); end
50 | 8'h19 : begin {no_error, corrected_error, error} = 3'b010; PH_out = PH_in[(PH_SIZE-ECC_SIZE-1):0] ^ (1<<7); end
51 | 8'h1A : begin {no_error, corrected_error, error} = 3'b010; PH_out = PH_in[(PH_SIZE-ECC_SIZE-1):0] ^ (1<<8); end
52 | 8'h1C : begin {no_error, corrected_error, error} = 3'b010; PH_out = PH_in[(PH_SIZE-ECC_SIZE-1):0] ^ (1<<9); end
53 | 8'h23 : begin {no_error, corrected_error, error} = 3'b010; PH_out = PH_in[(PH_SIZE-ECC_SIZE-1):0] ^ (1<<10); end
54 | 8'h25 : begin {no_error, corrected_error, error} = 3'b010; PH_out = PH_in[(PH_SIZE-ECC_SIZE-1):0] ^ (1<<11); end
55 | 8'h26 : begin {no_error, corrected_error, error} = 3'b010; PH_out = PH_in[(PH_SIZE-ECC_SIZE-1):0] ^ (1<<12); end
56 | 8'h29 : begin {no_error, corrected_error, error} = 3'b010; PH_out = PH_in[(PH_SIZE-ECC_SIZE-1):0] ^ (1<<13); end
57 | 8'h2A : begin {no_error, corrected_error, error} = 3'b010; PH_out = PH_in[(PH_SIZE-ECC_SIZE-1):0] ^ (1<<14); end
58 | 8'h2C : begin {no_error, corrected_error, error} = 3'b010; PH_out = PH_in[(PH_SIZE-ECC_SIZE-1):0] ^ (1<<15); end
59 | 8'h31 : begin {no_error, corrected_error, error} = 3'b010; PH_out = PH_in[(PH_SIZE-ECC_SIZE-1):0] ^ (1<<16); end
60 | 8'h32 : begin {no_error, corrected_error, error} = 3'b010; PH_out = PH_in[(PH_SIZE-ECC_SIZE-1):0] ^ (1<<17); end
61 | 8'h34 : begin {no_error, corrected_error, error} = 3'b010; PH_out = PH_in[(PH_SIZE-ECC_SIZE-1):0] ^ (1<<18); end
62 | 8'h38 : begin {no_error, corrected_error, error} = 3'b010; PH_out = PH_in[(PH_SIZE-ECC_SIZE-1):0] ^ (1<<19); end
63 | 8'h1F : begin {no_error, corrected_error, error} = 3'b010; PH_out = PH_in[(PH_SIZE-ECC_SIZE-1):0] ^ (1<<20); end
64 | 8'h2F : begin {no_error, corrected_error, error} = 3'b010; PH_out = PH_in[(PH_SIZE-ECC_SIZE-1):0] ^ (1<<21); end
65 | 8'h37 : begin {no_error, corrected_error, error} = 3'b010; PH_out = PH_in[(PH_SIZE-ECC_SIZE-1):0] ^ (1<<22); end
66 | 8'h3B : begin {no_error, corrected_error, error} = 3'b010; PH_out = PH_in[(PH_SIZE-ECC_SIZE-1):0] ^ (1<<23); end
67 | 8'h00 : begin {no_error, corrected_error, error} = 3'b100; PH_out = PH_in[(PH_SIZE-ECC_SIZE-1):0]; end
68 | default: begin {no_error, corrected_error, error} = 3'b001; PH_out = PH_in[(PH_SIZE-ECC_SIZE-1):0]; end
69 | endcase
70 | end
71 | endmodule
--------------------------------------------------------------------------------
/hdl/pckthandler.v:
--------------------------------------------------------------------------------
1 | /* Packet Handler: implements the csi protocol and part of the application-layer protocol
2 | * Gedeon Nyengele
3 | * 08 January 2018
4 | */
5 |
6 |
7 | /*
8 | * @param rxbyteclkhs byte clock to synchronize to (input)
9 | * @param reset active-high synchronous reset signal (input)
10 | * @param in_stream byte-and-lane-aligned input stream (input)
11 | * @param in_stream_valid determines whether the input stream is valid (input)
12 | * @param out_stream csi payload stream (output)
13 | * @param frame_active determines whether new frame either about to transmitted or in progress (output)
14 | * @param frame_valid determines whether a frame output is in progress (output)
15 | * @param lines_per_frame is the number of image lines per frame
16 | * @param last_packet indicates whether the packet on out_stream is the last packet for the frame
17 | */
18 | module pckthandler(rxbyteclkhs, reset, in_stream, in_stream_valid, out_stream, frame_active, frame_valid, lines_per_frame, last_packet);
19 |
20 | /* parameters */
21 | parameter IN_STREAM_WIDTH = 16;
22 | parameter OUT_STREAM_WIDTH = IN_STREAM_WIDTH;
23 |
24 | /* inputs */
25 | input rxbyteclkhs, reset, in_stream_valid;
26 | input [(IN_STREAM_WIDTH-1):0] in_stream;
27 | input [31:0] lines_per_frame;
28 |
29 | /* outputs */
30 | output frame_active, frame_valid;
31 | output [(OUT_STREAM_WIDTH-1):0] out_stream;
32 | output last_packet;
33 |
34 | /* internal decl */
35 | wire [31:0] ph_finder_out;
36 | wire ph_finder_ph_select;
37 | wire ph_finder_valid, ecc_error;
38 | wire [23:0] ecc_ph;
39 | wire ph_finder_reset;
40 |
41 | assign ph_finder_reset = reset | (~in_stream_valid);
42 |
43 | // Packet Finder
44 | ph_finder phf(
45 | .rxbyteclkhs(rxbyteclkhs),
46 | .reset(ph_finder_reset),
47 | .din(in_stream),
48 | .din_valid(in_stream_valid),
49 | .dout(ph_finder_out),
50 | .dout_valid(ph_finder_valid),
51 | .ph_select(ph_finder_ph_select)
52 | );
53 |
54 | // ECC block
55 | ecc_block eccb(.PH_in(ph_finder_out), .PH_out(ecc_ph), .error(ecc_error));
56 |
57 | // Packet Handler FSM
58 | pckthandler_fsm fsm(
59 | .rxbyteclkhs(rxbyteclkhs),
60 | .reset(reset),
61 | .data_stream(ph_finder_out[31:16]),
62 | .ph_stream(ecc_ph),
63 | .ph_select(ph_finder_ph_select),
64 | .valid_stream(ph_finder_valid),
65 | .ecc_error(ecc_error),
66 | .out_stream(out_stream),
67 | .frame_active(frame_active),
68 | .frame_valid(frame_valid),
69 | .lines_per_frame(lines_per_frame),
70 | .last_packet(last_packet)
71 | );
72 | endmodule
--------------------------------------------------------------------------------
/hdl/pckthandler_fsm.v:
--------------------------------------------------------------------------------
1 | /* Packet Handler FSM: this module represents the core logic of the packet handler FSM
2 | * Gedeon Nyengele
3 | * 08 January 2018
4 | */
5 |
6 | /*
7 | * @param rxbyteclkhs the byte clock to synchronize to (input)
8 | * @param reset an acitve-high synchronous reset signal (input)
9 | * @param data_stream csi payload stream
10 | * @param ph_stream packet header data (WC_MSB, WC_LSB, DATA_ID)
11 | * @param ph_select defines whether to select the ph_stream or not
12 | * @param valid_stream determines if either stream is valid
13 | * @param ecc_error determines if the PH has an error
14 | * @param out_stream csi payload stream to next module
15 | * @param frame_active determines if we're either about to/in the middle TX'ing a frame
16 | * @param frame_valid signals that a frame output is in progress
17 | * @param lines_per_frame is the number of image lines per frame
18 | * @param last_packet indicates whether the packet on out_stream is the last packet for the frame
19 | */
20 | module pckthandler_fsm(rxbyteclkhs, reset, data_stream, ph_stream, ph_select, valid_stream, ecc_error,
21 | out_stream, frame_active, frame_valid, lines_per_frame, last_packet
22 | );
23 |
24 | /* parameters */
25 | parameter DATA_STREAM_WIDTH = 16;
26 | parameter PH_STREAM_WIDTH = 24;
27 |
28 | /* inputs */
29 | input rxbyteclkhs, reset, ph_select, valid_stream, ecc_error;
30 | input [(DATA_STREAM_WIDTH-1):0] data_stream;
31 | input [(PH_STREAM_WIDTH-1):0] ph_stream;
32 | input [31:0] lines_per_frame;
33 |
34 | /* outputs */
35 | output frame_active, frame_valid;
36 | output [(DATA_STREAM_WIDTH-1):0] out_stream;
37 | output last_packet;
38 |
39 | /* internal decl */
40 | reg frame_active, frame_valid;
41 | reg [(DATA_STREAM_WIDTH-1):0] out_stream;
42 |
43 | wire sof_id, eof_id, pxdata_id;
44 | assign sof_id = (ph_stream[5:0] == 6'h00) ? 1'b1 : 1'b0;
45 | assign eof_id = (ph_stream[5:0] == 6'h01) ? 1'b1 : 1'b0;
46 | assign pxdata_id = (ph_stream[5:0] == 6'h2B) ? 1'b1 : 1'b0; // 2B = RAW10
47 |
48 | reg [1:0] state;
49 | reg [15:0] packet_size, byte_count;
50 | reg [31:0] line_count;
51 | reg last_line, last_out;
52 |
53 | parameter PH_DECODE = 2'b00;
54 | parameter WAIT_EOT = 2'b01;
55 | parameter REC_DATA = 2'b10;
56 |
57 | assign last_packet = last_out;
58 |
59 | always @(posedge rxbyteclkhs) begin
60 | if(reset) begin
61 | frame_active <= 0;
62 | frame_valid <= 0;
63 | packet_size <= 0;
64 | byte_count <= 0;
65 | out_stream <= 0;
66 | line_count <= 0;
67 | last_line <= 0;
68 | last_out <= 0;
69 | state <= PH_DECODE;
70 | end
71 | else begin
72 | case(state)
73 | PH_DECODE: begin
74 | if(valid_stream && ph_select && ~ecc_error) begin
75 | if(sof_id) begin
76 | frame_active <= 1'b1;
77 | line_count <= 0;
78 | last_line <= 0;
79 | last_out <= 0;
80 | state <= PH_DECODE;
81 | end
82 | else if(eof_id) begin
83 | frame_active <= 1'b0;
84 | line_count <= 0;
85 | last_line <= 0;
86 | last_out <= 0;
87 | state <= PH_DECODE;
88 | end
89 | else if(pxdata_id) begin
90 | if(frame_active) begin
91 | byte_count <= 0;
92 | packet_size <= ph_stream[23:8];
93 | line_count <= line_count + 1;
94 | if((line_count + 1) == lines_per_frame) last_line <= 1'b1;
95 | else last_line <= 1'b0;
96 | state <= REC_DATA;
97 | end
98 | else state <= WAIT_EOT;
99 | end
100 | end
101 | else if(valid_stream && ~ph_select) state <= WAIT_EOT;
102 | else state <= PH_DECODE;
103 | end
104 | WAIT_EOT: begin
105 | if(valid_stream) state <= WAIT_EOT;
106 | else state <= PH_DECODE;
107 | end
108 | REC_DATA: begin
109 | if(byte_count < packet_size) begin
110 | frame_valid <= 1'b1;
111 | out_stream <= data_stream;
112 | byte_count <= byte_count + 2;
113 | state <= REC_DATA;
114 | if(((byte_count + 2) >= packet_size) && last_line) last_out <= 1'b1;
115 | else last_out <= 1'b0;
116 | end
117 | else begin
118 | frame_valid <= 1'b0;
119 | out_stream <= 0;
120 | last_out <= 0;
121 | state <= WAIT_EOT;
122 | end
123 | end
124 | endcase
125 | end
126 | end
127 |
128 | endmodule
--------------------------------------------------------------------------------
/hdl/ph_finder.v:
--------------------------------------------------------------------------------
1 | /* Packet Header Finder: this module searches for the packet header in a stream of data
2 | * Gedeon Nyengele
3 | * 08 January 2018
4 | */
5 |
6 | /*
7 | * @param rxbyteclkhs the byte clock to synchrnize to (input)
8 | * @param reset an active-high synchronous reset signal (input)
9 | * @param din 16-bit word input. MSB = lane1_byte, LSB = lane2_byte (input)
10 | * @param din_valid defines if word_in is valid (input)
11 | * @param dout 32-bit output containing either the packet header or forwarded data stream (output)
12 | * PH is formatted as [ECC, WC_MSB, WC_LSB, DATA_ID]
13 | * forwarded data stream format: MSB = lane1_byte, LSB = lane2_byte
14 | * @param dout_valid defines if dout is valid (output)
15 | * @param ph_select defines whether 'dout' contains the PH or not
16 | */
17 |
18 | module ph_finder(rxbyteclkhs, reset, din, din_valid, dout, dout_valid, ph_select);
19 |
20 | /* inputs */
21 | input wire rxbyteclkhs, reset;
22 | input wire [15:0] din; // { lane0[7:0], lane1[7:0] }
23 | input wire din_valid;
24 |
25 | /* outputs */
26 | output reg [31:0] dout;
27 | output reg dout_valid;
28 | output reg ph_select;
29 |
30 | /* internal decl */
31 | parameter STATE_HALF_PH = 2'b00;
32 | parameter STATE_FULL_PH = 2'b01;
33 | parameter STATE_BYPASS = 2'b10;
34 |
35 | reg [7:0] prev_byte1, prev_byte2;
36 | reg [1:0] state;
37 |
38 | /* state machine */
39 | always @(posedge rxbyteclkhs) begin
40 | if(reset | ~din_valid) begin
41 | dout <= 32'd0;
42 | dout_valid <= 1'b0;
43 | ph_select <= 1'b0;
44 | prev_byte1 <= 8'd0;
45 | prev_byte2 <= 8'd0;
46 | state <= STATE_HALF_PH;
47 | end
48 | else begin
49 | case(state)
50 | STATE_HALF_PH: begin
51 | prev_byte1 <= din[15:8];
52 | prev_byte2 <= din[7:0];
53 | state <= STATE_FULL_PH;
54 | end
55 |
56 | STATE_FULL_PH: begin
57 | dout <= {din[7:0], din[15:8], prev_byte2, prev_byte1};
58 | dout_valid <= 1'b1;
59 | ph_select <= 1'b1;
60 | state <= STATE_BYPASS;
61 | end
62 |
63 | STATE_BYPASS: begin
64 | dout <= {din, 16'd0};
65 | ph_select <= 1'b0;
66 | state <= STATE_BYPASS;
67 | end
68 |
69 | default: begin
70 | dout <= 32'd0;
71 | dout_valid <= 1'b0;
72 | ph_select <= 1'b0;
73 | end
74 | endcase
75 | end
76 | end
77 | endmodule
78 |
--------------------------------------------------------------------------------
/hdl/raw10_decoder.v:
--------------------------------------------------------------------------------
1 | /* RAW10 data decoder
2 | * Gedeon Nyengele
3 | * 22 January 2018
4 | */
5 |
6 | /*
7 | * @param rxbyteclkhs byte clock to synchronize to
8 | * @param reset an active-high reset line
9 | * @param data_in 16-bit input data (byte1, byte2)
10 | * @param data_out 64-bit (4pixels: [pixel4, pixel3, pixel2, pixel1])
11 | * @param out_valid 1-bit output to indicate whether the 64-bit output is valid or not
12 | * @param last_packet_in input signal to indicate if data_in contains the last packet for the frame
13 | * @param last_packet_out output signal to indicate that data_out contains the last packet for the frame
14 | */
15 |
16 | module raw10_decoder(rxbyteclkhs, reset, data_in, frame_active, frame_valid, data_out, out_valid, last_packet_in, last_packet_out);
17 |
18 | // parameters
19 | parameter IN_DATA_WIDTH = 16;
20 | parameter OUT_DATA_WIDTH = 64;
21 |
22 | // inputs
23 | input wire rxbyteclkhs, reset, frame_active, frame_valid;
24 | input [(IN_DATA_WIDTH-1):0] data_in;
25 | input last_packet_in;
26 |
27 | // outputs
28 | output out_valid;
29 | output [(OUT_DATA_WIDTH-1):0] data_out;
30 | output reg last_packet_out;
31 |
32 | // internal decls
33 | reg out_valid;
34 | reg [(OUT_DATA_WIDTH-1):0] data_out;
35 |
36 | reg [7:0] buff[3:0];
37 | reg [2:0] state;
38 |
39 | wire valid = frame_active & frame_valid;
40 |
41 | always @(posedge rxbyteclkhs) begin
42 | if(reset | ~valid) last_packet_out <= 0;
43 | else last_packet_out <= last_packet_in;
44 | end
45 |
46 | always @(posedge rxbyteclkhs) begin
47 | if(reset | ~valid) begin
48 | out_valid <= 0;
49 | data_out <= 0;
50 | state <= 3'b000;
51 | end
52 | else begin
53 | case(state)
54 | 3'b000: begin
55 | data_out <= 0;
56 | out_valid <= 0;
57 | buff[0] <= data_in[15:8];
58 | buff[1] <= data_in[7:0];
59 | state <= 3'b001;
60 | end
61 | 3'b001: begin
62 | buff[2] <= data_in[15:8];
63 | buff[3] <= data_in[7:0];
64 | state <= 3'b010;
65 | end
66 | 3'b010: begin
67 | data_out <= { 6'd0, buff[3], data_in[15:14], // 4th pixel data (16 bits)
68 | 6'd0, buff[2], data_in[13:12], // 3rd pixel data (16 bits)
69 | 6'd0, buff[1], data_in[11:10], // 2nd pixel data (16 bits)
70 | 6'd0, buff[0], data_in[9:8] // 1st pixel data (16 bits)
71 | };
72 | out_valid <= 1'b1;
73 | buff[0] <= data_in[7:0];
74 | state <= 3'b011;
75 | end
76 | 3'b011: begin
77 | data_out <= 0;
78 | out_valid <= 0;
79 | buff[1] <= data_in[15:8];
80 | buff[2] <= data_in[7:0];
81 | state <= 3'b100;
82 | end
83 | 3'b100: begin
84 | data_out <= { 6'd0, data_in[15:8], data_in[7:6], // 4th pixel data (16 bits)
85 | 6'd0, buff[2], data_in[5:4], // 3rd pixel data (16 bits)
86 | 6'd0, buff[1], data_in[3:2], // 2nd pixel data (16 bits)
87 | 6'd0, buff[0], data_in[1:0] // 1st pixel data (16 bits)
88 | };
89 | out_valid <= 1'b1;
90 | state <= 3'b000;
91 | end
92 | endcase
93 | end
94 | end
95 | endmodule
--------------------------------------------------------------------------------
/hdl/wordalign.v:
--------------------------------------------------------------------------------
1 | /* Align two data channels based on their sync signals, so that each 16-bit
2 | * output word has a corresponding byte from each channel, and the whole word
3 | * becomes valid/invalid at the same time.
4 | *
5 | * This is loosely based on David Shah's work:
6 | * https://github.com/daveshah1/CSI2Rx/blob/master/mipi-csi-rx/csi_rx_word_align.vhd
7 | *
8 | * Steven Bell
9 | * 2 January 2018
10 | */
11 |
12 | module wordalign # (
13 | parameter integer MAX_CHANNEL_DELAY = 2
14 | )
15 | (
16 | input wire clk,
17 | input wire resetn,
18 | // We just use the valid line to generate the sync
19 | input wire dl0_rxvalidhs, // Lane 0 valid
20 | input wire dl1_rxvalidhs, // Lane 1 valid
21 | input wire [7:0] dl0_rxdatahs, // Lane 0 data
22 | input wire [7:0] dl1_rxdatahs, // Lane 1 data
23 | output wire [15:0] word_out, // { lane 0[7:0], lane 1[7:0] }
24 | output reg word_valid
25 | );
26 |
27 | // Delayed copies of the input word, which is the concatenation of the input bytes
28 | reg[15:0] word_delay[MAX_CHANNEL_DELAY+1:0];
29 | // Delayed copies of the sync lines, which form a set of one-hot delay counters
30 | reg[1:0] sync_delay[MAX_CHANNEL_DELAY+1:0];
31 | // Delayed copies of the valid bits, so the output invalidation is synced
32 | reg[1:0] valid_delay[MAX_CHANNEL_DELAY+1:0];
33 |
34 | wire locked; // Whether we have aquired a sync pulse from all channels
35 | reg[7:0] byte_lane0;
36 | reg[7:0] byte_lane1;
37 |
38 | integer i; // Loop counter
39 |
40 | always @(posedge clk) begin
41 | if(~resetn) begin
42 | byte_lane0 <= 0;
43 | byte_lane1 <= 0;
44 | for(i = 0; i <= MAX_CHANNEL_DELAY; i = i+1) begin
45 | word_delay[i] <= 0;
46 | sync_delay[i] <= 2'b00;
47 | valid_delay[i] <= 2'b00;
48 | end
49 | word_valid <= 1'b0;
50 | end
51 | else begin
52 | // Push the incoming data and valid bits down the chain
53 | word_delay[0] <= {dl0_rxdatahs, dl1_rxdatahs};
54 | word_delay[1] <= word_delay[0];
55 | word_delay[2] <= word_delay[1];
56 |
57 | valid_delay[0] <= {dl0_rxvalidhs, dl1_rxvalidhs};
58 | valid_delay[1] <= valid_delay[0];
59 | valid_delay[2] <= valid_delay[1];
60 |
61 | // If we haven't yet gotten a sync from all the channels,
62 | // then keep pushing them back.
63 | // Once we have a sync from each channel, the position of those bits
64 | // represents the delay that we need to apply to each data stream.
65 | if(~locked) begin
66 | sync_delay[0] <= {dl0_rxvalidhs != valid_delay[0][1],
67 | dl1_rxvalidhs != valid_delay[0][0]};
68 | sync_delay[1] <= sync_delay[0];
69 | sync_delay[2] <= sync_delay[1];
70 | end
71 |
72 | // Output is valid one cycle after locking
73 | word_valid <= locked;
74 |
75 | // Select the appropriate bytes from the delay chain based on the sync delays
76 | if(sync_delay[0][1])
77 | byte_lane0 <= word_delay[0][15:8];
78 | else if(sync_delay[1][1])
79 | byte_lane0 <= word_delay[1][15:8];
80 | else if(sync_delay[2][1])
81 | byte_lane0 <= word_delay[2][15:8];
82 | else
83 | byte_lane0 <= 0;
84 |
85 | if(sync_delay[0][0])
86 | byte_lane1 <= word_delay[0][7:0];
87 | else if(sync_delay[1][0])
88 | byte_lane1 <= word_delay[1][7:0];
89 | else if(sync_delay[2][0])
90 | byte_lane1 <= word_delay[2][7:0];
91 | else
92 | byte_lane1 <= 0;
93 | end // else (~reset)
94 | end
95 |
96 | // We're locked (i.e., have a valid set of delays in sync_delay) if each
97 | // lane has a sync pulse, and the corresponding valid bit is set (to handle desync)
98 | // This is a continuous assignment since we need to stop the sync on the next cycle
99 | assign locked = ((sync_delay[0][0] & valid_delay[0][0]) |
100 | (sync_delay[1][0] & valid_delay[1][0]) |
101 | (sync_delay[2][0] & valid_delay[2][0])) &
102 | ((sync_delay[0][1] & valid_delay[0][1]) |
103 | (sync_delay[1][1] & valid_delay[1][1]) |
104 | (sync_delay[2][1] & valid_delay[2][1]));
105 |
106 | assign word_out = {byte_lane0, byte_lane1};
107 |
108 | endmodule
109 |
110 |
--------------------------------------------------------------------------------
/unit_tests/Makefile:
--------------------------------------------------------------------------------
1 | OUTPUT ?= testbench
2 | ROOT = ../
3 | FLAGS = -g2005 -y $(ROOT)
4 |
5 | pckthandler: pckthandler_tb.v
6 | iverilog $(FLAGS) $^ -o $(OUTPUT)
7 |
8 | pckthandler2: pckthandler_tb2.v
9 | iverilog $(FLAGS) $^ -o $(OUTPUT)
10 |
11 | pckthandler_fsm: pckthandler_fsm_tb.v
12 | iverilog $(FLAGS) $^ -o $(OUTPUT)
13 |
14 | ph_finder: ph_finder_tb.v
15 | iverilog $(FLAGS) $^ -o $(OUTPUT)
16 |
17 | ecc_block: ecc_block_tb.v
18 | iverilog $(FLAGS) $^ -o $(OUTPUT)
19 |
20 | raw10_decoder: raw10_decoder_tb.v
21 | iverilog $(FLAGS) $^ -o $(OUTPUT)
22 |
23 | .PHONY: run, clean
24 | run: $(OUTPUT)
25 | vvp $(OUTPUT)
26 | clean:
27 | rm -rf $(OUTPUT)
--------------------------------------------------------------------------------
/unit_tests/csirx_tb.v:
--------------------------------------------------------------------------------
1 | `timescale 1ns/1ps
2 |
3 | module csirx_tb #
4 | (
5 | parameter integer N_DATA_LANES = 2
6 | )
7 | ();
8 |
9 | reg clk;
10 | reg resetn;
11 |
12 | // PPI input simulating Xilinx D-PHY core
13 | reg cl_stopstate;
14 | reg dl0_rxactivehs; // Whether high-speed receive is in progress
15 | reg dl1_rxactivehs;
16 | reg dl0_rxsynchs; // Pulse at the beginning of high-speed transmission
17 | reg dl1_rxsynchs;
18 | wire cl_enable; // Clock enable
19 | wire dl0_enable; // Data lane 0 enable
20 | wire dl1_enable; // Data lane 1 enables
21 | wire dl0_forcerxmode;
22 | wire dl1_forcerxmode;
23 | reg dl0_rxvalidhs; // Lane 0 valid
24 | reg dl1_rxvalidhs; // Lane 1 valid
25 | reg [7:0] dl0_rxdatahs; // Lane 0 data
26 | reg [7:0] dl1_rxdatahs; // Lane 1 data
27 |
28 | // AXI-stream master output
29 | wire m_axis_tvalid;
30 | wire [(N_DATA_LANES*8)-1 : 0] m_axis_tdata;
31 | wire [N_DATA_LANES-1 : 0] m_axis_tstrb;
32 | wire m_axis_tlast;
33 | reg m_axis_tready;
34 |
35 | // Simulation control variables
36 | integer d0_start;
37 | integer d1_start;
38 | integer datalen;
39 | integer n_cycles;
40 |
41 | // Simulation control
42 | initial begin
43 | $display("Starting the test...");
44 | $dumpfile("csirx_test.vcd");
45 | $dumpvars; // Dump everything
46 | #500 $finish; // End after N ticks
47 | end
48 |
49 | // Initialization
50 | initial begin
51 | clk = 1'b0;
52 | resetn = 1'b1;
53 |
54 | d0_start = 4;
55 | d1_start = 2;
56 | datalen = 16;
57 | n_cycles = 0;
58 | end
59 |
60 | // Reset signal
61 | initial begin
62 | #5
63 | resetn = 1'b0;
64 | #10
65 | resetn = 1'b1;
66 | end
67 |
68 |
69 | always begin
70 | #10
71 |
72 | clk = 1'b1;
73 |
74 | // Sync pulse once at the start
75 | dl0_rxsynchs = (n_cycles == d0_start-1);
76 | dl1_rxsynchs = (n_cycles == d1_start-1);
77 |
78 | // If the start time has passed, then set the data valid bit
79 | // and set the data to a counting value
80 | if(n_cycles >= d0_start && n_cycles < d0_start + datalen) begin
81 | dl0_rxdatahs = n_cycles - d0_start;
82 | dl0_rxvalidhs = 1'b1;
83 | end
84 | else begin
85 | dl0_rxdatahs = 8'hxx;
86 | dl0_rxvalidhs = 1'b0;
87 | end
88 |
89 | if(n_cycles >= d1_start && n_cycles < d1_start + datalen) begin
90 | dl1_rxdatahs = n_cycles - d1_start + 8'h10;
91 | dl1_rxvalidhs = 1'b1;
92 | end
93 | else begin
94 | dl1_rxdatahs = 8'hxx;
95 | dl1_rxvalidhs = 1'b0;
96 | end
97 |
98 |
99 | #10
100 | clk = 1'b0;
101 |
102 | n_cycles += 1;
103 | end
104 |
105 | // DUT
106 | csirx csirx_dut(
107 | .cl_stopstate(cl_stopstate),
108 | .dl0_rxactivehs(dl0_rxactivehs),
109 | .dl1_rxactivehs(dl1_rxactivehs),
110 | .dl0_rxsynchs(dl0_rxsynchs),
111 | .dl1_rxsynchs(dl1_rxsynchs),
112 | .cl_enable(cl_enable),
113 | .dl0_enable(dl0_enable),
114 | .dl1_enable(dl1_enable),
115 | .dl0_forcerxmode(dl0_forcerxmode),
116 | .dl1_forcerxmode(dl1_forcerxmode),
117 | .dl0_rxvalidhs(dl0_rxvalidhs),
118 | .dl1_rxvalidhs(dl1_rxvalidhs),
119 | .dl0_rxdatahs(dl0_rxdatahs),
120 | .dl1_rxdatahs(dl1_rxdatahs),
121 | .rxbyteclkhs(clk),
122 | .rxbyteclkhs_resetn(resetn),
123 | .m_axis_tvalid(m_axis_tvalid),
124 | .m_axis_tdata(m_axis_tdata),
125 | .m_axis_tstrb(m_axis_tstrb),
126 | .m_axis_tlast(m_axis_tlast),
127 | .m_axis_tready(m_axis_tready)
128 | );
129 |
130 | endmodule
131 |
132 |
--------------------------------------------------------------------------------
/unit_tests/ecc_block_tb.v:
--------------------------------------------------------------------------------
1 | module ecc_block_tb;
2 | reg [31:0] PH_in;
3 |
4 | wire [23:0] PH_out;
5 | wire no_error, corrected_error, error;
6 |
7 | reg [23:0] PH_out_exp;
8 | reg error_exp;
9 |
10 | reg clk;
11 | integer fd, status;
12 |
13 | ecc_block DUT(PH_in, PH_out, no_error, corrected_error, error);
14 |
15 | // clock
16 | initial clk = 0;
17 | always #10 clk=~clk;
18 |
19 | // files
20 | initial fd = $fopen("ecc_block_testvec.txt", "r");
21 |
22 | // data provider
23 | initial begin
24 | PH_in = 0;
25 | //@(posedge clk);
26 | while(!$feof(fd)) begin
27 | @(posedge clk);
28 | #1 status = $fscanf(fd, "%h, %h, %h\n",PH_in, PH_out_exp, error_exp);
29 | #4 $display("PH_in=%h, PH_out=%h, PH_out_exp=%h, error=%b, error_exp=%b", PH_in, PH_out, PH_out_exp, error, error_exp);
30 | end
31 | @(posedge clk);
32 | $fclose(fd);
33 | $finish;
34 | end
35 |
36 | endmodule
--------------------------------------------------------------------------------
/unit_tests/ecc_block_testvec.txt:
--------------------------------------------------------------------------------
1 | 0x3400042b, 0x00042b, 0x0
2 | 0x3400042a, 0x00042b, 0x0
3 | 0x3400042c, 0x00042c, 0x1
4 | 0x3400142b, 0x00042b, 0x0
5 | 0x3410042b, 0x00042b, 0x0
6 | 0x3401043b, 0x01043b, 0x1
--------------------------------------------------------------------------------
/unit_tests/image4.bin:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/stevenbell/csirx/2c37eb0e8ec25d011185fbc1c5a678123e198c7f/unit_tests/image4.bin
--------------------------------------------------------------------------------
/unit_tests/image4_out.bin:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/stevenbell/csirx/2c37eb0e8ec25d011185fbc1c5a678123e198c7f/unit_tests/image4_out.bin
--------------------------------------------------------------------------------
/unit_tests/pckthandler_fsm_tb.v:
--------------------------------------------------------------------------------
1 | module pckthandler_fsm_tb;
2 | reg clk, reset;
3 | reg [15:0] data_stream;
4 | reg [23:0] ph_stream;
5 | reg ph_select, valid_stream, ecc_error;
6 |
7 | wire [15:0] out_stream;
8 | wire frame_active, frame_valid;
9 |
10 | integer fd, status;
11 |
12 | reg [15:0] out_exp;
13 | reg fr_active_exp, fr_valid_exp;
14 |
15 | pckthandler_fsm DUT(clk, reset, data_stream, ph_stream, ph_select, valid_stream,
16 | ecc_error, out_stream, frame_active, frame_valid);
17 |
18 | // clock & reset
19 | initial begin
20 | clk = 0; reset =1;
21 | repeat(4) #10 clk=~clk;
22 | reset = 0;
23 | forever #10 clk=~clk;
24 | end
25 |
26 | // test vector files
27 | initial begin
28 | fd = $fopen("pckthandler_fsm_testvec.txt", "r");
29 | end
30 |
31 | // data provider
32 | initial begin
33 | data_stream = 0; ph_stream= 0; ph_select = 0; valid_stream=0; ecc_error=0;
34 | @(negedge reset);
35 | while(!$feof(fd)) begin
36 | status = $fscanf(fd, "%h, %h, %h, %h, %h, %h, %h\n", data_stream, ph_stream, valid_stream, ph_select,
37 | out_exp, fr_active_exp, fr_valid_exp);
38 | @(posedge clk);
39 | #1 $display("out=%h, out_exp=%h, fr_active=%h, fr_active_exp=%h, fr_valid=%h, fr_valid_exp=%h",
40 | out_stream, out_exp, frame_active, fr_active_exp, frame_valid, fr_valid_exp);
41 | end
42 | repeat(20) @(posedge clk);
43 | $fclose(fd);
44 | $finish;
45 | end
46 | endmodule
--------------------------------------------------------------------------------
/unit_tests/pckthandler_fsm_testvec.txt:
--------------------------------------------------------------------------------
1 | 0x0000, 0x000000, 0x1, 0x1, 0x0000, 0x1, 0x0
2 | 0x0000, 0x000412, 0x1, 0x1, 0x0000, 0x1, 0x0
3 | 0xeeff, 0x000000, 0x1, 0x0, 0x0000, 0x1, 0x0
4 | 0xffee, 0x000000, 0x1, 0x0, 0x0000, 0x1, 0x0
5 | 0xeeff, 0x000000, 0x1, 0x0, 0x0000, 0x1, 0x0
6 | 0xffee, 0x000000, 0x1, 0x0, 0x0000, 0x1, 0x0
7 | 0x0000, 0x000000, 0x0, 0x0, 0x0000, 0x1, 0x0
8 | 0x0000, 0x000412, 0x1, 0x1, 0x0000, 0x1, 0x0
9 | 0xeeff, 0x000000, 0x1, 0x0, 0x0000, 0x1, 0x0
10 | 0xffee, 0x000000, 0x1, 0x0, 0x0000, 0x1, 0x0
11 | 0xeeff, 0x000000, 0x1, 0x0, 0x0000, 0x1, 0x0
12 | 0xffee, 0x000000, 0x1, 0x0, 0x0000, 0x1, 0x0
13 | 0x0000, 0x000000, 0x0, 0x0, 0x0000, 0x1, 0x0
14 | 0x0000, 0x00062b, 0x1, 0x1, 0x0000, 0x1, 0x0
15 | 0x1122, 0x000000, 0x1, 0x0, 0x1122, 0x1, 0x1
16 | 0x3344, 0x000000, 0x1, 0x0, 0x3344, 0x1, 0x1
17 | 0x5566, 0x000000, 0x1, 0x0, 0x5566, 0x1, 0x1
18 | 0x1122, 0x000000, 0x1, 0x0, 0x0000, 0x1, 0x0
19 | 0x1342, 0x000000, 0x1, 0x0, 0x0000, 0x1, 0x0
20 | 0x1562, 0x000000, 0x1, 0x0, 0x0000, 0x1, 0x0
21 | 0x0000, 0x000000, 0x0, 0x0, 0x0000, 0x1, 0x0
22 | 0x0000, 0x00062b, 0x1, 0x1, 0x0000, 0x1, 0x0
23 | 0x1122, 0x000000, 0x1, 0x0, 0x1122, 0x1, 0x1
24 | 0x3344, 0x000000, 0x1, 0x0, 0x3344, 0x1, 0x1
25 | 0x5566, 0x000000, 0x1, 0x0, 0x5566, 0x1, 0x1
26 | 0x1122, 0x000000, 0x1, 0x0, 0x0000, 0x1, 0x0
27 | 0x1342, 0x000000, 0x1, 0x0, 0x0000, 0x1, 0x0
28 | 0x1562, 0x000000, 0x1, 0x0, 0x0000, 0x1, 0x0
29 | 0x0000, 0x000000, 0x0, 0x0, 0x0000, 0x1, 0x0
30 | 0x0000, 0x000001, 0x1, 0x1, 0x0000, 0x0, 0x0
--------------------------------------------------------------------------------
/unit_tests/pckthandler_tb.v:
--------------------------------------------------------------------------------
1 | /* Vector-based testbench for pckthandler.v
2 | * The first part of the test uses a set of test vectors in the text file
3 | * pckthandler_testvec.txt, and exercises all the basic functionality.
4 | * See also pckthandler_tb2.v
5 | *
6 | * Gedeon Nyengele
7 | * January 2018
8 | */
9 |
10 | module pckthandler_tb;
11 | reg clk, reset, din_valid;
12 | reg [15:0] din;
13 | wire dout_valid, fr_active, fr_valid;
14 | wire [15:0] dout;
15 |
16 | reg [15:0] dout_exp;
17 | reg fr_valid_exp, fr_active_exp;
18 | integer fd, status;
19 | reg [128*8-1:0] vecstr;
20 |
21 | pckthandler DUT(clk, reset, din, din_valid, dout, fr_active, fr_valid);
22 |
23 | // clock & reset
24 | initial begin
25 | clk = 0; reset = 1;
26 | repeat(4) #10 clk = ~clk;
27 | reset = 0;
28 | forever #10 clk = ~clk;
29 | end
30 |
31 | // files
32 | initial begin
33 | fd = $fopen("pckthandler_testvec.txt", "r");
34 | end
35 |
36 | // data provider
37 | initial begin
38 | din = 0; din_valid = 0;
39 | @(negedge reset);
40 | while(!$feof(fd)) begin
41 | status = $fgets(vecstr, fd);
42 | if($sscanf(vecstr, "%h, %h, %h, %h, %h\n", din, din_valid, dout_exp, fr_active_exp, fr_valid_exp) == 5) begin
43 | @(posedge clk);
44 | #1 $display("din=%h, din_valid=%h, dout=%h, dout_exp=%h, fr_active=%h, fr_active_exp=%h, fr_valid=%h, fr_valid_exp=%h",
45 | din, din_valid, dout, dout_exp, fr_active, fr_active_exp, fr_valid, fr_valid_exp);
46 | end
47 |
48 | end
49 | repeat(25) @(posedge clk);
50 | $fclose(fd);
51 | $finish;
52 | end
53 | endmodule
54 |
--------------------------------------------------------------------------------
/unit_tests/pckthandler_tb2.v:
--------------------------------------------------------------------------------
1 | /* Data-based testbench for pckthandler.v
2 | * This test pushes part of a real data dump from the byte aligner through.
3 | * We have to manually confirm that the output appears in whole frames and that
4 | * the header/footer is stripped off correctly.
5 | *
6 | * Steven Bell
7 | * 22 January 2018
8 | */
9 |
10 | module pckthandler_tb2;
11 |
12 | reg clk, reset, din_valid;
13 | reg [7:0] char_in; // Used to get data byte-by-byte
14 | reg [15:0] din;
15 | wire dout_valid, fr_active, fr_valid;
16 | wire [15:0] dout;
17 |
18 | reg [15:0] dout_exp;
19 | reg fr_valid_exp, fr_active_exp;
20 | integer infile, outfile, count, stat;
21 |
22 | pckthandler DUT(clk, reset, din, din_valid, dout, fr_active, fr_valid);
23 |
24 | // clock & reset
25 | initial begin
26 | clk = 0; reset = 1;
27 | repeat(4) #10 clk = ~clk;
28 | reset = 0;
29 | forever #10 clk = ~clk;
30 | end
31 |
32 | // files
33 | initial begin
34 | infile = $fopen("image4.bin", "r");
35 | outfile = $fopen("image4_out.bin", "w");
36 | end
37 |
38 |
39 | // data provider
40 | initial begin
41 | din = 0; din_valid = 0;
42 | count = 0;
43 | @(negedge reset); // Wait until (active-high) reset goes low
44 |
45 | while(!$feof(infile)) begin
46 | stat = $fread(char_in, infile); // Read the first input byte
47 | din[15:8] = char_in;
48 | stat = $fread(char_in, infile); // Read the second byte
49 | din[7:0] = char_in;
50 |
51 | din_valid = 1; // Always valid
52 |
53 | // Wait for the next cycle
54 | @(posedge clk);
55 | #1
56 |
57 | // Write the output bits if they are valid
58 | if(dout_valid) begin
59 | $fwrite(outfile, "%s", dout);
60 | end
61 |
62 | // Print some progress
63 | if(count % 16'h1000 == 0) begin
64 | $display("count: %x din: %x fr_active: %d, fr_valid: %d, dout_valid: %d",
65 | count, din, fr_active, fr_valid, dout_valid);
66 | end
67 | count = count+1;
68 | end
69 | $fclose(infile);
70 | $fclose(outfile);
71 | $finish;
72 | end
73 | endmodule
--------------------------------------------------------------------------------
/unit_tests/pckthandler_testvec.txt:
--------------------------------------------------------------------------------
1 | # send SOF short packet
2 | 0x0000, 0x1, 0x0000, 0x0, 0x0
3 | 0x0000, 0x1, 0x0000, 0x0, 0x0
4 |
5 | # end of packet
6 | 0x0000, 0x0, 0x0000, 0x1, 0x0
7 |
8 | # send a 4-byte pixel data packet
9 | # with additional trailing bytes
10 | 0x2b04, 0x1, 0x0000, 0x1, 0x0
11 | 0x0034, 0x1, 0x0000, 0x1, 0x0
12 | 0x1122, 0x1, 0x0000, 0x1, 0x0
13 | 0x3344, 0x1, 0x1122, 0x1, 0x1
14 | 0x5566, 0x1, 0x3344, 0x1, 0x1
15 | 0x7788, 0x1, 0x0000, 0x1, 0x0
16 | 0x99aa, 0x1, 0x0000, 0x1, 0x0
17 |
18 | # end of packet
19 | 0x0000, 0x0, 0x0000, 0x1, 0x0
20 |
21 | # send an EoF short packet
22 | 0x0100, 0x1, 0x0000, 0x1, 0x0
23 | 0x0007, 0x1, 0x0000, 0x1, 0x0
24 |
25 | # end of packet
26 | 0x0000, 0x0, 0x0000, 0x0, 0x0
--------------------------------------------------------------------------------
/unit_tests/ph_finder_tb.v:
--------------------------------------------------------------------------------
1 | /* testbench for ph_finder module
2 | * Gedeon Nyengele
3 | * Jan 12 2018
4 | */
5 |
6 | module ph_finder_tb;
7 | reg clk, reset, din_valid;
8 | reg [15:0] din;
9 | wire [31:0] dout;
10 | wire dout_valid, ph_select;
11 |
12 | integer fd, status;
13 | reg [31:0] d_exp;
14 | reg v_exp, ph_exp;
15 |
16 | ph_finder DUT(clk, reset, din, din_valid, dout, dout_valid, ph_select);
17 |
18 | // clock
19 | initial begin
20 | clk = 0; reset = 1;
21 | repeat(4) #10 clk = ~clk;
22 | reset = 0;
23 | forever #10 clk = ~clk;
24 | end
25 |
26 | // files
27 | initial begin
28 | fd = $fopen("ph_finder_testvec.txt", "r");
29 | end
30 |
31 | // data provider
32 | initial begin
33 | din = 0; din_valid = 1;
34 | @(negedge reset);
35 | while(!$feof(fd)) begin
36 | status = $fscanf(fd, "%h, %h, %h, %h, %h\n", din, din_valid, d_exp, v_exp, ph_exp);
37 | @(posedge clk);
38 | #1 $display("input=%h, output=%h, output_exp=%h, v=%b, v_exp=%b, ph_sel=%b, ph_sel_exp=%b",
39 | din, dout, d_exp, dout_valid, v_exp, ph_select, ph_exp);
40 | end
41 | @(posedge clk);
42 | $fclose(fd);
43 | $finish;
44 | end
45 | endmodule
--------------------------------------------------------------------------------
/unit_tests/ph_finder_testvec.txt:
--------------------------------------------------------------------------------
1 | 0x0102, 0x1, 0x00000000, 0x0, 0x0
2 | 0x0304, 0x1, 0x04030201, 0x1, 0x1
3 | 0x0506, 0x1, 0x05060000, 0x1, 0x0
4 | 0x0708, 0x1, 0x07080000, 0x1, 0x0
5 | 0x090a, 0x1, 0x090a0000, 0x1, 0x0
6 | 0x0b0c, 0x0, 0x00000000, 0x0, 0x0
7 | 0x0d0e, 0x1, 0x00000000, 0x0, 0x0
8 | 0x0f10, 0x1, 0x100f0e0d, 0x1, 0x1
9 | 0x0f20, 0x1, 0x0f200000, 0x1, 0x0
10 | 0x0f30, 0x1, 0x0f300000, 0x1, 0x0
--------------------------------------------------------------------------------
/unit_tests/raw10_decoder_tb.v:
--------------------------------------------------------------------------------
1 | module raw10_decoder_tb;
2 | reg clk, reset, frame_active, frame_valid;
3 | reg [15:0] din;
4 |
5 | wire [63:0] dout;
6 | wire valid;
7 |
8 | reg [63:0] dout_exp;
9 | reg valid_exp;
10 |
11 | integer fd, status;
12 | reg [128*8-1:0] vecstr; // Line of file for input vector
13 |
14 | raw10_decoder DUT(clk, reset, din, frame_active, frame_valid, dout, valid);
15 |
16 | // clock and reset
17 | initial begin
18 | clk = 0; reset = 1;
19 | repeat(4) #10 clk=~clk;
20 | reset = 0;
21 | forever #10 clk=~clk;
22 | end
23 |
24 | // files
25 | initial begin
26 | fd = $fopen("raw10_decoder_testvec.txt", "r");
27 | end
28 |
29 |
30 | // data provider
31 | initial begin
32 | din = 0; frame_valid = 0; frame_active = 0;
33 | @(negedge reset);
34 | while(!$feof(fd)) begin
35 | status = $fgets(vecstr, fd);
36 | if($sscanf(vecstr, "%h, %h, %h, %h, %h\n", din, frame_active, frame_valid, dout_exp, valid_exp) == 5) begin
37 | @(posedge clk);
38 | #1 $display("din=%h, fr_active=%b, fr_valid=%b, dout=%h, dout_exp=%h, valid=%b, valid_exp=%b",
39 | din, frame_active, frame_valid, dout, dout_exp, valid, valid_exp);
40 | end
41 | end
42 | @(posedge clk);
43 | $fclose(fd);
44 | $finish;
45 | end
46 | endmodule
47 |
--------------------------------------------------------------------------------
/unit_tests/raw10_decoder_testvec.txt:
--------------------------------------------------------------------------------
1 | /* RAW10 decoder - Test vectors
2 | *
3 | * Gedeon Nyengele
4 | * Jan 22, 2018
5 | */
6 |
7 | # test 1: send and receive the following 10-bit raw pixels:
8 | # 0x17B, 0x308, 0x283, 0x2AC
9 |
10 | (data format: din, fr_active, fr_valid, dout_exp, valid_exp)
11 | 0x5EC2, 0x1, 0x1, 0x0000000000000000, 0x0
12 | 0xA0AB, 0x1, 0x1, 0x0000000000000000, 0x0
13 | 0x335E, 0x1, 0x1, 0x02AC02830308017B, 0x1
14 | 0xC2A0, 0x1, 0x1, 0x0000000000000000, 0x0
15 | 0xAB33, 0x1, 0x1, 0x02AC02830308017B, 0x1
16 | 0x6DEC, 0x0, 0x0, 0x0000000000000000, 0x0
17 | 0x5EC2, 0x1, 0x1, 0x0000000000000000, 0x0
18 | 0xA0AB, 0x1, 0x1, 0x0000000000000000, 0x0
19 | 0x335E, 0x1, 0x1, 0x02AC02830308017B, 0x1
20 | 0xC2A0, 0x1, 0x1, 0x0000000000000000, 0x0
21 | 0xAB33, 0x1, 0x1, 0x02AC02830308017B, 0x1
22 | 0x6DEC, 0x0, 0x0, 0x0000000000000000, 0x0
--------------------------------------------------------------------------------
/unit_tests/viewdump.py:
--------------------------------------------------------------------------------
1 | # Decode a binary blob from the camera into something resembling an image
2 | # Steven Bell
3 | # 29 December 2017
4 |
5 | import numpy as np
6 | import matplotlib.pyplot as plt
7 | from IPython import embed
8 |
9 | # Load the data
10 | blob = np.fromfile('image4.bin', dtype=np.uint8)
11 |
12 | # Flip the channels
13 | ch1 = blob[0::2]
14 | ch2 = blob[1::2]
15 |
16 | merged = np.zeros(len(ch1) + len(ch2))
17 | merged[1::2] = ch1
18 | merged[0::2] = ch2
19 |
20 | #merged = np.delete(merged, np.s_[1::5]) # Throw out the packed low 2 bits
21 |
22 | # This looks like 1640 pixels wide
23 | w = 1040*2; # 832*2; #832*4 # 1040 includes the low-order bits
24 | h = len(merged) / w
25 |
26 | im = merged[0:w*h].reshape(h, w)
27 |
28 | #plt.imshow(im[1000:2000,0:1200])
29 | plt.imshow(im)
30 | plt.show()
31 |
32 | #embed()
33 |
34 |
--------------------------------------------------------------------------------
/xgui/axi_csi_v1_1.tcl:
--------------------------------------------------------------------------------
1 | # Definitional proc to organize widgets for parameters.
2 | proc init_gui { IPINST } {
3 | ipgui::add_param $IPINST -name "Component_Name"
4 | #Adding Page
5 | ipgui::add_page $IPINST -name "Page 0"
6 |
7 |
8 | }
9 |
10 |
11 |
--------------------------------------------------------------------------------
/xgui/axi_csi_v1_1_v1_0.tcl:
--------------------------------------------------------------------------------
1 | # Definitional proc to organize widgets for parameters.
2 | proc init_gui { IPINST } {
3 | ipgui::add_param $IPINST -name "Component_Name"
4 | #Adding Page
5 | set Page_0 [ipgui::add_page $IPINST -name "Page 0"]
6 | ipgui::add_param $IPINST -name "C_RegSpace_S_AXI_ADDR_WIDTH" -parent ${Page_0}
7 | ipgui::add_param $IPINST -name "C_RegSpace_S_AXI_DATA_WIDTH" -parent ${Page_0}
8 | ipgui::add_param $IPINST -name "N_DATA_LANES" -parent ${Page_0}
9 |
10 |
11 | }
12 |
13 | proc update_PARAM_VALUE.C_RegSpace_S_AXI_ADDR_WIDTH { PARAM_VALUE.C_RegSpace_S_AXI_ADDR_WIDTH } {
14 | # Procedure called to update C_RegSpace_S_AXI_ADDR_WIDTH when any of the dependent parameters in the arguments change
15 | }
16 |
17 | proc validate_PARAM_VALUE.C_RegSpace_S_AXI_ADDR_WIDTH { PARAM_VALUE.C_RegSpace_S_AXI_ADDR_WIDTH } {
18 | # Procedure called to validate C_RegSpace_S_AXI_ADDR_WIDTH
19 | return true
20 | }
21 |
22 | proc update_PARAM_VALUE.C_RegSpace_S_AXI_DATA_WIDTH { PARAM_VALUE.C_RegSpace_S_AXI_DATA_WIDTH } {
23 | # Procedure called to update C_RegSpace_S_AXI_DATA_WIDTH when any of the dependent parameters in the arguments change
24 | }
25 |
26 | proc validate_PARAM_VALUE.C_RegSpace_S_AXI_DATA_WIDTH { PARAM_VALUE.C_RegSpace_S_AXI_DATA_WIDTH } {
27 | # Procedure called to validate C_RegSpace_S_AXI_DATA_WIDTH
28 | return true
29 | }
30 |
31 | proc update_PARAM_VALUE.N_DATA_LANES { PARAM_VALUE.N_DATA_LANES } {
32 | # Procedure called to update N_DATA_LANES when any of the dependent parameters in the arguments change
33 | }
34 |
35 | proc validate_PARAM_VALUE.N_DATA_LANES { PARAM_VALUE.N_DATA_LANES } {
36 | # Procedure called to validate N_DATA_LANES
37 | return true
38 | }
39 |
40 |
41 | proc update_MODELPARAM_VALUE.N_DATA_LANES { MODELPARAM_VALUE.N_DATA_LANES PARAM_VALUE.N_DATA_LANES } {
42 | # Procedure called to set VHDL generic/Verilog parameter value(s) based on TCL parameter value
43 | set_property value [get_property value ${PARAM_VALUE.N_DATA_LANES}] ${MODELPARAM_VALUE.N_DATA_LANES}
44 | }
45 |
46 | proc update_MODELPARAM_VALUE.C_RegSpace_S_AXI_DATA_WIDTH { MODELPARAM_VALUE.C_RegSpace_S_AXI_DATA_WIDTH PARAM_VALUE.C_RegSpace_S_AXI_DATA_WIDTH } {
47 | # Procedure called to set VHDL generic/Verilog parameter value(s) based on TCL parameter value
48 | set_property value [get_property value ${PARAM_VALUE.C_RegSpace_S_AXI_DATA_WIDTH}] ${MODELPARAM_VALUE.C_RegSpace_S_AXI_DATA_WIDTH}
49 | }
50 |
51 | proc update_MODELPARAM_VALUE.C_RegSpace_S_AXI_ADDR_WIDTH { MODELPARAM_VALUE.C_RegSpace_S_AXI_ADDR_WIDTH PARAM_VALUE.C_RegSpace_S_AXI_ADDR_WIDTH } {
52 | # Procedure called to set VHDL generic/Verilog parameter value(s) based on TCL parameter value
53 | set_property value [get_property value ${PARAM_VALUE.C_RegSpace_S_AXI_ADDR_WIDTH}] ${MODELPARAM_VALUE.C_RegSpace_S_AXI_ADDR_WIDTH}
54 | }
55 |
56 |
--------------------------------------------------------------------------------