├── FPGA_guide.gif ├── LICENSE ├── README.md ├── creator_core ├── Makefile ├── creator.ucf ├── creator_dcm.v ├── rtl │ ├── wb_bram │ │ ├── bram.v │ │ └── init_ram.py │ ├── wb_conbus │ │ ├── conbus.v │ │ └── conbus_arb.v │ ├── wb_everloop │ │ ├── everloop.v │ │ ├── everloop_bram.v │ │ ├── everloop_fsm.v │ │ ├── image.ram │ │ ├── init_ram.py │ │ └── wb_everloop.v │ ├── wb_gpio │ │ ├── core_clk.v │ │ ├── mux_io.v │ │ ├── pwm.v │ │ ├── single_mux.v │ │ ├── timer.v │ │ ├── timer_core.v │ │ └── wb_gpio.v │ ├── wb_mcu_bram │ │ └── wb_mcu_bram.v │ ├── wb_mic_array │ │ ├── cic.v │ │ ├── cic_comb.v │ │ ├── cic_int.v │ │ ├── cic_op_fsm.v │ │ ├── cic_sync.v │ │ ├── fir.v │ │ ├── fir_pipe_fsm.v │ │ ├── mic_array.v │ │ ├── mic_array_buffer.v │ │ └── wb_mic_array.v │ ├── wb_spi_slave │ │ ├── spi_slave.v │ │ └── wb_spi_slave.v │ ├── wb_uart │ │ ├── uart.v │ │ ├── uart_fifo.v │ │ ├── uart_fsm.v │ │ └── wb_uart.v │ └── wb_zwave_gpio │ │ └── wb_zwave_gpio.v ├── system.v └── system_TB.v ├── thrid_party └── unisims │ ├── BUFG.v │ ├── BUFT.v │ ├── DCM_CLKGEN.v │ ├── DCM_SP.v │ ├── FDDRRSE.v │ ├── IBUFG.v │ ├── IDDR2.v │ ├── IOBUF_.v │ ├── LUT3_test.v │ ├── OBUFT.v │ ├── ODDR2.v │ ├── RAMB16_S9_S18.v │ ├── RAMB16_S9_S9.v │ ├── ddr.v │ ├── ddr_parameters.vh │ └── subtest.vh └── verilogCheatSheet.md /FPGA_guide.gif: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/matrix-io/matrix-creator-fpga/5f8c757abbca260e2f389df79df9c52facc11541/FPGA_guide.gif -------------------------------------------------------------------------------- /README.md: -------------------------------------------------------------------------------- 1 | # MATRIX Creator FPGA 2 | To edit, compile, and upload this verilog code, follow the tutorial below: 3 | https://www.hackster.io/matrix-labs/get-started-with-fpga-programming-on-matrix-devices-525cd5 4 | 5 | Check out our [Verilog Cheat Sheet](verilogCheatSheet.md) for refreshers! 6 | 7 | ![](https://github.com/matrix-io/matrix-creator-fpga/blob/ac/full_core/FPGA_guide.gif) 8 | -------------------------------------------------------------------------------- /creator_core/Makefile: -------------------------------------------------------------------------------- 1 | DESIGN = system 2 | UCF = creator 3 | PINS = $(UCF).ucf 4 | DEVICE = xc6slx4-2tqg144 5 | BGFLAGS = -g TdoPin:PULLNONE -g DonePin:PULLUP \ 6 | -g CRC:enable -g StartUpClk:CCLK 7 | ISE_SIM_ROOT = /opt/Xilinx/14.7/ISE_DS/ISE/verilog/src 8 | XILINXCADROOT = /opt/Xilinx/14.7/ISE_DS/ISE/bin/lin/ise 9 | SIMGEN_OPTIONS = -p $(FPGA_ARCH) -lang $(LANGUAGE) 10 | IVERILOG = iverilog 11 | 12 | 13 | MIC_SRC = rtl/wb_mic_array/cic_comb.v \ 14 | rtl/wb_mic_array/cic_sync.v \ 15 | rtl/wb_mic_array/cic_int.v \ 16 | rtl/wb_mic_array/cic.v \ 17 | rtl/wb_mic_array/mic_array.v \ 18 | rtl/wb_mic_array/mic_array_buffer.v \ 19 | rtl/wb_mic_array/cic_op_fsm.v \ 20 | rtl/wb_mic_array/fir.v \ 21 | rtl/wb_mic_array/fir_pipe_fsm.v \ 22 | rtl/wb_mic_array/wb_mic_array.v 23 | 24 | MCU_SRC = rtl/wb_mcu_bram/wb_mcu_bram.v 25 | 26 | UART_SRC = rtl/wb_uart/uart.v \ 27 | rtl/wb_uart/wb_uart.v \ 28 | rtl/wb_uart/uart_fifo.v 29 | 30 | EVERLOOP_SRC = rtl/wb_everloop/everloop_bram.v \ 31 | rtl/wb_everloop/everloop.v \ 32 | rtl/wb_everloop/everloop_fsm.v \ 33 | rtl/wb_everloop/wb_everloop.v 34 | 35 | SPI_SRC = rtl/wb_spi_slave/wb_spi_slave.v \ 36 | rtl/wb_spi_slave/spi_slave.v \ 37 | 38 | GPIO_SRC = rtl/wb_gpio/wb_gpio.v \ 39 | rtl/wb_gpio/pwm.v \ 40 | rtl/wb_gpio/core_clk.v \ 41 | rtl/wb_gpio/timer.v \ 42 | rtl/wb_gpio/timer_core.v \ 43 | rtl/wb_gpio/mux_io.v \ 44 | rtl/wb_gpio/single_mux.v 45 | 46 | ZWAVE_GPIO = rtl/wb_zwave_gpio/wb_zwave_gpio.v 47 | 48 | SRC = $(DESIGN).v \ 49 | creator_dcm.v \ 50 | rtl/wb_bram/bram.v \ 51 | rtl/wb_conbus/conbus_arb.v \ 52 | rtl/wb_conbus/conbus.v \ 53 | $(MCU_SRC) \ 54 | $(SPI_SRC) \ 55 | $(MIC_SRC) \ 56 | $(UART_SRC) \ 57 | $(GPIO_SRC) \ 58 | $(ZWAVE_GPIO) \ 59 | $(EVERLOOP_SRC) 60 | 61 | SIM_SRC = $(DESIGN)_TB.v \ 62 | ../thrid_party/unisims/DCM_SP.v \ 63 | ../thrid_party/unisims/BUFG.v \ 64 | ../thrid_party/unisims/IBUFG.v 65 | 66 | 67 | all: bits 68 | 69 | remake: clean-build all 70 | 71 | clean: 72 | rm -f *~ */*~ a.out *.log *.key *.edf *.ps trace.dat 73 | rm -f *.bit 74 | rm -rf build 75 | 76 | cleanall: clean 77 | rm -rf build simulation/work simulation/transcript simulation/vsim.wlf simulation/$(DESIGN)_TB.vvp simulation/* 78 | 79 | bits: $(DESIGN).bit 80 | 81 | # 82 | # Synthesis 83 | # 84 | build/project.src: 85 | @[ -d build ] || mkdir build 86 | @[ -d simulation ] || mkdir simulation 87 | @rm -f $@ 88 | for i in $(SRC); do echo verilog work ../$$i >> $@; done 89 | for i in $(SRC_HDL); do echo VHDL work ../$$i >> $@; done 90 | 91 | build/project.xst: build/project.src 92 | echo "run" > $@ 93 | echo "-top $(DESIGN) " >> $@ 94 | echo "-p $(DEVICE)" >> $@ 95 | echo "-opt_mode Area" >> $@ 96 | echo "-opt_level 2" >> $@ 97 | echo "-ifn project.src" >> $@ 98 | echo "-ifmt mixed" >> $@ 99 | echo "-ofn project.ngc" >> $@ 100 | echo "-ofmt NGC" >> $@ 101 | echo "-rtlview yes" >> $@ 102 | echo "-register_balancing yes" >> $@ 103 | 104 | build/project.ngc: build/project.xst $(SRC) 105 | cd build && xst -ifn project.xst -ofn project.log 106 | 107 | build/project.ngd: build/project.ngc $(PINS) 108 | cd build && ngdbuild -p $(DEVICE) project.ngc -uc ../$(PINS) 109 | 110 | build/project.ncd: build/project.ngd 111 | cd build && map -pr b -p $(DEVICE) project 112 | 113 | build/project_r.ncd: build/project.ncd 114 | cd build && par -w project project_r.ncd 115 | 116 | build/project_r.twr: build/project_r.ncd 117 | cd build && trce -v 25 project_r.ncd project.pcf 118 | 119 | $(DESIGN).bit: build/project_r.ncd build/project_r.twr 120 | cd build && bitgen project_r.ncd -l -w $(BGFLAGS) 121 | @mv -f build/project_r.bit $@ 122 | 123 | build/project_r.v: build/project_r.ncd 124 | cd build && ngd2ver project.ngd -w project.v 125 | 126 | postsim: build/project.ngc 127 | cd build && netgen -sim -ofmt verilog project.ngc 128 | cd build && iverilog -Wall \ 129 | -y $(XILINXCADROOT)/verilog/src/unisims \ 130 | -y $(XILINXCADROOT)/verilog/src/XilinxCoreLib \ 131 | project.v ../$(DESIGN)_TB.v -o $(DESIGN).bin 132 | cd build && vvp $(DESIGN).bin 133 | gtkwave build/$(DESIGN)_TB.vcd& 134 | 135 | iversim: build/project.src 136 | $(IVERILOG) -g2012 -gno-io-range-error -o simulation/$(DESIGN)_TB.vvp $(VINCDIR) $(SRC) $(SIM_SRC) -s $(DESIGN)_TB -y $(ISE_SIM_ROOT) -y $(ISE_SIM_ROOT)/unisims -y $(ISE_SIM_ROOT)/unimacro -y $(ISE_SIM_ROOT)/simprims 137 | vvp simulation/$(DESIGN)_TB.vvp; mv $(DESIGN)_TB.vcd simulation/ 138 | gtkwave simulation/$(DESIGN)_TB.vcd& 139 | 140 | upload: 141 | xc3sprog -c imx283 -v -p1 $(DESIGN).bit 142 | -------------------------------------------------------------------------------- /creator_core/creator.ucf: -------------------------------------------------------------------------------- 1 | ###################################################### 2 | ###################################################### 3 | ## These constraints are for MATRIX-CREATOR ## 4 | ###################################################### 5 | ###################################################### 6 | 7 | ###################### 8 | # Timing Constraints # 9 | ###################### 10 | 11 | ##### Grouping Constraints ##### 12 | NET clk_50 TNM_NET = clk50_grp; 13 | 14 | ##### Clock Period Constraints ##### 15 | TIMESPEC TS_PER_CLK50 = PERIOD "clk50_grp" 20.0 ns HIGH 50%; 16 | 17 | ##### Grouping Constraints ##### 18 | NET sck TNM_NET = sck_grp; 19 | 20 | ##### Clock Period Constraints ##### 21 | TIMESPEC TS_PER_SCK = PERIOD "sck_grp" 20.0 ns HIGH 50%; 22 | 23 | 24 | ####################### 25 | # Pin LOC Constraints # 26 | ####################### 27 | 28 | #OSC 29 | NET "clk_50" LOC = "P84" | IOSTANDARD = LVCMOS33; 30 | 31 | #LED 32 | NET "debug_led" LOC = "P39" | IOSTANDARD = LVCMOS33 | DRIVE = 24; 33 | 34 | #EVERLOOP 35 | NET "everloop_ctl" LOC = "P56" | IOSTANDARD = LVCMOS33; 36 | 37 | #RPI CONTROL 38 | NET "resetn" LOC = "P142" | IOSTANDARD = LVCMOS33 | PULLDOWN; 39 | NET "sck" LOC = "P115" | IOSTANDARD = LVCMOS33; 40 | NET "mosi" LOC = "P112" | IOSTANDARD = LVCMOS33; 41 | NET "miso" LOC = "P114" | IOSTANDARD = LVCMOS33; 42 | NET "ss" LOC = "P116" | IOSTANDARD = LVCMOS33; 43 | NET "ss1" LOC = "P123" | IOSTANDARD = LVCMOS33; #RPI_GPIO12 44 | 45 | #RPI UART 46 | NET "uart_tx_pi" LOC = "P70"| IOSTANDARD = LVCMOS33; 47 | NET "uart_rx_pi" LOC = "P69"| IOSTANDARD = LVCMOS33; 48 | 49 | #RPI IR 50 | #NET "ir_rx_pi" LOC = "P119" | IOSTANDARD = LVCMOS33; 51 | NET "ir_rx_pi" LOC = "P119" | IOSTANDARD = LVCMOS33; 52 | NET "ir_tx_pi" LOC = "P120" | IOSTANDARD = LVCMOS33; 53 | 54 | #IR 55 | NET "ir_ring" LOC = "P143" | IOSTANDARD = LVCMOS33; 56 | NET "ir_tx" LOC = "P118" | IOSTANDARD = LVCMOS33; 57 | NET "ir_rx" LOC = "P144" | IOSTANDARD = LVCMOS33; 58 | 59 | #RPI IRQ 60 | NET "mic_irq" LOC = "P139" | IOSTANDARD = LVCMOS33; #RPI_GPIO6 61 | NET "uart_irq" LOC = "P138" | IOSTANDARD = LVCMOS33; #RPI_GPIO5 62 | NET "nfc_irq_pi" LOC = "P1" | IOSTANDARD = LVCMOS33; #RPI_GPIO25 63 | 64 | 65 | ####################### 66 | # MIC ARRAY # 67 | ####################### 68 | 69 | NET "pdm_data<0>" LOC = "P45" | IOSTANDARD = LVCMOS33; 70 | NET "pdm_data<1>" LOC = "P46" | IOSTANDARD = LVCMOS33; 71 | NET "pdm_data<2>" LOC = "P47" | IOSTANDARD = LVCMOS33; 72 | NET "pdm_data<3>" LOC = "P58" | IOSTANDARD = LVCMOS33; 73 | NET "pdm_data<4>" LOC = "P59" | IOSTANDARD = LVCMOS33; 74 | NET "pdm_data<5>" LOC = "P64" | IOSTANDARD = LVCMOS33; 75 | NET "pdm_data<6>" LOC = "P65" | IOSTANDARD = LVCMOS33; 76 | NET "pdm_data<7>" LOC = "P44" | IOSTANDARD = LVCMOS33; 77 | NET "pdm_clk" LOC = "P67" | IOSTANDARD = LVCMOS33; 78 | 79 | ####################### 80 | # SAM 3S INTERFACE # 81 | ####################### 82 | #ADDRESS BUS 83 | #NET "mcu_addr<13>" LOC = "P24" | IOSTANDARD = LVCMOS33; 84 | #NET "mcu_addr<12>" LOC = "P26" | IOSTANDARD = LVCMOS33; 85 | #NET "mcu_addr<11>" LOC = "P27" | IOSTANDARD = LVCMOS33; 86 | NET "mcu_addr<10>" LOC = "P100" | IOSTANDARD = LVCMOS33; 87 | NET "mcu_addr<9>" LOC = "P14" | IOSTANDARD = LVCMOS33; 88 | NET "mcu_addr<8>" LOC = "P17" | IOSTANDARD = LVCMOS33; 89 | NET "mcu_addr<7>" LOC = "P48" | IOSTANDARD = LVCMOS33; 90 | NET "mcu_addr<6>" LOC = "P50" | IOSTANDARD = LVCMOS33; 91 | NET "mcu_addr<5>" LOC = "P51" | IOSTANDARD = LVCMOS33; 92 | NET "mcu_addr<4>" LOC = "P57" | IOSTANDARD = LVCMOS33; 93 | NET "mcu_addr<3>" LOC = "P60" | IOSTANDARD = LVCMOS33; 94 | NET "mcu_addr<2>" LOC = "P61" | IOSTANDARD = LVCMOS33; 95 | NET "mcu_addr<1>" LOC = "P62" | IOSTANDARD = LVCMOS33; 96 | NET "mcu_addr<0>" LOC = "P66" | IOSTANDARD = LVCMOS33; 97 | 98 | #DATA BUS 99 | NET "mcu_sram_data<7>" LOC = "P137" | IOSTANDARD = LVCMOS33; 100 | NET "mcu_sram_data<6>" LOC = "P132" | IOSTANDARD = LVCMOS33; 101 | NET "mcu_sram_data<5>" LOC = "P131" | IOSTANDARD = LVCMOS33; 102 | NET "mcu_sram_data<4>" LOC = "P127" | IOSTANDARD = LVCMOS33; 103 | NET "mcu_sram_data<3>" LOC = "P124" | IOSTANDARD = LVCMOS33; 104 | NET "mcu_sram_data<2>" LOC = "P121" | IOSTANDARD = LVCMOS33; 105 | NET "mcu_sram_data<1>" LOC = "P117" | IOSTANDARD = LVCMOS33; 106 | NET "mcu_sram_data<0>" LOC = "P6" | IOSTANDARD = LVCMOS33; 107 | 108 | #CONTROL BUS 109 | NET "mcu_nwe" LOC = "P97" | IOSTANDARD = LVCMOS33; 110 | NET "mcu_nrd" LOC = "P87" | IOSTANDARD = LVCMOS33; 111 | NET "mcu_ncs" LOC = "P8" | IOSTANDARD = LVCMOS33; 112 | #NET "mcu_nwait" LOC = "P10" | IOSTANDARD = LVCMOS33; 113 | 114 | ####################### 115 | # EXP-CONN # 116 | ####################### 117 | 118 | NET "gpio_io<15>" LOC="P102" | IOSTANDARD = LVCMOS33; 119 | NET "gpio_io<14>" LOC="P101" | IOSTANDARD = LVCMOS33; 120 | NET "gpio_io<13>" LOC="P99" | IOSTANDARD = LVCMOS33; 121 | NET "gpio_io<12>" LOC="P98" | IOSTANDARD = LVCMOS33; 122 | NET "gpio_io<11>" LOC="P95" | IOSTANDARD = LVCMOS33; 123 | NET "gpio_io<10>" LOC="P94" | IOSTANDARD = LVCMOS33; 124 | NET "gpio_io<9>" LOC="P93" | IOSTANDARD = LVCMOS33; 125 | NET "gpio_io<8>" LOC="P92" | IOSTANDARD = LVCMOS33; 126 | NET "gpio_io<7>" LOC="P88" | IOSTANDARD = LVCMOS33; 127 | NET "gpio_io<6>" LOC="P85" | IOSTANDARD = LVCMOS33; 128 | NET "gpio_io<5>" LOC="P83" | IOSTANDARD = LVCMOS33; 129 | NET "gpio_io<4>" LOC="P82" | IOSTANDARD = LVCMOS33; 130 | NET "gpio_io<3>" LOC="P81" | IOSTANDARD = LVCMOS33; 131 | NET "gpio_io<2>" LOC="P80" | IOSTANDARD = LVCMOS33; 132 | NET "gpio_io<1>" LOC="P79" | IOSTANDARD = LVCMOS33; 133 | NET "gpio_io<0>" LOC="P78" | IOSTANDARD = LVCMOS33; 134 | 135 | 136 | ######################### 137 | # ZIGBEE # 138 | ######################### 139 | 140 | NET "zigbee_rx" LOC = "P34" | IOSTANDARD = LVCMOS33; 141 | NET "zigbee_tx" LOC = "P35" | IOSTANDARD = LVCMOS33; 142 | #NET "ZnRTS" LOC = "P33" | IOSTANDARD = LVCMOS33; 143 | #NET "ZnCTS" LOC = "P32" | IOSTANDARD = LVCMOS33; 144 | 145 | ######################### 146 | # NFC # 147 | ######################### 148 | 149 | NET "nfc_miso" LOC = "P134" | IOSTANDARD = LVCMOS33; 150 | NET "nfc_cs" LOC = "P141" | IOSTANDARD = LVCMOS33; 151 | NET "nfc_mosi" LOC = "P133" | IOSTANDARD = LVCMOS33; 152 | NET "nfc_sck" LOC = "P126" | IOSTANDARD = LVCMOS33; 153 | NET "nfc_rst" LOC = "P111" | IOSTANDARD = LVCMOS33; 154 | NET "nfc_irq" LOC = "P140" | IOSTANDARD = LVCMOS33; 155 | ######################### 156 | # ZWAVE # 157 | ######################### 158 | 159 | NET "zwave_nreset" LOC = "P23" | IOSTANDARD = LVCMOS33; 160 | NET "zwave_txd" LOC = "P16" | IOSTANDARD = LVCMOS33; 161 | NET "zwave_rxd" LOC = "P21" | IOSTANDARD = LVCMOS33; 162 | NET "zwave_miso" LOC = "P11" | IOSTANDARD = LVCMOS33; 163 | NET "zwave_mosi" LOC = "P15" | IOSTANDARD = LVCMOS33; 164 | NET "zwave_cs" LOC = "P22" | IOSTANDARD = LVCMOS33; 165 | NET "zwave_sck" LOC = "P12" | IOSTANDARD = LVCMOS33; 166 | 167 | ######################### 168 | # Workaround # 169 | ######################### 170 | NET "nrst_deprecated" LOC = "P105" | IOSTANDARD = LVCMOS33; 171 | NET "i2c_sda" LOC = "P74" | IOSTANDARD = LVCMOS33; 172 | NET "i2c_scl" LOC = "P75" | IOSTANDARD = LVCMOS33; 173 | -------------------------------------------------------------------------------- /creator_core/creator_dcm.v: -------------------------------------------------------------------------------- 1 | /* 2 | * Copyright 2016 3 | * MATRIX Labs [http://creator.matrix.one] 4 | * This file is part of MATRIX Creator HDL for Spartan 6 5 | * 6 | * MATRIX Creator HDL is like free software: you can redistribute 7 | * it and/or modify it under the terms of the GNU General Public License 8 | * as published by the Free Software Foundation, either version 3 of the 9 | * License, or (at your option) any later version. 10 | 11 | * This program is distributed in the hope that it will be useful, but 12 | * WITHOUT ANY WARRANTY; without even the implied warranty of 13 | * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU 14 | * General Public License for more details. 15 | 16 | * You should have received a copy of the GNU General Public License along 17 | * with this program. If not, see . 18 | */ 19 | 20 | module creator_dcm #( 21 | parameter CLKFX_DIVIDE = 1, 22 | parameter CLKFX_MULTIPLY = 4 23 | ) ( 24 | // Clock in ports 25 | input clkin , 26 | // Clock out ports 27 | output clk_out_200 , 28 | output nclk_out_200, 29 | output clk_out_25 30 | ); 31 | 32 | IBUFG clkin_buf ( 33 | .O(b_clkin), 34 | .I(clkin ) 35 | ); 36 | 37 | wire locked_int; 38 | wire [7:0] status_int; 39 | wire clkfb ; 40 | wire clk0 ; 41 | wire clkfx ; 42 | wire nclkfx ; 43 | wire clkdv ; 44 | 45 | DCM_SP 46 | #(.CLKDV_DIVIDE (2.000), 47 | .CLKFX_DIVIDE (CLKFX_DIVIDE), 48 | .CLKFX_MULTIPLY (CLKFX_MULTIPLY), 49 | .CLKIN_DIVIDE_BY_2 ("FALSE"), 50 | .CLKIN_PERIOD (20.000), 51 | .CLKOUT_PHASE_SHIFT ("NONE"), 52 | .CLK_FEEDBACK ("1X"), 53 | .DESKEW_ADJUST ("SYSTEM_SYNCHRONOUS"), 54 | .PHASE_SHIFT (0), 55 | .STARTUP_WAIT ("FALSE")) 56 | dcm_sp_inst ( 57 | .CLKIN (b_clkin), 58 | .CLKFB (clkfb), 59 | // Output clocks 60 | .CLK0 (clk0), 61 | .CLK90 (), 62 | .CLK180 (), 63 | .CLK270 (), 64 | .CLK2X (), 65 | .CLK2X180 (), 66 | .CLKFX (clkfx), 67 | .CLKFX180 (nclkfx), 68 | .CLKDV (clkdv), 69 | // Ports for dynamic phase shift 70 | .PSCLK (1'b0), 71 | .PSEN (1'b0), 72 | .PSINCDEC (1'b0), 73 | .PSDONE (), 74 | // Other control and status signals 75 | .LOCKED (locked_int), 76 | .STATUS (status_int), 77 | .RST (1'b0), 78 | // Unused pin- tie low 79 | .DSSEN (1'b0) 80 | ); 81 | 82 | 83 | BUFG clkf_buf 84 | (.O (clkfb), 85 | .I (clk0)); 86 | 87 | BUFG clkout1_buf 88 | (.O (clk_out_200), 89 | .I (clkfx)); 90 | 91 | BUFG clkout2_buf 92 | (.O (nclk_out_200), 93 | .I (nclkfx)); 94 | 95 | BUFG clkout3_buf 96 | (.O (clk_out_25), 97 | .I (clkdv)); 98 | 99 | endmodule 100 | 101 | -------------------------------------------------------------------------------- /creator_core/rtl/wb_bram/bram.v: -------------------------------------------------------------------------------- 1 | /* 2 | * Copyright 2016-2020 MATRIX Labs 3 | * MATRIX Labs [http://creator.matrix.one] 4 | * Authors: Andres Calderon 5 | * Kevin Patiño 6 | * 7 | * This file is part of MATRIX Creator HDL for Spartan 6 8 | * 9 | * MATRIX Creator HDL is like free software: you can redistribute 10 | * it and/or modify it under the terms of the GNU General Public License 11 | * as published by the Free Software Foundation, either version 3 of the 12 | * License, or (at your option) any later version. 13 | 14 | * This program is distributed in the hope that it will be useful, but 15 | * WITHOUT ANY WARRANTY; without even the implied warranty of 16 | * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU 17 | * General Public License for more details. 18 | 19 | * You should have received a copy of the GNU General Public License along 20 | * with this program. If not, see . 21 | */ 22 | 23 | module wb_bram #( 24 | parameter DATA_WIDTH = "mandatory", 25 | parameter ADDR_WIDTH = "mandatory", 26 | //General configuration 27 | parameter CLKFX_DIVIDE = "mandatory", 28 | parameter CLKFX_MULTIPLY = "mandatory", 29 | parameter [63:0] VERSION = "mandatory", 30 | //Microphone Configuration 31 | parameter [DATA_WIDTH-1:0] DECIMATION_RATIO = "mandatory", 32 | parameter [DATA_WIDTH-1:0] DATA_GAIN_DEFAULT = "mandatory", 33 | // Memory Configuration 34 | parameter MEM_ADDR_WIDTH = ADDR_WIDTH-7, 35 | parameter DEPTH = (1 << MEM_ADDR_WIDTH) 36 | ) ( 37 | input clk , 38 | input resetn , 39 | // 40 | input wb_stb_i , 41 | input wb_cyc_i , 42 | input wb_we_i , 43 | input [ADDR_WIDTH-1:0] wb_adr_i , 44 | output reg [DATA_WIDTH-1:0] wb_dat_o , 45 | input [DATA_WIDTH-1:0] wb_dat_i , 46 | input [ 1:0] wb_sel_i , 47 | output reg wb_ack_o , 48 | // Microphone Register Configuration 49 | output reg [DATA_WIDTH-1:0] mic_sample_rate, 50 | output reg [DATA_WIDTH-1:0] mic_data_gain 51 | ); 52 | 53 | wire wb_wr,wb_rd; 54 | 55 | assign wb_wr = wb_cyc_i & wb_stb_i & wb_we_i & ~wb_ack_o; 56 | assign wb_rd = wb_cyc_i & wb_stb_i & ~wb_we_i & ~wb_ack_o; 57 | 58 | reg [DATA_WIDTH-1:0] ram[0:DEPTH-1]; 59 | 60 | //------------------------------------------------------------------ 61 | // read/write port A 62 | //------------------------------------------------------------------ 63 | always @(posedge clk) begin 64 | wb_ack_o <= 0; 65 | if(wb_wr | wb_rd) begin 66 | wb_ack_o <= 1; 67 | if (wb_wr) 68 | ram[wb_adr_i[MEM_ADDR_WIDTH-1:0]] <= wb_dat_i; 69 | 70 | wb_dat_o <= ram[wb_adr_i[MEM_ADDR_WIDTH-1:0]]; 71 | end 72 | end 73 | 74 | //------------------------------------------------------------------ 75 | // read port B 76 | //------------------------------------------------------------------ 77 | reg [DATA_WIDTH-1:0] data_ram ; 78 | reg [ 3:0] update_counter; //TODO: Parameter 79 | 80 | reg update_enable; 81 | 82 | localparam S_IDLE = 1'd0; 83 | localparam S_UPDATE = 1'd1; 84 | 85 | reg state; 86 | 87 | always @(state) begin 88 | case(state) 89 | S_IDLE : 90 | update_enable = 1'b0; 91 | S_UPDATE : 92 | update_enable = 1'b1; 93 | endcase 94 | end 95 | 96 | always @(posedge clk or posedge resetn) begin 97 | if(resetn) 98 | state <= S_IDLE; 99 | else begin 100 | case(state) 101 | S_IDLE : 102 | if(wb_ack_o) 103 | state <= S_UPDATE; 104 | S_UPDATE : 105 | if(update_counter == 4'd12) 106 | state <= S_IDLE; 107 | else 108 | state <= S_UPDATE; 109 | endcase 110 | end 111 | end 112 | 113 | always @(posedge clk or posedge resetn) begin 114 | if(resetn) begin 115 | update_counter <= 0; 116 | end else begin 117 | if(update_enable) 118 | update_counter <= update_counter + 1; 119 | else 120 | update_counter <= 0; 121 | end 122 | end 123 | 124 | always @(posedge clk) begin 125 | data_ram <= ram[update_counter]; 126 | end 127 | 128 | always @(posedge clk or posedge resetn) begin 129 | if(resetn) 130 | mic_sample_rate <= DECIMATION_RATIO; 131 | else if (update_counter == 4'd6 + 1) 132 | mic_sample_rate <= data_ram; 133 | end 134 | 135 | always @(posedge clk or posedge resetn) begin 136 | if(resetn) 137 | mic_data_gain <= DATA_GAIN_DEFAULT; 138 | else if (update_counter == 4'd7 + 1) 139 | mic_data_gain <= data_ram; 140 | end 141 | 142 | integer i; 143 | initial 144 | begin 145 | ram[0] = VERSION[63-:16]; 146 | ram[1] = VERSION[63-16-:16]; 147 | ram[2] = VERSION[63-32-:16]; 148 | ram[3] = VERSION[63-48-:16]; 149 | ram[4] = CLKFX_DIVIDE; 150 | ram[5] = CLKFX_MULTIPLY; 151 | ram[6] = DECIMATION_RATIO; 152 | ram[7] = DATA_GAIN_DEFAULT; 153 | for (i = 8; i < DEPTH ; i=i+1) begin 154 | ram[i] = 0; 155 | end 156 | end 157 | 158 | endmodule 159 | 160 | -------------------------------------------------------------------------------- /creator_core/rtl/wb_bram/init_ram.py: -------------------------------------------------------------------------------- 1 | import os,random 2 | 3 | f = open('image.ram', 'w') 4 | # f.write("{") 5 | for i in range(0,1024): 6 | line = i+20*i+i*5+20 7 | f.write("%04x\n" % line) 8 | 9 | #f.write("{") 10 | f.close(); 11 | -------------------------------------------------------------------------------- /creator_core/rtl/wb_conbus/conbus.v: -------------------------------------------------------------------------------- 1 | /* 2 | * Wishbone Arbiter and Address Decoder 3 | * Copyright (C) 2008, 2009, 2010 Sebastien Bourdeauducq 4 | * Copyright (C) 2000 Johny Chi - chisuhua@yahoo.com.cn 5 | * This file is part of Milkymist. 6 | * 7 | * This source file may be used and distributed without 8 | * restriction provided that this copyright statement is not 9 | * removed from the file and that any derivative work contains 10 | * the original copyright notice and the associated disclaimer. 11 | * 12 | * This source file is free software; you can redistribute it 13 | * and/or modify it under the terms of the GNU Lesser General 14 | * Public License as published by the Free Software Foundation; 15 | * either version 2.1 of the License, or (at your option) any 16 | * later version. 17 | * 18 | * This source is distributed in the hope that it will be 19 | * useful, but WITHOUT ANY WARRANTY; without even the implied 20 | * warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR 21 | * PURPOSE. See the GNU Lesser General Public License for more 22 | * details. 23 | * 24 | * You should have received a copy of the GNU Lesser General 25 | * Public License along with this source; if not, download it 26 | * from http://www.opencores.org/lgpl.shtml. 27 | */ 28 | 29 | module conbus #( 30 | parameter ADDR_WIDTH = "mandatory" , 31 | parameter DATA_WIDTH = "mandatory" , 32 | parameter s_addr_w = 4 , 33 | parameter s0_addr = 4'h0, 34 | parameter s1_addr = 4'h1, 35 | parameter s2_addr = 4'h2, 36 | parameter s3_addr = 4'h3, 37 | parameter s4_addr = 4'h5, 38 | parameter s5_addr = 4'h6, 39 | parameter s6_addr = 4'h7, 40 | parameter s7_addr = 4'h8 41 | ) ( 42 | input sys_clk , 43 | input sys_rst , 44 | // Master 0 Interface 45 | input [DATA_WIDTH-1:0] m0_dat_i, 46 | output [DATA_WIDTH-1:0] m0_dat_o, 47 | input [ADDR_WIDTH-1:0] m0_adr_i, 48 | input [ 2:0] m0_cti_i, 49 | input [ 1:0] m0_sel_i, 50 | input m0_we_i , 51 | input m0_cyc_i, 52 | input m0_stb_i, 53 | output m0_ack_o, 54 | // Master 1 Interface 55 | input [DATA_WIDTH-1:0] m1_dat_i, 56 | output [DATA_WIDTH-1:0] m1_dat_o, 57 | input [ADDR_WIDTH-1:0] m1_adr_i, 58 | input [ 2:0] m1_cti_i, 59 | input [ 1:0] m1_sel_i, 60 | input m1_we_i , 61 | input m1_cyc_i, 62 | input m1_stb_i, 63 | output m1_ack_o, 64 | // Slave 0 Interface 65 | input [DATA_WIDTH-1:0] s0_dat_i, 66 | output [DATA_WIDTH-1:0] s0_dat_o, 67 | output [ADDR_WIDTH-1:0] s0_adr_o, 68 | output [ 2:0] s0_cti_o, 69 | output [ 1:0] s0_sel_o, 70 | output s0_we_o , 71 | output s0_cyc_o, 72 | output s0_stb_o, 73 | input s0_ack_i, 74 | // Slave 1 Interface 75 | input [DATA_WIDTH-1:0] s1_dat_i, 76 | output [DATA_WIDTH-1:0] s1_dat_o, 77 | output [ADDR_WIDTH-1:0] s1_adr_o, 78 | output [ 2:0] s1_cti_o, 79 | output [ 1:0] s1_sel_o, 80 | output s1_we_o , 81 | output s1_cyc_o, 82 | output s1_stb_o, 83 | input s1_ack_i, 84 | // Slave 2 Interface 85 | input [DATA_WIDTH-1:0] s2_dat_i, 86 | output [DATA_WIDTH-1:0] s2_dat_o, 87 | output [ADDR_WIDTH-1:0] s2_adr_o, 88 | output [ 2:0] s2_cti_o, 89 | output [ 1:0] s2_sel_o, 90 | output s2_we_o , 91 | output s2_cyc_o, 92 | output s2_stb_o, 93 | input s2_ack_i, 94 | // Slave 3 Interface 95 | input [DATA_WIDTH-1:0] s3_dat_i, 96 | output [DATA_WIDTH-1:0] s3_dat_o, 97 | output [ADDR_WIDTH-1:0] s3_adr_o, 98 | output [ 2:0] s3_cti_o, 99 | output [ 1:0] s3_sel_o, 100 | output s3_we_o , 101 | output s3_cyc_o, 102 | output s3_stb_o, 103 | input s3_ack_i, 104 | // Slave 4 Interface 105 | input [DATA_WIDTH-1:0] s4_dat_i, 106 | output [DATA_WIDTH-1:0] s4_dat_o, 107 | output [ADDR_WIDTH-1:0] s4_adr_o, 108 | output [ 2:0] s4_cti_o, 109 | output [ 1:0] s4_sel_o, 110 | output s4_we_o , 111 | output s4_cyc_o, 112 | output s4_stb_o, 113 | input s4_ack_i, 114 | // Slave 5 Interface 115 | input [DATA_WIDTH-1:0] s5_dat_i, 116 | output [DATA_WIDTH-1:0] s5_dat_o, 117 | output [ADDR_WIDTH-1:0] s5_adr_o, 118 | output [ 2:0] s5_cti_o, 119 | output [ 1:0] s5_sel_o, 120 | output s5_we_o , 121 | output s5_cyc_o, 122 | output s5_stb_o, 123 | input s5_ack_i, 124 | // Slave 6 Interface 125 | input [DATA_WIDTH-1:0] s6_dat_i, 126 | output [DATA_WIDTH-1:0] s6_dat_o, 127 | output [ADDR_WIDTH-1:0] s6_adr_o, 128 | output [ 2:0] s6_cti_o, 129 | output [ 1:0] s6_sel_o, 130 | output s6_we_o , 131 | output s6_cyc_o, 132 | output s6_stb_o, 133 | input s6_ack_i, 134 | // Slave 7 Interface 135 | input [DATA_WIDTH-1:0] s7_dat_i, 136 | output [DATA_WIDTH-1:0] s7_dat_o, 137 | output [ADDR_WIDTH-1:0] s7_adr_o, 138 | output [ 2:0] s7_cti_o, 139 | output [ 1:0] s7_sel_o, 140 | output s7_we_o , 141 | output s7_cyc_o, 142 | output s7_stb_o, 143 | input s7_ack_i 144 | ); 145 | 146 | // address + CTI + data + byte select 147 | // + cyc + we + stb 148 | `define mbusw_ls ADDR_WIDTH + 3 + DATA_WIDTH + 2 + 3 149 | 150 | wire [ 7:0] slave_sel; 151 | wire [ 1:0] gnt ; 152 | wire [`mbusw_ls -1:0] i_bus_m ; // internal shared bus, master data and control to slave 153 | wire [DATA_WIDTH-1:0] i_dat_s ; // internal shared bus, slave data to master 154 | wire i_bus_ack; // internal shared bus, ack signal 155 | 156 | // master 0 157 | assign m0_dat_o = i_dat_s; 158 | assign m0_ack_o = i_bus_ack & gnt[0]; 159 | 160 | // master 1 161 | assign m1_dat_o = i_dat_s; 162 | assign m1_ack_o = i_bus_ack & gnt[1]; 163 | 164 | assign i_bus_ack = s0_ack_i | s1_ack_i | s2_ack_i | s3_ack_i | s4_ack_i | s5_ack_i | s6_ack_i | s7_ack_i; 165 | 166 | // slave 0 167 | assign {s0_adr_o, s0_cti_o, s0_sel_o, s0_dat_o, s0_we_o, s0_cyc_o} = i_bus_m[`mbusw_ls -1:1]; 168 | assign s0_stb_o = i_bus_m[1] & i_bus_m[0] & slave_sel[0]; // stb_o = cyc_i & stb_i & slave_sel 169 | 170 | // slave 1 171 | assign {s1_adr_o, s1_cti_o, s1_sel_o, s1_dat_o, s1_we_o, s1_cyc_o} = i_bus_m[`mbusw_ls -1:1]; 172 | assign s1_stb_o = i_bus_m[1] & i_bus_m[0] & slave_sel[1]; 173 | 174 | // slave 2 175 | assign {s2_adr_o, s2_cti_o, s2_sel_o, s2_dat_o, s2_we_o, s2_cyc_o} = i_bus_m[`mbusw_ls -1:1]; 176 | assign s2_stb_o = i_bus_m[1] & i_bus_m[0] & slave_sel[2]; 177 | 178 | // slave 3 179 | assign {s3_adr_o, s3_cti_o, s3_sel_o, s3_dat_o, s3_we_o, s3_cyc_o} = i_bus_m[`mbusw_ls -1:1]; 180 | assign s3_stb_o = i_bus_m[1] & i_bus_m[0] & slave_sel[3]; 181 | 182 | // slave 4 183 | assign {s4_adr_o, s4_cti_o, s4_sel_o, s4_dat_o, s4_we_o, s4_cyc_o} = i_bus_m[`mbusw_ls -1:1]; 184 | assign s4_stb_o = i_bus_m[1] & i_bus_m[0] & slave_sel[4]; 185 | 186 | // slave 5 187 | assign {s5_adr_o, s5_cti_o, s5_sel_o, s5_dat_o, s5_we_o, s5_cyc_o} = i_bus_m[`mbusw_ls -1:1]; 188 | assign s5_stb_o = i_bus_m[1] & i_bus_m[0] & slave_sel[5]; 189 | 190 | // slave 6 191 | assign {s6_adr_o, s6_cti_o, s6_sel_o, s6_dat_o, s6_we_o, s6_cyc_o} = i_bus_m[`mbusw_ls -1:1]; 192 | assign s6_stb_o = i_bus_m[1] & i_bus_m[0] & slave_sel[6]; 193 | 194 | // slave 7 195 | assign {s7_adr_o, s7_cti_o, s7_sel_o, s7_dat_o, s7_we_o, s7_cyc_o} = i_bus_m[`mbusw_ls -1:1]; 196 | assign s7_stb_o = i_bus_m[1] & i_bus_m[0] & slave_sel[7]; 197 | 198 | assign i_bus_m = 199 | ({`mbusw_ls{gnt[0]}} & {m0_adr_i, m0_cti_i, m0_sel_i, m0_dat_i, m0_we_i, m0_cyc_i, m0_stb_i}) 200 | |({`mbusw_ls{gnt[1]}} & {m1_adr_i, m1_cti_i, m1_sel_i, m1_dat_i, m1_we_i, m1_cyc_i, m1_stb_i}); 201 | 202 | assign i_dat_s = 203 | ({16{slave_sel[0]}} & s0_dat_i) 204 | |({16{slave_sel[1]}} & s1_dat_i) 205 | |({16{slave_sel[2]}} & s2_dat_i) 206 | |({16{slave_sel[3]}} & s3_dat_i) 207 | |({16{slave_sel[4]}} & s4_dat_i) 208 | |({16{slave_sel[5]}} & s5_dat_i) 209 | |({16{slave_sel[6]}} & s6_dat_i) 210 | |({16{slave_sel[7]}} & s7_dat_i); 211 | 212 | 213 | wire [1:0] req = {m1_cyc_i, m0_cyc_i}; 214 | 215 | conbus_arb conbus_arb ( 216 | .sys_clk(sys_clk), 217 | .sys_rst(sys_rst), 218 | .req (req ), 219 | .gnt (gnt ) 220 | ); 221 | 222 | wire [`mbusw_ls-1 : `mbusw_ls-s_addr_w] a = (i_bus_m[`mbusw_ls-1 : `mbusw_ls-s_addr_w]); 223 | 224 | wire [3:0] b = s2_addr; 225 | assign slave_sel[0] = (i_bus_m[`mbusw_ls-1 : `mbusw_ls-s_addr_w] == s0_addr); 226 | assign slave_sel[1] = (i_bus_m[`mbusw_ls-1 : `mbusw_ls-s_addr_w] == s1_addr); 227 | assign slave_sel[2] = (i_bus_m[`mbusw_ls-1 : `mbusw_ls-s_addr_w] == s2_addr); 228 | assign slave_sel[3] = (i_bus_m[`mbusw_ls-1 : `mbusw_ls-s_addr_w] == s3_addr); 229 | assign slave_sel[4] = (i_bus_m[`mbusw_ls-1 : `mbusw_ls-s_addr_w] == s4_addr); 230 | assign slave_sel[5] = (i_bus_m[`mbusw_ls-1 : `mbusw_ls-s_addr_w] == s5_addr); 231 | assign slave_sel[6] = (i_bus_m[`mbusw_ls-1 : `mbusw_ls-s_addr_w] == s6_addr); 232 | assign slave_sel[7] = (i_bus_m[`mbusw_ls-1 : `mbusw_ls-s_addr_w] == s7_addr); 233 | 234 | 235 | endmodule 236 | -------------------------------------------------------------------------------- /creator_core/rtl/wb_conbus/conbus_arb.v: -------------------------------------------------------------------------------- 1 | /* 2 | * Milkymist VJ SoC 3 | * Copyright (C) 2007, 2008, 2009, 2010 Sebastien Bourdeauducq 4 | * 5 | * This program is free software: you can redistribute it and/or modify 6 | * it under the terms of the GNU General Public License as published by 7 | * the Free Software Foundation, version 3 of the License. 8 | * 9 | * This program is distributed in the hope that it will be useful, 10 | * but WITHOUT ANY WARRANTY; without even the implied warranty of 11 | * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 12 | * GNU General Public License for more details. 13 | * 14 | * You should have received a copy of the GNU General Public License 15 | * along with this program. If not, see . 16 | */ 17 | 18 | module conbus_arb ( 19 | input sys_clk, 20 | input sys_rst, 21 | input [1:0] req , 22 | output reg [1:0] gnt 23 | ); 24 | 25 | parameter [1:0] grant0 = 2'b01; 26 | parameter [1:0] grant1 = 2'b10; 27 | 28 | reg [1:0] state ; 29 | reg [1:0] next_state; 30 | 31 | initial begin 32 | state = grant0; 33 | end 34 | 35 | always @(posedge sys_clk or posedge sys_rst) begin 36 | if(sys_rst) 37 | state <= grant0; 38 | else 39 | case (state) 40 | grant0 : begin 41 | if (~req[0] & req[1]) 42 | state <= grant1; 43 | else 44 | state <= grant0; 45 | end 46 | grant1 : begin 47 | if (~req[1] & req[0]) 48 | state <= grant0; 49 | else 50 | state <= grant1; 51 | end 52 | default : state <= grant0; 53 | endcase 54 | end 55 | 56 | always @(state) begin 57 | case (state) 58 | grant0 : gnt[1:0] = 2'b01; 59 | grant1 : gnt[1:0] = 2'b10; 60 | default : gnt[1:0] = 2'b01; 61 | endcase 62 | end 63 | endmodule 64 | -------------------------------------------------------------------------------- /creator_core/rtl/wb_everloop/everloop.v: -------------------------------------------------------------------------------- 1 | /* 2 | * Copyright 2016-2020 MATRIX Labs 3 | * MATRIX Labs [http://creator.matrix.one] 4 | * Authors: Kevin Patiño 5 | * 6 | * This file is part of MATRIX Creator HDL for Spartan 6 7 | * 8 | * MATRIX Creator HDL is like free software: you can redistribute 9 | * it and/or modify it under the terms of the GNU General Public License 10 | * as published by the Free Software Foundation, either version 3 of the 11 | * License, or (at your option) any later version. 12 | 13 | * This program is distributed in the hope that it will be useful, but 14 | * WITHOUT ANY WARRANTY; without even the implied warranty of 15 | * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU 16 | * General Public License for more details. 17 | 18 | * You should have received a copy of the GNU General Public License along 19 | * with this program. If not, see . 20 | */ 21 | 22 | module everloop #( 23 | parameter SYS_FREQ_HZ = "mandatory", 24 | parameter DATA_WIDTH = "mandatory", 25 | parameter DATA_PERIOD = 833_000, 26 | parameter ZERO_HIGH_TIME = 300 , 27 | parameter ONE_HIGH_TIME = 600 , 28 | parameter [8:0] DATA_PERIOD_COUNTER = $ceil(SYS_FREQ_HZ/DATA_PERIOD), 29 | parameter [8:0] ZERO_HIGH_COUNTER = $ceil(SYS_FREQ_HZ/($pow(10,9)/(ZERO_HIGH_TIME))), 30 | parameter [8:0] ONE_HIGH_COUNTER = $ceil(SYS_FREQ_HZ/($pow(10,9)/(ONE_HIGH_TIME))) 31 | ) ( 32 | input clk , 33 | input resetn , 34 | input [DATA_WIDTH-1:0] data_everloop , 35 | input data_en , 36 | output reg everloop_control, 37 | output send_complete , 38 | input reset_everloop 39 | ); 40 | 41 | reg [7:0] clk_cnt ; 42 | reg [7:0] data_cnt; 43 | 44 | reg [DATA_WIDTH-1:0] data_register; 45 | 46 | reg shift_enable; 47 | wire s_data ; 48 | 49 | assign send_complete = shift_enable & (data_cnt == DATA_WIDTH); 50 | assign s_data = data_register[DATA_WIDTH-1]; 51 | 52 | always @(posedge clk or posedge resetn) begin 53 | if (resetn | shift_enable) 54 | clk_cnt <= 0; 55 | else 56 | clk_cnt <= clk_cnt + 1; 57 | end 58 | 59 | always @(posedge clk or posedge resetn) begin 60 | if(resetn | reset_everloop) begin 61 | shift_enable <= 0; 62 | data_cnt <= 0; 63 | end else begin 64 | if (clk_cnt == DATA_PERIOD_COUNTER) begin 65 | data_cnt <= data_cnt + 1; 66 | shift_enable <= 1'b1; 67 | end else if(data_cnt == DATA_WIDTH) begin 68 | data_cnt <= 0; 69 | shift_enable <= 0; 70 | end else begin 71 | shift_enable <= 1'b0; 72 | data_cnt <= data_cnt; 73 | end 74 | end 75 | end 76 | 77 | always @(posedge clk or posedge resetn) begin 78 | if(resetn | reset_everloop) begin 79 | data_register <= 0; 80 | end else begin 81 | if(data_en) begin 82 | data_register <= {data_everloop[7:0],data_everloop[DATA_WIDTH-1-:8]}; 83 | end else if(shift_enable) begin 84 | data_register <= data_register << 1; 85 | end else begin 86 | data_register <= data_register; 87 | end 88 | end 89 | end 90 | 91 | always @(posedge clk or posedge resetn) begin 92 | if(resetn | reset_everloop) begin 93 | everloop_control <= 0; 94 | end else begin 95 | case(s_data) 96 | 1'b0 : begin 97 | if(clk_cnt < ZERO_HIGH_COUNTER) begin 98 | everloop_control <= 1; 99 | end else begin 100 | everloop_control <= 0; 101 | end 102 | end 103 | 1'b1 : begin 104 | if(clk_cnt < ONE_HIGH_COUNTER ) begin 105 | everloop_control <= 1; 106 | end else begin 107 | everloop_control <= 0; 108 | end 109 | end 110 | endcase 111 | end 112 | end 113 | 114 | 115 | endmodule 116 | 117 | 118 | 119 | -------------------------------------------------------------------------------- /creator_core/rtl/wb_everloop/everloop_bram.v: -------------------------------------------------------------------------------- 1 | /* 2 | * Copyright 2016-2020 MATRIX Labs 3 | * MATRIX Labs [http://creator.matrix.one] 4 | * Authors: Andres Calderon 5 | * Kevin Patiño 6 | * 7 | * This file is part of MATRIX Creator HDL for Spartan 6 8 | * 9 | * MATRIX Creator HDL is like free software: you can redistribute 10 | * it and/or modify it under the terms of the GNU General Public License 11 | * as published by the Free Software Foundation, either version 3 of the 12 | * License, or (at your option) any later version. 13 | 14 | * This program is distributed in the hope that it will be useful, but 15 | * WITHOUT ANY WARRANTY; without even the implied warranty of 16 | * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU 17 | * General Public License for more details. 18 | 19 | * You should have received a copy of the GNU General Public License along 20 | * with this program. If not, see . 21 | */ 22 | 23 | 24 | module everloop_ram #( 25 | parameter MEM_FILE_NAME = "none", 26 | parameter ADDR_WIDTH = "mandatory", 27 | parameter DATA_WIDTH = "mandatory" 28 | )( 29 | input clk, 30 | input we_a, 31 | output reg ack_a, 32 | input [ADDR_WIDTH-1:0] adr_a, 33 | input [DATA_WIDTH-1:0] dat_a, 34 | // read port b 35 | input [ADDR_WIDTH-1:0] adr_b, 36 | output reg [DATA_WIDTH-1:0] dat_b 37 | ); 38 | 39 | localparam DEPTH = (1 << ADDR_WIDTH); 40 | 41 | reg [DATA_WIDTH-1:0] ram[0:DEPTH-1]; 42 | //------------------------------------------------------------------ 43 | // read port B 44 | //------------------------------------------------------------------ 45 | always @(posedge clk) begin 46 | dat_b <= ram[adr_b]; 47 | end 48 | 49 | //------------------------------------------------------------------ 50 | // write port A 51 | //------------------------------------------------------------------ 52 | always @(posedge clk) begin 53 | ack_a <= 0; 54 | if (we_a) begin 55 | ack_a <= 1; 56 | if(~adr_a[0]) 57 | ram[adr_a] <= {dat_a[7:0],dat_a[DATA_WIDTH-1-:8]}; 58 | else 59 | ram[adr_a] <= dat_a; 60 | end 61 | end 62 | 63 | integer i; 64 | initial 65 | begin 66 | for (i = 0; i < DEPTH ; i=i+1) begin 67 | ram[i] = 0; 68 | end 69 | end 70 | 71 | 72 | endmodule 73 | -------------------------------------------------------------------------------- /creator_core/rtl/wb_everloop/everloop_fsm.v: -------------------------------------------------------------------------------- 1 | /* 2 | * Copyright 2016-2020 MATRIX Labs 3 | * MATRIX Labs [http://creator.matrix.one] 4 | * Authors: Kevin Patiño 5 | * 6 | * This file is part of MATRIX Creator HDL for Spartan 6 7 | * 8 | * MATRIX Creator HDL is like free software: you can redistribute 9 | * it and/or modify it under the terms of the GNU General Public License 10 | * as published by the Free Software Foundation, either version 3 of the 11 | * License, or (at your option) any later version. 12 | 13 | * This program is distributed in the hope that it will be useful, but 14 | * WITHOUT ANY WARRANTY; without even the implied warranty of 15 | * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU 16 | * General Public License for more details. 17 | 18 | * You should have received a copy of the GNU General Public License along 19 | * with this program. If not, see . 20 | */ 21 | 22 | module everloop_fsm #( 23 | parameter SYS_FREQ_HZ = "mandatory", 24 | parameter N_LEDS = "mandatory", 25 | parameter RESET_COUNTER = 12000 // uS 26 | )( 27 | input clk, // Clock 28 | input resetn, // Asynchronous reset active low 29 | 30 | input send_complete, 31 | 32 | output reg read_en, 33 | 34 | output reg [7:0] read_count, 35 | 36 | output reset_everloop 37 | ); 38 | 39 | reg [2:0] state; 40 | reg reset_count_en; 41 | 42 | assign reset_everloop = reset_count_en; 43 | 44 | localparam [1:0] S_IDLE = 3'd0; 45 | localparam [1:0] S_READ = 3'd1; 46 | localparam [1:0] S_DATA = 3'd2; 47 | 48 | always @(state) begin 49 | case(state) 50 | S_IDLE :begin 51 | read_en = 0; 52 | reset_count_en = 1; 53 | end 54 | S_READ : begin 55 | read_en = 1; 56 | reset_count_en = 0; 57 | end 58 | S_DATA : begin 59 | read_en = 0; 60 | reset_count_en = 0; 61 | end 62 | default : begin 63 | read_en = 0; 64 | reset_count_en = 0; 65 | end 66 | endcase 67 | end 68 | 69 | reg [13:0] reset_count; 70 | 71 | always @(posedge clk or posedge resetn) begin 72 | if(resetn | ~reset_count_en) begin 73 | reset_count <= 0; 74 | end else begin 75 | if(reset_count_en) 76 | reset_count <= reset_count + 1; 77 | end 78 | end 79 | 80 | 81 | always @(posedge clk or posedge resetn) begin 82 | if(resetn | reset_count_en) begin 83 | read_count <= 0; 84 | end else begin 85 | if(read_en) 86 | read_count <= read_count + 1; 87 | end 88 | end 89 | 90 | always @(posedge clk or posedge resetn) begin 91 | if(resetn) 92 | state <= S_IDLE; 93 | else begin 94 | case(state) 95 | S_IDLE : begin 96 | if(reset_count == RESET_COUNTER) 97 | state <= S_READ; 98 | else 99 | state <= S_IDLE; 100 | end 101 | S_READ : 102 | if(read_count == 2*N_LEDS) 103 | state <= S_IDLE; 104 | else 105 | state <= S_DATA; 106 | S_DATA: 107 | if(send_complete) 108 | state <= S_READ; 109 | else 110 | state <= S_DATA; 111 | default : 112 | state <= S_IDLE; 113 | endcase 114 | end 115 | end 116 | 117 | endmodule 118 | -------------------------------------------------------------------------------- /creator_core/rtl/wb_everloop/init_ram.py: -------------------------------------------------------------------------------- 1 | import os,random 2 | 3 | f = open('image.ram', 'w') 4 | # f.write("{") 5 | 6 | 7 | for j in range(0,2048/4): 8 | RGB=[0,0,0,0] 9 | 10 | for i in range(0,4): 11 | line = RGB[i] 12 | f.write("%02x\n" % line) 13 | 14 | #f.write("{") 15 | f.close(); 16 | -------------------------------------------------------------------------------- /creator_core/rtl/wb_everloop/wb_everloop.v: -------------------------------------------------------------------------------- 1 | /* 2 | * Copyright 2016 3 | * MATRIX Labs [http://creator.matrix.one] 4 | * This file is part of MATRIX Creator HDL for Spartan 6 5 | * 6 | * MATRIX Creator HDL is like free software: you can redistribute 7 | * it and/or modify it under the terms of the GNU General Public License 8 | * as published by the Free Software Foundation, either version 3 of the 9 | * License, or (at your option) any later version. 10 | 11 | * This program is distributed in the hope that it will be useful, but 12 | * WITHOUT ANY WARRANTY; without even the implied warranty of 13 | * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU 14 | * General Public License for more details. 15 | 16 | * You should have received a copy of the GNU General Public License along 17 | * with this program. If not, see . 18 | */ 19 | 20 | module wb_everloop #( 21 | parameter MEM_FILE_NAME = "none" , 22 | parameter SYS_FREQ_HZ = "mandatory", 23 | parameter DATA_WIDTH = "mandatory", 24 | parameter ADDR_WIDTH = "mandatory", 25 | parameter N_LEDS = "mandatory", 26 | parameter MEM_ADDR_WIDTH = 8 27 | ) ( 28 | input clk , 29 | input resetn , 30 | input led_fb , 31 | input wb_stb_i , 32 | input wb_cyc_i , 33 | input wb_we_i , 34 | input [ 1:0] wb_sel_i , 35 | input [ADDR_WIDTH-1:0] wb_adr_i , 36 | input [DATA_WIDTH-1:0] wb_dat_i , 37 | output [DATA_WIDTH-1:0] wb_dat_o , 38 | output wb_ack_o , 39 | //Everloop 40 | output everloop_ctl 41 | ); 42 | 43 | wire wb_rd = wb_stb_i & wb_cyc_i & ~wb_we_i & ~wb_ack_o; 44 | wire wb_wr = wb_stb_i & wb_cyc_i & wb_we_i & ~wb_ack_o ; 45 | 46 | wire [MEM_ADDR_WIDTH-1:0] adr_b; 47 | 48 | wire [DATA_WIDTH-1:0] data_everloop; 49 | reg [DATA_WIDTH-1:0] data_a ; 50 | 51 | wire reset_everloop; 52 | wire read_en ; 53 | 54 | 55 | everloop #( 56 | .SYS_FREQ_HZ(SYS_FREQ_HZ), 57 | .DATA_WIDTH (DATA_WIDTH ) 58 | ) everloop0 ( 59 | .clk (clk ), 60 | .resetn (resetn ), 61 | .send_complete (send_complete ), 62 | .data_everloop (data_everloop ), 63 | .data_en (read_en ), 64 | .everloop_control(everloop_ctl ), 65 | .reset_everloop (reset_everloop) 66 | ); 67 | 68 | everloop_ram #( 69 | .ADDR_WIDTH (MEM_ADDR_WIDTH), 70 | .DATA_WIDTH (DATA_WIDTH ), 71 | .MEM_FILE_NAME(MEM_FILE_NAME ) 72 | ) everloopram0 ( 73 | // write port a 74 | .clk (clk ), 75 | .adr_a(wb_adr_i[MEM_ADDR_WIDTH-1:0]), 76 | .dat_a(wb_dat_i ), 77 | .we_a (wb_wr ), 78 | .ack_a(wb_ack_o ), 79 | // read port b 80 | .adr_b(adr_b ), 81 | .dat_b(data_everloop ) 82 | ); 83 | 84 | everloop_fsm #( 85 | .SYS_FREQ_HZ(SYS_FREQ_HZ), 86 | .N_LEDS (N_LEDS ) 87 | ) everloop_fsm0 ( 88 | .clk (clk ), 89 | .resetn (resetn ), 90 | .send_complete (send_complete ), 91 | .read_en (read_en ), 92 | .read_count (adr_b ), 93 | .reset_everloop(reset_everloop) 94 | ); 95 | 96 | 97 | endmodule 98 | -------------------------------------------------------------------------------- /creator_core/rtl/wb_gpio/core_clk.v: -------------------------------------------------------------------------------- 1 | /* 2 | * Copyright 2016-2020 MATRIX Labs 3 | * MATRIX Labs [http://creator.matrix.one] 4 | * Authors: Andres Calderon 5 | * Kevin Patiño 6 | * 7 | * This file is part of MATRIX Creator HDL for Spartan 6 8 | * 9 | * MATRIX Creator HDL is like free software: you can redistribute 10 | * it and/or modify it under the terms of the GNU General Public License 11 | * as published by the Free Software Foundation, either version 3 of the 12 | * License, or (at your option) any later version. 13 | 14 | * This program is distributed in the hope that it will be useful, but 15 | * WITHOUT ANY WARRANTY; without even the implied warranty of 16 | * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU 17 | * General Public License for more details. 18 | 19 | * You should have received a copy of the GNU General Public License along 20 | * with this program. If not, see . 21 | */ 22 | 23 | module core_clk#( 24 | parameter PRESCALER = 16 25 | )( 26 | input clk, 27 | input rst, 28 | 29 | output reg [PRESCALER-1:0] core_clk); 30 | 31 | initial begin 32 | core_clk = 0; 33 | end 34 | 35 | always @(posedge clk or posedge rst ) begin 36 | if (rst) 37 | core_clk <= 0; 38 | else 39 | core_clk <= core_clk + 1; 40 | end 41 | 42 | endmodule 43 | -------------------------------------------------------------------------------- /creator_core/rtl/wb_gpio/mux_io.v: -------------------------------------------------------------------------------- 1 | /* 2 | * Copyright 2016-2020 MATRIX Labs 3 | * MATRIX Labs [http://creator.matrix.one] 4 | * Authors: Andres Calderon 5 | * Kevin Patiño 6 | * 7 | * This file is part of MATRIX Creator HDL for Spartan 6 8 | * 9 | * MATRIX Creator HDL is like free software: you can redistribute 10 | * it and/or modify it under the terms of the GNU General Public License 11 | * as published by the Free Software Foundation, either version 3 of the 12 | * License, or (at your option) any later version. 13 | 14 | * This program is distributed in the hope that it will be useful, but 15 | * WITHOUT ANY WARRANTY; without even the implied warranty of 16 | * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU 17 | * General Public License for more details. 18 | 19 | * You should have received a copy of the GNU General Public License along 20 | * with this program. If not, see . 21 | */ 22 | 23 | 24 | module mux_io#( 25 | parameter GPIO_WIDTH = 16)( 26 | input [GPIO_WIDTH-1:0] sig1, 27 | input [GPIO_WIDTH-1:0] sig2, 28 | input [GPIO_WIDTH-1:0] select, 29 | output [GPIO_WIDTH-1:0] mux_out); 30 | 31 | genvar i; 32 | generate 33 | for ( i = 0; i < GPIO_WIDTH; i = i + 1 ) 34 | begin:gpio_selector 35 | single_mux mux0( 36 | .sig1(sig1[i]), 37 | .sig2(sig2[i]), 38 | .select(select[i]), 39 | .mux_output(mux_out[i]) 40 | ); 41 | end 42 | endgenerate 43 | 44 | 45 | endmodule 46 | -------------------------------------------------------------------------------- /creator_core/rtl/wb_gpio/pwm.v: -------------------------------------------------------------------------------- 1 | /* 2 | * Copyright 2016-2020 MATRIX Labs 3 | * MATRIX Labs [http://creator.matrix.one] 4 | * Authors: Andres Calderon 5 | * Kevin Patiño 6 | * 7 | * This file is part of MATRIX Creator HDL for Spartan 6 8 | * 9 | * MATRIX Creator HDL is like free software: you can redistribute 10 | * it and/or modify it under the terms of the GNU General Public License 11 | * as published by the Free Software Foundation, either version 3 of the 12 | * License, or (at your option) any later version. 13 | 14 | * This program is distributed in the hope that it will be useful, but 15 | * WITHOUT ANY WARRANTY; without even the implied warranty of 16 | * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU 17 | * General Public License for more details. 18 | 19 | * You should have received a copy of the GNU General Public License along 20 | * with this program. If not, see . 21 | */ 22 | 23 | module pwm #( 24 | parameter CORE_WIDTH = 4 , 25 | parameter PWM_COUNTER_WIDTH = 16 26 | ) ( 27 | input clk , 28 | input rst , 29 | //PWM 30 | input [ PWM_COUNTER_WIDTH-1:0] period, 31 | input [PWM_COUNTER_WIDTH*CORE_WIDTH:0] duty , 32 | output reg [ CORE_WIDTH-1:0] pwm 33 | ); 34 | 35 | 36 | reg[PWM_COUNTER_WIDTH-1:0] counter; 37 | 38 | 39 | initial begin 40 | counter = 0; 41 | pwm = 0; 42 | end 43 | 44 | genvar i; 45 | generate 46 | for(i=0; i < CORE_WIDTH ; i=i+1) begin:pwm_out 47 | always@(*)begin 48 | if(counter < duty[((i+1)*PWM_COUNTER_WIDTH)-1-:16]) 49 | pwm[i] = 1'b1; 50 | else 51 | pwm[i] = 1'b0; 52 | end 53 | end 54 | endgenerate 55 | 56 | always @(posedge clk or posedge rst) begin 57 | if (rst) begin 58 | counter <= 0; 59 | end else begin 60 | if(counter > period ) 61 | counter <= 0; 62 | else 63 | counter <= counter + 1; 64 | end 65 | end 66 | 67 | 68 | 69 | endmodule 70 | 71 | 72 | 73 | -------------------------------------------------------------------------------- /creator_core/rtl/wb_gpio/single_mux.v: -------------------------------------------------------------------------------- 1 | /* 2 | * Copyright 2016-2020 MATRIX Labs 3 | * MATRIX Labs [http://creator.matrix.one] 4 | * Authors: Andres Calderon 5 | * Kevin Patiño 6 | * 7 | * This file is part of MATRIX Creator HDL for Spartan 6 8 | * 9 | * MATRIX Creator HDL is like free software: you can redistribute 10 | * it and/or modify it under the terms of the GNU General Public License 11 | * as published by the Free Software Foundation, either version 3 of the 12 | * License, or (at your option) any later version. 13 | 14 | * This program is distributed in the hope that it will be useful, but 15 | * WITHOUT ANY WARRANTY; without even the implied warranty of 16 | * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU 17 | * General Public License for more details. 18 | 19 | * You should have received a copy of the GNU General Public License along 20 | * with this program. If not, see . 21 | */ 22 | 23 | module single_mux( 24 | input sig1, 25 | input sig2, 26 | input select, 27 | output reg mux_output); 28 | 29 | always @(*)begin 30 | if (select) 31 | mux_output = sig1; 32 | else 33 | mux_output = sig2; 34 | end 35 | 36 | 37 | endmodule 38 | -------------------------------------------------------------------------------- /creator_core/rtl/wb_gpio/timer.v: -------------------------------------------------------------------------------- 1 | /* 2 | * Copyright 2016-2020 MATRIX Labs 3 | * MATRIX Labs [http://creator.matrix.one] 4 | * Authors: Andres Calderon 5 | * Kevin Patiño 6 | * 7 | * This file is part of MATRIX Creator HDL for Spartan 6 8 | * 9 | * MATRIX Creator HDL is like free software: you can redistribute 10 | * it and/or modify it under the terms of the GNU General Public License 11 | * as published by the Free Software Foundation, either version 3 of the 12 | * License, or (at your option) any later version. 13 | 14 | * This program is distributed in the hope that it will be useful, but 15 | * WITHOUT ANY WARRANTY; without even the implied warranty of 16 | * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU 17 | * General Public License for more details. 18 | 19 | * You should have received a copy of the GNU General Public License along 20 | * with this program. If not, see . 21 | */ 22 | module timer #( 23 | parameter CORE_WIDTH = 4, 24 | parameter TIMER_COUNTER_WIDTH = 16 25 | )( 26 | input clk, 27 | input rst, 28 | input ps_clk, 29 | 30 | 31 | //TIMER 32 | 33 | input [CORE_WIDTH-1:0] timer_input, 34 | input [2*CORE_WIDTH-1:0] timer_conf, 35 | output [CORE_WIDTH*TIMER_COUNTER_WIDTH-1:0] timer_result); 36 | 37 | 38 | initial begin 39 | rTimer_input = 0; 40 | enable_signal = 0; 41 | final_signal = 0; 42 | end 43 | 44 | reg [3*CORE_WIDTH-1 : 0] rTimer_input; 45 | 46 | genvar i; 47 | generate 48 | for(i=0 ; i < CORE_WIDTH ; i = i+1) begin:edge_detector 49 | always@(negedge clk) rTimer_input[3*i+2 -: 3] <= {rTimer_input[3*i+1 -: 2], timer_input[i]} ; 50 | end 51 | endgenerate 52 | 53 | wire [CORE_WIDTH-1 : 0]rise_edges; 54 | wire [CORE_WIDTH-1 : 0]fall_edges; 55 | 56 | genvar j; 57 | generate 58 | for(j=0 ; j < CORE_WIDTH ; j = j+1) begin:logic_detector 59 | assign rise_edges[j] = rTimer_input[3*j+2-:2]==2'b01; 60 | assign fall_edges[j] = rTimer_input[3*j+2-:2]==2'b10; 61 | end 62 | endgenerate 63 | 64 | reg [CORE_WIDTH-1:0]enable_signal; 65 | reg [CORE_WIDTH-1:0]final_signal; 66 | 67 | genvar l; 68 | generate 69 | for(l=0 ; l < CORE_WIDTH ; l = l+1) begin:conf_enable_stage 70 | always@(*) begin 71 | case(timer_conf[l]) 72 | 1'b0: enable_signal[l] = rise_edges[l]; 73 | 1'b1: enable_signal[l] = fall_edges[l]; 74 | endcase 75 | end 76 | end 77 | endgenerate 78 | 79 | 80 | genvar m; 81 | generate 82 | for(m=0 ; m < CORE_WIDTH ; m = m+1) begin:conf_final_stage 83 | always@(*) begin 84 | case(timer_conf[m+4]) 85 | 1'b0: final_signal[m] = rise_edges[m]; 86 | 1'b1: final_signal[m] = fall_edges[m]; 87 | endcase 88 | end 89 | end 90 | endgenerate 91 | 92 | 93 | genvar k; 94 | generate 95 | for(k=0 ; k < CORE_WIDTH ; k = k+1) begin:counter_stage 96 | timer_core #( 97 | .TIMER_COUNTER_WIDTH(TIMER_COUNTER_WIDTH) 98 | )timer_core0( 99 | .clk(clk), 100 | .rst(rst), 101 | .ps_clk(ps_clk), 102 | 103 | .enable_signal(enable_signal[k]), 104 | .final_signal(final_signal[k]), 105 | .counter_result(timer_result[16*k+15-:16]) 106 | ); 107 | end 108 | endgenerate 109 | 110 | 111 | endmodule 112 | 113 | 114 | 115 | -------------------------------------------------------------------------------- /creator_core/rtl/wb_gpio/timer_core.v: -------------------------------------------------------------------------------- 1 | /* 2 | * Copyright 2016-2020 MATRIX Labs 3 | * MATRIX Labs [http://creator.matrix.one] 4 | * Authors: Andres Calderon 5 | * Kevin Patiño 6 | * 7 | * This file is part of MATRIX Creator HDL for Spartan 6 8 | * 9 | * MATRIX Creator HDL is like free software: you can redistribute 10 | * it and/or modify it under the terms of the GNU General Public License 11 | * as published by the Free Software Foundation, either version 3 of the 12 | * License, or (at your option) any later version. 13 | 14 | * This program is distributed in the hope that it will be useful, but 15 | * WITHOUT ANY WARRANTY; without even the implied warranty of 16 | * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU 17 | * General Public License for more details. 18 | 19 | * You should have received a copy of the GNU General Public License along 20 | * with this program. If not, see . 21 | */ 22 | module timer_core #( 23 | parameter TIMER_COUNTER_WIDTH = 16 24 | )( 25 | input clk, 26 | input rst, 27 | input ps_clk, 28 | 29 | input enable_signal, 30 | input final_signal, 31 | 32 | //TIMER 33 | output reg [TIMER_COUNTER_WIDTH-1:0] counter_result); 34 | 35 | initial begin 36 | enable_counter = 0; 37 | reset_counter = 0; 38 | done = 0; 39 | counter = 0; 40 | state = 0; 41 | counter_result = 0; 42 | end 43 | 44 | reg [TIMER_COUNTER_WIDTH-1:0] counter; 45 | reg enable_counter; 46 | reg reset_counter; 47 | reg done; 48 | 49 | always @(posedge ps_clk or posedge rst) begin 50 | if(rst|reset_counter) begin 51 | counter <= 0; 52 | end else begin 53 | if(enable_counter) 54 | counter <= counter + 1; 55 | end 56 | end 57 | 58 | always @(negedge clk or posedge rst) begin 59 | if(rst) begin 60 | counter_result <= 0; 61 | end else begin 62 | if(done) 63 | counter_result <= counter; 64 | end 65 | end 66 | 67 | parameter [2:0] S_IDLE = 2'd0; 68 | parameter [2:0] S_COUNTER=2'd1; 69 | parameter [2:0] S_RESULT=2'd2; 70 | 71 | 72 | reg [2:0] state; 73 | 74 | always @(state) begin 75 | case(state) 76 | S_IDLE: 77 | {enable_counter,reset_counter,done} = {1'b0,1'b1,1'b0}; 78 | 79 | S_COUNTER: 80 | {enable_counter,reset_counter,done} = {1'b1,1'b0,1'b0}; 81 | 82 | S_RESULT: 83 | {enable_counter,reset_counter,done} = {1'b0,1'b0,1'b1}; 84 | 85 | default: 86 | {enable_counter,reset_counter,done} = {1'b0,1'b1,1'b0}; 87 | 88 | endcase 89 | end 90 | 91 | 92 | always @(posedge clk or posedge rst) begin 93 | if(rst) 94 | state <= S_IDLE; 95 | else begin 96 | case(state) 97 | S_IDLE: 98 | if( enable_signal ) 99 | state <= S_COUNTER; 100 | else 101 | state <= S_IDLE; 102 | 103 | S_COUNTER: 104 | if( final_signal ) 105 | state <= S_RESULT; 106 | else 107 | state <= S_COUNTER; 108 | 109 | S_RESULT: 110 | state <= S_IDLE; 111 | 112 | 113 | default: 114 | state <= S_IDLE; 115 | endcase 116 | end 117 | end 118 | 119 | 120 | 121 | endmodule 122 | -------------------------------------------------------------------------------- /creator_core/rtl/wb_gpio/wb_gpio.v: -------------------------------------------------------------------------------- 1 | /* 2 | * Copyright 2016-2020 MATRIX Labs 3 | * MATRIX Labs [http://creator.matrix.one] 4 | * Authors: Andres Calderon 5 | * Kevin Patiño 6 | * 7 | * This file is part of MATRIX Creator HDL for Spartan 6 8 | * 9 | * MATRIX Creator HDL is like free software: you can redistribute 10 | * it and/or modify it under the terms of the GNU General Public License 11 | * as published by the Free Software Foundation, either version 3 of the 12 | * License, or (at your option) any later version. 13 | 14 | * This program is distributed in the hope that it will be useful, but 15 | * WITHOUT ANY WARRANTY; without even the implied warranty of 16 | * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU 17 | * General Public License for more details. 18 | 19 | * You should have received a copy of the GNU General Public License along 20 | * with this program. If not, see . 21 | */ 22 | 23 | module wb_gpio #( 24 | parameter ADDR_WIDTH = "mandatory", 25 | parameter DATA_WIDTH = "mandatory", 26 | parameter GPIO_WIDTH = "mandatory" 27 | ) ( 28 | input clk , 29 | input rst , 30 | //WishBone Interface 31 | input [ADDR_WIDTH-1:0] wb_adr_i, 32 | input [DATA_WIDTH-1:0] wb_dat_i, 33 | input wb_we_i , 34 | input wb_cyc_i, 35 | input wb_stb_i, 36 | output reg [DATA_WIDTH-1:0] wb_dat_o, 37 | output reg wb_ack_o, 38 | //I/O PORT 39 | inout [ GPIO_WIDTH-1:0] gpio_io 40 | ); 41 | 42 | parameter PRESCALER_WIDTH = 4; 43 | 44 | parameter PWM_STAGES = 4 ; 45 | parameter PWM_CORE_WIDTH = 4 ; 46 | parameter PWM_COUNTER_WIDTH = 16; 47 | 48 | parameter TIMER_STAGES = 1 ; 49 | parameter TIMER_CORE_WIDTH = 4 ; 50 | parameter TIMER_COUNTER_WIDTH = 16; 51 | //Intial Stage 52 | 53 | initial begin 54 | wb_dat_o = 0; 55 | gpio_dir = 0; 56 | gpio_out = 0; 57 | gpio_function = 0; 58 | core_prescaler = 0; 59 | core_clk_bank = 0; 60 | end 61 | 62 | reg [ GPIO_WIDTH-1:0] gpio_dir ; 63 | reg [ GPIO_WIDTH-1:0] gpio_out ; 64 | reg [ GPIO_WIDTH-1:0] gpio_function ; 65 | reg [PWM_STAGES*PRESCALER_WIDTH-1:0] core_prescaler ; 66 | reg [ DATA_WIDTH-1:0] pwm_period [ 0:PWM_STAGES-1]; 67 | reg [ DATA_WIDTH-1:0] pwm_duty [0:4*PWM_STAGES-1]; 68 | 69 | //Wisbone logical Interface 70 | wire wb_rd = wb_stb_i & wb_cyc_i & ~wb_we_i & ~wb_ack_o; 71 | wire wb_wr = wb_stb_i & wb_cyc_i & wb_we_i & ~wb_ack_o ; 72 | // Internal GPIO registers 73 | wire [GPIO_WIDTH-1:0] gpio_o; 74 | wire [GPIO_WIDTH-1:0] gpio_i; 75 | 76 | // Tristate logic for IO 77 | genvar i; 78 | generate 79 | for (i=0;i 5 | * Kevin Patiño 6 | * 7 | * This file is part of MATRIX Creator HDL for Spartan 6 8 | * 9 | * MATRIX Creator HDL is like free software: you can redistribute 10 | * it and/or modify it under the terms of the GNU General Public License 11 | * as published by the Free Software Foundation, either version 3 of the 12 | * License, or (at your option) any later version. 13 | 14 | * This program is distributed in the hope that it will be useful, but 15 | * WITHOUT ANY WARRANTY; without even the implied warranty of 16 | * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU 17 | * General Public License for more details. 18 | 19 | * You should have received a copy of the GNU General Public License along 20 | * with this program. If not, see . 21 | */ 22 | 23 | module wb_mcu_bram #( 24 | parameter ADDR_WIDTH = "mandatory", 25 | parameter DATA_WIDTH = "mandatory", 26 | parameter MCU_ADDR_WIDTH = 11, 27 | parameter MCU_DATA_WIDTH = 8 28 | ) ( 29 | input clk_i , 30 | //Wishbone interface 31 | input wb_stb_i , 32 | input wb_cyc_i , 33 | input wb_we_i , 34 | input [ ADDR_WIDTH-1:0] wb_adr_i , 35 | output [ DATA_WIDTH-1:0] wb_dat_o , 36 | input [ DATA_WIDTH-1:0] wb_dat_i , 37 | input [ 1:0] wb_sel_i , 38 | //MCU SAM 39 | input mcu_clk , 40 | input mcu_nwe , 41 | input mcu_ncs , 42 | input mcu_nrd , 43 | input [MCU_ADDR_WIDTH-1:0] mcu_addr , //TODO(andres.calderon): parameterize 44 | inout [MCU_DATA_WIDTH-1:0] mcu_sram_data, //TODO(andres.calderon): parameterize 45 | output reg wb_ack_o 46 | ); 47 | 48 | wire wb_rd = wb_stb_i & wb_cyc_i & ~wb_we_i & ~wb_ack_o; 49 | wire wb_wr = wb_cyc_i & wb_stb_i & wb_we_i & ~wb_ack_o; 50 | 51 | always @(posedge clk_i) begin 52 | wb_ack_o <= 0; 53 | if(wb_wr|wb_rd) 54 | wb_ack_o <= 1; 55 | else 56 | wb_ack_o <= 0; 57 | end 58 | 59 | 60 | /* synchronize signals */ 61 | reg mcu_sncs ; 62 | reg mcu_snwe ; 63 | reg [MCU_ADDR_WIDTH-1:0] mcu_buffer_addr; 64 | reg [MCU_DATA_WIDTH-1:0] mcu_buffer_data; 65 | 66 | /* bram interfaz signals */ 67 | reg mcu_we ; 68 | reg mcu_w_st; 69 | 70 | reg [MCU_DATA_WIDTH-1:0] mcu_wdBus; 71 | wire [MCU_DATA_WIDTH-1:0] mcu_rdBus; 72 | 73 | /* interefaz signals assignments */ 74 | wire T = (mcu_nrd | mcu_ncs); 75 | assign mcu_sram_data = T?8'bZ:mcu_rdBus; 76 | 77 | 78 | /* synchronize assignment */ 79 | always @(posedge mcu_clk) 80 | begin 81 | mcu_sncs <= mcu_ncs; 82 | mcu_snwe <= mcu_nwe; 83 | mcu_buffer_data <= mcu_sram_data; 84 | mcu_buffer_addr <= mcu_addr; 85 | end 86 | 87 | /* write access cpu to bram */ 88 | always @(negedge mcu_clk) 89 | begin 90 | mcu_wdBus <= mcu_buffer_data; 91 | case (mcu_w_st) 92 | 0 : begin 93 | mcu_we <= 0; 94 | if (mcu_sncs | mcu_snwe) 95 | mcu_w_st <= 1; 96 | end 97 | 1 : begin 98 | if (~(mcu_sncs | mcu_snwe)) begin 99 | mcu_we <= 1; 100 | mcu_w_st <= 0; 101 | end 102 | else mcu_we <= 0; 103 | end 104 | endcase 105 | end 106 | 107 | RAMB16_S9_S18 ram ( 108 | /* MCU port */ 109 | .CLKA (mcu_clk ), /* Port A Clock */ 110 | .ENA (1'b1 ), /* Port A RAM Enable Input */ 111 | .SSRA (1'b0 ), /* Port A Synchronous Set/Reset Input */ 112 | .WEA (mcu_we ), /* Port A Write Enable Input */ 113 | .DOA (mcu_rdBus ), /* Port A 8-bit Data Output */ 114 | .DOPA ( ), /* Port A 1-bit Parity Output */ 115 | .ADDRA(mcu_buffer_addr ), /* Port A 11-bit Address Input */ 116 | .DIA (mcu_wdBus ), /* Port A 8-bit Data Input */ 117 | .DIPA (1'b0 ), /* Port A 1-bit parity Input */ 118 | 119 | /* Wishbone port */ 120 | .CLKB (clk_i ), /* Port B Clock */ 121 | .ENB (1'b1 ), /* Port B RAM Enable Input */ 122 | .SSRB (1'b0 ), /* Port B Synchronous Set/Reset Input */ 123 | .WEB (wb_wr ), /* Port B Write Enable Input */ 124 | .DOB (wb_dat_o ), /* Port B 8-bit Data Output */ 125 | .DOPB ( ), /* Port B 1-bit Parity Output */ 126 | .ADDRB(wb_adr_i[MCU_ADDR_WIDTH-2:0]), /* Port B MCU_ADDR_WIDTH-1-bit Address Input */ 127 | .DIB (wb_dat_i ), /* Port B 8-bit Data Input */ 128 | .DIPB (2'b00 ) /* Port B 1-bit parity Input */ 129 | ); 130 | 131 | endmodule 132 | -------------------------------------------------------------------------------- /creator_core/rtl/wb_mic_array/cic.v: -------------------------------------------------------------------------------- 1 | /* 2 | * Copyright 2016-2020 MATRIX Labs 3 | * MATRIX Labs [http://creator.matrix.one] 4 | * Authors: Andres Calderon 5 | * Kevin Patiño 6 | * 7 | * This file is part of MATRIX Creator HDL for Spartan 6 8 | * 9 | * MATRIX Creator HDL is like free software: you can redistribute 10 | * it and/or modify it under the terms of the GNU General Public License 11 | * as published by the Free Software Foundation, either version 3 of the 12 | * License, or (at your option) any later version. 13 | 14 | * This program is distributed in the hope that it will be useful, but 15 | * WITHOUT ANY WARRANTY; without even the implied warranty of 16 | * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU 17 | * General Public License for more details. 18 | 19 | * You should have received a copy of the GNU General Public License along 20 | * with this program. If not, see . 21 | */ 22 | 23 | module cic #( 24 | parameter WIDTH="mandatory", 25 | parameter STAGES="mandatory", 26 | parameter CHANNELS="mandatory" 27 | )( 28 | input clk, 29 | input resetn, 30 | input [CHANNELS-1:0] pdm_data, /* MIC_Interface */ 31 | input integrator_enable, 32 | input comb_enable, 33 | input pdm_read_enable, 34 | output [$clog2(CHANNELS)-1:0] channel, 35 | output signed [WIDTH-1:0] data_out, 36 | output write_memory 37 | ); 38 | 39 | wire wr_en,read_en; 40 | 41 | assign write_memory = wr_en & comb_enable; 42 | 43 | localparam signed [WIDTH-1:0] HIGH_LEVEL = 1 ; 44 | localparam signed [WIDTH-1:0] LOW_LEVEL = ~(HIGH_LEVEL)+1; 45 | 46 | //PDM Data 47 | reg signed [WIDTH-1:0] signed_data; 48 | 49 | reg [CHANNELS-1:0] pdm_data_reg; 50 | 51 | always @(posedge clk or posedge resetn) begin 52 | if (resetn) 53 | pdm_data_reg <= {CHANNELS{1'b0}}; 54 | else begin 55 | if (pdm_read_enable) 56 | pdm_data_reg <= pdm_data; 57 | else 58 | pdm_data_reg <= pdm_data_reg; 59 | end 60 | end 61 | 62 | always @(*) begin 63 | case(pdm_data_reg[channel]) 64 | 1'b0 : signed_data = LOW_LEVEL; 65 | 1'b1 : signed_data = HIGH_LEVEL; 66 | endcase 67 | end 68 | 69 | wire signed [WIDTH-1:0] data_int [STAGES:0]; 70 | wire signed [WIDTH-1:0] data_comb[STAGES:0]; 71 | 72 | assign data_int[0] = signed_data; 73 | 74 | cic_op_fsm #( 75 | .WIDTH (WIDTH ), 76 | .CHANNELS(CHANNELS) 77 | ) op_fsm0 ( 78 | .clk (clk ), 79 | .resetn (resetn ), 80 | .enable (integrator_enable), 81 | .read_en(read_en ), 82 | .wr_en (wr_en ), 83 | .channel(channel ) 84 | ); 85 | 86 | genvar i; 87 | generate 88 | for (i=0; i 5 | * Kevin Patiño 6 | * 7 | * This file is part of MATRIX Creator HDL for Spartan 6 8 | * 9 | * MATRIX Creator HDL is like free software: you can redistribute 10 | * it and/or modify it under the terms of the GNU General Public License 11 | * as published by the Free Software Foundation, either version 3 of the 12 | * License, or (at your option) any later version. 13 | 14 | * This program is distributed in the hope that it will be useful, but 15 | * WITHOUT ANY WARRANTY; without even the implied warranty of 16 | * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU 17 | * General Public License for more details. 18 | 19 | * You should have received a copy of the GNU General Public License along 20 | * with this program. If not, see . 21 | */ 22 | 23 | module cic_comb#( 24 | parameter WIDTH = "mandatory", 25 | parameter CHANNELS = "mandatory" 26 | )( 27 | input clk, 28 | input resetn, 29 | input read_en, 30 | input wr_en, 31 | input [$clog2(CHANNELS)-1:0] channel, 32 | input signed [WIDTH-1:0] data_in, 33 | output reg signed [WIDTH-1:0] data_out 34 | ); 35 | 36 | reg signed [WIDTH-1:0] data_in_prev [0:CHANNELS-1]; 37 | reg signed [WIDTH-1:0] data_out_prev[0:CHANNELS-1]; 38 | 39 | localparam [2:0] S_IDLE = 2'd0; 40 | localparam [2:0] S_READ = 2'd1; 41 | localparam [2:0] S_STORE = 2'd2; 42 | 43 | reg signed [WIDTH-1:0] prev; 44 | wire signed [WIDTH-1:0] diff; 45 | 46 | assign diff = data_in - prev; 47 | 48 | always @(posedge clk or posedge resetn) begin 49 | if (resetn) begin 50 | data_out <= 0; 51 | prev <= 0; 52 | end 53 | else begin 54 | case({read_en,wr_en}) 55 | 2'b10 : 56 | begin 57 | data_out <= data_out_prev[channel]; 58 | prev <= data_in_prev[channel]; 59 | end 60 | 2'b01 : 61 | begin 62 | data_in_prev[channel] <= data_in; 63 | data_out_prev[channel] <= diff; 64 | end 65 | default : 66 | data_out <= data_out; 67 | endcase 68 | end 69 | end 70 | 71 | integer i; 72 | initial begin 73 | for (i=0; i 5 | * Kevin Patiño 6 | * 7 | * This file is part of MATRIX Creator HDL for Spartan 6 8 | * 9 | * MATRIX Creator HDL is like free software: you can redistribute 10 | * it and/or modify it under the terms of the GNU General Public License 11 | * as published by the Free Software Foundation, either version 3 of the 12 | * License, or (at your option) any later version. 13 | 14 | * This program is distributed in the hope that it will be useful, but 15 | * WITHOUT ANY WARRANTY; without even the implied warranty of 16 | * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU 17 | * General Public License for more details. 18 | 19 | * You should have received a copy of the GNU General Public License along 20 | * with this program. If not, see . 21 | */ 22 | 23 | module cic_int#( 24 | parameter WIDTH = "mandatory", 25 | parameter CHANNELS = "mandatory" 26 | )( 27 | input clk, 28 | input resetn, 29 | input wr_en, 30 | input read_en, 31 | input [$clog2(CHANNELS)-1:0] channel, 32 | input signed [WIDTH-1:0] data_in, 33 | output reg signed [WIDTH-1:0] data_out 34 | ); 35 | 36 | wire signed [WIDTH-1:0] sum ; 37 | reg signed [WIDTH-1:0] accumulator[0:CHANNELS-1]; 38 | 39 | assign sum = data_out + data_in; 40 | 41 | always @(posedge clk or posedge resetn) begin 42 | if (resetn) 43 | data_out <= 0; 44 | else begin 45 | case({read_en,wr_en}) 46 | 2'b10 : begin 47 | data_out <= accumulator[channel]; 48 | end 49 | 2'b01 : begin 50 | accumulator[channel] <= sum; 51 | data_out <= data_out; 52 | end 53 | default : 54 | data_out <= data_out; 55 | endcase 56 | end 57 | end 58 | 59 | integer i; 60 | initial begin 61 | for (i=0; i 5 | * Kevin Patiño 6 | * 7 | * This file is part of MATRIX Creator HDL for Spartan 6 8 | * 9 | * MATRIX Creator HDL is like free software: you can redistribute 10 | * it and/or modify it under the terms of the GNU General Public License 11 | * as published by the Free Software Foundation, either version 3 of the 12 | * License, or (at your option) any later version. 13 | 14 | * This program is distributed in the hope that it will be useful, but 15 | * WITHOUT ANY WARRANTY; without even the implied warranty of 16 | * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU 17 | * General Public License for more details. 18 | 19 | * You should have received a copy of the GNU General Public License along 20 | * with this program. If not, see . 21 | */ 22 | 23 | module cic_op_fsm#( 24 | parameter WIDTH = "mandatory", 25 | parameter CHANNELS = "mandatory" 26 | )( 27 | input clk, 28 | input resetn, 29 | input enable, 30 | output reg read_en, 31 | output reg wr_en, 32 | output reg [$clog2(CHANNELS)-1:0] channel 33 | ); 34 | 35 | wire channel_en; 36 | 37 | always @(posedge clk or posedge resetn) begin 38 | if (resetn|~enable) 39 | channel <= 0; 40 | else 41 | if (wr_en) 42 | channel <= channel + 1'b1; 43 | end 44 | 45 | localparam [2:0] S_IDLE = 3'd0; 46 | localparam [2:0] S_READ = 3'd1; 47 | localparam [2:0] S_STORE = 3'd2; 48 | 49 | reg [2:0] state; 50 | 51 | always @(state) begin 52 | case(state) 53 | S_IDLE : 54 | {read_en,wr_en} = 3'b00; 55 | S_READ : 56 | {read_en,wr_en} = 2'b10; 57 | S_STORE : 58 | {read_en,wr_en} = 2'b01; 59 | default : 60 | {read_en,wr_en} = 2'b00; 61 | endcase 62 | end 63 | 64 | always @(posedge clk or posedge resetn) begin 65 | if(resetn) 66 | state <= S_IDLE; 67 | else begin 68 | case(state) 69 | S_IDLE : 70 | if(enable) 71 | state <= S_READ; 72 | S_READ : 73 | state <= S_STORE; 74 | S_STORE : 75 | if(enable) 76 | state <= S_READ; 77 | else 78 | state <= S_IDLE; 79 | 80 | default : 81 | state <= S_IDLE; 82 | endcase 83 | end 84 | end 85 | 86 | endmodule 87 | -------------------------------------------------------------------------------- /creator_core/rtl/wb_mic_array/cic_sync.v: -------------------------------------------------------------------------------- 1 | /* 2 | * Copyright 2016-2020 MATRIX Labs 3 | * MATRIX Labs [http://creator.matrix.one] 4 | * Authors: Andres Calderon 5 | * Kevin Patiño 6 | * 7 | * This file is part of MATRIX Creator HDL for Spartan 6 8 | * 9 | * MATRIX Creator HDL is like free software: you can redistribute 10 | * it and/or modify it under the terms of the GNU General Public License 11 | * as published by the Free Software Foundation, either version 3 of the 12 | * License, or (at your option) any later version. 13 | 14 | * This program is distributed in the hope that it will be useful, but 15 | * WITHOUT ANY WARRANTY; without even the implied warranty of 16 | * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU 17 | * General Public License for more details. 18 | 19 | * You should have received a copy of the GNU General Public License along 20 | * with this program. If not, see . 21 | */ 22 | 23 | module cic_sync #( 24 | parameter SYS_FREQ_HZ = "mandatory", 25 | parameter PDM_FREQ_HZ = "mandatory", 26 | parameter CHANNELS = "mandatory", 27 | parameter DATA_WIDTH = "mandatory", 28 | parameter PDM_READING_TIME = "mandatory", 29 | parameter PDM_RATIO = "mandatory", 30 | parameter COUNTER_WIDTH = $clog2(SYS_FREQ_HZ/PDM_FREQ_HZ), 31 | parameter CHANNELS_WIDTH = $clog2(CHANNELS) 32 | ) ( 33 | input clk, 34 | input resetn, 35 | //CIC_Configuration_Register 36 | input [DATA_WIDTH-1:0]sample_rate, 37 | input [$clog2(CHANNELS)-1:0] channel, 38 | 39 | input cic_finish, 40 | output reg pdm_clk, 41 | output reg read_enable, 42 | output reg integrator_enable, 43 | output comb_enable 44 | ); 45 | 46 | localparam [2:0] S_IDLE = 3'd0; 47 | localparam [2:0] S_READING_TIME = 3'd1; 48 | localparam [2:0] S_COMPUTE = 3'd2; 49 | localparam [2:0] S_HOLD = 3'd3; 50 | 51 | 52 | reg [COUNTER_WIDTH:0] sys_count ; 53 | reg [ DATA_WIDTH-1:0] comb_count ; 54 | wire pdm_codition ; 55 | wire comb_condition ; 56 | wire [COUNTER_WIDTH:0] pdm_half_ratio = PDM_RATIO >> 1; 57 | 58 | assign pdm_conndition = (sys_count == PDM_RATIO); 59 | assign comb_condition = (comb_count == sample_rate); 60 | assign comb_enable = comb_condition; 61 | 62 | reg [2:0] state; 63 | 64 | always @(state) begin 65 | case(state) 66 | S_IDLE : 67 | {integrator_enable,read_enable} = {1'b0,1'b0}; 68 | 69 | S_READING_TIME : 70 | {integrator_enable,read_enable}= {1'b0,1'b1}; 71 | 72 | S_COMPUTE : 73 | {integrator_enable,read_enable} = {1'b1,1'b0}; 74 | 75 | S_HOLD : 76 | {integrator_enable,read_enable} = {1'b1,1'b0}; 77 | 78 | default : 79 | {integrator_enable,read_enable} = {1'b0,1'b0}; 80 | endcase 81 | end 82 | 83 | always @(posedge clk or posedge resetn) begin 84 | if(resetn) 85 | state <= S_IDLE; 86 | else begin 87 | case(state) 88 | S_IDLE : 89 | if( sys_count == PDM_READING_TIME) 90 | state <= S_READING_TIME; 91 | else 92 | state <= S_IDLE; 93 | 94 | S_READING_TIME : 95 | state <= S_COMPUTE; 96 | 97 | S_COMPUTE : 98 | state <= S_HOLD; 99 | 100 | S_HOLD : 101 | if(channel == (CHANNELS-1)) 102 | state <= S_IDLE; 103 | else 104 | state <= S_COMPUTE; 105 | default : 106 | state <= S_IDLE; 107 | endcase 108 | end 109 | end 110 | 111 | always @(posedge clk or posedge resetn) begin 112 | if (resetn) 113 | sys_count <= {COUNTER_WIDTH{1'b0}}; 114 | else begin 115 | if (pdm_conndition) 116 | sys_count <= {COUNTER_WIDTH{1'b0}}; 117 | else 118 | sys_count <= sys_count + 1'b1; 119 | end 120 | end 121 | 122 | always @(posedge clk or posedge resetn) begin 123 | if (resetn | pdm_conndition) 124 | pdm_clk <= 1'b1; 125 | else begin 126 | if (sys_count == pdm_half_ratio) 127 | pdm_clk <= 1'b0; 128 | else 129 | pdm_clk <= pdm_clk; 130 | end 131 | end 132 | 133 | always @(posedge clk or posedge resetn) begin 134 | if (resetn) 135 | comb_count <= {COUNTER_WIDTH{1'b0}}; 136 | else 137 | if (pdm_conndition) begin 138 | if(comb_condition) 139 | comb_count <= 0; 140 | else 141 | comb_count <= comb_count + 1; 142 | end 143 | end 144 | 145 | endmodule 146 | -------------------------------------------------------------------------------- /creator_core/rtl/wb_mic_array/fir.v: -------------------------------------------------------------------------------- 1 | /* 2 | * Copyright 2016-2020 MATRIX Labs 3 | * MATRIX Labs [http://creator.matrix.one] 4 | * Authors: Andres Calderon 5 | * Kevin Patiño 6 | * 7 | * This file is part of MATRIX Creator HDL for Spartan 6 8 | * 9 | * MATRIX Creator HDL is like free software: you can redistribute 10 | * it and/or modify it under the terms of the GNU General Public License 11 | * as published by the Free Software Foundation, either version 3 of the 12 | * License, or (at your option) any later version. 13 | 14 | * This program is distributed in the hope that it will be useful, but 15 | * WITHOUT ANY WARRANTY; without even the implied warranty of 16 | * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU 17 | * General Public License for more details. 18 | 19 | * You should have received a copy of the GNU General Public License along 20 | * with this program. If not, see . 21 | */ 22 | 23 | module mic_fir #( 24 | parameter DATA_WIDTH = "mandatory", 25 | parameter CHANNELS = "mandatory", 26 | parameter CHANNELS_WIDTH = "mandatory", 27 | parameter FIR_TAP_WIDTH = "mandatory", 28 | parameter FIR_TAP = "mandatory", 29 | parameter FIR_TAP_ADDR = "mandatory", 30 | parameter FIR_MEM_DATA_ADDR = $clog2(FIR_TAP*CHANNELS) 31 | ) ( 32 | input clk , 33 | input resetn , 34 | input data_load , 35 | input [CHANNELS_WIDTH-1:0] channel , 36 | input ce , 37 | input signed [ DATA_WIDTH-1:0] data_in , 38 | output signed [ DATA_WIDTH-1:0] data_out , 39 | output write_data_mem, 40 | // FIR Coeff 41 | output [ FIR_TAP_ADDR-1:0] coeff_addr , 42 | input signed [ FIR_TAP_WIDTH-1:0] coeff_data 43 | ); 44 | 45 | reg [FIR_MEM_DATA_ADDR-1:0] wr_data_addr; 46 | 47 | wire end_write_data; 48 | assign end_write_data = (&channel) & data_load; 49 | 50 | always @(posedge clk or posedge resetn) begin 51 | if (resetn) 52 | wr_data_addr <= 0; 53 | else begin 54 | if (data_load) 55 | wr_data_addr <= wr_data_addr + 1; 56 | end 57 | end 58 | 59 | wire [FIR_MEM_DATA_ADDR-1:0] wr_addr_deinterlaced; 60 | assign wr_addr_deinterlaced = {wr_data_addr[CHANNELS_WIDTH-1:0],wr_data_addr[FIR_MEM_DATA_ADDR-1:CHANNELS_WIDTH]}; 61 | 62 | wire [FIR_MEM_DATA_ADDR-1:0] data_memory_addr; 63 | wire [ CHANNELS_WIDTH-1:0] pipe_channel ; 64 | wire load_data_memory; 65 | 66 | wire reset_tap ; 67 | reg reset_tap_p1,reset_tap_p2; 68 | 69 | wire write_data ; 70 | reg write_data_p1,write_data_p2; 71 | 72 | fir_pipe_fsm #( 73 | .CHANNELS (CHANNELS ), 74 | .FIR_TAP (FIR_TAP ), 75 | .CHANNELS_WIDTH(CHANNELS_WIDTH) 76 | ) fir_pipe0 ( 77 | .clk (clk ), 78 | .resetn (resetn ), 79 | .end_write_data (end_write_data ), 80 | 81 | .tap_count (coeff_addr ), 82 | .channel_count (pipe_channel ), 83 | .load_data_memory(load_data_memory), 84 | .reset_tap (reset_tap ), 85 | .write_data (write_data ) 86 | ); 87 | 88 | // Pipe LIne Register 89 | wire signed [FIR_TAP_WIDTH-1:0] data_reg_a; 90 | 91 | wire signed [DATA_WIDTH-1:0] data_reg_b; 92 | assign data_reg_a = coeff_data; 93 | 94 | wire [(FIR_MEM_DATA_ADDR-CHANNELS_WIDTH-1):0] read_pointer; 95 | assign read_pointer = coeff_addr+wr_data_addr[FIR_MEM_DATA_ADDR-1:CHANNELS_WIDTH]-1; 96 | 97 | assign data_memory_addr = {pipe_channel,read_pointer}; 98 | 99 | //Data Memory 100 | mic_array_buffer #( 101 | .ADDR_WIDTH(FIR_MEM_DATA_ADDR), 102 | .DATA_WIDTH(DATA_WIDTH ) 103 | ) mic_fir_data0 ( 104 | // write port a 105 | .clk_a(clk ), 106 | .we_a (data_load ), 107 | .adr_a(wr_addr_deinterlaced), 108 | .dat_a(data_in ), 109 | 110 | // read port b 111 | .clk_b(clk ), 112 | .adr_b(data_memory_addr ), 113 | .en_b (load_data_memory ), 114 | .dat_b(data_reg_b ) 115 | ); 116 | 117 | // Pipe line stage 1 118 | always @(posedge clk or posedge resetn) begin 119 | if(resetn) begin 120 | reset_tap_p1 <= 0; 121 | write_data_p1 <= 0; 122 | end else begin 123 | reset_tap_p1 <= reset_tap; 124 | write_data_p1 <= write_data; 125 | end 126 | end 127 | 128 | wire signed [(FIR_TAP_WIDTH+DATA_WIDTH)-1:0] factor_wire; 129 | assign factor_wire = data_reg_a * data_reg_b; 130 | 131 | reg signed [DATA_WIDTH-1:0] data_reg_c; 132 | 133 | // Pipe line stage 2 134 | always @(posedge clk or posedge resetn) begin 135 | if(resetn) begin 136 | data_reg_c <= 0; 137 | reset_tap_p2 <= 0; 138 | write_data_p2 <= 0; 139 | end else begin 140 | write_data_p2 <= write_data_p1; 141 | data_reg_c <= {factor_wire[(FIR_TAP_WIDTH+DATA_WIDTH)-1],factor_wire[(FIR_TAP_WIDTH+DATA_WIDTH)-3:FIR_TAP_WIDTH-1]}; 142 | reset_tap_p2 <= reset_tap_p1; 143 | end 144 | end 145 | 146 | reg signed [DATA_WIDTH-1:0] data_reg_d; 147 | 148 | // Pipe line stage 3 149 | always @(posedge clk or posedge resetn) begin 150 | if(resetn | reset_tap_p2) begin 151 | data_reg_d <= 0; 152 | end else begin 153 | data_reg_d <= (data_reg_d + data_reg_c); 154 | end 155 | end 156 | 157 | assign data_out = data_reg_d; 158 | assign write_data_mem = write_data_p2; 159 | 160 | endmodule 161 | -------------------------------------------------------------------------------- /creator_core/rtl/wb_mic_array/fir_pipe_fsm.v: -------------------------------------------------------------------------------- 1 | /* 2 | * Copyright 2016-2020 MATRIX Labs 3 | * MATRIX Labs [http://creator.matrix.one] 4 | * Authors: Kevin Patiño 5 | * 6 | * This file is part of MATRIX Creator HDL for Spartan 6 7 | * 8 | * MATRIX Creator HDL is like free software: you can redistribute 9 | * it and/or modify it under the terms of the GNU General Public License 10 | * as published by the Free Software Foundation, either version 3 of the 11 | * License, or (at your option) any later version. 12 | 13 | * This program is distributed in the hope that it will be useful, but 14 | * WITHOUT ANY WARRANTY; without even the implied warranty of 15 | * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU 16 | * General Public License for more details. 17 | 18 | * You should have received a copy of the GNU General Public License along 19 | * with this program. If not, see . 20 | */ 21 | 22 | module fir_pipe_fsm #( 23 | parameter CHANNELS = "mandatory", 24 | parameter CHANNELS_WIDTH = "mandatory", 25 | parameter FIR_TAP = "mandatory", 26 | parameter TAP_COUNT_WIDTH = $clog2(FIR_TAP) 27 | ) ( 28 | input clk , 29 | input resetn , 30 | input end_write_data , 31 | output reg [TAP_COUNT_WIDTH-1:0] tap_count , 32 | output reg [ CHANNELS_WIDTH-1:0] channel_count , 33 | output reg load_data_memory, 34 | output reg reset_tap , 35 | output write_data 36 | ); 37 | 38 | reg [2:0] state ; 39 | reg count_en,reset_channel; 40 | 41 | assign write_data = count_en; 42 | 43 | localparam [1:0] S_IDLE = 3'd0; 44 | localparam [1:0] S_PIPE = 3'd1; 45 | localparam [1:0] S_NEXT = 3'd2; 46 | 47 | always @(state) begin 48 | case(state) 49 | S_IDLE : begin 50 | count_en = 0; 51 | reset_tap = 1; 52 | reset_channel = 1; 53 | load_data_memory = 0; 54 | end 55 | S_PIPE : begin 56 | count_en = 0; 57 | reset_tap = 0; 58 | reset_channel = 0; 59 | load_data_memory = 1; 60 | end 61 | S_NEXT : begin 62 | count_en = 1; 63 | reset_tap = 1; 64 | reset_channel = 0; 65 | load_data_memory = 0; 66 | end 67 | default : begin 68 | count_en = 0; 69 | reset_tap = 1; 70 | reset_channel = 1; 71 | load_data_memory = 0; 72 | end 73 | endcase 74 | end 75 | 76 | always @(posedge clk or posedge resetn) begin 77 | if(resetn | reset_tap) begin 78 | tap_count <= 0; 79 | end else begin 80 | tap_count <= tap_count + 1; 81 | end 82 | end 83 | 84 | always @(posedge clk or posedge resetn) begin 85 | if(resetn | reset_channel) begin 86 | channel_count <= 0; 87 | end else begin 88 | if(count_en) 89 | channel_count <= channel_count + 1; 90 | end 91 | end 92 | 93 | always @(posedge clk or posedge resetn) begin 94 | if(resetn) 95 | state <= S_IDLE; 96 | else begin 97 | case(state) 98 | S_IDLE : begin 99 | if(end_write_data) 100 | state <= S_PIPE; 101 | else 102 | state <= S_IDLE; 103 | end 104 | S_PIPE : 105 | if(tap_count == FIR_TAP-1) // PipeLine stages 106 | state <= S_NEXT; 107 | else 108 | state <= S_PIPE; 109 | S_NEXT : 110 | if(channel_count == CHANNELS-1) 111 | state <= S_IDLE; 112 | else 113 | state <= S_PIPE; 114 | default : 115 | state <= S_IDLE; 116 | endcase 117 | end 118 | end 119 | 120 | endmodule 121 | -------------------------------------------------------------------------------- /creator_core/rtl/wb_mic_array/mic_array.v: -------------------------------------------------------------------------------- 1 | /* 2 | * Copyright 2016-2020 MATRIX Labs 3 | * MATRIX Labs [http://creator.matrix.one] 4 | * Authors: Andres Calderon 5 | * Kevin Patiño 6 | * 7 | * This file is part of MATRIX Creator HDL for Spartan 6 8 | * 9 | * MATRIX Creator HDL is like free software: you can redistribute 10 | * it and/or modify it under the terms of the GNU General Public License 11 | * as published by the Free Software Foundation, either version 3 of the 12 | * License, or (at your option) any later version. 13 | 14 | * This program is distributed in the hope that it will be useful, but 15 | * WITHOUT ANY WARRANTY; without even the implied warranty of 16 | * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU 17 | * General Public License for more details. 18 | 19 | * You should have received a copy of the GNU General Public License along 20 | * with this program. If not, see . 21 | */ 22 | 23 | module mic_array #( 24 | // Simple Integrator 25 | parameter SYS_FREQ_HZ = "mandatory", 26 | parameter PDM_FREQ_HZ = "mandatory", 27 | parameter PDM_READING_TIME = "mandatory", 28 | parameter DATA_WIDTH = "mandatory", 29 | parameter ADDR_WIDTH = "mandatory", 30 | parameter PDM_RATIO = "mandatory", 31 | parameter FIR_TAP_WIDTH = "mandatory", 32 | parameter FIR_TAP = "mandatory", 33 | parameter FIR_TAP_ADDR = "mandatory", 34 | parameter CIC_DATA_WIDTH = 23 , 35 | parameter STAGES = 3 , 36 | parameter ADDR_WIDTH_BUFFER = 13 , 37 | parameter CHANNELS = 8 , 38 | parameter CHANNELS_WIDTH = $clog2(CHANNELS) 39 | ) ( 40 | input clk , 41 | input resetn , 42 | input [ CHANNELS-1:0] pdm_data , 43 | output pdm_clk , 44 | input out_clk , 45 | input read_en , 46 | input [ ADDR_WIDTH-1:0] addr_out , 47 | output buffer_selector, 48 | output [ DATA_WIDTH-1:0] data_out , 49 | //Configuration_Registers 50 | input [ DATA_WIDTH-1:0] sample_rate , 51 | input [ DATA_WIDTH-1:0] data_gain , 52 | //FIR Coeff 53 | output [ FIR_TAP_ADDR-1:0] coeff_addr , 54 | input signed [FIR_TAP_WIDTH-1:0] coeff_data 55 | ); 56 | 57 | /* strobe signals */ 58 | wire integrator_enable; 59 | wire comb_enable ; 60 | wire write_memory ; 61 | wire pdm_read_enable ; 62 | 63 | wire signed [CIC_DATA_WIDTH-1:0] data_cic; 64 | 65 | wire [CHANNELS_WIDTH-1:0] channel; 66 | 67 | cic_sync #( 68 | .SYS_FREQ_HZ (SYS_FREQ_HZ ), 69 | .CHANNELS (CHANNELS ), 70 | .DATA_WIDTH (DATA_WIDTH ), 71 | .PDM_FREQ_HZ (PDM_FREQ_HZ ), 72 | .PDM_READING_TIME(PDM_READING_TIME), 73 | .PDM_RATIO (PDM_RATIO ) 74 | ) cic_sync0 ( 75 | .clk (clk ), 76 | .resetn (resetn ), 77 | .pdm_clk (pdm_clk ), 78 | .channel (channel ), 79 | 80 | //CIC_Configuration_Registers 81 | .integrator_enable(integrator_enable), 82 | .sample_rate (sample_rate ), 83 | .read_enable (pdm_read_enable ), 84 | .comb_enable (comb_enable ) 85 | ); 86 | 87 | cic #( 88 | .STAGES (STAGES ), 89 | .WIDTH (CIC_DATA_WIDTH), 90 | .CHANNELS(CHANNELS ) 91 | ) cic0 ( 92 | .clk (clk ), 93 | .resetn (resetn ), 94 | .pdm_data (pdm_data ), 95 | .integrator_enable(integrator_enable), 96 | .comb_enable (comb_enable ), 97 | .data_out (data_cic ), 98 | .channel (channel ), 99 | .pdm_read_enable (pdm_read_enable ), 100 | .write_memory (write_memory ) 101 | ); 102 | 103 | wire[DATA_WIDTH-1:0] data_out_p; 104 | wire write_data ; 105 | reg [DATA_WIDTH-1:0] boundered_data; 106 | 107 | mic_fir #( 108 | .DATA_WIDTH (DATA_WIDTH ), 109 | .CHANNELS (CHANNELS ), 110 | .CHANNELS_WIDTH(CHANNELS_WIDTH), 111 | .FIR_TAP_WIDTH (FIR_TAP_WIDTH ), 112 | .FIR_TAP (FIR_TAP ), 113 | .FIR_TAP_ADDR (FIR_TAP_ADDR ) 114 | ) mic_fir0 ( 115 | .clk (clk ), 116 | .resetn (resetn ), 117 | .data_load (write_memory ), 118 | .channel (channel ), 119 | .ce (write_memory ), 120 | .data_in (boundered_data), 121 | .data_out (data_out_p ), 122 | .write_data_mem(write_data ), 123 | //FIR Coeff 124 | .coeff_addr (coeff_addr ), 125 | .coeff_data (coeff_data ) 126 | ); 127 | 128 | reg [ADDR_WIDTH_BUFFER-1:0] wr_addr; 129 | 130 | always @(posedge clk or posedge resetn) begin 131 | if (resetn) 132 | wr_addr <= 0; 133 | else begin 134 | if (write_data) 135 | wr_addr <= wr_addr + 1; 136 | end 137 | end 138 | 139 | assign buffer_selector = wr_addr[ADDR_WIDTH_BUFFER-1]; 140 | 141 | /* positive overflow detection */ 142 | reg pof; 143 | always @(data_cic) begin 144 | case(data_gain) 145 | 0 : pof = 1'b0; 146 | 1 : pof = data_cic[CIC_DATA_WIDTH-2]; 147 | 2 : pof = |data_cic[(CIC_DATA_WIDTH-2)-:2]; 148 | 3 : pof = |data_cic[(CIC_DATA_WIDTH-2)-:3]; 149 | 4 : pof = |data_cic[(CIC_DATA_WIDTH-2)-:4]; 150 | 5 : pof = |data_cic[(CIC_DATA_WIDTH-2)-:5]; 151 | 6 : pof = |data_cic[(CIC_DATA_WIDTH-2)-:6]; 152 | 7 : pof = |data_cic[(CIC_DATA_WIDTH-2)-:7]; 153 | 8 : pof = |data_cic[(CIC_DATA_WIDTH-2)-:8]; 154 | 9 : pof = |data_cic[(CIC_DATA_WIDTH-2)-:9]; 155 | 10 : pof = |data_cic[(CIC_DATA_WIDTH-2)-:10]; 156 | default : pof = 1'b1; 157 | endcase 158 | end 159 | 160 | /* negative overflow detection */ 161 | reg nof; 162 | always @(data_cic) begin 163 | case(data_gain) 164 | 0 : nof = 1'b0; 165 | 1 : nof = ~data_cic[CIC_DATA_WIDTH-2]; 166 | 2 : nof = ~(&data_cic[(CIC_DATA_WIDTH-2)-:2]); 167 | 3 : nof = ~(&data_cic[(CIC_DATA_WIDTH-2)-:3]); 168 | 4 : nof = ~(&data_cic[(CIC_DATA_WIDTH-2)-:4]); 169 | 5 : nof = ~(&data_cic[(CIC_DATA_WIDTH-2)-:5]); 170 | 6 : nof = ~(&data_cic[(CIC_DATA_WIDTH-2)-:6]); 171 | 7 : nof = ~(&data_cic[(CIC_DATA_WIDTH-2)-:7]); 172 | 8 : nof = ~(&data_cic[(CIC_DATA_WIDTH-2)-:8]); 173 | 9 : nof = ~(&data_cic[(CIC_DATA_WIDTH-2)-:9]); 174 | 10 : nof = ~(&data_cic[(CIC_DATA_WIDTH-2)-:10]); 175 | default : nof = 1'b1; 176 | endcase 177 | end 178 | 179 | always @(data_cic) begin 180 | case({(data_cic[CIC_DATA_WIDTH-1] & nof) , (~data_cic[CIC_DATA_WIDTH-1] & pof) }) 181 | 2'b01 : boundered_data = {1'b0,{(DATA_WIDTH-1){1'b1}}}; /* positive overflow*/ 182 | 2'b10 : boundered_data = {1'b1,{(DATA_WIDTH-1){1'b0}}}; /* negative overflow */ 183 | default : boundered_data = {data_cic[CIC_DATA_WIDTH-1],data_cic[(CIC_DATA_WIDTH-2-data_gain)-:DATA_WIDTH-1]}; 184 | endcase 185 | end 186 | 187 | wire [ADDR_WIDTH_BUFFER-1:0] addr_buffer_read; 188 | assign addr_buffer_read = {~buffer_selector,addr_out[ADDR_WIDTH_BUFFER-2:0]}; 189 | 190 | wire [ADDR_WIDTH_BUFFER-1:0] wr_addr_deinterlaced; 191 | assign wr_addr_deinterlaced = {wr_addr[ADDR_WIDTH_BUFFER-1],wr_addr[CHANNELS_WIDTH-1:0],wr_addr[ADDR_WIDTH_BUFFER-2:CHANNELS_WIDTH]}; 192 | 193 | mic_array_buffer #( 194 | .ADDR_WIDTH(ADDR_WIDTH_BUFFER), 195 | .DATA_WIDTH(DATA_WIDTH ) 196 | ) mic_array_buffer0 ( 197 | // write port a 198 | .clk_a(clk ), 199 | .we_a (write_data ), 200 | .adr_a(wr_addr_deinterlaced), 201 | .dat_a(data_out_p ), 202 | 203 | // read port b 204 | .clk_b(clk ), 205 | .adr_b(addr_buffer_read ), 206 | .en_b (read_en ), 207 | .dat_b(data_out ) 208 | ); 209 | 210 | endmodule 211 | -------------------------------------------------------------------------------- /creator_core/rtl/wb_mic_array/mic_array_buffer.v: -------------------------------------------------------------------------------- 1 | /* 2 | * Copyright 2016-2020 MATRIX Labs 3 | * MATRIX Labs [http://creator.matrix.one] 4 | * Authors: Andres Calderon 5 | * Kevin Patiño 6 | * 7 | * This file is part of MATRIX Creator HDL for Spartan 6 8 | * 9 | * MATRIX Creator HDL is like free software: you can redistribute 10 | * it and/or modify it under the terms of the GNU General Public License 11 | * as published by the Free Software Foundation, either version 3 of the 12 | * License, or (at your option) any later version. 13 | 14 | * This program is distributed in the hope that it will be useful, but 15 | * WITHOUT ANY WARRANTY; without even the implied warranty of 16 | * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU 17 | * General Public License for more details. 18 | 19 | * You should have received a copy of the GNU General Public License along 20 | * with this program. If not, see . 21 | */ 22 | 23 | module mic_array_buffer #( 24 | parameter ADDR_WIDTH = "mandatory", 25 | parameter DATA_WIDTH = 16 26 | ) ( 27 | // write port a 28 | input clk_a, 29 | input we_a , 30 | input [ADDR_WIDTH-1:0] adr_a, 31 | input [DATA_WIDTH-1:0] dat_a, 32 | // read port b 33 | input clk_b, 34 | input [ADDR_WIDTH-1:0] adr_b, 35 | output reg [DATA_WIDTH-1:0] dat_b, 36 | input en_b 37 | ); 38 | 39 | localparam DEPTH = (2 ** ADDR_WIDTH); 40 | 41 | reg [DATA_WIDTH-1:0] ram[0:DEPTH-1]; 42 | //------------------------------------------------------------------ 43 | // write port A 44 | //------------------------------------------------------------------ 45 | always @(posedge clk_a) 46 | begin 47 | if (we_a) 48 | ram[adr_a] <= dat_a; 49 | end 50 | 51 | //------------------------------------------------------------------ 52 | // read port B 53 | //------------------------------------------------------------------ 54 | always @(posedge clk_b) begin 55 | if(en_b) 56 | dat_b <= ram[adr_b]; 57 | else 58 | dat_b <= 0; 59 | end 60 | endmodule 61 | -------------------------------------------------------------------------------- /creator_core/rtl/wb_mic_array/wb_mic_array.v: -------------------------------------------------------------------------------- 1 | /* 2 | * Copyright 2016-2020 MATRIX Labs 3 | * MATRIX Labs [http://creator.matrix.one] 4 | * Authors: Andres Calderon 5 | * Kevin Patiño 6 | * 7 | * This file is part of MATRIX Creator HDL for Spartan 6 8 | * 9 | * MATRIX Creator HDL is like free software: you can redistribute 10 | * it and/or modify it under the terms of the GNU General Public License 11 | * as published by the Free Software Foundation, either version 3 of the 12 | * License, or (at your option) any later version. 13 | 14 | * This program is distributed in the hope that it will be useful, but 15 | * WITHOUT ANY WARRANTY; without even the implied warranty of 16 | * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU 17 | * General Public License for more details. 18 | 19 | * You should have received a copy of the GNU General Public License along 20 | * with this program. If not, see . 21 | */ 22 | /* 23 | Frequency Default Gain 24 | 8000 0 25 | 12000 2 26 | 16000 3 27 | 22500 5 28 | 24000 5 29 | 32000 6 30 | 44100 8 31 | 48000 8 32 | */ 33 | 34 | module wb_mic_array #( 35 | parameter SYS_FREQ_HZ = "mandatory", 36 | parameter ADDR_WIDTH = "mandatory", 37 | parameter DATA_WIDTH = "mandatory", 38 | parameter PDM_FREQ_HZ = "mandatory", 39 | parameter [DATA_WIDTH-1:0] PDM_RATIO = "mandatory", 40 | parameter [DATA_WIDTH-1:0] PDM_READING_TIME = "mandatory", 41 | parameter FIR_TAP = 128 , 42 | parameter FIR_TAP_WIDTH = 16 , 43 | parameter FIR_TAP_ADDR = $clog2(FIR_TAP) 44 | ) ( 45 | input clk , 46 | input resetn , 47 | // MIC_Interface 48 | input [ 7:0] pdm_data , 49 | output pdm_clk , 50 | output irq , 51 | // Wishbone 52 | input wb_clk , 53 | input wb_stb_i , 54 | input wb_cyc_i , 55 | input wb_we_i , 56 | input [ 1:0] wb_sel_i , 57 | input [ADDR_WIDTH-1:0] wb_adr_i , 58 | input [DATA_WIDTH-1:0] wb_dat_i , 59 | output [DATA_WIDTH-1:0] wb_dat_o , 60 | output reg wb_ack_o , 61 | //Configuration Register 62 | input [DATA_WIDTH-1:0] sample_rate, 63 | input [DATA_WIDTH-1:0] data_gain 64 | ); 65 | 66 | wire wb_rd = wb_stb_i & wb_cyc_i & ~wb_we_i & ~wb_ack_o; 67 | wire wb_wr = wb_stb_i & wb_cyc_i & wb_we_i & ~wb_ack_o ; 68 | 69 | wire [DATA_WIDTH-1:0] mic_data; 70 | 71 | wire signed [FIR_TAP_WIDTH-1:0] coeff_data; 72 | wire signed [ FIR_TAP_ADDR-1:0] coeff_addr; 73 | 74 | mic_array #( 75 | .SYS_FREQ_HZ (SYS_FREQ_HZ ), 76 | .DATA_WIDTH (DATA_WIDTH ), 77 | .ADDR_WIDTH (ADDR_WIDTH ), 78 | .PDM_FREQ_HZ (PDM_FREQ_HZ ), 79 | .PDM_READING_TIME(PDM_READING_TIME), 80 | .PDM_RATIO (PDM_RATIO ), 81 | .FIR_TAP_WIDTH (FIR_TAP_WIDTH ), 82 | .FIR_TAP (FIR_TAP ), 83 | .FIR_TAP_ADDR (FIR_TAP_ADDR ) 84 | ) mic_array0 ( 85 | .clk (clk ), 86 | .resetn (resetn ), 87 | // MIC_Interface 88 | .pdm_data (pdm_data ), 89 | .pdm_clk (pdm_clk ), 90 | //Configuration_Register 91 | .sample_rate (sample_rate), 92 | .data_gain (data_gain ), 93 | // Read Interface 94 | .out_clk (wb_clk ), 95 | .read_en (wb_rd ), 96 | .addr_out (wb_adr_i ), 97 | .data_out (mic_data ), 98 | .buffer_selector(irq ), 99 | //FIR Coeff 100 | .coeff_addr (coeff_addr ), 101 | .coeff_data (coeff_data ) 102 | ); 103 | 104 | mic_array_buffer #( 105 | .ADDR_WIDTH(FIR_TAP_ADDR ), 106 | .DATA_WIDTH(FIR_TAP_WIDTH) 107 | ) mic_fir_coeff0 ( 108 | // write port a 109 | .clk_a(clk ), 110 | .we_a (wb_wr ), 111 | .adr_a(wb_adr_i ), 112 | .dat_a(wb_dat_i ), 113 | 114 | // read port b 115 | .clk_b(clk ), 116 | .adr_b(coeff_addr), 117 | .en_b (1'b1 ), 118 | .dat_b(coeff_data) 119 | ); 120 | 121 | assign wb_dat_o = mic_data; 122 | 123 | always @(posedge clk or posedge resetn) begin 124 | if(resetn) begin 125 | wb_ack_o <= 0; 126 | end else begin 127 | wb_ack_o <= 0; 128 | if(wb_rd ^ wb_wr) 129 | wb_ack_o <= 1'b1; 130 | end 131 | end 132 | 133 | endmodule 134 | -------------------------------------------------------------------------------- /creator_core/rtl/wb_spi_slave/spi_slave.v: -------------------------------------------------------------------------------- 1 | /* 2 | * Copyright 2016-2020 MATRIX Labs 3 | * MATRIX Labs [http://creator.matrix.one] 4 | * Authors: Andres Calderon 5 | * Kevin Patiño 6 | * 7 | * This file is part of MATRIX Creator HDL for Spartan 6 8 | * 9 | * MATRIX Creator HDL is like free software: you can redistribute 10 | * it and/or modify it under the terms of the GNU General Public License 11 | * as published by the Free Software Foundation, either version 3 of the 12 | * License, or (at your option) any later version. 13 | 14 | * This program is distributed in the hope that it will be useful, but 15 | * WITHOUT ANY WARRANTY; without even the implied warranty of 16 | * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU 17 | * General Public License for more details. 18 | 19 | * You should have received a copy of the GNU General Public License along 20 | * with this program. If not, see . 21 | */ 22 | 23 | module spi_slave #(parameter DATA_WIDTH = "mandatory") ( 24 | input clk , 25 | input resetn , 26 | // SPI interface 27 | input mosi , 28 | input ss , 29 | input sck , 30 | output miso , 31 | output reg [DATA_WIDTH-1:0] data_bus_r , 32 | input [DATA_WIDTH-1:0] data_bus_w , 33 | output reg data_enable , 34 | output SSEL_active , 35 | input load_data_miso 36 | ); 37 | 38 | // Sync signals 39 | // Sync SCK to the FPGA clock using a 3-bits shift register 40 | reg [2:0] SCKr; always @(negedge clk) SCKr <= {SCKr[1:0], sck}; 41 | 42 | // Sync ss to the FPGA clock using a 3-bits shift register 43 | reg [2:0] SSELr; always @(posedge clk) SSELr <= {SSELr[1:0], ss}; 44 | 45 | // and for MOSI 46 | reg [1:0] MOSIr; always @(posedge clk) MOSIr <= {MOSIr[0], mosi}; 47 | 48 | wire SCK_risingedge = (SCKr[2:1]==2'b01); // now we can detect SCK rising edges 49 | 50 | 51 | assign SSEL_active = ~SSELr[1] ; // SSEL is active low 52 | wire SSEL_startmessage = (SSELr[2:1]==2'b10); // message starts at falling edge 53 | 54 | wire MOSI_data = MOSIr[1]; 55 | 56 | reg [2:0] state ; 57 | reg [4:0] counter ; 58 | reg shift_enable,counter_reset; 59 | 60 | always @(posedge clk or posedge resetn) begin 61 | if (resetn | counter_reset) 62 | counter <= 0; 63 | else begin 64 | if(SCK_risingedge) 65 | counter <= counter + 1; 66 | else 67 | counter <= counter; 68 | end 69 | end 70 | 71 | localparam [2:0] S_IDLE = 3'd0; 72 | localparam [2:0] S_START_WORD = 3'd1; 73 | localparam [2:0] S_SERDES_PRESAMPLE = 3'd2; 74 | localparam [2:0] S_SERDES_SAMPLE = 3'd3; 75 | localparam [2:0] S_COMPLETED = 3'd4; 76 | 77 | always @(posedge clk or posedge resetn) begin 78 | if(resetn) 79 | state <= S_IDLE; 80 | else begin 81 | case(state) 82 | S_IDLE : 83 | if(SSEL_startmessage) 84 | state <= S_START_WORD; 85 | else 86 | state <= S_IDLE; 87 | 88 | S_START_WORD : 89 | if(!SSEL_active) 90 | state <= S_IDLE; 91 | else 92 | state <= S_SERDES_PRESAMPLE; 93 | 94 | S_SERDES_PRESAMPLE : 95 | if(!SSEL_active) 96 | state <= S_IDLE; 97 | else if(SCK_risingedge) 98 | state <= S_SERDES_SAMPLE; 99 | else 100 | state <= S_SERDES_PRESAMPLE; 101 | 102 | S_SERDES_SAMPLE : 103 | if(!SSEL_active) 104 | state <= S_IDLE; 105 | else if(counter==DATA_WIDTH) 106 | state <= S_COMPLETED; 107 | else 108 | state <= S_SERDES_PRESAMPLE; 109 | 110 | S_COMPLETED : 111 | if(!SSEL_active) 112 | state <= S_IDLE; 113 | else 114 | state <= S_START_WORD; 115 | 116 | default : 117 | state <= S_IDLE; 118 | 119 | endcase 120 | end 121 | end 122 | 123 | always @(state) begin 124 | shift_enable = 1'b0; 125 | data_enable = 1'b0; 126 | counter_reset = 1'b0; 127 | 128 | case(state) 129 | S_IDLE : 130 | counter_reset = 1'b1; 131 | 132 | S_SERDES_SAMPLE : 133 | shift_enable = 1'b1; 134 | 135 | S_COMPLETED : begin 136 | data_enable = 1'b1; 137 | counter_reset = 1'b1; 138 | end 139 | 140 | default : begin 141 | shift_enable = 1'b0; 142 | data_enable = 1'b0; 143 | counter_reset = 1'b0; 144 | end 145 | 146 | endcase 147 | end 148 | 149 | always @(posedge clk or posedge resetn) begin 150 | if (resetn| ~SSEL_active) 151 | data_bus_r <= 0; 152 | else begin 153 | if(shift_enable) 154 | data_bus_r <= {data_bus_r[DATA_WIDTH-2:0],MOSI_data}; 155 | else 156 | data_bus_r <= data_bus_r; 157 | end 158 | end 159 | 160 | reg [DATA_WIDTH-1:0] MISOr; 161 | assign miso = MISOr[DATA_WIDTH-1]; 162 | 163 | always @(posedge clk or posedge resetn) begin 164 | if (resetn | ~SSEL_active) 165 | MISOr <= 0; 166 | else begin 167 | if(load_data_miso) 168 | MISOr <= data_bus_w; 169 | else if (shift_enable) 170 | MISOr <= {MISOr[DATA_WIDTH-2:0],1'b0}; 171 | else 172 | MISOr <= MISOr; 173 | end 174 | end 175 | 176 | endmodule 177 | 178 | 179 | -------------------------------------------------------------------------------- /creator_core/rtl/wb_spi_slave/wb_spi_slave.v: -------------------------------------------------------------------------------- 1 | /* 2 | * Copyright 2016-2020 MATRIX Labs 3 | * MATRIX Labs [http://creator.matrix.one] 4 | * Authors: Andres Calderon 5 | * Kevin Patiño 6 | * 7 | * This file is part of MATRIX Creator HDL for Spartan 6 8 | * 9 | * MATRIX Creator HDL is like free software: you can redistribute 10 | * it and/or modify it under the terms of the GNU General Public License 11 | * as published by the Free Software Foundation, either version 3 of the 12 | * License, or (at your option) any later version. 13 | 14 | * This program is distributed in the hope that it will be useful, but 15 | * WITHOUT ANY WARRANTY; without even the implied warranty of 16 | * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU 17 | * General Public License for more details. 18 | 19 | * You should have received a copy of the GNU General Public License along 20 | * with this program. If not, see . 21 | */ 22 | 23 | module wb_spi_slave #( 24 | parameter ADDR_WIDTH = "mandatory", 25 | parameter DATA_WIDTH = "mandatory" 26 | ) ( 27 | input clk, 28 | input resetn, 29 | // SPI interface 30 | input mosi, 31 | input ss, 32 | input sck, 33 | output miso, 34 | // WishBone Interface 35 | input ack, 36 | output [DATA_WIDTH-1:0] data_bus_r, 37 | input [DATA_WIDTH-1:0] data_bus_w, 38 | output reg [ADDR_WIDTH-1:0] addr_bus, 39 | output reg wr, 40 | output reg strobe, 41 | output cycle 42 | ); 43 | // SPI Slave Core 44 | spi_slave #(.DATA_WIDTH(DATA_WIDTH)) spi0 ( 45 | .clk (clk ), 46 | .resetn (resetn ), 47 | 48 | .mosi (mosi ), 49 | .ss (ss ), 50 | .sck (sck ), 51 | .miso (miso ), 52 | 53 | .data_bus_r ({data_bus_r[7:0],data_bus_r[DATA_WIDTH-1:8]}), 54 | .data_bus_w ({data_bus_w[7:0],data_bus_w[DATA_WIDTH-1:8]}), 55 | 56 | .data_enable (data_enable ), 57 | .SSEL_active(spi_active ), 58 | .load_data_miso (ack ) 59 | ); 60 | 61 | reg [3:0] state; 62 | reg rd,addr_enable,addr_inc; 63 | assign cycle = strobe; 64 | 65 | localparam [3:0] S_IDLE = 4'd0; 66 | localparam [3:0] S_ADDRES = 4'd1; 67 | localparam [3:0] S_MODE = 4'd2; 68 | localparam [3:0] S_WRITE = 4'd3; 69 | localparam [3:0] S_READ = 4'd4; 70 | localparam [3:0] S_WAIT = 4'd5; 71 | localparam [3:0] S_WAIT_ACK_RD = 4'd6; 72 | localparam [3:0] S_WAIT_ACK_WR = 4'd7; 73 | localparam [3:0] S_ADDR_INC = 4'd8; 74 | 75 | always @(posedge clk or posedge resetn) begin 76 | if(resetn) 77 | state <= S_IDLE; 78 | else begin 79 | case(state) 80 | S_IDLE : 81 | if(data_enable) 82 | state <= S_ADDRES; 83 | else 84 | state <= S_IDLE; 85 | S_ADDRES : 86 | if(~spi_active) 87 | state <= S_IDLE; 88 | else 89 | state <= S_MODE; 90 | S_MODE : 91 | if(~spi_active) 92 | state <= S_IDLE; 93 | else if (rd_nwr) 94 | state <= S_READ; 95 | else if (~rd_nwr) 96 | state <= S_WAIT; 97 | else 98 | state <= S_MODE; 99 | S_READ : 100 | if(~spi_active) 101 | state <= S_IDLE; 102 | else if (ack) 103 | state <= S_WAIT; 104 | else 105 | state <= S_WAIT_ACK_RD; 106 | S_WAIT : 107 | if(~spi_active) 108 | state <= S_IDLE; 109 | else if (data_enable & ~rd_nwr) 110 | state <= S_WRITE; 111 | else if (data_enable) 112 | state <= S_MODE; 113 | else 114 | state <= S_WAIT; 115 | S_WRITE : 116 | if(~spi_active) 117 | state <= S_IDLE; 118 | else 119 | state <= S_WAIT_ACK_WR; 120 | S_WAIT_ACK_RD : 121 | if(~spi_active) 122 | state <= S_IDLE; 123 | else if(ack & rd_nwr) 124 | state <= S_ADDR_INC; 125 | else 126 | state <= S_WAIT_ACK_RD; 127 | S_WAIT_ACK_WR : 128 | if(~spi_active) 129 | state <= S_IDLE; 130 | else if(ack & ~rd_nwr) 131 | state <= S_ADDR_INC; 132 | else 133 | state <= S_WAIT_ACK_WR; 134 | S_ADDR_INC : 135 | if(~spi_active) 136 | state <= S_IDLE; 137 | else if(rd_nwr) 138 | state <= S_WAIT; 139 | else if(~rd_nwr) 140 | state <= S_MODE; 141 | else 142 | state <= S_IDLE; 143 | default : 144 | state <= S_IDLE; 145 | endcase 146 | end 147 | end 148 | 149 | always @(state) begin 150 | case(state) 151 | S_IDLE : 152 | {addr_enable,wr,rd,strobe,addr_inc} = {1'b0,1'b0,1'b0,1'b0,1'b0}; 153 | S_ADDRES : 154 | {addr_enable,wr,rd,strobe,addr_inc} = {1'b1,1'b0,1'b0,1'b0,1'b0}; 155 | S_MODE : 156 | {addr_enable,wr,rd,strobe,addr_inc} = {1'b0,1'b0,1'b0,1'b0,1'b0}; 157 | S_READ : 158 | {addr_enable,wr,rd,strobe,addr_inc} = {1'b0,1'b0,1'b1,1'b1,1'b0}; 159 | S_WRITE : 160 | {addr_enable,wr,rd,strobe,addr_inc} = {1'b0,1'b1,1'b0,1'b1,1'b0}; 161 | S_WAIT_ACK_RD : 162 | {addr_enable,wr,rd,strobe,addr_inc} = {1'b0,1'b0,1'b1,1'b1,1'b0}; 163 | S_WAIT_ACK_WR : 164 | {addr_enable,wr,rd,strobe,addr_inc} = {1'b0,1'b1,1'b0,1'b1,1'b0}; 165 | S_WAIT : 166 | {addr_enable,wr,rd,strobe,addr_inc} = {1'b0,1'b0,1'b0,1'b0,1'b0}; 167 | S_ADDR_INC : 168 | {addr_enable,wr,rd,strobe,addr_inc} = {1'b0,1'b0,1'b0,1'b0,1'b1}; 169 | default : 170 | {addr_enable,wr,rd,strobe,addr_inc} = {1'b0,1'b0,1'b0,1'b0,1'b0}; 171 | endcase 172 | end 173 | 174 | reg rd_nwr; 175 | 176 | always @(posedge clk or posedge resetn) begin 177 | if (resetn | ~spi_active) begin 178 | addr_bus <= 0; 179 | rd_nwr <= 0; 180 | end 181 | else begin 182 | if(addr_enable) begin 183 | addr_bus <= data_bus_r[DATA_WIDTH-1:1]; 184 | rd_nwr <= data_bus_r[0]; 185 | end else if(addr_inc) 186 | addr_bus <= addr_bus + 1; 187 | else begin 188 | rd_nwr <= rd_nwr; 189 | addr_bus <= addr_bus; 190 | end 191 | end 192 | end 193 | 194 | endmodule 195 | 196 | 197 | -------------------------------------------------------------------------------- /creator_core/rtl/wb_uart/uart.v: -------------------------------------------------------------------------------- 1 | //----------------------------------------------------- 2 | // Design Name : uart 3 | // File Name : uart.v 4 | //----------------------------------------------------- 5 | module uart #( 6 | parameter SYS_FREQ_HZ = 100000000, 7 | parameter BAUD_RATE = 115200 8 | ) ( 9 | input resetn , 10 | input clk , 11 | // UART lines 12 | input uart_rxd, 13 | output reg uart_txd, 14 | // 15 | output reg [7:0] rx_data , 16 | output reg rx_avail, 17 | output reg rx_error, 18 | input rx_ack , 19 | input [7:0] tx_data , 20 | input tx_wr , 21 | output reg tx_busy 22 | ); 23 | 24 | localparam divisor = SYS_FREQ_HZ/BAUD_RATE/16; 25 | //----------------------------------------------------------------- 26 | // enable16 generator 27 | //----------------------------------------------------------------- 28 | reg [15:0] enable16_counter; 29 | 30 | wire enable16; 31 | assign enable16 = (enable16_counter == 0); 32 | 33 | always @(posedge clk) 34 | begin 35 | if (resetn) begin 36 | enable16_counter <= divisor-1; 37 | end else begin 38 | enable16_counter <= enable16_counter - 1; 39 | if (enable16_counter == 0) begin 40 | enable16_counter <= divisor-1; 41 | end 42 | end 43 | end 44 | 45 | //----------------------------------------------------------------- 46 | // syncronize uart_rxd 47 | //----------------------------------------------------------------- 48 | reg uart_rxd1; 49 | reg uart_rxd2; 50 | 51 | always @(posedge clk) 52 | begin 53 | uart_rxd1 <= uart_rxd; 54 | uart_rxd2 <= uart_rxd1; 55 | end 56 | 57 | //----------------------------------------------------------------- 58 | // UART RX Logic 59 | //----------------------------------------------------------------- 60 | reg rx_busy ; 61 | reg [3:0] rx_count16 ; 62 | reg [3:0] rx_bitcount; 63 | reg [7:0] rxd_reg ; 64 | 65 | always @ (posedge clk) 66 | begin 67 | if (resetn) begin 68 | rx_busy <= 0; 69 | rx_count16 <= 0; 70 | rx_bitcount <= 0; 71 | rx_avail <= 0; 72 | rx_error <= 0; 73 | end else begin 74 | if (rx_ack) begin 75 | rx_avail <= 0; 76 | rx_error <= 0; 77 | end 78 | 79 | if (enable16) begin 80 | if (!rx_busy) begin // look for start bit 81 | if (!uart_rxd2) begin // start bit found 82 | rx_busy <= 1; 83 | rx_count16 <= 7; 84 | rx_bitcount <= 0; 85 | end 86 | end else begin 87 | rx_count16 <= rx_count16 + 1; 88 | 89 | if (rx_count16 == 0) begin // sample 90 | rx_bitcount <= rx_bitcount + 1; 91 | 92 | if (rx_bitcount == 0) begin // verify startbit 93 | if (uart_rxd2) begin 94 | rx_busy <= 0; 95 | end 96 | end else if (rx_bitcount == 9) begin // look for stop bit 97 | rx_busy <= 0; 98 | if (uart_rxd2) begin // stop bit ok 99 | rx_data <= rxd_reg; 100 | rx_avail <= 1; 101 | rx_error <= 0; 102 | end else begin // bad stop bit 103 | rx_error <= 1; 104 | end 105 | end else begin 106 | rxd_reg <= { uart_rxd2, rxd_reg[7:1] }; 107 | end 108 | end 109 | end 110 | end 111 | end 112 | end 113 | 114 | //----------------------------------------------------------------- 115 | // UART TX Logic 116 | //----------------------------------------------------------------- 117 | reg [3:0] tx_bitcount; 118 | reg [3:0] tx_count16 ; 119 | reg [7:0] txd_reg ; 120 | 121 | always @ (posedge clk) 122 | begin 123 | if (resetn) begin 124 | tx_busy <= 0; 125 | uart_txd <= 1; 126 | tx_count16 <= 0; 127 | end else begin 128 | if (tx_wr && !tx_busy) begin 129 | txd_reg <= tx_data; 130 | tx_bitcount <= 0; 131 | tx_count16 <= 0; 132 | tx_busy <= 1; 133 | end 134 | 135 | if (enable16) begin 136 | tx_count16 <= tx_count16 + 1; 137 | 138 | if ((tx_count16 == 0) && tx_busy) begin 139 | tx_bitcount <= tx_bitcount + 1; 140 | 141 | if (tx_bitcount == 0) begin 142 | uart_txd <= 'b0; 143 | end else if (tx_bitcount == 9) begin 144 | uart_txd <= 'b1; 145 | end else if (tx_bitcount == 10) begin 146 | tx_bitcount <= 0; 147 | tx_busy <= 0; 148 | end else begin 149 | uart_txd <= txd_reg[0]; 150 | txd_reg <= { 1'b0, txd_reg[7:1] }; 151 | end 152 | end 153 | 154 | end 155 | end 156 | end 157 | 158 | endmodule 159 | -------------------------------------------------------------------------------- /creator_core/rtl/wb_uart/uart_fifo.v: -------------------------------------------------------------------------------- 1 | /* 2 | * Copyright 2016-2020 MATRIX Labs 3 | * MATRIX Labs [http://creator.matrix.one] 4 | * Authors: Andres Calderon 5 | * Kevin Patiño 6 | * 7 | * This file is part of MATRIX Creator HDL for Spartan 6 8 | * 9 | * MATRIX Creator HDL is like free software: you can redistribute 10 | * it and/or modify it under the terms of the GNU General Public License 11 | * as published by the Free Software Foundation, either version 3 of the 12 | * License, or (at your option) any later version. 13 | 14 | * This program is distributed in the hope that it will be useful, but 15 | * WITHOUT ANY WARRANTY; without even the implied warranty of 16 | * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU 17 | * General Public License for more details. 18 | 19 | * You should have received a copy of the GNU General Public License along 20 | * with this program. If not, see . 21 | */ 22 | module uart_fifo #( 23 | parameter ADDRESS_WIDTH = "mandatory", 24 | parameter DATA_WIDTH = "mandatory" 25 | ) ( 26 | input clk , 27 | input resetn , 28 | // write port a 29 | input write_enable, 30 | output reg write_ack , 31 | input [DATA_WIDTH-1:0] data_a , 32 | // read port b 33 | input read_enable , 34 | output reg read_ack , 35 | output reg [DATA_WIDTH-1:0] data_b , 36 | //status 37 | input fifo_flush, 38 | output empty 39 | ); 40 | 41 | reg [ADDRESS_WIDTH-1:0] read_pointer; 42 | reg [ADDRESS_WIDTH-1:0] write_pointer; 43 | 44 | initial begin 45 | write_ack = 0; 46 | end 47 | 48 | localparam DEPTH = (2 ** ADDRESS_WIDTH); 49 | 50 | reg [DATA_WIDTH-1:0] ram[0:DEPTH-1]; 51 | 52 | assign empty = (write_pointer == read_pointer); 53 | 54 | always @(posedge clk or posedge resetn) begin 55 | if(resetn | fifo_flush) begin 56 | read_pointer <= 0; 57 | end else if(read_ack) begin 58 | read_pointer <= read_pointer + 1; 59 | end 60 | end 61 | 62 | always @(posedge clk or posedge resetn) begin 63 | if(resetn | fifo_flush) begin 64 | write_pointer <= 0; 65 | end else if(write_ack ) begin 66 | write_pointer <= write_pointer + 1; 67 | end 68 | end 69 | 70 | //------------------------------------------------------------------ 71 | // write port A 72 | //------------------------------------------------------------------ 73 | always @(posedge clk) begin 74 | write_ack <= 0; 75 | if (write_enable) begin 76 | ram[write_pointer] <= data_a; 77 | write_ack <= 1; 78 | end 79 | end 80 | 81 | //------------------------------------------------------------------ 82 | // read port B 83 | //------------------------------------------------------------------ 84 | always @(posedge clk) begin 85 | read_ack <= 0; 86 | if(read_enable & (~empty)) begin 87 | data_b <= ram[read_pointer]; 88 | read_ack <= 1; 89 | end else 90 | data_b <= data_b; 91 | end 92 | 93 | endmodule // uart_fifo 94 | -------------------------------------------------------------------------------- /creator_core/rtl/wb_uart/uart_fsm.v: -------------------------------------------------------------------------------- 1 | module uart_fsm ( 2 | input clk, // Clock 3 | input resetn, // Asynchronous reset active low 4 | 5 | ); 6 | 7 | 8 | 9 | 10 | 11 | endmodule -------------------------------------------------------------------------------- /creator_core/rtl/wb_uart/wb_uart.v: -------------------------------------------------------------------------------- 1 | /* 2 | * Copyright 2016-2020 MATRIX Labs 3 | * MATRIX Labs [http://creator.matrix.one] 4 | * Authors: Andres Calderon 5 | * Kevin Patiño 6 | * 7 | * This file is part of MATRIX Creator HDL for Spartan 6 8 | * 9 | * MATRIX Creator HDL is like free software: you can redistribute 10 | * it and/or modify it under the terms of the GNU General Public License 11 | * as published by the Free Software Foundation, either version 3 of the 12 | * License, or (at your option) any later version. 13 | 14 | * This program is distributed in the hope that it will be useful, but 15 | * WITHOUT ANY WARRANTY; without even the implied warranty of 16 | * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU 17 | * General Public License for more details. 18 | 19 | * You should have received a copy of the GNU General Public License along 20 | * with this program. If not, see . 21 | */ 22 | 23 | module wb_uart #( 24 | parameter ADDR_WIDTH = "mandatory", 25 | parameter DATA_WIDTH = "mandatory", 26 | parameter SYS_FREQ_HZ = "mandatory", 27 | parameter BAUD_RATE = "mandatory", 28 | parameter FIFO_ADDR_SIZE = 8 , 29 | parameter PULSE_WIDTH = 13 , 30 | parameter UART_DATA_WIDTH = 8 31 | ) ( 32 | input clk , 33 | input resetn , 34 | // Wishbone interface 35 | input wb_stb_i, 36 | input wb_cyc_i, 37 | input wb_we_i , 38 | input [ 3:0] wb_sel_i, 39 | input [ADDR_WIDTH-1:0] wb_adr_i, 40 | input [DATA_WIDTH-1:0] wb_dat_i, 41 | output [DATA_WIDTH-1:0] wb_dat_o, 42 | output wb_ack_o, 43 | // Serial Wires 44 | input uart_rxd, 45 | output uart_txd, 46 | output uart_irq 47 | ); 48 | 49 | wire wb_rd = wb_stb_i & wb_cyc_i & ~wb_we_i & ~wb_ack_o; 50 | wire wb_wr = wb_cyc_i & wb_stb_i & wb_we_i & ~wb_ack_o ; 51 | 52 | //--------------------------------------------------------------------------- 53 | // UART engine 54 | //--------------------------------------------------------------------------- 55 | wire [UART_DATA_WIDTH-1:0] rx_data; 56 | wire [UART_DATA_WIDTH-1:0] tx_data; 57 | 58 | wire rx_avail; 59 | wire rx_error; 60 | wire rx_ack ; 61 | reg tx_wr ; 62 | wire tx_busy ; 63 | 64 | uart #( 65 | .SYS_FREQ_HZ(SYS_FREQ_HZ), 66 | .BAUD_RATE (BAUD_RATE ) 67 | ) uart0 ( 68 | .clk (clk ), 69 | .resetn (resetn ), 70 | .uart_rxd(uart_rxd), 71 | .uart_txd(uart_txd), 72 | .rx_data (rx_data ), 73 | .rx_avail(rx_avail), 74 | .rx_error(rx_error), 75 | .rx_ack (rx_ack ), 76 | .tx_data (tx_data ), 77 | .tx_wr (tx_wr ), 78 | .tx_busy (tx_busy ) 79 | ); 80 | //--------------------------------------------------------------------------- 81 | // FIFO engine 82 | //--------------------------------------------------------------------------- 83 | wire [UART_DATA_WIDTH-1:0] read_data; 84 | 85 | wire read_rx_wishbone; 86 | assign read_rx_wishbone = (wb_adr_i[FIFO_ADDR_SIZE:0]==0) & wb_rd; 87 | 88 | wire fifo_empty ; 89 | wire read_ack ; 90 | reg fifo_flush ; 91 | reg write_enable; 92 | 93 | uart_fifo #( 94 | .ADDRESS_WIDTH(FIFO_ADDR_SIZE ), 95 | .DATA_WIDTH (UART_DATA_WIDTH) 96 | ) uart_fifo0 ( 97 | .clk (clk ), 98 | .resetn (resetn ), 99 | .write_enable(write_enable ), 100 | .write_ack (rx_ack ), 101 | .data_a (rx_data ), 102 | .read_enable (read_rx_wishbone), 103 | .read_ack (read_ack ), 104 | .data_b (read_data ), 105 | .fifo_flush (fifo_flush ), 106 | .empty (fifo_empty ) 107 | ); 108 | 109 | 110 | wire [DATA_WIDTH-1:0] ucr; 111 | assign ucr[7:0] = {7'b0,fifo_empty}; 112 | assign ucr[DATA_WIDTH-1-:8] = {4'b0,tx_busy,rx_error,rx_avail,fifo_empty}; 113 | 114 | reg [DATA_WIDTH-1:0] wb_dat; 115 | assign wb_dat_o = (wb_adr_i[FIFO_ADDR_SIZE:0]==0) ? {ucr[7:0],read_data} : wb_dat ; 116 | 117 | reg wb_ack; 118 | assign wb_ack_o = read_ack | wb_ack ; 119 | 120 | //--------------------------------------------------------------------------- 121 | // IRQ engine 122 | //--------------------------------------------------------------------------- 123 | reg [PULSE_WIDTH-1:0] pulse_width; 124 | 125 | always @(posedge clk or posedge resetn) begin 126 | if(resetn) begin 127 | pulse_width <= 0; 128 | end else begin 129 | if(~fifo_empty) 130 | pulse_width <= pulse_width + 1; 131 | else 132 | pulse_width <= 0; 133 | end 134 | end 135 | 136 | assign uart_irq = pulse_width[PULSE_WIDTH-1]; 137 | 138 | //--------------------------------------------------------------------------- 139 | // STATE MACHINE 140 | //--------------------------------------------------------------------------- 141 | 142 | reg [1:0] state_write; 143 | 144 | localparam [1:0] S_IDLE = 2'd0; 145 | localparam [1:0] S_WRITE_FIFO = 2'd1; 146 | localparam [1:0] S_WAIT = 2'd2; 147 | 148 | always @(state_write) begin 149 | case(state_write) 150 | S_IDLE : 151 | write_enable = 1'b0; 152 | S_WRITE_FIFO : 153 | write_enable = 1'b1; 154 | S_WAIT : 155 | write_enable = 1'b0; 156 | default : 157 | write_enable = 1'b0; 158 | endcase 159 | end 160 | 161 | always @(posedge clk or posedge resetn) begin 162 | if(resetn) 163 | state_write <= S_IDLE; 164 | else begin 165 | case(state_write) 166 | S_IDLE : 167 | if(rx_avail) 168 | state_write <= S_WRITE_FIFO; 169 | else 170 | state_write <= S_IDLE; 171 | S_WRITE_FIFO : 172 | state_write <= S_WAIT; 173 | S_WAIT : 174 | if( ~rx_avail ) 175 | state_write <= S_IDLE; 176 | else 177 | state_write <= S_WAIT; 178 | default : 179 | state_write <= S_IDLE; 180 | endcase 181 | end 182 | end 183 | 184 | assign tx_data = wb_dat_i[7:0]; 185 | 186 | always @(posedge clk or posedge resetn) 187 | begin 188 | if (resetn) begin 189 | wb_ack <= 0; 190 | wb_dat[DATA_WIDTH-1:8] <= {DATA_WIDTH{1'b0}}; 191 | tx_wr <= 0; 192 | fifo_flush <= 0; 193 | end else begin 194 | wb_ack <= 0; 195 | wb_dat[DATA_WIDTH-1:0] <= 16'b0; 196 | tx_wr <= 0; 197 | if (wb_rd & wb_adr_i[FIFO_ADDR_SIZE]) begin 198 | wb_ack <= 1; 199 | case (wb_adr_i[1:0]) 200 | 2'b00 : begin 201 | wb_dat[DATA_WIDTH-1:0] <= ucr; 202 | end 203 | default : begin 204 | wb_dat[DATA_WIDTH-1:0] <= 8'b0; 205 | end 206 | endcase 207 | end else if (wb_wr & wb_adr_i[FIFO_ADDR_SIZE]) begin 208 | wb_ack <= 1; 209 | case (wb_adr_i[1:0]) 210 | 2'b01 : begin 211 | tx_wr <= 1; 212 | end 213 | 2'b10 : begin 214 | fifo_flush <= wb_dat_i[0]; 215 | end 216 | default : begin 217 | tx_wr <= 0; 218 | fifo_flush <= 0; 219 | end 220 | endcase 221 | end 222 | end 223 | end 224 | 225 | endmodule 226 | -------------------------------------------------------------------------------- /creator_core/rtl/wb_zwave_gpio/wb_zwave_gpio.v: -------------------------------------------------------------------------------- 1 | /* 2 | * Copyright 2016-2020 MATRIX Labs 3 | * MATRIX Labs [http://creator.matrix.one] 4 | * Authors: Andres Calderon 5 | * Kevin Patiño 6 | * 7 | * This file is part of MATRIX Creator HDL for Spartan 6 8 | * 9 | * MATRIX Creator HDL is like free software: you can redistribute 10 | * it and/or modify it under the terms of the GNU General Public License 11 | * as published by the Free Software Foundation, either version 3 of the 12 | * License, or (at your option) any later version. 13 | 14 | * This program is distributed in the hope that it will be useful, but 15 | * WITHOUT ANY WARRANTY; without even the implied warranty of 16 | * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU 17 | * General Public License for more details. 18 | 19 | * You should have received a copy of the GNU General Public License along 20 | * with this program. If not, see . 21 | */ 22 | 23 | module wb_zwave_gpio #( 24 | parameter ADDR_WIDTH = "mandatory", 25 | parameter DATA_WIDTH = "mandatory" 26 | ) ( 27 | input clk , 28 | input resetn , 29 | // Wishbone interface 30 | input wb_stb_i , 31 | input wb_cyc_i , 32 | input wb_we_i , 33 | input [ 3:0] wb_sel_i , 34 | input [ADDR_WIDTH-1:0] wb_adr_i , 35 | input [DATA_WIDTH-1:0] wb_dat_i , 36 | output reg [DATA_WIDTH-1:0] wb_dat_o , 37 | output reg wb_ack_o , 38 | // Serial Wires 39 | input zwave_cs , 40 | inout zwave_sck , 41 | inout zwave_mosi , 42 | input zwave_miso , 43 | output reg zwave_nreset 44 | ); 45 | 46 | wire wb_rd = wb_stb_i & wb_cyc_i & ~wb_we_i & ~wb_ack_o; 47 | wire wb_wr = wb_cyc_i & wb_stb_i & wb_we_i & ~wb_ack_o ; 48 | 49 | // Internal Register 50 | reg zwave_dir ; 51 | wire [DATA_WIDTH-1:0] zwave_data; 52 | 53 | // Internal GPIO registers 54 | reg zwave_sck_o ; 55 | reg zwave_mosi_o; 56 | 57 | assign zwave_data = {12'b0,zwave_miso,3'b0}; 58 | 59 | // Tristate logic for IO 60 | assign zwave_sck = zwave_dir ? zwave_sck_o : 1'bz; 61 | assign zwave_mosi = zwave_dir ? zwave_mosi_o : 1'bz; 62 | 63 | always @(posedge clk or posedge resetn) 64 | begin 65 | if (resetn) begin 66 | wb_ack_o <= 0; 67 | zwave_dir <= 0; 68 | zwave_nreset <= 1; 69 | wb_dat_o <= 0; 70 | {zwave_mosi_o,zwave_sck_o} <= 2'b0; 71 | end else begin 72 | wb_ack_o <= 0; 73 | if (wb_rd) begin 74 | wb_ack_o <= 1; 75 | case (wb_adr_i[1:0]) 76 | 2'b00 : begin 77 | wb_dat_o[DATA_WIDTH-1:0] <= zwave_data; 78 | end 79 | 2'b01 : begin 80 | wb_dat_o[DATA_WIDTH-1:0] <= {14'b0,zwave_nreset,zwave_dir}; 81 | end 82 | default : begin 83 | wb_dat_o[DATA_WIDTH-1:0] <= 0; 84 | end 85 | endcase 86 | end else if (wb_wr) begin 87 | wb_ack_o <= 1; 88 | case (wb_adr_i[1:0]) 89 | 2'b00 : begin 90 | {zwave_mosi_o,zwave_sck_o} <= wb_dat_i[2:1]; 91 | end 92 | 2'b01 : begin 93 | zwave_dir <= wb_dat_i[0]; 94 | zwave_nreset <= wb_dat_i[1]; 95 | end 96 | default : begin 97 | {zwave_mosi_o,zwave_sck_o} <= {zwave_mosi_o,zwave_sck_o}; 98 | zwave_nreset <= zwave_nreset; 99 | zwave_dir <= zwave_dir; 100 | end 101 | endcase 102 | end 103 | end 104 | end 105 | 106 | endmodule // wb_zwave_gpio 107 | -------------------------------------------------------------------------------- /creator_core/system.v: -------------------------------------------------------------------------------- 1 | /* 2 | * Copyright 2016 3 | * MATRIX Labs [http://creator.matrix.one] 4 | * This file is part of MATRIX Creator HDL for Spartan 6 5 | * 6 | * MATRIX Creator HDL is like free software: you can redistribute 7 | * it and/or modify it under the terms of the GNU General Public License 8 | * as published by the Free Software Foundation, either version 3 of the 9 | * License, or (at your option) any later version. 10 | 11 | * This program is distributed in the hope that it will be useful, but 12 | * WITHOUT ANY WARRANTY; without even the implied warranty of 13 | * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU 14 | * General Public License for more details. 15 | 16 | * You should have received a copy of the GNU General Public License along 17 | * with this program. If not, see . 18 | */ 19 | 20 | module system #( 21 | parameter EVERLOOP_FILE = "rtl/wb_everloop/image .ram", 22 | parameter ADDR_WIDTH = 15 , 23 | parameter DATA_WIDTH = 16 , 24 | parameter GPIO_WIDTH = 16 , 25 | //General Configuration 26 | parameter SYS_FREQ_HZ = 150_000_000 , 27 | parameter CLKFX_DIVIDE = 1 , 28 | parameter CLKFX_MULTIPLY = 3 , 29 | parameter [ 63:0] VERSION = 64'h44E8_05C3_000A_0001, 30 | //Microphone Configuration 31 | parameter OUT_FREQ_HZ = 16_000 , 32 | parameter PDM_FREQ_HZ = 3_000_000 , /* this frequency must be multiple of 16000, 22000, 44000, 48000 Hz */ 33 | parameter [DATA_WIDTH-1:0] PDM_RATIO = $floor(SYS_FREQ_HZ/PDM_FREQ_HZ)-1, 34 | parameter [DATA_WIDTH-1:0] PDM_READING_TIME = $floor(7*PDM_RATIO/12), 35 | parameter [DATA_WIDTH-1:0] DECIMATION_RATIO = $floor((SYS_FREQ_HZ ) / (OUT_FREQ_HZ * (PDM_RATIO+1)))-1, 36 | parameter [DATA_WIDTH-1:0] DATA_GAIN_DEFAULT = 3 , 37 | // Everloop 38 | parameter [DATA_WIDTH-1:0] N_LEDS = 35 39 | ) ( 40 | input clk_50 , 41 | input resetn , 42 | /* RASPBERRY's SPI interface */ 43 | input mosi , 44 | input ss , 45 | input ss1 , 46 | input sck , 47 | output miso , 48 | /* RASPBERRY's UART interface */ 49 | input uart_rx_pi , 50 | output uart_tx_pi , 51 | /* RASPBERRY's UART interface */ 52 | input ir_tx_pi , 53 | output ir_rx_pi , 54 | /* PDM MIC Array */ 55 | input [ 7:0] pdm_data , 56 | output pdm_clk , 57 | output mic_irq , 58 | /* Everloop */ 59 | output everloop_ctl , 60 | /* MCU SAM */ 61 | input mcu_nwe , 62 | input mcu_ncs , 63 | input mcu_nrd , 64 | input [ 10:0] mcu_addr , //TODO(andres.calderon): parameterize 65 | inout [ 7:0] mcu_sram_data , //TODO(andres.calderon): parameterize 66 | /* IR */ 67 | input ir_rx , 68 | output ir_tx , 69 | output ir_ring , 70 | /* GPIO */ 71 | inout [GPIO_WIDTH-1:0] gpio_io , 72 | //EM358 73 | input zigbee_rx , 74 | output zigbee_tx , 75 | //NFC - SPI Interface 76 | input nfc_miso , 77 | output nfc_mosi , 78 | output nfc_cs , 79 | output nfc_sck , 80 | output nfc_rst , 81 | input nfc_irq , 82 | output nfc_irq_pi , 83 | //Zwave - Serial - SPI 84 | input zwave_rxd , 85 | output zwave_txd , 86 | inout zwave_mosi , 87 | input zwave_miso , 88 | inout zwave_sck , 89 | input zwave_cs , 90 | output zwave_nreset , 91 | // Serial Interruption 92 | output uart_irq , 93 | /* Debug */ 94 | output debug_led , 95 | /* workarounds */ 96 | /* workaround: resetn signal (P105) has disconnected in the v 1.0 rev 1 */ 97 | input i2c_sda , 98 | input i2c_scl , 99 | input nrst_deprecated 100 | ); 101 | 102 | //Set up IR 103 | assign debug_led = ~ir_rx; 104 | assign ir_rx_pi = ir_rx; 105 | assign ir_tx = ir_tx_pi; 106 | assign ir_ring = ir_tx_pi; 107 | //Set up UART-ZWAVE 108 | assign zigbee_tx = uart_rx_pi; 109 | assign uart_tx_pi = zigbee_rx; 110 | //Set up NFC PN512 111 | assign nfc_cs = ss1; 112 | assign nfc_sck = sck; 113 | assign nfc_irq_pi = nfc_irq; 114 | assign nfc_mosi = mosi; 115 | assign nfc_rst = 1'b1; 116 | 117 | // SPI multi-slave logic 118 | wire system_miso; 119 | assign miso = (ss == 0) ? system_miso : (ss1 == 0) ? nfc_miso : 1'b1; 120 | //------------------------------------------------------------------ 121 | // DCM Logic 122 | //------------------------------------------------------------------ 123 | wire clk ; 124 | wire nclk; 125 | creator_dcm #( 126 | .CLKFX_DIVIDE (CLKFX_DIVIDE ), 127 | .CLKFX_MULTIPLY(CLKFX_MULTIPLY) 128 | ) dcm ( 129 | .clkin (clk_50), 130 | .clk_out_200 (clk ), 131 | .nclk_out_200(nclk ), 132 | .clk_out_25 ( ) 133 | ); 134 | //------------------------------------------------------------------ 135 | // Whishbone Wires 136 | //------------------------------------------------------------------ 137 | wire gnd = 1'b0 ; 138 | wire [ 1:0] gnd2 = 4'h0 ; 139 | wire [DATA_WIDTH-1:0] gnd16 = {DATA_WIDTH{1'b0}}; 140 | wire [ADDR_WIDTH-1:0] gnd15 = {ADDR_WIDTH{1'b0}}; 141 | 142 | wire [ADDR_WIDTH-1:0] spi0_adr, 143 | mcu_bram_adr, 144 | uart0_adr, 145 | bram0_adr, 146 | mic_array_adr, 147 | gpio0_adr, 148 | everloop_adr, 149 | zwave_gpio_adr; 150 | 151 | wire [DATA_WIDTH-1:0] spi0_dat_r, 152 | spi0_dat_w, 153 | mcu_bram_r, 154 | mcu_bram_w, 155 | uart0_dat_r, 156 | uart0_dat_w, 157 | bram0_dat_r, 158 | bram0_dat_w, 159 | mic_array_dat_r, 160 | mic_array_dat_w, 161 | gpio0_dat_r, 162 | gpio0_dat_w, 163 | everloop_dat_r, 164 | everloop_dat_w, 165 | zwave_gpio_r, 166 | zwave_gpio_w; 167 | 168 | wire [1:0] mcu_bram_sel, 169 | uart0_sel, 170 | bram0_sel, 171 | gpio0_sel, 172 | mic_array_sel, 173 | everloop_sel, 174 | zwave_gpio_sel; 175 | 176 | wire spi0_we, 177 | mcu_bram_we, 178 | uart0_we, 179 | bram0_we, 180 | gpio0_we, 181 | mic_array_we, 182 | everloop_we, 183 | zwave_gpio_we; 184 | 185 | wire spi0_cyc, 186 | mcu_bram_cyc, 187 | uart0_cyc, 188 | bram0_cyc, 189 | gpio0_cyc, 190 | mic_array_cyc, 191 | everloop_cyc, 192 | zwave_gpio_cyc; 193 | 194 | wire spi0_stb, 195 | mcu_bram_stb, 196 | uart0_stb, 197 | bram0_stb, 198 | gpio0_stb, 199 | mic_array_stb, 200 | everloop_stb, 201 | zwave_gpio_stb; 202 | 203 | wire spi0_ack, 204 | bram0_ack, 205 | mic_array_ack, 206 | everloop_ack, 207 | gpio0_ack, 208 | mcu_bram_ack, 209 | uart0_ack, 210 | zwave_gpio_ack; 211 | 212 | //--------------------------------------------------------------------------- 213 | // Wishbone Interconnect 214 | //--------------------------------------------------------------------------- 215 | conbus #( 216 | .ADDR_WIDTH(ADDR_WIDTH), 217 | .DATA_WIDTH(DATA_WIDTH), 218 | .s_addr_w (3 ), 219 | .s0_addr (3'b000 ), // bram 000 0000 0000 0000 0x0000 220 | .s1_addr (3'b001 ), // uart0 001 0000 0000 0000 0x1000 221 | .s2_addr (3'b010 ), // mic_array 010 0000 0000 0000 0x2000 222 | .s3_addr (3'b011 ), // everloop0 011 0000 0000 0000 0x3000 223 | .s4_addr (3'b100 ), // gpio0 100 0000 0000 0000 0x4000 224 | .s5_addr (3'b101 ), // mcu_bram 101 0000 0000 0000 0x5000 225 | .s6_addr (3'b111 ) // zwave_gpio 111 0000 0000 0000 0x7000 226 | ) conbus0 ( 227 | .sys_clk (clk ), 228 | .sys_rst (resetn ), 229 | // Master0 to the RPi 230 | .m0_dat_i(spi0_dat_r ), 231 | .m0_dat_o(spi0_dat_w ), 232 | .m0_adr_i(spi0_adr ), 233 | .m0_we_i (spi0_we ), 234 | .m0_sel_i(gnd2 ), 235 | .m0_cyc_i(spi0_cyc ), 236 | .m0_stb_i(spi0_stb ), 237 | .m0_cti_i(3'b000 ), 238 | .m0_ack_o(spi0_ack ), 239 | // Master1 240 | .m1_dat_i(gnd16 ), 241 | .m1_adr_i(gnd15 ), 242 | .m1_sel_i(gnd2 ), 243 | .m1_cyc_i(gnd ), 244 | .m1_stb_i(gnd ), 245 | // Slave0 bram 246 | .s0_dat_i(bram0_dat_r ), 247 | .s0_dat_o(bram0_dat_w ), 248 | .s0_adr_o(bram0_adr ), 249 | .s0_sel_o(bram0_sel ), 250 | .s0_we_o (bram0_we ), 251 | .s0_cyc_o(bram0_cyc ), 252 | .s0_stb_o(bram0_stb ), 253 | .s0_ack_i(bram0_ack ), 254 | // Slave1 255 | .s1_dat_i(uart0_dat_r ), 256 | .s1_dat_o(uart0_dat_w ), 257 | .s1_adr_o(uart0_adr ), 258 | .s1_sel_o(uart0_sel ), 259 | .s1_we_o (uart0_we ), 260 | .s1_cyc_o(uart0_cyc ), 261 | .s1_stb_o(uart0_stb ), 262 | .s1_ack_i(uart0_ack ), 263 | // Slave3 mic_array 264 | .s2_dat_i(mic_array_dat_r), 265 | .s2_dat_o(mic_array_dat_w), 266 | .s2_adr_o(mic_array_adr ), 267 | .s2_sel_o(mic_array_sel ), 268 | .s2_we_o (mic_array_we ), 269 | .s2_cyc_o(mic_array_cyc ), 270 | .s2_stb_o(mic_array_stb ), 271 | .s2_ack_i(mic_array_ack ), 272 | // Slave3 Everloop 273 | .s3_dat_i(everloop_dat_r ), 274 | .s3_dat_o(everloop_dat_w ), 275 | .s3_adr_o(everloop_adr ), 276 | .s3_sel_o(everloop_sel ), 277 | .s3_we_o (everloop_we ), 278 | .s3_cyc_o(everloop_cyc ), 279 | .s3_stb_o(everloop_stb ), 280 | .s3_ack_i(everloop_ack ), 281 | // Slave5 282 | .s4_dat_i(gpio0_dat_r ), 283 | .s4_dat_o(gpio0_dat_w ), 284 | .s4_adr_o(gpio0_adr ), 285 | .s4_sel_o(gpio0_sel ), 286 | .s4_we_o (gpio0_we ), 287 | .s4_cyc_o(gpio0_cyc ), 288 | .s4_stb_o(gpio0_stb ), 289 | .s4_ack_i(gpio0_ack ), 290 | // Slave7 291 | .s5_dat_i(mcu_bram_r ), 292 | .s5_dat_o(mcu_bram_w ), 293 | .s5_adr_o(mcu_bram_adr ), 294 | .s5_sel_o(mcu_bram_sel ), 295 | .s5_we_o (mcu_bram_we ), 296 | .s5_cyc_o(mcu_bram_cyc ), 297 | .s5_stb_o(mcu_bram_stb ), 298 | .s5_ack_i(mcu_bram_ack ), 299 | // Slave6 300 | .s6_dat_i(zwave_gpio_r ), 301 | .s6_dat_o(zwave_gpio_w ), 302 | .s6_adr_o(zwave_gpio_adr ), 303 | .s6_sel_o(zwave_gpio_sel ), 304 | .s6_we_o (zwave_gpio_we ), 305 | .s6_cyc_o(zwave_gpio_cyc ), 306 | .s6_stb_o(zwave_gpio_stb ), 307 | .s6_ack_i(zwave_gpio_ack ), 308 | 309 | .s7_ack_i(gnd ), 310 | .s7_dat_i(gnd16 ) 311 | ); 312 | 313 | //--------------------------------------------------------------------------- 314 | // RASPBERRY's SPI INTERFACE 315 | //--------------------------------------------------------------------------- 316 | wb_spi_slave #( 317 | .ADDR_WIDTH(ADDR_WIDTH), 318 | .DATA_WIDTH(DATA_WIDTH) 319 | ) spi0 ( 320 | .clk (clk ), 321 | .resetn (resetn ), 322 | 323 | .mosi (mosi ), 324 | .ss (ss ), 325 | .sck (sck ), 326 | .miso (system_miso), 327 | 328 | .data_bus_r(spi0_dat_r ), 329 | .data_bus_w(spi0_dat_w ), 330 | .addr_bus (spi0_adr ), 331 | .strobe (spi0_stb ), 332 | .cycle (spi0_cyc ), 333 | .wr (spi0_we ), 334 | .ack (spi0_ack ) 335 | ); 336 | 337 | //--------------------------------------------------------------------------- 338 | // Block RAM 339 | //--------------------------------------------------------------------------- 340 | wire [DATA_WIDTH-1:0] mic_sample_rate; 341 | wire [DATA_WIDTH-1:0] mic_data_gain ; 342 | 343 | wb_bram #( 344 | .ADDR_WIDTH (ADDR_WIDTH ), 345 | .DATA_WIDTH (DATA_WIDTH ), 346 | .VERSION (VERSION ), 347 | .CLKFX_DIVIDE (CLKFX_DIVIDE ), 348 | .CLKFX_MULTIPLY (CLKFX_MULTIPLY ), 349 | .DECIMATION_RATIO (DECIMATION_RATIO ), 350 | .DATA_GAIN_DEFAULT(DATA_GAIN_DEFAULT) 351 | ) bram0 ( 352 | .clk (clk ), 353 | .resetn (resetn ), 354 | .wb_adr_i (bram0_adr ), 355 | .wb_dat_o (bram0_dat_r ), 356 | .wb_dat_i (bram0_dat_w ), 357 | .wb_sel_i (bram0_sel ), 358 | .wb_stb_i (bram0_stb ), 359 | .wb_cyc_i (bram0_cyc ), 360 | .wb_we_i (bram0_we ), 361 | .wb_ack_o (bram0_ack ), 362 | // MIC Configuration 363 | .mic_sample_rate(mic_sample_rate), 364 | .mic_data_gain (mic_data_gain ) 365 | ); 366 | //--------------------------------------------------------------------------- 367 | // MCU BRAM 368 | //--------------------------------------------------------------------------- 369 | wb_mcu_bram #( 370 | .ADDR_WIDTH(ADDR_WIDTH), 371 | .DATA_WIDTH(DATA_WIDTH) 372 | ) mcu_bram0 ( 373 | //Wishbone interface 374 | .clk_i (clk ), 375 | .wb_adr_i (mcu_bram_adr ), 376 | .wb_dat_o (mcu_bram_r ), 377 | .wb_dat_i (mcu_bram_w ), 378 | .wb_sel_i (mcu_bram_sel ), 379 | .wb_stb_i (mcu_bram_stb ), 380 | .wb_cyc_i (mcu_bram_cyc ), 381 | .wb_we_i (mcu_bram_we ), 382 | //MCU SAM 383 | .mcu_clk (nclk ), 384 | .mcu_nwe (mcu_nwe ), 385 | .mcu_ncs (mcu_ncs ), 386 | .mcu_nrd (mcu_nrd ), 387 | .mcu_addr (mcu_addr ), 388 | .mcu_sram_data(mcu_sram_data), 389 | .wb_ack_o (mcu_bram_ack ) 390 | ); 391 | //--------------------------------------------------------------------------- 392 | // Microphone Array 393 | //--------------------------------------------------------------------------- 394 | wb_mic_array #( 395 | .SYS_FREQ_HZ (SYS_FREQ_HZ ), 396 | .ADDR_WIDTH (ADDR_WIDTH ), 397 | .DATA_WIDTH (DATA_WIDTH ), 398 | .PDM_FREQ_HZ (PDM_FREQ_HZ ), 399 | .PDM_RATIO (PDM_RATIO ), 400 | .PDM_READING_TIME(PDM_READING_TIME) 401 | ) mic_array0 ( 402 | .clk (clk ), 403 | .resetn (resetn ), 404 | // MIC_Interface 405 | .pdm_data (pdm_data ), 406 | .pdm_clk (pdm_clk ), 407 | .irq (mic_irq ), 408 | // Wishbone interface 409 | .wb_clk (clk ), 410 | .wb_stb_i (mic_array_stb ), 411 | .wb_cyc_i (mic_array_cyc ), 412 | .wb_we_i (mic_array_we ), 413 | .wb_adr_i (mic_array_adr ), 414 | .wb_sel_i (mic_array_sel ), 415 | .wb_dat_i (mic_array_dat_w), 416 | .wb_dat_o (mic_array_dat_r), 417 | .wb_ack_o (mic_array_ack ), 418 | //Configuration 419 | .sample_rate(mic_sample_rate), 420 | .data_gain (mic_data_gain ) 421 | ); 422 | 423 | //--------------------------------------------------------------------------- 424 | // Everloop 425 | //--------------------------------------------------------------------------- 426 | wb_everloop #( 427 | .MEM_FILE_NAME(EVERLOOP_FILE), 428 | .SYS_FREQ_HZ (SYS_FREQ_HZ ), 429 | .ADDR_WIDTH (ADDR_WIDTH ), 430 | .DATA_WIDTH (DATA_WIDTH ), 431 | .N_LEDS (N_LEDS ) 432 | ) everloop0 ( 433 | .clk (clk ), 434 | .resetn (resetn ), 435 | // Wishbone interface 436 | .wb_stb_i (everloop_stb ), 437 | .wb_cyc_i (everloop_cyc ), 438 | .wb_we_i (everloop_we ), 439 | .wb_adr_i (everloop_adr ), 440 | .wb_sel_i (everloop_sel ), 441 | .wb_dat_i (everloop_dat_w), 442 | .wb_dat_o (everloop_dat_r), 443 | .everloop_ctl(everloop_ctl ), 444 | .wb_ack_o (everloop_ack ) 445 | ); 446 | 447 | //--------------------------------------------------------------------------- 448 | // GPIO 449 | //--------------------------------------------------------------------------- 450 | wb_gpio #( 451 | .ADDR_WIDTH(ADDR_WIDTH), 452 | .DATA_WIDTH(DATA_WIDTH), 453 | .GPIO_WIDTH(GPIO_WIDTH) 454 | ) gpio0 ( 455 | .clk (clk ), 456 | .rst (resetn ), 457 | .wb_stb_i(gpio0_stb ), 458 | .wb_cyc_i(gpio0_cyc ), 459 | .wb_we_i (gpio0_we ), 460 | .wb_adr_i(gpio0_adr ), 461 | .wb_dat_i(gpio0_dat_w), 462 | .wb_dat_o(gpio0_dat_r), 463 | .gpio_io (gpio_io ), 464 | .wb_ack_o(gpio0_ack ) 465 | ); 466 | //--------------------------------------------------------------------------- 467 | // Zwave UART SPI interface 468 | //--------------------------------------------------------------------------- 469 | wb_uart #( 470 | .ADDR_WIDTH (ADDR_WIDTH ), 471 | .DATA_WIDTH (DATA_WIDTH ), 472 | .SYS_FREQ_HZ(SYS_FREQ_HZ), 473 | .BAUD_RATE (115200 ) 474 | ) uart0 ( 475 | .clk (clk ), 476 | .resetn (resetn ), 477 | // Wishbone interface 478 | .wb_stb_i(uart0_stb ), 479 | .wb_cyc_i(uart0_cyc ), 480 | .wb_we_i (uart0_we ), 481 | .wb_adr_i(uart0_adr ), 482 | .wb_dat_i(uart0_dat_w), 483 | .wb_dat_o(uart0_dat_r), 484 | .wb_ack_o(uart0_ack ), 485 | // Serial Wires 486 | .uart_rxd(zwave_rxd ), 487 | .uart_txd(zwave_txd ), 488 | .uart_irq(uart_irq ) 489 | ); 490 | 491 | //--------------------------------------------------------------------------- 492 | // Zwave GPIO 493 | //--------------------------------------------------------------------------- 494 | wb_zwave_gpio #( 495 | .ADDR_WIDTH(ADDR_WIDTH), 496 | .DATA_WIDTH(DATA_WIDTH) 497 | ) wb_zwave_gpio0 ( 498 | .clk (clk ), 499 | .resetn (resetn ), 500 | // Wishbone interface 501 | .wb_stb_i(zwave_gpio_stb), 502 | .wb_cyc_i(zwave_gpio_cyc), 503 | .wb_we_i (zwave_gpio_we ), 504 | .wb_adr_i(zwave_gpio_adr), 505 | .wb_dat_i(zwave_gpio_w ), 506 | .wb_dat_o(zwave_gpio_r ), 507 | .wb_ack_o(zwave_gpio_ack), 508 | //Zwave Dignals 509 | .zwave_cs (zwave_cs), 510 | .zwave_sck (zwave_sck), 511 | .zwave_mosi (zwave_mosi), 512 | .zwave_miso (zwave_miso), 513 | .zwave_nreset(zwave_nreset) 514 | ); 515 | 516 | endmodule 517 | -------------------------------------------------------------------------------- /creator_core/system_TB.v: -------------------------------------------------------------------------------- 1 | `timescale 1ns / 1ps 2 | 3 | module nfc_spi ( 4 | input [7:0] data_nfc, 5 | input nfc_sck , 6 | output reg nfc_miso 7 | ); 8 | 9 | parameter TBIT = 1; 10 | initial begin 11 | nfc_miso = 0; 12 | end 13 | 14 | reg [5:0] n; 15 | 16 | always @(*) begin 17 | for(n=0; n<8; n=n+1) begin 18 | nfc_miso <= data_nfc[7-n]; 19 | repeat(TBIT) begin 20 | @(negedge nfc_sck); 21 | end 22 | end 23 | nfc_miso <= 0; 24 | 25 | end 26 | 27 | endmodule 28 | 29 | module system_TB; 30 | 31 | // Inputs 32 | reg clk; 33 | reg clk_esp; 34 | reg resetn; 35 | reg rpi_mosi; 36 | reg rpi_ss; 37 | reg rpi_sck; 38 | reg esp_mosi; 39 | reg esp_ss; 40 | reg esp_sck; 41 | reg ss1; 42 | reg uart0_rx; 43 | reg [7:0] pdm_data; 44 | reg uart_rxd; 45 | 46 | // Outputs 47 | wire miso ; 48 | wire [15:0] gpio_io; 49 | 50 | 51 | wire nfc_sck ; 52 | wire nfc_miso; 53 | 54 | system uut ( 55 | .clk_50 (clk ), 56 | .resetn (resetn ), 57 | .mosi (rpi_mosi ), 58 | .ss (rpi_ss ), 59 | .ss1 (ss1 ), 60 | .sck (rpi_sck ), 61 | .miso (rpi_miso ), 62 | .pdm_data(pdm_data), 63 | .nfc_miso(nfc_miso), 64 | .nfc_sck (nfc_sck ), 65 | .gpio_io (gpio_io ), 66 | .zwave_rxd (uart_rxd) 67 | ); 68 | 69 | nfc_spi nfc ( 70 | .data_nfc(8'hAA ), 71 | .nfc_sck (nfc_sck ), 72 | .nfc_miso(nfc_miso) 73 | ); 74 | 75 | initial begin 76 | // Initialize Inputs 77 | resetn = 0; clk = 0; rpi_mosi = 0; rpi_ss = 1; rpi_sck = 1; uart0_rx = 0; ss1 = 1; 78 | end 79 | 80 | //------------------------------------------ 81 | // TRI-STATE GENERATION 82 | //------------------------------------------ 83 | parameter PERIOD_INPUT = 8000; 84 | parameter real DUTY_CYCLE_INPUT = 0.8; 85 | 86 | reg [15:0] data; 87 | reg [15:0] gpio_dir; 88 | 89 | genvar k; 90 | generate 91 | for (k=0;k<16;k=k+1) begin: gpio_tris 92 | assign gpio_io[k] = ~(gpio_dir[k]) ? data[k] : 1'bz; 93 | end 94 | endgenerate 95 | 96 | initial // Clock process for clk 97 | begin 98 | #OFFSET; 99 | forever 100 | begin 101 | data = 16'h0000; 102 | #(PERIOD_INPUT-(PERIOD_INPUT*DUTY_CYCLE_INPUT)) data = 16'hFFFF; 103 | #(PERIOD_INPUT*DUTY_CYCLE_INPUT); 104 | end 105 | end 106 | 107 | 108 | //------------------------------------------ 109 | // RESET GENERATION 110 | //------------------------------------------ 111 | 112 | event reset_trigger; 113 | event reset_done_trigger; 114 | 115 | initial begin 116 | forever begin 117 | @ (reset_trigger); 118 | @ (negedge clk); 119 | resetn = 1; 120 | @ (negedge clk); 121 | resetn = 0; 122 | -> reset_done_trigger; 123 | end 124 | end 125 | 126 | 127 | //------------------------------------------ 128 | // CLOCK GENERATION 129 | //------------------------------------------ 130 | 131 | parameter TBIT = 2; 132 | parameter PERIOD = 20; 133 | parameter real DUTY_CYCLE = 0.5; 134 | parameter OFFSET = 0; 135 | 136 | //------------------------------------------ 137 | // MEMORY MAP 138 | //------------------------------------------ 139 | 140 | parameter bram_addr = 0; 141 | parameter uart_addr = 14'h0800; 142 | parameter mica_addr = 14'h1000; 143 | parameter pxxx_addr = 14'h1800; 144 | parameter pyyy_addr = 14'h2000; 145 | 146 | parameter read = 1; 147 | parameter write = 0; 148 | parameter single = 0; 149 | parameter burst = 1; 150 | 151 | initial // Clock process for clk 152 | begin 153 | #OFFSET; 154 | forever 155 | begin 156 | clk = 1'b0; 157 | #(PERIOD-(PERIOD*DUTY_CYCLE)) clk = 1'b1; 158 | #(PERIOD*DUTY_CYCLE); 159 | end 160 | end 161 | 162 | initial // Clock process for clk 163 | begin 164 | #OFFSET; 165 | forever 166 | begin 167 | clk_esp = 1'b0; 168 | #(PERIOD-(PERIOD*DUTY_CYCLE)) clk_esp = 1'b1; 169 | #(PERIOD*DUTY_CYCLE); 170 | end 171 | end 172 | 173 | 174 | //------------------------------------------ 175 | // SPI SINGLE TRANSFER TASK 176 | //------------------------------------------ 177 | reg [4:0] i; 178 | reg [15:0] data_tx_rpi; 179 | reg [15:0] data_tx_e_rpi; 180 | 181 | task automatic spi_transfer_pi; 182 | input [14:0] address; 183 | input [15:0] data; 184 | input RnW; 185 | begin 186 | data_tx_e_rpi = {address,RnW}; 187 | data_tx_rpi = {data_tx_e_rpi[7:0],data_tx_e_rpi[15:8]}; 188 | rpi_ss = 1; 189 | repeat(4*TBIT) begin 190 | @(negedge clk); 191 | end 192 | rpi_ss = 0; 193 | repeat(2*TBIT) begin 194 | @(negedge clk); 195 | end 196 | /////////////////// 197 | // Send address 198 | /////////////////// 199 | for(i=0; i<16; i=i+1) begin 200 | rpi_sck = 0; 201 | rpi_mosi <= data_tx_rpi[15-i]; 202 | repeat(TBIT) begin 203 | @(negedge clk); 204 | end 205 | rpi_sck = 1; 206 | repeat(TBIT) begin 207 | @(negedge clk); 208 | end 209 | end 210 | /////////////////// 211 | // Send data 212 | /////////////////// 213 | data_tx_rpi <= {data[7:0],data[15:8]}; 214 | repeat(2*TBIT) begin 215 | @(negedge clk); 216 | end 217 | for(i=0; i<16; i=i+1) begin 218 | rpi_sck = 0; 219 | rpi_mosi <= data_tx_rpi[15-i]; 220 | repeat(TBIT) begin 221 | @(negedge clk); 222 | end 223 | rpi_sck = 1; 224 | repeat(TBIT) begin 225 | @(negedge clk); 226 | end 227 | end 228 | repeat(4*TBIT) begin 229 | @(negedge clk); 230 | end 231 | rpi_ss = 1; 232 | repeat(4*TBIT) begin 233 | @(negedge clk); 234 | end 235 | end 236 | endtask 237 | 238 | reg [4:0] j; 239 | reg [15:0] data_tx_esp; 240 | reg [15:0] data_tx_e_esp; 241 | 242 | task automatic spi_transfer_esp; 243 | input [14:0] address_esp; 244 | input [15:0] data_esp; 245 | input RnW_esp; 246 | begin 247 | data_tx_e_esp = {address_esp,RnW_esp}; 248 | data_tx_esp = {data_tx_e_esp[7:0],data_tx_e_esp[15:8]}; 249 | esp_ss = 1; 250 | repeat(4*TBIT) begin 251 | @(negedge clk_esp); 252 | end 253 | esp_ss = 0; 254 | repeat(2*TBIT) begin 255 | @(negedge clk_esp); 256 | end 257 | /////////////////// 258 | // Send address 259 | /////////////////// 260 | for(j=0; j<16; j=j+1) begin 261 | esp_sck = 0; 262 | esp_mosi <= data_tx_esp[15-j]; 263 | repeat(TBIT) begin 264 | @(negedge clk_esp); 265 | end 266 | esp_sck = 1; 267 | repeat(TBIT) begin 268 | @(negedge clk_esp); 269 | end 270 | end 271 | /////////////////// 272 | // Send data 273 | /////////////////// 274 | data_tx_esp <= {data_esp[7:0],data_esp[15:8]}; 275 | repeat(2*TBIT) begin 276 | @(negedge clk_esp); 277 | end 278 | for(j=0; j<16; j=j+1) begin 279 | esp_sck = 0; 280 | esp_mosi <= data_tx_esp[15-j]; 281 | repeat(TBIT) begin 282 | @(negedge clk_esp); 283 | end 284 | esp_sck = 1; 285 | repeat(TBIT) begin 286 | @(negedge clk_esp); 287 | end 288 | end 289 | repeat(4*TBIT) begin 290 | @(negedge clk_esp); 291 | end 292 | esp_ss = 1; 293 | repeat(4*TBIT) begin 294 | @(negedge clk_esp); 295 | end 296 | end 297 | endtask 298 | 299 | parameter depth = (1 << 8); 300 | // actual ram cells 301 | reg [15:0] ram [0:depth-1]; 302 | localparam MEM_FILE_NAME = "sine"; 303 | 304 | initial 305 | begin 306 | if (MEM_FILE_NAME != "none") 307 | begin 308 | $readmemh(MEM_FILE_NAME, ram); 309 | end 310 | end 311 | 312 | //------------------------------------------ 313 | // SPI BURST TRANSFER TASK 314 | //------------------------------------------ 315 | reg [4:0] ib; 316 | reg [4:0] jb; 317 | reg [15:0] data_txb[18:0]; 318 | reg [15:0] data_txb_e; 319 | 320 | task automatic spi_burst_transfer; 321 | input [15:0] address_b; 322 | input [4:0] count; 323 | input RnW_b; 324 | begin 325 | data_txb_e = {address_b,RnW_b}; 326 | data_txb[0] = {data_txb_e[7:0],data_txb_e[15:8]}; 327 | data_txb[1] = ram[0]; 328 | data_txb[2] = ram[1]; 329 | data_txb[3] = ram[2]; 330 | data_txb[4] = ram[3]; 331 | data_txb[5] = ram[4]; 332 | data_txb[6] = ram[5]; 333 | data_txb[7] = ram[6]; 334 | data_txb[8] = ram[7]; 335 | data_txb[9] = ram[8]; 336 | data_txb[10] = ram[9]; 337 | data_txb[11] = ram[10]; 338 | data_txb[12] = ram[11]; 339 | data_txb[13] = ram[12]; 340 | data_txb[14] = ram[13]; 341 | data_txb[15] = ram[14]; 342 | data_txb[16] = ram[15]; 343 | data_txb[17] = ram[16]; 344 | data_txb[18] = ram[17]; 345 | 346 | rpi_ss = 1; 347 | repeat(20*TBIT) begin 348 | @(negedge clk); 349 | end 350 | rpi_ss = 0; 351 | repeat(2*TBIT) begin 352 | @(negedge clk); 353 | end 354 | for(jb = 0; jb < count; jb = jb + 1) begin 355 | repeat(2*TBIT) begin 356 | @(negedge clk); 357 | end 358 | for(ib = 0; ib < 16; ib = ib + 1) begin 359 | rpi_sck = 0; 360 | rpi_mosi <= data_txb[jb][15-ib]; 361 | repeat(TBIT) begin 362 | @(negedge clk); 363 | end 364 | rpi_sck = 1; 365 | repeat(TBIT) begin 366 | @(negedge clk); 367 | end 368 | end 369 | end 370 | rpi_ss = 1; 371 | repeat(4*TBIT) begin 372 | @(negedge clk); 373 | end 374 | end 375 | endtask 376 | 377 | 378 | //------------------------------------------ 379 | // SPI NFC TRANSFER TASK 380 | //------------------------------------------ 381 | /* reg [ 5:0] n ; 382 | reg [7:0] data_nfc; 383 | 384 | task automatic nfc_spi; 385 | input [7:0] data; 386 | begin 387 | data_nfc = data; 388 | for(n=0; n<8; n=n+1) begin 389 | nfc_miso <= data_nfc[7-n]; 390 | repeat(TBIT) begin 391 | @(negedge nfc_sck); 392 | end 393 | end 394 | nfc_miso <= 0; 395 | end 396 | endtask 397 | */ 398 | //------------------------------------------ 399 | // UART TRANSFER TASK 400 | //------------------------------------------ 401 | reg [3:0] u ; 402 | reg [7:0] data_uart_rx; 403 | 404 | parameter UART_BIT = 432; //Bit time 405 | 406 | task automatic uart_rx; 407 | input [9:0] data; 408 | begin 409 | data_uart_rx = data; 410 | uart_rxd <= 0; 411 | 412 | repeat(UART_BIT) begin 413 | @(negedge clk); 414 | end 415 | 416 | for(u=0; u<8; u=u+1) 417 | begin 418 | uart_rxd <= data_uart_rx[u]; 419 | repeat(UART_BIT) begin 420 | @(negedge clk); 421 | end 422 | end 423 | uart_rxd <= 1; 424 | end 425 | endtask 426 | 427 | //------------------------------------------ 428 | // TEST SINGLE SPI TRANSFER 429 | //------------------------------------------ 430 | initial begin: TEST_CASE 431 | #250 -> reset_trigger; 432 | uart_rxd <= 1; 433 | #0 pdm_data <= 8'hAA; 434 | @ (reset_done_trigger); 435 | spi_transfer_pi(15'h7001, 16'h01, write); 436 | spi_transfer_pi(15'h7000, 16'h01, write); 437 | spi_transfer_pi(15'h7001, 16'h02, write); 438 | spi_transfer_pi(15'h7001, 16'h0A, read); 439 | spi_burst_transfer(15'h6000, 5'h12, write); 440 | uart_rx(9'hAA); 441 | #50000 442 | uart_rx(9'hAB); 443 | #50000 444 | uart_rx(9'hAC); 445 | #30000 446 | spi_transfer_pi(15'h1000, 0, read); 447 | spi_transfer_pi(15'h1101, 0, read); 448 | 449 | end 450 | 451 | initial begin: TEST_DUMP 452 | 453 | $dumpfile("system_TB.vcd"); 454 | $dumpvars(-1); 455 | #((PERIOD*DUTY_CYCLE)*75000) $finish; 456 | end 457 | 458 | endmodule 459 | -------------------------------------------------------------------------------- /thrid_party/unisims/BUFG.v: -------------------------------------------------------------------------------- 1 | module BUFG ( 2 | input I, 3 | output O 4 | ); 5 | assign O = I; 6 | 7 | endmodule 8 | -------------------------------------------------------------------------------- /thrid_party/unisims/BUFT.v: -------------------------------------------------------------------------------- 1 | module BUFT ( 2 | input I, 3 | output O, 4 | input T 5 | ); 6 | assign O = ~T ? I: 1'bz; 7 | 8 | endmodule 9 | -------------------------------------------------------------------------------- /thrid_party/unisims/FDDRRSE.v: -------------------------------------------------------------------------------- 1 | // $Header: /devl/xcs/repo/env/Databases/CAEInterfaces/verunilibs/data/unisims/FDDRRSE.v,v 1.15.48.1 2007/03/09 18:13:02 patrickp Exp $ 2 | /////////////////////////////////////////////////////////////////////////////// 3 | // Copyright (c) 1995/2004 Xilinx, Inc. 4 | // All Right Reserved. 5 | /////////////////////////////////////////////////////////////////////////////// 6 | // ____ ____ 7 | // / /\/ / 8 | // /___/ \ / Vendor : Xilinx 9 | // \ \ \/ Version : 8.1i (I.27) 10 | // \ \ Description : Xilinx Functional Simulation Library Component 11 | // / / Dual Data Rate D Flip-Flop with Synchronous Reset and Set and Clock Enable 12 | // /___/ /\ Filename : FDDRRSE.v 13 | // \ \ / \ Timestamp : Thu Mar 25 16:42:16 PST 2004 14 | // \___\/\___\ 15 | // 16 | // Revision: 17 | // 03/23/04 - Initial version. 18 | // 02/04/05 - Rev 0.0.1 Remove input/output bufs; Seperate GSR from clock block. 19 | // 05/06/05 - Remove internal input data strobe and add to the output. (CR207678) 20 | // 10/20/05 - Add set & reset check to main block. (CR219794) 21 | // 10/28/05 - combine strobe block and data block. (CR220298). 22 | // 2/07/06 - Remove set & reset from main block and add specify block (CR225119) 23 | // 2/10/06 - Change Q from reg to wire (CR 225613) 24 | // End Revision 25 | 26 | `timescale 1 ps / 1 ps 27 | 28 | 29 | module FDDRRSE (Q, C0, C1, CE, D0, D1, R, S); 30 | 31 | parameter INIT = 1'h0; 32 | 33 | output Q; 34 | 35 | input C0, C1, CE, D0, D1, R, S; 36 | 37 | wire Q; 38 | reg q_out; 39 | 40 | reg q0_out, q1_out; 41 | reg C0_tmp, C1_tmp; 42 | 43 | initial begin 44 | q_out = INIT; 45 | q0_out = INIT; 46 | q1_out = INIT; 47 | C0_tmp = 0; 48 | C1_tmp = 0; 49 | end 50 | 51 | assign Q = q_out; 52 | 53 | always @(posedge C0) 54 | if (CE == 1 || R == 1 || S == 1) begin 55 | C0_tmp <= 1; 56 | C0_tmp <= #100 0; 57 | end 58 | 59 | always @(posedge C1) 60 | if (CE == 1 || R == 1 || S == 1) begin 61 | C1_tmp <= 1; 62 | C1_tmp <= #100 0; 63 | end 64 | 65 | always @(posedge C0) 66 | if (R) 67 | q0_out <= 0; 68 | else if (S) 69 | q0_out <= 1; 70 | else if (CE) 71 | q0_out <= D0; 72 | 73 | always @(posedge C1) 74 | if (R) 75 | q1_out <= 0; 76 | else if (S) 77 | q1_out <= 1; 78 | else if (CE) 79 | q1_out <= D1; 80 | 81 | always @(posedge C0_tmp or posedge C1_tmp ) 82 | if (C1_tmp) 83 | q_out = q1_out; 84 | else 85 | q_out = q0_out; 86 | 87 | specify 88 | if (R) 89 | (posedge C0 => (Q +: 1'b0)) = (100, 100); 90 | if (!R && S) 91 | (posedge C0 => (Q +: 1'b1)) = (100, 100); 92 | if (!R && !S && CE) 93 | (posedge C0 => (Q +: D0)) = (100, 100); 94 | if (R) 95 | (posedge C1 => (Q +: 1'b0)) = (100, 100); 96 | if (!R && S) 97 | (posedge C1 => (Q +: 1'b1)) = (100, 100); 98 | if (!R && !S && CE) 99 | (posedge C1 => (Q +: D1)) = (100, 100); 100 | endspecify 101 | 102 | endmodule 103 | -------------------------------------------------------------------------------- /thrid_party/unisims/IBUFG.v: -------------------------------------------------------------------------------- 1 | // $Header: /devl/xcs/repo/env/Databases/CAEInterfaces/verunilibs/data/unisims/IBUFG.v,v 1.7 2007/05/23 21:43:34 patrickp Exp $ 2 | /////////////////////////////////////////////////////////////////////////////// 3 | // Copyright (c) 1995/2004 Xilinx, Inc. 4 | // All Right Reserved. 5 | /////////////////////////////////////////////////////////////////////////////// 6 | // ____ ____ 7 | // / /\/ / 8 | // /___/ \ / Vendor : Xilinx 9 | // \ \ \/ Version : 10.1 10 | // \ \ Description : Xilinx Functional Simulation Library Component 11 | // / / Input Clock Buffer 12 | // /___/ /\ Filename : IBUFG.v 13 | // \ \ / \ Timestamp : Thu Mar 25 16:42:24 PST 2004 14 | // \___\/\___\ 15 | // 16 | // Revision: 17 | // 03/23/04 - Initial version. 18 | // 05/23/07 - Changed timescale to 1 ps / 1 ps. 19 | 20 | `timescale 1 ps / 1 ps 21 | 22 | 23 | module IBUFG (O, I); 24 | 25 | parameter CAPACITANCE = "DONT_CARE"; 26 | parameter IBUF_DELAY_VALUE = "0"; 27 | parameter IOSTANDARD = "DEFAULT"; 28 | 29 | output O; 30 | input I; 31 | 32 | buf B1 (O, I); 33 | 34 | initial begin 35 | 36 | case (CAPACITANCE) 37 | 38 | "LOW", "NORMAL", "DONT_CARE" : ; 39 | default : begin 40 | $display("Attribute Syntax Error : The attribute CAPACITANCE on IBUFG instance %m is set to %s. Legal values for this attribute are DONT_CARE, LOW or NORMAL.", CAPACITANCE); 41 | $finish; 42 | end 43 | 44 | endcase 45 | 46 | 47 | case (IBUF_DELAY_VALUE) 48 | 49 | "0", "1", "2", "3", "4", "5", "6", "7", "8", "9", "10", "11", "12", "13", "14", "15", "16" : ; 50 | default : begin 51 | $display("Attribute Syntax Error : The attribute IBUF_DELAY_VALUE on IBUFG instance %m is set to %s. Legal values for this attribute are 0, 1, 2, ... or 16.", IBUF_DELAY_VALUE); 52 | $finish; 53 | end 54 | 55 | endcase 56 | 57 | end // initial begin 58 | 59 | endmodule 60 | -------------------------------------------------------------------------------- /thrid_party/unisims/IDDR2.v: -------------------------------------------------------------------------------- 1 | 2 | module IDDR2#( 3 | parameter DDR_ALIGNMENT = "NONE", 4 | parameter INIT_Q0 = 1'b0, 5 | parameter INIT_Q1 = 1'b0, 6 | parameter SRTYPE = "ASYNC" 7 | )( 8 | input D, 9 | input C0, 10 | input C1, 11 | input CE, 12 | input R, 13 | input S, 14 | output Q1, 15 | output Q0 16 | ); 17 | 18 | 19 | flip_flop_d ffD0( 20 | .D(D), 21 | .clk(C0), 22 | .ce(CE), 23 | .reset(R), 24 | .set(S), 25 | .Q(Q0) 26 | ); 27 | 28 | flip_flop_d ffD1( 29 | .D(D), 30 | .clk(C1), 31 | .ce(CE), 32 | .reset(R), 33 | .set(S), 34 | .Q(Q1) 35 | ); 36 | 37 | endmodule 38 | 39 | 40 | 41 | 42 | 43 | 44 | -------------------------------------------------------------------------------- /thrid_party/unisims/IOBUF_.v: -------------------------------------------------------------------------------- 1 | module IOBUF ( 2 | input T, 3 | input I, 4 | output O, 5 | inout IO 6 | ); 7 | assign IO = ~T ? I : 1'bz; 8 | assign O = T ? IO : 1'bz; 9 | 10 | endmodule 11 | -------------------------------------------------------------------------------- /thrid_party/unisims/LUT3_test.v: -------------------------------------------------------------------------------- 1 | module LUT3 #( 2 | parameter INIT = 8'he4 3 | )(I2,I1,I0,O); 4 | 5 | 6 | input I1; 7 | input I2; 8 | input I0; 9 | output O; 10 | 11 | 12 | assign O = out; 13 | 14 | reg out; 15 | wire [7:0] init; 16 | assign init = INIT; 17 | 18 | always @(*) begin 19 | case({I2,I1,I0}) 20 | 3'b000: begin 21 | out = INIT[0]; 22 | end 23 | 3'b001: begin 24 | out = INIT[1]; 25 | end 26 | 3'b010: begin 27 | out = INIT[2]; 28 | end 29 | 3'b011: begin 30 | out = INIT[3]; 31 | end 32 | 3'b100: begin 33 | out = INIT[4]; 34 | end 35 | 3'b101: begin 36 | out = INIT[5]; 37 | end 38 | 3'b110: begin 39 | out = INIT[6]; 40 | end 41 | 3'b111: begin 42 | out = INIT[7]; 43 | end 44 | endcase 45 | end 46 | 47 | /* 48 | LUT3 LUT3_mux (.O (out), 49 | .I0 (sel), 50 | .I1 (a), 51 | .I2 (b)); 52 | defparam LUT3_mux.INIT = 8'he4; 53 | */ 54 | 55 | endmodule 56 | -------------------------------------------------------------------------------- /thrid_party/unisims/OBUFT.v: -------------------------------------------------------------------------------- 1 | module OBUFT ( 2 | input T, 3 | input I, 4 | output O 5 | ); 6 | assign O = ~T ? I : 1'bz; 7 | 8 | endmodule 9 | -------------------------------------------------------------------------------- /thrid_party/unisims/ODDR2.v: -------------------------------------------------------------------------------- 1 | 2 | module ODDR2 #( 3 | parameter DDR_ALIGNMENT = "NONE", 4 | parameter INIT = 1'b0, 5 | parameter SRTYPE = "ASYNC" 6 | )( 7 | input D0, 8 | input D1, 9 | input C0, 10 | input C1, 11 | input CE, 12 | input R, 13 | input S, 14 | output reg Q 15 | ); 16 | 17 | wire Q0, Q1; 18 | 19 | flip_flop_d ffD0( 20 | .D(D0), 21 | .clk(C0), 22 | .ce(CE), 23 | .reset(R), 24 | .set(S), 25 | .Q(Q0) 26 | ); 27 | 28 | flip_flop_d ffD1( 29 | .D(D1), 30 | .clk(C1), 31 | .ce(CE), 32 | .reset(R), 33 | .set(S), 34 | .Q(Q1) 35 | ); 36 | 37 | always @(*) begin 38 | if (C0 & ~C1) 39 | Q <= Q0; 40 | else if(~C0 & C1) 41 | Q <= Q1; 42 | end 43 | endmodule 44 | 45 | 46 | 47 | 48 | 49 | 50 | -------------------------------------------------------------------------------- /thrid_party/unisims/ddr_parameters.vh: -------------------------------------------------------------------------------- 1 | /**************************************************************************************** 2 | * 3 | * Disclaimer This software code and all associated documentation, comments or other 4 | * of Warranty: information (collectively "Software") is provided "AS IS" without 5 | * warranty of any kind. MICRON TECHNOLOGY, INC. ("MTI") EXPRESSLY 6 | * DISCLAIMS ALL WARRANTIES EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED 7 | * TO, NONINFRINGEMENT OF THIRD PARTY RIGHTS, AND ANY IMPLIED WARRANTIES 8 | * OF MERCHANTABILITY OR FITNESS FOR ANY PARTICULAR PURPOSE. MTI DOES NOT 9 | * WARRANT THAT THE SOFTWARE WILL MEET YOUR REQUIREMENTS, OR THAT THE 10 | * OPERATION OF THE SOFTWARE WILL BE UNINTERRUPTED OR ERROR-FREE. 11 | * FURTHERMORE, MTI DOES NOT MAKE ANY REPRESENTATIONS REGARDING THE USE OR 12 | * THE RESULTS OF THE USE OF THE SOFTWARE IN TERMS OF ITS CORRECTNESS, 13 | * ACCURACY, RELIABILITY, OR OTHERWISE. THE ENTIRE RISK ARISING OUT OF USE 14 | * OR PERFORMANCE OF THE SOFTWARE REMAINS WITH YOU. IN NO EVENT SHALL MTI, 15 | * ITS AFFILIATED COMPANIES OR THEIR SUPPLIERS BE LIABLE FOR ANY DIRECT, 16 | * INDIRECT, CONSEQUENTIAL, INCIDENTAL, OR SPECIAL DAMAGES (INCLUDING, 17 | * WITHOUT LIMITATION, DAMAGES FOR LOSS OF PROFITS, BUSINESS INTERRUPTION, 18 | * OR LOSS OF INFORMATION) ARISING OUT OF YOUR USE OF OR INABILITY TO USE 19 | * THE SOFTWARE, EVEN IF MTI HAS BEEN ADVISED OF THE POSSIBILITY OF SUCH 20 | * DAMAGES. Because some jurisdictions prohibit the exclusion or 21 | * limitation of liability for consequential or incidental damages, the 22 | * above limitation may not apply to you. 23 | * 24 | * Copyright 2003 Micron Technology, Inc. All rights reserved. 25 | * 26 | ****************************************************************************************/ 27 | 28 | `define sg5B 29 | `define x16 30 | 31 | // Timing parameters based on Speed Grade 04/07 32 | // SYMBOL UNITS DESCRIPTION 33 | // ------ ----- ----------- 34 | `ifdef sg5B // Timing Parameters for -5B (CL = 3) 35 | parameter tCK = 5.0; // tCK ns Nominal Clock Cycle Time 36 | parameter tDQSQ = 0.4; // tDQSQ ns DQS-DQ skew, DQS to last DQ valid, per group, per access 37 | parameter tMRD = 10.0; // tMRD ns Load Mode Register command cycle time 38 | parameter tRAP = 15.0; // tRAP ns ACTIVE to READ with Auto precharge command 39 | parameter tRAS = 40.0; // tRAS ns Active to Precharge command time 40 | parameter tRC = 55.0; // tRC ns Active to Active/Auto Refresh command time 41 | parameter tRFC = 70.0; // tRFC ns Refresh to Refresh Command interval time 42 | parameter tRCD = 15.0; // tRCD ns Active to Read/Write command time 43 | parameter tRP = 15.0; // tRP ns Precharge command period 44 | parameter tRRD = 10.0; // tRRD ns Active bank a to Active bank b command time 45 | parameter tWR = 15.0; // tWR ns Write recovery time 46 | `endif 47 | `ifdef sg6T // Timing Parameters for -6T (CL = 2.5) 48 | parameter tCK = 6.0; // tCK ns Nominal Clock Cycle Time 49 | parameter tDQSQ = 0.45; // tDQSQ ns DQS-DQ skew, DQS to last DQ valid, per group, per access 50 | parameter tMRD = 12.0; // tMRD ns Load Mode Register command cycle time 51 | parameter tRAP = 15.0; // tRAP ns ACTIVE to READ with Auto precharge command 52 | parameter tRAS = 42.0; // tRAS ns Active to Precharge command time 53 | parameter tRC = 60.0; // tRC ns Active to Active/Auto Refresh command time 54 | parameter tRFC = 72.0; // tRFC ns Refresh to Refresh Command interval time 55 | parameter tRCD = 15.0; // tRCD ns Active to Read/Write command time 56 | parameter tRP = 15.0; // tRP ns Precharge command period 57 | parameter tRRD = 12.0; // tRRD ns Active bank a to Active bank b command time 58 | parameter tWR = 15.0; // tWR ns Write recovery time 59 | `endif 60 | `ifdef sg6 // Timing Parameters for -6 (CL = 2.5) 61 | parameter tCK = 6.0; // tCK ns Nominal Clock Cycle Time 62 | parameter tDQSQ = 0.4; // tDQSQ ns DQS-DQ skew, DQS to last DQ valid, per group, per access 63 | parameter tMRD = 12.0; // tMRD ns Load Mode Register command cycle time 64 | parameter tRAP = 15.0; // tRAP ns ACTIVE to READ with Auto precharge command 65 | parameter tRAS = 42.0; // tRAS ns Active to Precharge command time 66 | parameter tRC = 60.0; // tRC ns Active to Active/Auto Refresh command time 67 | parameter tRFC = 72.0; // tRFC ns Refresh to Refresh Command interval time 68 | parameter tRCD = 15.0; // tRCD ns Active to Read/Write command time 69 | parameter tRP = 15.0; // tRP ns Precharge command period 70 | parameter tRRD = 12.0; // tRRD ns Active bank a to Active bank b command time 71 | parameter tWR = 15.0; // tWR ns Write recovery time 72 | `endif 73 | `ifdef sg75E // Timing Parameters for -75E (CL = 2) 74 | parameter tCK = 7.5; // tCK ns Nominal Clock Cycle Time 75 | parameter tDQSQ = 0.5; // tDQSQ ns DQS-DQ skew, DQS to last DQ valid, per group, per access 76 | parameter tMRD = 15.0; // tMRD ns Load Mode Register command cycle time 77 | parameter tRAP = 15.0; // tRAP ns ACTIVE to READ with Auto precharge command 78 | parameter tRAS = 40.0; // tRAS ns Active to Precharge command time 79 | parameter tRC = 60.0; // tRC ns Active to Active/Auto Refresh command time 80 | parameter tRFC = 75.0; // tRFC ns Refresh to Refresh Command interval time 81 | parameter tRCD = 15.0; // tRCD ns Active to Read/Write command time 82 | parameter tRP = 15.0; // tRP ns Precharge command period 83 | parameter tRRD = 15.0; // tRRD ns Active bank a to Active bank b command time 84 | parameter tWR = 15.0; // tWR ns Write recovery time 85 | `endif 86 | `ifdef sg75Z // Timing Parameters for -75Z (CL = 2) 87 | parameter tCK = 7.5; // tCK ns Nominal Clock Cycle Time 88 | parameter tDQSQ = 0.5; // tDQSQ ns DQS-DQ skew, DQS to last DQ valid, per group, per access 89 | parameter tMRD = 15.0; // tMRD ns Load Mode Register command cycle time 90 | parameter tRAP = 20.0; // tRAP ns ACTIVE to READ with Auto precharge command 91 | parameter tRAS = 40.0; // tRAS ns Active to Precharge command time 92 | parameter tRC = 65.0; // tRC ns Active to Active/Auto Refresh command time 93 | parameter tRFC = 75.0; // tRFC ns Refresh to Refresh Command interval time 94 | parameter tRCD = 20.0; // tRCD ns Active to Read/Write command time 95 | parameter tRP = 20.0; // tRP ns Precharge command period 96 | parameter tRRD = 15.0; // tRRD ns Active bank a to Active bank b command time 97 | parameter tWR = 15.0; // tWR ns Write recovery time 98 | `endif 99 | `ifdef sg75 // Timing Parameters for -75 (CL = 2.5) 100 | parameter tCK = 7.5; // tCK ns Nominal Clock Cycle Time 101 | parameter tDQSQ = 0.5; // tDQSQ ns DQS-DQ skew, DQS to last DQ valid, per group, per access 102 | parameter tMRD = 15.0; // tMRD ns Load Mode Register command cycle time 103 | parameter tRAP = 20.0; // tRAP ns ACTIVE to READ with Auto precharge command 104 | parameter tRAS = 40.0; // tRAS ns Active to Precharge command time 105 | parameter tRC = 65.0; // tRC ns Active to Active/Auto Refresh command time 106 | parameter tRFC = 75.0; // tRFC ns Refresh to Refresh Command interval time 107 | parameter tRCD = 20.0; // tRCD ns Active to Read/Write command time 108 | parameter tRP = 20.0; // tRP ns Precharge command period 109 | parameter tRRD = 15.0; // tRRD ns Active bank a to Active bank b command time 110 | parameter tWR = 15.0; // tWR ns Write recovery time 111 | `endif 112 | 113 | // Size Parameters based on Part Width 114 | 115 | `ifdef x4 116 | parameter ADDR_BITS = 13; // Set this parameter to control how many Address bits are used 117 | parameter DQ_BITS = 4; // Set this parameter to control how many Data bits are used 118 | parameter DQS_BITS = 1; // Set this parameter to control how many DQS bits are used 119 | parameter DM_BITS = 1; // Set this parameter to control how many DM bits are used 120 | parameter COL_BITS = 11; // Set this parameter to control how many Column bits are used 121 | `endif 122 | `ifdef x8 123 | parameter ADDR_BITS = 13; // Set this parameter to control how many Address bits are used 124 | parameter DQ_BITS = 8; // Set this parameter to control how many Data bits are used 125 | parameter DQS_BITS = 1; // Set this parameter to control how many DQS bits are used 126 | parameter DM_BITS = 1; // Set this parameter to control how many DM bits are used 127 | parameter COL_BITS = 10; // Set this parameter to control how many Column bits are used 128 | `endif 129 | `ifdef x16 130 | parameter ADDR_BITS = 13; // Set this parameter to control how many Address bits are used 131 | parameter DQ_BITS = 16; // Set this parameter to control how many Data bits are used 132 | parameter DQS_BITS = 2; // Set this parameter to control how many DQS bits are used 133 | parameter DM_BITS = 2; // Set this parameter to control how many DM bits are used 134 | parameter COL_BITS = 9; // Set this parameter to control how many Column bits are used 135 | `endif 136 | 137 | parameter BA_BITS = 2; // Set this parmaeter to control how many Bank Address bits are used 138 | parameter full_mem_bits = BA_BITS+ADDR_BITS+COL_BITS; // Set this parameter to control how many unique addresses are used 139 | parameter part_mem_bits = 10; // Set this parameter to control how many unique addresses are used 140 | 141 | parameter no_halt = 0; // If set to 1, the model won't halt on command sequence/major errors 142 | parameter DEBUG = 1; // Turn on DEBUG message 143 | `define FULL_MEM 144 | -------------------------------------------------------------------------------- /thrid_party/unisims/subtest.vh: -------------------------------------------------------------------------------- 1 | initial begin : test 2 | 3 | cke <= 1'b0; 4 | cs_n <= 1'b1; 5 | ras_n <= 1'b1; 6 | cas_n <= 1'b1; 7 | we_n <= 1'b1; 8 | ba <= {BA_BITS{1'bz}}; 9 | a <= {ADDR_BITS{1'bz}}; 10 | dq_en <= 1'b0; 11 | dqs_en <= 1'b0; 12 | cke <= 1'b1; 13 | power_up; 14 | $display("Powerup complete"); 15 | precharge('h00000000, 1); 16 | nop(trp); 17 | load_mode('h1, 'h00002000); 18 | nop(tmrd-1); 19 | load_mode('h0, 'h0000013A); 20 | nop(tmrd-1); 21 | precharge('h00000000, 1); 22 | nop(trp); 23 | refresh; 24 | nop(trfc); 25 | refresh; 26 | nop(trfc); 27 | load_mode('h0, 'h0000003A); 28 | nop(tmrd-1); 29 | nop('h000000C8); 30 | activate('h00000000, 'h00000000); 31 | nop(trcd-1); 32 | write('h00000000, 'h00000000, 1, { 4'h0, 4'h0, 4'h0, 4'h0}, { 32'h30003000, 32'h20002000, 32'h10001000, 32'h0}); 33 | nop(BL/2+twr); 34 | activate('h00000001, 'h00000000); 35 | nop(trcd-1); 36 | write('h00000001, 'h00000000, 1, { 4'h0, 4'h0, 4'h0, 4'h0}, { 32'h30013001, 32'h20012001, 32'h10011001, 32'h10001}); 37 | nop(BL/2+twr); 38 | activate('h00000002, 'h00000000); 39 | nop(trcd-1); 40 | write('h00000002, 'h00000000, 1, { 4'h0, 4'h0, 4'h0, 4'h0}, { 32'h30023002, 32'h20022002, 32'h10021002, 32'h20002}); 41 | nop(BL/2+twr); 42 | activate('h00000003, 'h00000000); 43 | nop(trcd-1); 44 | write('h00000003, 'h00000000, 1, { 4'h0, 4'h0, 4'h0, 4'h0}, { 32'h30033003, 32'h20032003, 32'h10031003, 32'h30003}); 45 | nop(BL/2+twr); 46 | activate('h00000000, 'h00000000); 47 | nop(trrd-1); 48 | activate('h00000001, 'h00000000); 49 | nop(trrd-1); 50 | activate('h00000002, 'h00000000); 51 | nop(trrd-1); 52 | activate('h00000003, 'h00000000); 53 | read('h00000000, 'h00000000, 1); 54 | nop(BL/2-1); 55 | read('h00000001, 'h00000000, 1); 56 | nop(BL/2-1); 57 | read('h00000002, 'h00000000, 1); 58 | nop(BL/2-1); 59 | read('h00000003, 'h00000000, 1); 60 | nop(BL/2+twr-2); 61 | activate('h00000001, 'h00000000); 62 | nop(trrd-1); 63 | activate('h00000000, 'h00000000); 64 | nop(trcd-1); 65 | $display("%m At time %t: WRITE Burst", $time);write('h00000000, 'h00000004, 0, { 4'h0, 4'h0, 4'h0, 4'h0}, { 32'h30403040, 32'h20402040, 32'h10401040, 32'h400040}); 66 | nop(BL/2+4); 67 | $display("%m At time %t: Consecutive WRITE to WRITE", $time);write('h00000000, 'h00000008, 0, { 4'h0, 4'h0, 4'h0, 4'h0}, { 32'h30803080, 32'h20802080, 32'h10801080, 32'h800080}); 68 | nop(BL/2-1); 69 | write('h00000000, 'h0000000C, 0, { 4'h0, 4'h0, 4'h0, 4'h0}, { 32'h31203120, 32'h21202120, 32'h11201120, 32'h1200120}); 70 | nop(BL/2-1); 71 | $display("%m At time %t: Nonconsecutive WRITE to WRITE", $time);write('h00000000, 'h00000010, 0, { 4'h0, 4'h0, 4'h0, 4'h0}, { 32'h31603160, 32'h21602160, 32'h11601160, 32'h1600160}); 72 | nop(BL/2+4); 73 | write('h00000000, 'h00000014, 0, { 4'h0, 4'h0, 4'h0, 4'h0}, { 32'h32003200, 32'h22002200, 32'h12001200, 32'h2000200}); 74 | nop(BL/2+twr+4); 75 | $display("%m At time %t: Random WRITE Cycles", $time);write('h00000000, 'h00000018, 0, { 4'h0, 4'h0, 4'h0, 4'h0}, { 32'h32403240, 32'h22402240, 32'h12401240, 32'h2400240}); 76 | nop(BL/2-1); 77 | write('h00000000, 'h0000001C, 0, { 4'h0, 4'h0, 4'h0, 4'h0}, { 32'h32803280, 32'h22802280, 32'h12801280, 32'h2800280}); 78 | nop(BL/2-1); 79 | write('h00000000, 'h00000020, 0, { 4'h0, 4'h0, 4'h0, 4'h0}, { 32'h33203320, 32'h23202320, 32'h13201320, 32'h3200320}); 80 | nop(BL/2-1); 81 | write('h00000000, 'h00000024, 0, { 4'h0, 4'h0, 4'h0, 4'h0}, { 32'h33603360, 32'h23602360, 32'h13601360, 32'h3600360}); 82 | nop(BL/2-1); 83 | $display("%m At time %t: WRITE to READ - Uninterrupting", $time);write('h00000000, 'h00000028, 0, { 4'h0, 4'h0, 4'h0, 4'h0}, { 32'h34003400, 32'h24002400, 32'h14001400, 32'h4000400}); 84 | nop(BL/2+1); 85 | read('h00000000, 'h00000028, 0); 86 | nop(CL+BL/2-1); 87 | $display("%m At time %t: WRITE to READ - Interrupting", $time);write('h00000000, 'h0000002C, 0, { 4'h1, 4'h1, 4'h0, 4'h0}, { 32'h34403440, 32'h24402440, 32'h14401440, 32'h4400440}); 88 | nop(BL/2+1); 89 | read('h00000000, 'h0000002C, 0); 90 | nop(CL+BL/2-1); 91 | $display("%m At time %t: WRITE to READ - Odd Number of Data, Interrupting", $time);write('h00000000, 'h00000030, 0, { 4'h1, 4'h1, 4'h1, 4'h0}, { 32'h34803480, 32'h24802480, 32'h14801480, 32'h4800480}); 92 | nop(BL/2+1); 93 | read('h00000000, 'h00000030, 0); 94 | nop(CL+BL/2-1); 95 | $display("%m At time %t: WRITE to PRECHARGE - Uninterrupting", $time);write('h00000000, 'h00000034, 0, { 4'h0, 4'h0, 4'h0, 4'h0}, { 32'h35203520, 32'h25202520, 32'h15201520, 32'h5200520}); 96 | nop(BL/2+twr); 97 | precharge('h00000000, 0); 98 | nop(trp-1); 99 | $display("%m At time %t: WRITE with AUTO PRECHARGE", $time);activate('h00000000, 'h00000000); 100 | nop(trcd-1); 101 | write('h00000000, 'h00000040, 1, { 4'h0, 4'h0, 4'h0, 4'h0}, { 32'h36603660, 32'h26602660, 32'h16601660, 32'h6600660}); 102 | nop(BL/2+twr+trp); 103 | activate('h00000000, 'h00000000); 104 | nop(trcd-1); 105 | $display("%m At time %t: READ Burst", $time);read('h00000000, 'h00000000, 0); 106 | nop(BL/2-1); 107 | $display("%m At time %t: Consecutive READ Bursts", $time);read('h00000000, 'h00000004, 0); 108 | nop(BL/2-2); 109 | read('h00000000, 'h00000008, 0); 110 | nop(BL/2-1); 111 | $display("%m At time %t: Nonconsecutive READ Bursts", $time);read('h00000000, 'h0000000C, 0); 112 | nop(BL/2); 113 | read('h00000000, 'h00000010, 0); 114 | nop(BL/2); 115 | $display("%m At time %t: Random READ Accesses", $time);read('h00000000, 'h00000014, 0); 116 | read('h00000000, 'h00000018, 0); 117 | read('h00000000, 'h0000001C, 0); 118 | read('h00000000, 'h00000020, 0); 119 | nop(BL/2); 120 | $display("%m At time %t: Terminating a READ Burst", $time);read('h00000000, 'h00000024, 0); 121 | burst_term; 122 | nop(BL/2-2); 123 | $display("%m At time %t: READ to WRITE", $time);read('h00000000, 'h00000028, 0); 124 | burst_term; 125 | nop(CL); 126 | write('h00000000, 'h0000002C, 0, { 4'h0, 4'h0, 4'h0, 4'h0}, { 32'h34C034C0, 32'h24C024C0, 32'h14C014C0, 32'h4C004C0}); 127 | nop(BL/2+1); 128 | $display("%m At time %t: READ to PRECHARGE", $time);read('h00000000, 'h00000030, 0); 129 | nop('h00000001); 130 | precharge('h00000000, 0); 131 | nop(trp-1); 132 | $display("%m At time %t: READ with AUTO PRECHARGE", $time);activate('h00000000, 'h00000000); 133 | nop(trcd-1); 134 | read('h00000000, 'h00000034, 1); 135 | nop(CL+BL/2+twr); 136 | $display("%m At time %t: WRITE to READ - Mask byte 0 of Burst 0", $time);activate('h00000000, 'h00000000); 137 | nop(trcd-1); 138 | write('h00000000, 'h00000064, 0, { 4'h0, 4'h0, 4'h0, 4'h0}, { 32'hFFFFFFFF, 32'hFFFFFFFF, 32'hFFFFFFFF, 32'hFFFFFFFF}); 139 | nop(BL/2); 140 | write('h00000000, 'h00000064, 0, { 4'h0, 4'h0, 4'h0, 4'h1}, { 32'h33333333, 32'h22222222, 32'h11111111, 32'h0}); 141 | nop(BL/2+1); 142 | read('h00000000, 'h00000064, 0); 143 | nop(CL+BL/2-1); 144 | $display("%m At time %t: WRITE to READ - Mask byte 1 of Burst 0", $time);write('h00000000, 'h00000064, 0, { 4'h0, 4'h0, 4'h0, 4'h0}, { 32'hFFFFFFFF, 32'hFFFFFFFF, 32'hFFFFFFFF, 32'hFFFFFFFF}); 145 | nop(BL/2); 146 | write('h00000000, 'h00000064, 0, { 4'h0, 4'h0, 4'h0, 4'h2}, { 32'h33333333, 32'h22222222, 32'h11111111, 32'h0}); 147 | nop(BL/2+1); 148 | read('h00000000, 'h00000064, 0); 149 | nop(CL+BL/2-1); 150 | $display("%m At time %t: WRITE to READ - Mask byte 2 of Burst 0", $time);write('h00000000, 'h00000064, 0, { 4'h0, 4'h0, 4'h0, 4'h0}, { 32'hFFFFFFFF, 32'hFFFFFFFF, 32'hFFFFFFFF, 32'hFFFFFFFF}); 151 | nop(BL/2); 152 | write('h00000000, 'h00000064, 0, { 4'h0, 4'h0, 4'h0, 4'h4}, { 32'h33333333, 32'h22222222, 32'h11111111, 32'h0}); 153 | nop(BL/2+1); 154 | read('h00000000, 'h00000064, 0); 155 | nop(CL+BL/2-1); 156 | $display("%m At time %t: WRITE to READ - Mask byte 3 of Burst 0", $time);write('h00000000, 'h00000064, 0, { 4'h0, 4'h0, 4'h0, 4'h0}, { 32'hFFFFFFFF, 32'hFFFFFFFF, 32'hFFFFFFFF, 32'hFFFFFFFF}); 157 | nop(BL/2); 158 | write('h00000000, 'h00000064, 0, { 4'h0, 4'h0, 4'h0, 4'h8}, { 32'h33333333, 32'h22222222, 32'h11111111, 32'h0}); 159 | nop(BL/2+1); 160 | read('h00000000, 'h00000064, 0); 161 | nop(CL+BL/2-1); 162 | $display("%m At time %t: WRITE to READ - Mask byte 0 of Burst 1", $time);write('h00000000, 'h00000064, 0, { 4'h0, 4'h0, 4'h0, 4'h0}, { 32'hFFFFFFFF, 32'hFFFFFFFF, 32'hFFFFFFFF, 32'hFFFFFFFF}); 163 | nop(BL/2); 164 | write('h00000000, 'h00000064, 0, { 4'h0, 4'h0, 4'h1, 4'h0}, { 32'h33333333, 32'h22222222, 32'h11111111, 32'h0}); 165 | nop(BL/2+1); 166 | read('h00000000, 'h00000064, 0); 167 | nop(CL+BL/2-1); 168 | $display("%m At time %t: WRITE to READ - Mask byte 1 of Burst 1", $time);write('h00000000, 'h00000064, 0, { 4'h0, 4'h0, 4'h0, 4'h0}, { 32'hFFFFFFFF, 32'hFFFFFFFF, 32'hFFFFFFFF, 32'hFFFFFFFF}); 169 | nop(BL/2); 170 | write('h00000000, 'h00000064, 0, { 4'h0, 4'h0, 4'h2, 4'h0}, { 32'h33333333, 32'h22222222, 32'h11111111, 32'h0}); 171 | nop(BL/2+1); 172 | read('h00000000, 'h00000064, 0); 173 | nop(CL+BL/2-1); 174 | $display("%m At time %t: WRITE to READ - Mask byte 2 of Burst 1", $time);write('h00000000, 'h00000064, 0, { 4'h0, 4'h0, 4'h0, 4'h0}, { 32'hFFFFFFFF, 32'hFFFFFFFF, 32'hFFFFFFFF, 32'hFFFFFFFF}); 175 | nop(BL/2); 176 | write('h00000000, 'h00000064, 0, { 4'h0, 4'h0, 4'h4, 4'h0}, { 32'h33333333, 32'h22222222, 32'h11111111, 32'h0}); 177 | nop(BL/2+1); 178 | read('h00000000, 'h00000064, 0); 179 | nop(CL+BL/2-1); 180 | $display("%m At time %t: WRITE to READ - Mask byte 3 of Burst 1", $time);write('h00000000, 'h00000064, 0, { 4'h0, 4'h0, 4'h0, 4'h0}, { 32'hFFFFFFFF, 32'hFFFFFFFF, 32'hFFFFFFFF, 32'hFFFFFFFF}); 181 | nop(BL/2); 182 | write('h00000000, 'h00000064, 0, { 4'h0, 4'h0, 4'h8, 4'h0}, { 32'h33333333, 32'h22222222, 32'h11111111, 32'h0}); 183 | nop(BL/2+1); 184 | read('h00000000, 'h00000064, 0); 185 | nop(CL+BL/2-1); 186 | $display("%m At time %t: WRITE to READ - Mask byte 0 of Burst 2", $time);write('h00000000, 'h00000064, 0, { 4'h0, 4'h0, 4'h0, 4'h0}, { 32'hFFFFFFFF, 32'hFFFFFFFF, 32'hFFFFFFFF, 32'hFFFFFFFF}); 187 | nop(BL/2); 188 | write('h00000000, 'h00000064, 0, { 4'h0, 4'h1, 4'h0, 4'h0}, { 32'h33333333, 32'h22222222, 32'h11111111, 32'h0}); 189 | nop(BL/2+1); 190 | read('h00000000, 'h00000064, 0); 191 | nop(CL+BL/2-1); 192 | $display("%m At time %t: WRITE to READ - Mask byte 1 of Burst 2", $time);write('h00000000, 'h00000064, 0, { 4'h0, 4'h0, 4'h0, 4'h0}, { 32'hFFFFFFFF, 32'hFFFFFFFF, 32'hFFFFFFFF, 32'hFFFFFFFF}); 193 | nop(BL/2); 194 | write('h00000000, 'h00000064, 0, { 4'h0, 4'h2, 4'h0, 4'h0}, { 32'h33333333, 32'h22222222, 32'h11111111, 32'h0}); 195 | nop(BL/2+1); 196 | read('h00000000, 'h00000064, 0); 197 | nop(CL+BL/2-1); 198 | $display("%m At time %t: WRITE to READ - Mask byte 2 of Burst 2", $time);write('h00000000, 'h00000064, 0, { 4'h0, 4'h0, 4'h0, 4'h0}, { 32'hFFFFFFFF, 32'hFFFFFFFF, 32'hFFFFFFFF, 32'hFFFFFFFF}); 199 | nop(BL/2); 200 | write('h00000000, 'h00000064, 0, { 4'h0, 4'h4, 4'h0, 4'h0}, { 32'h33333333, 32'h22222222, 32'h11111111, 32'h0}); 201 | nop(BL/2+1); 202 | read('h00000000, 'h00000064, 0); 203 | nop(CL+BL/2-1); 204 | $display("%m At time %t: WRITE to READ - Mask byte 3 of Burst 2", $time);write('h00000000, 'h00000064, 0, { 4'h0, 4'h0, 4'h0, 4'h0}, { 32'hFFFFFFFF, 32'hFFFFFFFF, 32'hFFFFFFFF, 32'hFFFFFFFF}); 205 | nop(BL/2); 206 | write('h00000000, 'h00000064, 0, { 4'h0, 4'h8, 4'h0, 4'h0}, { 32'h33333333, 32'h22222222, 32'h11111111, 32'h0}); 207 | nop(BL/2+1); 208 | read('h00000000, 'h00000064, 0); 209 | nop(CL+BL/2-1); 210 | $display("%m At time %t: WRITE to READ - Mask byte 0 of Burst 3", $time);write('h00000000, 'h00000064, 0, { 4'h0, 4'h0, 4'h0, 4'h0}, { 32'hFFFFFFFF, 32'hFFFFFFFF, 32'hFFFFFFFF, 32'hFFFFFFFF}); 211 | nop(BL/2); 212 | write('h00000000, 'h00000064, 0, { 4'h1, 4'h0, 4'h0, 4'h0}, { 32'h33333333, 32'h22222222, 32'h11111111, 32'h0}); 213 | nop(BL/2+1); 214 | read('h00000000, 'h00000064, 0); 215 | nop(CL+BL/2-1); 216 | $display("%m At time %t: WRITE to READ - Mask byte 1 of Burst 3", $time);write('h00000000, 'h00000064, 0, { 4'h0, 4'h0, 4'h0, 4'h0}, { 32'hFFFFFFFF, 32'hFFFFFFFF, 32'hFFFFFFFF, 32'hFFFFFFFF}); 217 | nop(BL/2); 218 | write('h00000000, 'h00000064, 0, { 4'h2, 4'h0, 4'h0, 4'h0}, { 32'h33333333, 32'h22222222, 32'h11111111, 32'h0}); 219 | nop(BL/2+1); 220 | read('h00000000, 'h00000064, 0); 221 | nop(CL+BL/2-1); 222 | $display("%m At time %t: WRITE to READ - Mask byte 2 of Burst 3", $time);write('h00000000, 'h00000064, 0, { 4'h0, 4'h0, 4'h0, 4'h0}, { 32'hFFFFFFFF, 32'hFFFFFFFF, 32'hFFFFFFFF, 32'hFFFFFFFF}); 223 | nop(BL/2); 224 | write('h00000000, 'h00000064, 0, { 4'h4, 4'h0, 4'h0, 4'h0}, { 32'h33333333, 32'h22222222, 32'h11111111, 32'h0}); 225 | nop(BL/2+1); 226 | read('h00000000, 'h00000064, 0); 227 | nop(CL+BL/2-1); 228 | $display("%m At time %t: WRITE to READ - Mask byte 3 of Burst 3", $time);write('h00000000, 'h00000064, 0, { 4'h0, 4'h0, 4'h0, 4'h0}, { 32'hFFFFFFFF, 32'hFFFFFFFF, 32'hFFFFFFFF, 32'hFFFFFFFF}); 229 | nop(BL/2); 230 | write('h00000000, 'h00000064, 0, { 4'h8, 4'h0, 4'h0, 4'h0}, { 32'h33333333, 32'h22222222, 32'h11111111, 32'h0}); 231 | nop(BL/2+1); 232 | read('h00000000, 'h00000064, 1); 233 | nop(CL+BL/2-1); 234 | test_done = 1; 235 | end 236 | 237 | -------------------------------------------------------------------------------- /verilogCheatSheet.md: -------------------------------------------------------------------------------- 1 | # Verilog Cheat Sheet 2 | ## Disclaimers and notes 3 | ### - Verilog is meant to simulate and create digital versions of circuits 4 | ### - Verilog uses modules similar to how other languages use classes 5 | ### - Verilog doesn't use {}, instead it declares a keyword followed by a keywordend (example: module and moduleend are used to begin and end modules) 6 | -------------------- 7 | -------------------- 8 | ## Modules 9 | ### Modules are chunks of code that are used to simulate a certain functionality in a circuit. 10 | ```verilog 11 | module [module_name] #(parameters) (variables_for_input_output); 12 | //code for module 13 | endmodule 14 | 15 | //ex: 16 | module app 17 | #( 18 | parameter one, 19 | parameter two, 20 | parameter three 21 | ) 22 | ( 23 | input a, 24 | output b, 25 | inout z 26 | ); 27 | //module code here 28 | endmodule 29 | 30 | //example module meant to represent an AND gate: 31 | 32 | //we declare our module called andgate 33 | module andgate (inOne, inTwo, out); //we specify its inputs and outputs 34 | input inOne, inTwo; //here we declare inOne and two as inputs 35 | output out; //out is output 36 | 37 | assign out = inOne & inTwo; //this continually and implicitly assigns 38 | //out the value of inOne AND inTwo 39 | endmodule 40 | ``` 41 | 42 | 43 | --------------------------------- 44 | -------------------- 45 | ## Verilog variables 46 | ### Verilog variables function the same as regular variables but only usually come as `reg` or `int`. 47 | ### `reg` isn't necessarily meant to represent a physical register, rather it's meant to hold a value assigned to it. 48 | ### They can store values and drive values unlike NETWORKS (see below). 49 | `reg` 50 | ```verilog 51 | //ex: 52 | input a, b; 53 | output c; 54 | reg a, b; 55 | wire c; 56 | ``` 57 | 58 | `int` (basic 32 bit integer) 59 | ```verilog 60 | //ex: 61 | int number = 42; 62 | ``` 63 | -------------------- 64 | -------------------- 65 | ## Networks 66 | ### Nets are just meant to create networks, and so physically represent things like wires or other forms of connectors. 67 | ### Unlike verilog variables, nets can't hold values and so are only meant to connect ports, transmit signals, etc., like actual wires. 68 | ```verilog 69 | wire //a net type that acts like a wire 70 | ``` 71 | -------------------- 72 | -------------------- 73 | ## Parameters 74 | ### Parameters are like global/local constants. 75 | `parameter` (used for global constants in a module) 76 | ```verilog 77 | //ex: 78 | parameter a_variable_name = 8; 79 | ``` 80 | `localparam` (used for local constants in a module) 81 | ```verilog 82 | //ex: 83 | localparam a_variable_name = 8; 84 | ``` 85 | -------------------- 86 | -------------------- 87 | ## Declaring buses 88 | ```verilog 89 | [datatype] [Most significant bit : least significant bit] [variable name] 90 | 91 | //ex: 92 | wire [7:0] gpio // an 8 bit wire bus named gpio 93 | 94 | //ex: 95 | reg [9:0] led // a 10 bit reg bus named led 96 | ``` 97 | -------------------- 98 | -------------------- 99 | ## Numbers 100 | ### Verilog has a sort of short hand syntax to specify the size, base and value of a number. 101 | ```verilog 102 | [bitsize]'[base][number] 103 | 104 | //ex: 105 | 8'b10101; //8 bit binary 00010101 106 | 107 | //ex: 108 | 10'D102 //10 bit Decimal 102 109 | ``` 110 | -------------------- 111 | -------------------- 112 | ## Including other modules in the same folder 113 | ### Modules can include each other similar to how *js* files can include other *js* files. 114 | ### The syntax is similar to how you would create an instance of a class. 115 | ```verilog 116 | module_name #(parameter_values) instance_name(port_connection_list); 117 | 118 | //ex: 119 | counter #(delay.(delay_amount)) instance(gpio, mic) 120 | //when declaring parameters, parameter_name.(parameter) is often 121 | //used to specify what parameter a value is being assigned to 122 | ``` 123 | -------------------- 124 | ## Conditional Statements 125 | ```verilog 126 | if (this is a regular if) 127 | 128 | //ex: 129 | if (*something*) 130 | //code 131 | else if (*anotherThing*) 132 | //more code 133 | else 134 | //even more code 135 | ``` 136 | ----------------------------- 137 | ```verilog 138 | case (this is a switch) 139 | 140 | case(variable) 141 | case1: //code 142 | case2: //code 143 | default: //code 144 | endcase; 145 | 146 | //ex: 147 | case(a) 148 | 1: q = a; 149 | 2: b = a; 150 | 3: g = a; 151 | default: a = 0; 152 | endcase 153 | ``` 154 | -------------------- 155 | -------------------- 156 | ## `always@()` 157 | ### `always@`s occur at a certain change in the sensitivity list. 158 | ### So for `always@(a, b, c)`, the code block within the `always` will run if `a`, `b`, or `c` change. 159 | ```verilog 160 | always@(sensitivity list); 161 | //code 162 | end 163 | 164 | //ex: 165 | always @(posedge clk) begin 166 | if(!count[1]) 167 | count <= count + 1; 168 | end 169 | ``` 170 | -------------------- 171 | ## `posedge` and `negedge` 172 | ### `posedge` and `negedge` are used when dealing with clocks. 173 | ### "`posedge` *clk*" in a sensitivity list means that at every time the clock ticks to its positive edge, run the always block. 174 | ### `negedge` is similar but for the negative edge of the clock. 175 | -------------------- 176 | -------------------- 177 | ## `generate` 178 | ### A `generate` is similar to a for loop except any module instantiated in the loop, remains instantiated in memory. 179 | ```verilog 180 | generate 181 | genvar 182 | 183 | //ex: 184 | // Tristate logic for IO 185 | genvar i; //the genvar is like the variable i created in a for loop 186 | generate 187 | for (i=0;i