Add 'hw/' from commit 'd812378c4d61f7c957ac4bcba15a8344fb7fb458'
git-subtree-dir: hw git-subtree-mainline:e4af98b4aagit-subtree-split:d812378c4d
This commit is contained in:
		
							
								
								
									
										3
									
								
								hw/.gitignore
									
									
									
									
										vendored
									
									
										Normal file
									
								
							
							
						
						
									
										3
									
								
								hw/.gitignore
									
									
									
									
										vendored
									
									
										Normal file
									
								
							@@ -0,0 +1,3 @@
 | 
				
			|||||||
 | 
					build/
 | 
				
			||||||
 | 
					__pycache__/
 | 
				
			||||||
 | 
					.env
 | 
				
			||||||
							
								
								
									
										39
									
								
								hw/.gitmodules
									
									
									
									
										vendored
									
									
										Normal file
									
								
							
							
						
						
									
										39
									
								
								hw/.gitmodules
									
									
									
									
										vendored
									
									
										Normal file
									
								
							@@ -0,0 +1,39 @@
 | 
				
			|||||||
 | 
					[submodule "deps/migen"]
 | 
				
			||||||
 | 
						path = deps/migen
 | 
				
			||||||
 | 
						url = https://github.com/m-labs/migen.git
 | 
				
			||||||
 | 
					[submodule "deps/litex"]
 | 
				
			||||||
 | 
						path = deps/litex
 | 
				
			||||||
 | 
						url = https://github.com/enjoy-digital/litex.git
 | 
				
			||||||
 | 
					[submodule "deps/litescope"]
 | 
				
			||||||
 | 
						path = deps/litescope
 | 
				
			||||||
 | 
						url = https://github.com/enjoy-digital/litescope.git
 | 
				
			||||||
 | 
					[submodule "deps/pyserial"]
 | 
				
			||||||
 | 
						path = deps/pyserial
 | 
				
			||||||
 | 
						url = https://github.com/pyserial/pyserial.git
 | 
				
			||||||
 | 
					[submodule "deps/liteeth"]
 | 
				
			||||||
 | 
						path = deps/liteeth
 | 
				
			||||||
 | 
						url = https://github.com/enjoy-digital/liteeth.git
 | 
				
			||||||
 | 
					[submodule "deps/liteusb"]
 | 
				
			||||||
 | 
						path = deps/liteusb
 | 
				
			||||||
 | 
						url = https://github.com/enjoy-digital/liteusb.git
 | 
				
			||||||
 | 
					[submodule "deps/litedram"]
 | 
				
			||||||
 | 
						path = deps/litedram
 | 
				
			||||||
 | 
						url = https://github.com/enjoy-digital/litedram.git
 | 
				
			||||||
 | 
					[submodule "deps/litepcie"]
 | 
				
			||||||
 | 
						path = deps/litepcie
 | 
				
			||||||
 | 
						url = https://github.com/enjoy-digital/litepcie.git
 | 
				
			||||||
 | 
					[submodule "deps/litesdcard"]
 | 
				
			||||||
 | 
						path = deps/litesdcard
 | 
				
			||||||
 | 
						url = https://github.com/enjoy-digital/litesdcard.git
 | 
				
			||||||
 | 
					[submodule "deps/liteiclink"]
 | 
				
			||||||
 | 
						path = deps/liteiclink
 | 
				
			||||||
 | 
						url = https://github.com/enjoy-digital/liteiclink.git
 | 
				
			||||||
 | 
					[submodule "deps/litevideo"]
 | 
				
			||||||
 | 
						path = deps/litevideo
 | 
				
			||||||
 | 
						url = https://github.com/enjoy-digital/litevideo.git
 | 
				
			||||||
 | 
					[submodule "deps/lxsocsupport"]
 | 
				
			||||||
 | 
						path = deps/lxsocsupport
 | 
				
			||||||
 | 
						url = https://github.com/xobs/lxsocsupport.git
 | 
				
			||||||
 | 
					[submodule "deps/valentyusb"]
 | 
				
			||||||
 | 
						path = deps/valentyusb
 | 
				
			||||||
 | 
						url = https://github.com/xobs/valentyusb.git
 | 
				
			||||||
							
								
								
									
										14
									
								
								hw/bin/litex_read_verilog
									
									
									
									
									
										Executable file
									
								
							
							
						
						
									
										14
									
								
								hw/bin/litex_read_verilog
									
									
									
									
									
										Executable file
									
								
							@@ -0,0 +1,14 @@
 | 
				
			|||||||
 | 
					#!/usr/bin/env python3
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					import sys
 | 
				
			||||||
 | 
					import os
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					# This script lives in the "bin" directory, but uses a helper script in the parent
 | 
				
			||||||
 | 
					# directory.  Obtain the current path so we can get the absolute parent path.
 | 
				
			||||||
 | 
					script_path = os.path.dirname(os.path.realpath(
 | 
				
			||||||
 | 
					    __file__)) + os.path.sep + os.path.pardir + os.path.sep
 | 
				
			||||||
 | 
					sys.path.insert(0, script_path)
 | 
				
			||||||
 | 
					import lxbuildenv
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					from litex.utils.litex_read_verilog import main
 | 
				
			||||||
 | 
					main()
 | 
				
			||||||
							
								
								
									
										14
									
								
								hw/bin/litex_server
									
									
									
									
									
										Executable file
									
								
							
							
						
						
									
										14
									
								
								hw/bin/litex_server
									
									
									
									
									
										Executable file
									
								
							@@ -0,0 +1,14 @@
 | 
				
			|||||||
 | 
					#!/usr/bin/env python3
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					import sys
 | 
				
			||||||
 | 
					import os
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					# This script lives in the "bin" directory, but uses a helper script in the parent
 | 
				
			||||||
 | 
					# directory.  Obtain the current path so we can get the absolute parent path.
 | 
				
			||||||
 | 
					script_path = os.path.dirname(os.path.realpath(
 | 
				
			||||||
 | 
					    __file__)) + os.path.sep + os.path.pardir + os.path.sep
 | 
				
			||||||
 | 
					sys.path.insert(0, script_path)
 | 
				
			||||||
 | 
					import lxbuildenv
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					from litex.utils.litex_server import main
 | 
				
			||||||
 | 
					main()
 | 
				
			||||||
							
								
								
									
										14
									
								
								hw/bin/litex_sim
									
									
									
									
									
										Executable file
									
								
							
							
						
						
									
										14
									
								
								hw/bin/litex_sim
									
									
									
									
									
										Executable file
									
								
							@@ -0,0 +1,14 @@
 | 
				
			|||||||
 | 
					#!/usr/bin/env python3
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					import sys
 | 
				
			||||||
 | 
					import os
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					# This script lives in the "bin" directory, but uses a helper script in the parent
 | 
				
			||||||
 | 
					# directory.  Obtain the current path so we can get the absolute parent path.
 | 
				
			||||||
 | 
					script_path = os.path.dirname(os.path.realpath(
 | 
				
			||||||
 | 
					    __file__)) + os.path.sep + os.path.pardir + os.path.sep
 | 
				
			||||||
 | 
					sys.path.insert(0, script_path)
 | 
				
			||||||
 | 
					import lxbuildenv
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					from litex.utils.litex_sim import main
 | 
				
			||||||
 | 
					main()
 | 
				
			||||||
							
								
								
									
										14
									
								
								hw/bin/litex_simple
									
									
									
									
									
										Executable file
									
								
							
							
						
						
									
										14
									
								
								hw/bin/litex_simple
									
									
									
									
									
										Executable file
									
								
							@@ -0,0 +1,14 @@
 | 
				
			|||||||
 | 
					#!/usr/bin/env python3
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					import sys
 | 
				
			||||||
 | 
					import os
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					# This script lives in the "bin" directory, but uses a helper script in the parent
 | 
				
			||||||
 | 
					# directory.  Obtain the current path so we can get the absolute parent path.
 | 
				
			||||||
 | 
					script_path = os.path.dirname(os.path.realpath(
 | 
				
			||||||
 | 
					    __file__)) + os.path.sep + os.path.pardir + os.path.sep
 | 
				
			||||||
 | 
					sys.path.insert(0, script_path)
 | 
				
			||||||
 | 
					import lxbuildenv
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					from litex.boards.targets.simple import main
 | 
				
			||||||
 | 
					main()
 | 
				
			||||||
							
								
								
									
										14
									
								
								hw/bin/litex_term
									
									
									
									
									
										Executable file
									
								
							
							
						
						
									
										14
									
								
								hw/bin/litex_term
									
									
									
									
									
										Executable file
									
								
							@@ -0,0 +1,14 @@
 | 
				
			|||||||
 | 
					#!/usr/bin/env python3
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					import sys
 | 
				
			||||||
 | 
					import os
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					# This script lives in the "bin" directory, but uses a helper script in the parent
 | 
				
			||||||
 | 
					# directory.  Obtain the current path so we can get the absolute parent path.
 | 
				
			||||||
 | 
					script_path = os.path.dirname(os.path.realpath(
 | 
				
			||||||
 | 
					    __file__)) + os.path.sep + os.path.pardir + os.path.sep
 | 
				
			||||||
 | 
					sys.path.insert(0, script_path)
 | 
				
			||||||
 | 
					import lxbuildenv
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					from litex.utils.litex_term import main
 | 
				
			||||||
 | 
					main()
 | 
				
			||||||
							
								
								
									
										14
									
								
								hw/bin/mkmscimg
									
									
									
									
									
										Executable file
									
								
							
							
						
						
									
										14
									
								
								hw/bin/mkmscimg
									
									
									
									
									
										Executable file
									
								
							@@ -0,0 +1,14 @@
 | 
				
			|||||||
 | 
					#!/usr/bin/env python3
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					import sys
 | 
				
			||||||
 | 
					import os
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					# This script lives in the "bin" directory, but uses a helper script in the parent
 | 
				
			||||||
 | 
					# directory.  Obtain the current path so we can get the absolute parent path.
 | 
				
			||||||
 | 
					script_path = os.path.dirname(os.path.realpath(
 | 
				
			||||||
 | 
					    __file__)) + os.path.sep + os.path.pardir + os.path.sep
 | 
				
			||||||
 | 
					sys.path.insert(0, script_path)
 | 
				
			||||||
 | 
					import lxbuildenv
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					from litex.soc.tools.mkmscimg import main
 | 
				
			||||||
 | 
					main()
 | 
				
			||||||
							
								
								
									
										160
									
								
								hw/crc5-test.c
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										160
									
								
								hw/crc5-test.c
									
									
									
									
									
										Normal file
									
								
							@@ -0,0 +1,160 @@
 | 
				
			|||||||
 | 
					#include <stdio.h>
 | 
				
			||||||
 | 
					#include <stdint.h>
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					const uint8_t crc5Table4[] =
 | 
				
			||||||
 | 
					        {
 | 
				
			||||||
 | 
					            0x00, 0x0E, 0x1C, 0x12, 0x11, 0x1F, 0x0D, 0x03,
 | 
				
			||||||
 | 
					            0x0B, 0x05, 0x17, 0x19, 0x1A, 0x14, 0x06, 0x08};
 | 
				
			||||||
 | 
					const uint8_t crc5Table0[] =
 | 
				
			||||||
 | 
					        {
 | 
				
			||||||
 | 
					            0x00, 0x16, 0x05, 0x13, 0x0A, 0x1C, 0x0F, 0x19,
 | 
				
			||||||
 | 
					            0x14, 0x02, 0x11, 0x07, 0x1E, 0x08, 0x1B, 0x0D};
 | 
				
			||||||
 | 
					//---------------
 | 
				
			||||||
 | 
					int crc5Check(const uint8_t *data)
 | 
				
			||||||
 | 
					//---------------
 | 
				
			||||||
 | 
					{
 | 
				
			||||||
 | 
					    uint8_t b = data[0] ^ 0x1F;
 | 
				
			||||||
 | 
					    uint8_t crc = crc5Table4[b & 0x0F] ^ crc5Table0[(b >> 4) & 0x0F];
 | 
				
			||||||
 | 
					    b = data[1] ^ crc;
 | 
				
			||||||
 | 
					    return (crc5Table4[b & 0x0F] ^ crc5Table0[(b >> 4) & 0x0F]) == 0x06;
 | 
				
			||||||
 | 
					}
 | 
				
			||||||
 | 
					//  crc5Check
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					int do_check(uint16_t pkt) {
 | 
				
			||||||
 | 
					    uint8_t data[2] = {
 | 
				
			||||||
 | 
					        pkt >> 8,
 | 
				
			||||||
 | 
					        pkt,
 | 
				
			||||||
 | 
					    };
 | 
				
			||||||
 | 
					    return crc5Check(data);
 | 
				
			||||||
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					#define INT_SIZE 32
 | 
				
			||||||
 | 
					unsigned CRC5(unsigned dwInput, int iBitcnt)
 | 
				
			||||||
 | 
					{
 | 
				
			||||||
 | 
					    const uint32_t poly5 = (0x05 << (INT_SIZE-5));
 | 
				
			||||||
 | 
					    uint32_t crc5  = (0x1f << (INT_SIZE-5));
 | 
				
			||||||
 | 
					    uint32_t udata = (dwInput << (INT_SIZE-iBitcnt));
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					    if ( (iBitcnt<1) || (iBitcnt>INT_SIZE) )    // Validate iBitcnt
 | 
				
			||||||
 | 
					        return 0xffffffff;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					    while (iBitcnt--)
 | 
				
			||||||
 | 
					    {
 | 
				
			||||||
 | 
					        if ( (udata ^ crc5) & (0x1<<(INT_SIZE-1)) ) // bit4 != bit4?
 | 
				
			||||||
 | 
					        {
 | 
				
			||||||
 | 
					            crc5 <<= 1;
 | 
				
			||||||
 | 
					            crc5 ^= poly5;
 | 
				
			||||||
 | 
					        }
 | 
				
			||||||
 | 
					        else
 | 
				
			||||||
 | 
					            crc5 <<= 1;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					        udata <<= 1;
 | 
				
			||||||
 | 
					    }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					    // Shift back into position
 | 
				
			||||||
 | 
					    crc5 >>= (INT_SIZE-5);
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					    // Invert contents to generate crc field
 | 
				
			||||||
 | 
					    crc5 ^= 0x1f;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					    return crc5;
 | 
				
			||||||
 | 
					} //CRC5()
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					static uint32_t reverse_sof(uint32_t data) {
 | 
				
			||||||
 | 
					    int i;
 | 
				
			||||||
 | 
					    uint32_t data_flipped = 0;
 | 
				
			||||||
 | 
					    for (i = 0; i < 11; i++)
 | 
				
			||||||
 | 
					        if (data & (1 << i))
 | 
				
			||||||
 | 
					            data_flipped |= 1 << (10 - i);
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					    return data_flipped;
 | 
				
			||||||
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					static uint8_t reverse_byte(uint8_t data) {
 | 
				
			||||||
 | 
					    int i;
 | 
				
			||||||
 | 
					    uint8_t data_flipped = 0;
 | 
				
			||||||
 | 
					    for (i = 0; i < 8; i++)
 | 
				
			||||||
 | 
					        if (data & (1 << i))
 | 
				
			||||||
 | 
					            data_flipped |= 1 << (7 - i);
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					    return data_flipped;
 | 
				
			||||||
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					static uint8_t reverse_crc5(uint8_t data) {
 | 
				
			||||||
 | 
					    int i;
 | 
				
			||||||
 | 
					    uint8_t data_flipped = 0;
 | 
				
			||||||
 | 
					    for (i = 0; i < 5; i++)
 | 
				
			||||||
 | 
					        if (data & (1 << i))
 | 
				
			||||||
 | 
					            data_flipped |= 1 << (4 - i);
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					    return data_flipped;
 | 
				
			||||||
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					static uint16_t make_token(uint16_t data) {
 | 
				
			||||||
 | 
					    uint16_t val = 0;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					    data = reverse_sof(data);
 | 
				
			||||||
 | 
					    val = data << 5;
 | 
				
			||||||
 | 
					    val |= CRC5(data, 11);
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					    return (reverse_byte(val >> 8) << 8) | reverse_byte(val);
 | 
				
			||||||
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					int do_crc5(uint16_t pkt) {
 | 
				
			||||||
 | 
					    uint8_t pkt_flipped[2] = {
 | 
				
			||||||
 | 
					        reverse_byte(pkt >> 8),
 | 
				
			||||||
 | 
					        reverse_byte(pkt),
 | 
				
			||||||
 | 
					    };
 | 
				
			||||||
 | 
					    uint32_t data = (pkt_flipped[1] >> 5) | (pkt_flipped[0] << 3);
 | 
				
			||||||
 | 
					    uint32_t data_flipped;
 | 
				
			||||||
 | 
					    uint8_t crc;
 | 
				
			||||||
 | 
					    uint8_t found_crc = (pkt >> 3) & 0x1f;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					    data_flipped = reverse_sof(data);
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					    crc = CRC5(data, 11);
 | 
				
			||||||
 | 
					    crc = reverse_crc5(crc);
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					    uint16_t reconstructed = make_token(data_flipped);
 | 
				
			||||||
 | 
					    uint16_t wire = (reverse_byte(pkt >> 8) << 8) | reverse_byte(pkt);
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					    printf("Packet: 0x%04x  FCRC: %02x  Data: 0x%04x  "
 | 
				
			||||||
 | 
					    "Flipped: 0x%04x  CRC5: 0x%02x  Pass? %d  Reconstructed: 0x%04x  Wire: %04x\n",
 | 
				
			||||||
 | 
					        pkt, found_crc, data, data_flipped, crc, do_check(pkt),
 | 
				
			||||||
 | 
					        reconstructed,
 | 
				
			||||||
 | 
					        wire
 | 
				
			||||||
 | 
					        );
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					    return crc;
 | 
				
			||||||
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					#define ARRAY_SIZE(x) (sizeof(x) / sizeof(*x))
 | 
				
			||||||
 | 
					int main(int argc, char **argv)
 | 
				
			||||||
 | 
					{
 | 
				
			||||||
 | 
					    uint32_t check_bytes[] = {
 | 
				
			||||||
 | 
					        /*
 | 
				
			||||||
 | 
					        0xff3c,
 | 
				
			||||||
 | 
					        0x12c5,
 | 
				
			||||||
 | 
					        0xe17e,
 | 
				
			||||||
 | 
					        0x19f5,
 | 
				
			||||||
 | 
					        0x0225,
 | 
				
			||||||
 | 
					        0x0165,
 | 
				
			||||||
 | 
					        0x009d,
 | 
				
			||||||
 | 
					        0x102f,
 | 
				
			||||||
 | 
					        make_token(1013),
 | 
				
			||||||
 | 
					        make_token(1429),
 | 
				
			||||||
 | 
					        make_token(100),
 | 
				
			||||||
 | 
					        */
 | 
				
			||||||
 | 
					        0x82bc,
 | 
				
			||||||
 | 
					        make_token(0x0483),//0x5fde,
 | 
				
			||||||
 | 
					        0x843c,
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					    };
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					    unsigned int i;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					    for (i = 0; i < ARRAY_SIZE(check_bytes); i++)
 | 
				
			||||||
 | 
					        do_crc5(check_bytes[i]);
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					    return 0;
 | 
				
			||||||
 | 
					}
 | 
				
			||||||
							
								
								
									
										76
									
								
								hw/csr-test.py
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										76
									
								
								hw/csr-test.py
									
									
									
									
									
										Normal file
									
								
							@@ -0,0 +1,76 @@
 | 
				
			|||||||
 | 
					#!/usr/bin/env python3
 | 
				
			||||||
 | 
					# This variable defines all the external programs that this module
 | 
				
			||||||
 | 
					# relies on.  lxbuildenv reads this variable in order to ensure
 | 
				
			||||||
 | 
					# the build will finish without exiting due to missing third-party
 | 
				
			||||||
 | 
					# programs.
 | 
				
			||||||
 | 
					LX_DEPENDENCIES = ["riscv", "icestorm", "yosys"]
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					# Import lxbuildenv to integrate the deps/ directory
 | 
				
			||||||
 | 
					import lxbuildenv
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					# Disable pylint's E1101, which breaks completely on migen
 | 
				
			||||||
 | 
					#pylint:disable=E1101
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					from migen import Module, Signal, Instance, ClockDomain, If, run_simulation
 | 
				
			||||||
 | 
					from migen.genlib.resetsync import AsyncResetSynchronizer
 | 
				
			||||||
 | 
					from litex.build.lattice.platform import LatticePlatform
 | 
				
			||||||
 | 
					from litex.build.generic_platform import Pins, IOStandard, Misc, Subsignal
 | 
				
			||||||
 | 
					from litex.soc.integration import SoCCore
 | 
				
			||||||
 | 
					from litex.soc.integration.builder import Builder
 | 
				
			||||||
 | 
					from litex.soc.integration.soc_core import csr_map_update
 | 
				
			||||||
 | 
					from litex.soc.interconnect import wishbone
 | 
				
			||||||
 | 
					from litex.soc.interconnect.csr import CSR, CSRStorage, AutoCSR
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					def csr_test(dut):
 | 
				
			||||||
 | 
					    for i in range(20):
 | 
				
			||||||
 | 
					        counter = yield dut.counter
 | 
				
			||||||
 | 
					        # test_value = yield dut.test_value.w
 | 
				
			||||||
 | 
					        (test_value) = yield from dut.test_value.read()
 | 
				
			||||||
 | 
					        print("CSR value: {} / {}".format(counter, test_value))
 | 
				
			||||||
 | 
					        # yield from CSRStorage.update_csrs()
 | 
				
			||||||
 | 
					        yield
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					class TestCSR(Module, AutoCSR):
 | 
				
			||||||
 | 
					    def __init__(self):
 | 
				
			||||||
 | 
					        # self.counter = Signal(8)
 | 
				
			||||||
 | 
					        # self.test_value = CSR(8)
 | 
				
			||||||
 | 
					        # self.result = Signal(8)
 | 
				
			||||||
 | 
					        # self.read_result = Signal()
 | 
				
			||||||
 | 
					        # self.sync += [
 | 
				
			||||||
 | 
					        #     self.counter.eq(self.counter+1),
 | 
				
			||||||
 | 
					        #     self.test_value.w.eq(self.counter),
 | 
				
			||||||
 | 
					        #     self.result.eq(self.test_value.r),
 | 
				
			||||||
 | 
					        #     self.read_result.eq(self.test_value.re),
 | 
				
			||||||
 | 
					        # ]
 | 
				
			||||||
 | 
					        self.counter = Signal(8)
 | 
				
			||||||
 | 
					        self.test_value = CSRStorage(8, write_from_dev=True)
 | 
				
			||||||
 | 
					        self.result = Signal(8)
 | 
				
			||||||
 | 
					        self.result_re = Signal()
 | 
				
			||||||
 | 
					        self.sync += [
 | 
				
			||||||
 | 
					            self.counter.eq(self.counter+1),
 | 
				
			||||||
 | 
					            self.test_value.we.eq(1),
 | 
				
			||||||
 | 
					            self.test_value.dat_w.eq(self.counter),
 | 
				
			||||||
 | 
					            self.result.eq(self.test_value.storage),
 | 
				
			||||||
 | 
					            self.result_re.eq(self.test_value.re),
 | 
				
			||||||
 | 
					        ]
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					def main():
 | 
				
			||||||
 | 
					    dut = TestCSR()
 | 
				
			||||||
 | 
					    for x in dir(dut):
 | 
				
			||||||
 | 
					        print("x: {}".format(x))
 | 
				
			||||||
 | 
					    for csr in dut.get_csrs():
 | 
				
			||||||
 | 
					        print("csr: {}".format(csr))
 | 
				
			||||||
 | 
					        if isinstance(csr, CSRStorage) and hasattr(csr, "dat_w"):
 | 
				
			||||||
 | 
					            print("Adding CSRStorage patch")
 | 
				
			||||||
 | 
					            dut.sync += [
 | 
				
			||||||
 | 
					                If(csr.we,
 | 
				
			||||||
 | 
					                    csr.storage.eq(csr.dat_w),
 | 
				
			||||||
 | 
					                    csr.re.eq(1),
 | 
				
			||||||
 | 
					                ).Else(
 | 
				
			||||||
 | 
					                    csr.re.eq(0),
 | 
				
			||||||
 | 
					                )
 | 
				
			||||||
 | 
					            ]
 | 
				
			||||||
 | 
					    run_simulation(dut, csr_test(dut), vcd_name="csr-test.vcd")
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					if __name__ == "__main__":
 | 
				
			||||||
 | 
					    main()
 | 
				
			||||||
							
								
								
									
										1
									
								
								hw/deps/litedram
									
									
									
									
									
										Submodule
									
								
							
							
								
								
								
								
								
							
						
						
									
										1
									
								
								hw/deps/litedram
									
									
									
									
									
										Submodule
									
								
							 Submodule hw/deps/litedram added at fd3e9afbcd
									
								
							
							
								
								
									
										1
									
								
								hw/deps/liteeth
									
									
									
									
									
										Submodule
									
								
							
							
								
								
								
								
								
							
						
						
									
										1
									
								
								hw/deps/liteeth
									
									
									
									
									
										Submodule
									
								
							 Submodule hw/deps/liteeth added at 77fa4bfb1e
									
								
							
							
								
								
									
										1
									
								
								hw/deps/liteiclink
									
									
									
									
									
										Submodule
									
								
							
							
								
								
								
								
								
							
						
						
									
										1
									
								
								hw/deps/liteiclink
									
									
									
									
									
										Submodule
									
								
							 Submodule hw/deps/liteiclink added at ee9ae87641
									
								
							
							
								
								
									
										1
									
								
								hw/deps/litepcie
									
									
									
									
									
										Submodule
									
								
							
							
								
								
								
								
								
							
						
						
									
										1
									
								
								hw/deps/litepcie
									
									
									
									
									
										Submodule
									
								
							 Submodule hw/deps/litepcie added at 3804c4947a
									
								
							
							
								
								
									
										1
									
								
								hw/deps/litescope
									
									
									
									
									
										Submodule
									
								
							
							
								
								
								
								
								
							
						
						
									
										1
									
								
								hw/deps/litescope
									
									
									
									
									
										Submodule
									
								
							 Submodule hw/deps/litescope added at c1d8bdf6f2
									
								
							
							
								
								
									
										1
									
								
								hw/deps/litesdcard
									
									
									
									
									
										Submodule
									
								
							
							
								
								
								
								
								
							
						
						
									
										1
									
								
								hw/deps/litesdcard
									
									
									
									
									
										Submodule
									
								
							 Submodule hw/deps/litesdcard added at c07165ff9f
									
								
							
							
								
								
									
										1
									
								
								hw/deps/liteusb
									
									
									
									
									
										Submodule
									
								
							
							
								
								
								
								
								
							
						
						
									
										1
									
								
								hw/deps/liteusb
									
									
									
									
									
										Submodule
									
								
							 Submodule hw/deps/liteusb added at 0a9110f901
									
								
							
							
								
								
									
										1
									
								
								hw/deps/litevideo
									
									
									
									
									
										Submodule
									
								
							
							
								
								
								
								
								
							
						
						
									
										1
									
								
								hw/deps/litevideo
									
									
									
									
									
										Submodule
									
								
							 Submodule hw/deps/litevideo added at 98e145fba8
									
								
							
							
								
								
									
										1
									
								
								hw/deps/litex
									
									
									
									
									
										Submodule
									
								
							
							
								
								
								
								
								
							
						
						
									
										1
									
								
								hw/deps/litex
									
									
									
									
									
										Submodule
									
								
							 Submodule hw/deps/litex added at ff155a474d
									
								
							
							
								
								
									
										1
									
								
								hw/deps/lxsocsupport
									
									
									
									
									
										Submodule
									
								
							
							
								
								
								
								
								
							
						
						
									
										1
									
								
								hw/deps/lxsocsupport
									
									
									
									
									
										Submodule
									
								
							 Submodule hw/deps/lxsocsupport added at 74f1333401
									
								
							
							
								
								
									
										1
									
								
								hw/deps/migen
									
									
									
									
									
										Submodule
									
								
							
							
								
								
								
								
								
							
						
						
									
										1
									
								
								hw/deps/migen
									
									
									
									
									
										Submodule
									
								
							 Submodule hw/deps/migen added at ae421054f1
									
								
							
							
								
								
									
										1
									
								
								hw/deps/pyserial
									
									
									
									
									
										Submodule
									
								
							
							
								
								
								
								
								
							
						
						
									
										1
									
								
								hw/deps/pyserial
									
									
									
									
									
										Submodule
									
								
							 Submodule hw/deps/pyserial added at a4d8f27bf6
									
								
							
							
								
								
									
										1
									
								
								hw/deps/valentyusb
									
									
									
									
									
										Submodule
									
								
							
							
								
								
								
								
								
							
						
						
									
										1
									
								
								hw/deps/valentyusb
									
									
									
									
									
										Submodule
									
								
							 Submodule hw/deps/valentyusb added at ac9a522847
									
								
							
							
								
								
									
										266
									
								
								hw/foboot-bitstream.py
									
									
									
									
									
										Executable file
									
								
							
							
						
						
									
										266
									
								
								hw/foboot-bitstream.py
									
									
									
									
									
										Executable file
									
								
							@@ -0,0 +1,266 @@
 | 
				
			|||||||
 | 
					#!/usr/bin/env python3
 | 
				
			||||||
 | 
					# This variable defines all the external programs that this module
 | 
				
			||||||
 | 
					# relies on.  lxbuildenv reads this variable in order to ensure
 | 
				
			||||||
 | 
					# the build will finish without exiting due to missing third-party
 | 
				
			||||||
 | 
					# programs.
 | 
				
			||||||
 | 
					LX_DEPENDENCIES = ["riscv", "icestorm", "yosys"]
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					# Import lxbuildenv to integrate the deps/ directory
 | 
				
			||||||
 | 
					import lxbuildenv
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					# Disable pylint's E1101, which breaks completely on migen
 | 
				
			||||||
 | 
					#pylint:disable=E1101
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					#from migen import *
 | 
				
			||||||
 | 
					from migen import Module, Signal, Instance, ClockDomain, If
 | 
				
			||||||
 | 
					from migen.genlib.resetsync import AsyncResetSynchronizer
 | 
				
			||||||
 | 
					from litex.build.lattice.platform import LatticePlatform
 | 
				
			||||||
 | 
					from litex.build.generic_platform import Pins, IOStandard, Misc, Subsignal
 | 
				
			||||||
 | 
					from litex.soc.integration import SoCCore
 | 
				
			||||||
 | 
					from litex.soc.integration.builder import Builder
 | 
				
			||||||
 | 
					from litex.soc.integration.soc_core import csr_map_update
 | 
				
			||||||
 | 
					from litex.soc.interconnect import wishbone
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					from valentyusb import usbcore
 | 
				
			||||||
 | 
					from valentyusb.usbcore import io as usbio
 | 
				
			||||||
 | 
					from valentyusb.usbcore.cpu import epmem, unififo, epfifo
 | 
				
			||||||
 | 
					from valentyusb.usbcore.endpoint import EndpointType
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					from lxsocsupport import up5kspram, spi_flash
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					import argparse
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					_io = [
 | 
				
			||||||
 | 
					    ("serial", 0,
 | 
				
			||||||
 | 
					        Subsignal("rx", Pins("21")),
 | 
				
			||||||
 | 
					        Subsignal("tx", Pins("13"), Misc("PULLUP")),
 | 
				
			||||||
 | 
					        IOStandard("LVCMOS33")
 | 
				
			||||||
 | 
					    ),
 | 
				
			||||||
 | 
					    ("usb", 0,
 | 
				
			||||||
 | 
					        Subsignal("d_p", Pins("34")),
 | 
				
			||||||
 | 
					        Subsignal("d_n", Pins("37")),
 | 
				
			||||||
 | 
					        Subsignal("pullup", Pins("35")),
 | 
				
			||||||
 | 
					        IOStandard("LVCMOS33")
 | 
				
			||||||
 | 
					    ),
 | 
				
			||||||
 | 
					    ("spiflash", 0,
 | 
				
			||||||
 | 
					        Subsignal("cs_n",      Pins("16"), IOStandard("LVCMOS33")),
 | 
				
			||||||
 | 
					        Subsignal("clk",       Pins("15"), IOStandard("LVCMOS33")),
 | 
				
			||||||
 | 
					        Subsignal("miso",        Pins("17"), IOStandard("LVCMOS33")),
 | 
				
			||||||
 | 
					        Subsignal("mosi",        Pins("14"), IOStandard("LVCMOS33")),
 | 
				
			||||||
 | 
					        Subsignal("wp",      Pins("18"), IOStandard("LVCMOS33")),
 | 
				
			||||||
 | 
					        Subsignal("hold", Pins("19"), IOStandard("LVCMOS33")),
 | 
				
			||||||
 | 
					    ),
 | 
				
			||||||
 | 
					    ("spiflash4x", 0,
 | 
				
			||||||
 | 
					        Subsignal("cs_n", Pins("16"), IOStandard("LVCMOS33")),
 | 
				
			||||||
 | 
					        Subsignal("clk",  Pins("15"), IOStandard("LVCMOS33")),
 | 
				
			||||||
 | 
					        Subsignal("dq",   Pins("14 17 19 18"), IOStandard("LVCMOS33")),
 | 
				
			||||||
 | 
					    ),
 | 
				
			||||||
 | 
					    ("clk48", 0, Pins("44"), IOStandard("LVCMOS33"))
 | 
				
			||||||
 | 
					]
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					_connectors = []
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					class _CRG(Module):
 | 
				
			||||||
 | 
					    def __init__(self, platform):
 | 
				
			||||||
 | 
					        clk12 = Signal()
 | 
				
			||||||
 | 
					        # # "0b00" Sets 48MHz HFOSC output
 | 
				
			||||||
 | 
					        # # "0b01" Sets 24MHz HFOSC output.
 | 
				
			||||||
 | 
					        # # "0b10" Sets 12MHz HFOSC output.
 | 
				
			||||||
 | 
					        # # "0b11" Sets 6MHz HFOSC output
 | 
				
			||||||
 | 
					        # self.specials += Instance(
 | 
				
			||||||
 | 
					        #     "SB_HFOSC",
 | 
				
			||||||
 | 
					        #     i_CLKHFEN=1,
 | 
				
			||||||
 | 
					        #     i_CLKHFPU=1,
 | 
				
			||||||
 | 
					        #     o_CLKHF=clk12,
 | 
				
			||||||
 | 
					        #     p_CLKHF_DIV="0b10", # 12MHz
 | 
				
			||||||
 | 
					        # )
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					        self.clock_domains.cd_sys = ClockDomain()
 | 
				
			||||||
 | 
					        self.clock_domains.cd_usb_12 = ClockDomain()
 | 
				
			||||||
 | 
					        self.reset = Signal()
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					        # FIXME: Use PLL, increase system clock to 32 MHz, pending nextpnr
 | 
				
			||||||
 | 
					        # fixes.
 | 
				
			||||||
 | 
					        self.comb += self.cd_sys.clk.eq(clk12)
 | 
				
			||||||
 | 
					        self.comb += self.cd_usb_12.clk.eq(clk12)
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					        # POR reset logic- POR generated from sys clk, POR logic feeds sys clk
 | 
				
			||||||
 | 
					        # reset.
 | 
				
			||||||
 | 
					        self.clock_domains.cd_por = ClockDomain()
 | 
				
			||||||
 | 
					        reset_delay = Signal(12, reset=4095)
 | 
				
			||||||
 | 
					        self.comb += [
 | 
				
			||||||
 | 
					            self.cd_por.clk.eq(self.cd_sys.clk),
 | 
				
			||||||
 | 
					            self.cd_sys.rst.eq(reset_delay != 0),
 | 
				
			||||||
 | 
					            self.cd_usb_12.rst.eq(reset_delay != 0)
 | 
				
			||||||
 | 
					        ]
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					        # Divide clk48 down to clk12, to ensure they're synchronized.
 | 
				
			||||||
 | 
					        clk12_counter = Signal(2)
 | 
				
			||||||
 | 
					        self.sync.usb_48 += [
 | 
				
			||||||
 | 
					            clk12_counter.eq(clk12_counter + 1),
 | 
				
			||||||
 | 
					        ]
 | 
				
			||||||
 | 
					        self.specials += Instance(
 | 
				
			||||||
 | 
					            "SB_GB",
 | 
				
			||||||
 | 
					            i_USER_SIGNAL_TO_GLOBAL_BUFFER=clk12_counter[1],
 | 
				
			||||||
 | 
					            o_GLOBAL_BUFFER_OUTPUT=clk12,
 | 
				
			||||||
 | 
					        )
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					        self.sync.por += \
 | 
				
			||||||
 | 
					            If(reset_delay != 0,
 | 
				
			||||||
 | 
					                reset_delay.eq(reset_delay - 1)
 | 
				
			||||||
 | 
					            )
 | 
				
			||||||
 | 
					        self.specials += AsyncResetSynchronizer(self.cd_por, self.reset)
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					        self.clock_domains.cd_usb_48 = ClockDomain()
 | 
				
			||||||
 | 
					        platform.add_period_constraint(self.cd_usb_48.clk, 1e9/48e6)
 | 
				
			||||||
 | 
					        self.comb += [
 | 
				
			||||||
 | 
					            self.cd_usb_48.clk.eq(platform.request("clk48")),
 | 
				
			||||||
 | 
					        ]
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					class RandomFirmwareROM(wishbone.SRAM):
 | 
				
			||||||
 | 
					    """
 | 
				
			||||||
 | 
					    Seed the random data with a fixed number, so different bitstreams
 | 
				
			||||||
 | 
					    can all share firmware.
 | 
				
			||||||
 | 
					    """
 | 
				
			||||||
 | 
					    def __init__(self, size, seed=2373):
 | 
				
			||||||
 | 
					        def xorshift32(x):
 | 
				
			||||||
 | 
					            x = x ^ (x << 13) & 0xffffffff
 | 
				
			||||||
 | 
					            x = x ^ (x >> 17) & 0xffffffff
 | 
				
			||||||
 | 
					            x = x ^ (x << 5)  & 0xffffffff
 | 
				
			||||||
 | 
					            return x & 0xffffffff
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					        def get_rand(x):
 | 
				
			||||||
 | 
					            out = 0
 | 
				
			||||||
 | 
					            for i in range(32):
 | 
				
			||||||
 | 
					                x = xorshift32(x)
 | 
				
			||||||
 | 
					                if (x & 1) == 1:
 | 
				
			||||||
 | 
					                    out = out | (1 << i)
 | 
				
			||||||
 | 
					            return out & 0xffffffff
 | 
				
			||||||
 | 
					        data = []
 | 
				
			||||||
 | 
					        seed = 1
 | 
				
			||||||
 | 
					        for d in range(int(size / 4)):
 | 
				
			||||||
 | 
					            seed = get_rand(seed)
 | 
				
			||||||
 | 
					            data.append(seed)
 | 
				
			||||||
 | 
					        print("Firmware {} bytes of random data".format(size))
 | 
				
			||||||
 | 
					        wishbone.SRAM.__init__(self, size, read_only=True, init=data)
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					class Platform(LatticePlatform):
 | 
				
			||||||
 | 
					    default_clk_name = "clk48"
 | 
				
			||||||
 | 
					    default_clk_period = 20.833
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					    gateware_size = 0x20000
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					    def __init__(self, toolchain="icestorm"):
 | 
				
			||||||
 | 
					        LatticePlatform.__init__(self, "ice40-up5k-sg48", _io, _connectors, toolchain="icestorm")
 | 
				
			||||||
 | 
					    def create_programmer(self):
 | 
				
			||||||
 | 
					        raise ValueError("programming is not supported")
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					    # def do_finalize(self, fragment):
 | 
				
			||||||
 | 
					        # LatticePlatform.do_finalize(self, fragment)
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					class BaseSoC(SoCCore):
 | 
				
			||||||
 | 
					    csr_peripherals = [
 | 
				
			||||||
 | 
					        "cpu_or_bridge",
 | 
				
			||||||
 | 
					        "usb",
 | 
				
			||||||
 | 
					        "usb_obuf",
 | 
				
			||||||
 | 
					        "usb_ibuf",
 | 
				
			||||||
 | 
					    ]
 | 
				
			||||||
 | 
					    csr_map_update(SoCCore.csr_map, csr_peripherals)
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					    mem_map = {
 | 
				
			||||||
 | 
					        "spiflash": 0x20000000,  # (default shadow @0xa0000000)
 | 
				
			||||||
 | 
					    }
 | 
				
			||||||
 | 
					    mem_map.update(SoCCore.mem_map)
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					    interrupt_map = {
 | 
				
			||||||
 | 
					        "usb": 3,
 | 
				
			||||||
 | 
					    }
 | 
				
			||||||
 | 
					    interrupt_map.update(SoCCore.interrupt_map)
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					    def __init__(self, platform, boot_source="random_rom", **kwargs):
 | 
				
			||||||
 | 
					        # Disable integrated RAM as we'll add it later
 | 
				
			||||||
 | 
					        self.integrated_sram_size = 0
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					        clk_freq = int(12e6)
 | 
				
			||||||
 | 
					        self.submodules.crg = _CRG(platform)
 | 
				
			||||||
 | 
					        platform.add_period_constraint(self.crg.cd_sys.clk, 1e9/clk_freq)
 | 
				
			||||||
 | 
					        platform.add_period_constraint(self.crg.cd_usb_12.clk, 1e9/clk_freq)
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					        SoCCore.__init__(self, platform, clk_freq, integrated_sram_size=0, **kwargs)
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					        # SPRAM- UP5K has single port RAM, might as well use it as SRAM to
 | 
				
			||||||
 | 
					        # free up scarce block RAM.
 | 
				
			||||||
 | 
					        spram_size = 128*1024
 | 
				
			||||||
 | 
					        self.submodules.spram = up5kspram.Up5kSPRAM(size=spram_size)
 | 
				
			||||||
 | 
					        self.register_mem("sram", 0x10000000, self.spram.bus, spram_size)
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					        if boot_source == "random_rom":
 | 
				
			||||||
 | 
					            kwargs['cpu_reset_address']=0
 | 
				
			||||||
 | 
					            bios_size = 0x2000
 | 
				
			||||||
 | 
					            self.submodules.random_rom = RandomFirmwareROM(bios_size)
 | 
				
			||||||
 | 
					            self.add_constant("ROM_DISABLE", 1)
 | 
				
			||||||
 | 
					            self.register_rom(self.random_rom.bus, bios_size)
 | 
				
			||||||
 | 
					        elif boot_source == "bios_rom":
 | 
				
			||||||
 | 
					            kwargs['cpu_reset_address']=0
 | 
				
			||||||
 | 
					            bios_size = 0x2000
 | 
				
			||||||
 | 
					            self.add_memory_region("rom", kwargs['cpu_reset_address'], bios_size)
 | 
				
			||||||
 | 
					        elif boot_source == "spi_rom":
 | 
				
			||||||
 | 
					            bios_size = 0x8000
 | 
				
			||||||
 | 
					            kwargs['cpu_reset_address']=self.mem_map["spiflash"]+platform.gateware_size
 | 
				
			||||||
 | 
					            self.add_memory_region("rom", kwargs['cpu_reset_address'], bios_size)
 | 
				
			||||||
 | 
					            self.add_constant("ROM_DISABLE", 1)
 | 
				
			||||||
 | 
					            self.flash_boot_address = self.mem_map["spiflash"]+platform.gateware_size+bios_size
 | 
				
			||||||
 | 
					            self.add_memory_region("user_flash",
 | 
				
			||||||
 | 
					                self.flash_boot_address,
 | 
				
			||||||
 | 
					                # Leave a grace area- possible one-by-off bug in add_memory_region?
 | 
				
			||||||
 | 
					                # Possible fix: addr < origin + length - 1
 | 
				
			||||||
 | 
					                platform.spiflash_total_size - (self.flash_boot_address - self.mem_map["spiflash"]) - 0x100)
 | 
				
			||||||
 | 
					        else:
 | 
				
			||||||
 | 
					            raise ValueError("unrecognized boot_source: {}".format(boot_source))
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					        # Add USB pads
 | 
				
			||||||
 | 
					        usb_pads = platform.request("usb")
 | 
				
			||||||
 | 
					        usb_iobuf = usbio.IoBuf(usb_pads.d_p, usb_pads.d_n, usb_pads.pullup)
 | 
				
			||||||
 | 
					        self.submodules.usb = epfifo.PerEndpointFifoInterface(usb_iobuf, endpoints=[EndpointType.BIDIR])
 | 
				
			||||||
 | 
					        # self.submodules.usb = epmem.MemInterface(usb_iobuf)
 | 
				
			||||||
 | 
					        # self.submodules.usb = unififo.UsbUniFifo(usb_iobuf)
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					        # Disable final deep-sleep power down so firmware words are loaded
 | 
				
			||||||
 | 
					        # onto softcore's address bus.
 | 
				
			||||||
 | 
					        platform.toolchain.build_template[3] = "icepack -s {build_name}.txt {build_name}.bin"
 | 
				
			||||||
 | 
					        platform.toolchain.nextpnr_build_template[2] = "icepack -s {build_name}.txt {build_name}.bin"
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					def main():
 | 
				
			||||||
 | 
					    platform = Platform()
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					    parser = argparse.ArgumentParser(
 | 
				
			||||||
 | 
					        description="Build Fomu Main Gateware",
 | 
				
			||||||
 | 
					        add_help=False)
 | 
				
			||||||
 | 
					    parser.add_argument(
 | 
				
			||||||
 | 
					        "--bios", help="use bios as boot source", action="store_true"
 | 
				
			||||||
 | 
					    )
 | 
				
			||||||
 | 
					    parser.add_argument(
 | 
				
			||||||
 | 
					        "--rand", help="use random data as boot source", action="store_false"
 | 
				
			||||||
 | 
					    )
 | 
				
			||||||
 | 
					    parser.add_argument(
 | 
				
			||||||
 | 
					        "--spi", help="boot from spi", action="store_true"
 | 
				
			||||||
 | 
					    )
 | 
				
			||||||
 | 
					    (args, rest) = parser.parse_known_args()
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					    if args.rand:
 | 
				
			||||||
 | 
					        boot_source="random_rom"
 | 
				
			||||||
 | 
					        compile_software=False
 | 
				
			||||||
 | 
					    elif args.bios:
 | 
				
			||||||
 | 
					        boot_source="bios_rom"
 | 
				
			||||||
 | 
					        compile_software=True
 | 
				
			||||||
 | 
					    elif args.spi:
 | 
				
			||||||
 | 
					        boot_source = "spi_rom"
 | 
				
			||||||
 | 
					        compile_software = False
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					    soc = BaseSoC(platform, cpu_type="vexriscv", cpu_variant="min", boot_source=boot_source)
 | 
				
			||||||
 | 
					    builder = Builder(soc, output_dir="build", csr_csv="test/csr.csv", compile_software=compile_software)
 | 
				
			||||||
 | 
					    vns = builder.build()
 | 
				
			||||||
 | 
					    soc.do_exit(vns)
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					if __name__ == "__main__":
 | 
				
			||||||
 | 
					    main()
 | 
				
			||||||
							
								
								
									
										527
									
								
								hw/lxbuildenv.py
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										527
									
								
								hw/lxbuildenv.py
									
									
									
									
									
										Normal file
									
								
							@@ -0,0 +1,527 @@
 | 
				
			|||||||
 | 
					#!/usr/bin/env python3
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					# This script enables easy, cross-platform building without the need
 | 
				
			||||||
 | 
					# to install third-party Python modules.
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					import sys
 | 
				
			||||||
 | 
					import os
 | 
				
			||||||
 | 
					import subprocess
 | 
				
			||||||
 | 
					import argparse
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					DEPS_DIR = "deps"
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					DEFAULT_DEPS = {
 | 
				
			||||||
 | 
					    'migen':        'https://github.com/m-labs/migen.git',
 | 
				
			||||||
 | 
					    'litex':        'https://github.com/enjoy-digital/litex.git',
 | 
				
			||||||
 | 
					    'litescope':    'https://github.com/enjoy-digital/litescope.git',
 | 
				
			||||||
 | 
					    'pyserial':     'https://github.com/pyserial/pyserial.git',
 | 
				
			||||||
 | 
					    'liteeth':      'https://github.com/enjoy-digital/liteeth.git',
 | 
				
			||||||
 | 
					    'liteusb':      'https://github.com/enjoy-digital/liteusb.git',
 | 
				
			||||||
 | 
					    'litedram':     'https://github.com/enjoy-digital/litedram.git',
 | 
				
			||||||
 | 
					    'litepcie':     'https://github.com/enjoy-digital/litepcie.git',
 | 
				
			||||||
 | 
					    'litesdcard':   'https://github.com/enjoy-digital/litesdcard.git',
 | 
				
			||||||
 | 
					    'liteiclink':   'https://github.com/enjoy-digital/liteiclink.git',
 | 
				
			||||||
 | 
					    'litevideo':    'https://github.com/enjoy-digital/litevideo.git',
 | 
				
			||||||
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					# Obtain the path to this script, plus a trailing separator.  This will
 | 
				
			||||||
 | 
					# be used later on to construct various environment variables for paths
 | 
				
			||||||
 | 
					# to a variety of support directories.
 | 
				
			||||||
 | 
					script_path = os.path.dirname(os.path.realpath(__file__)) + os.path.sep
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					# Look through the specified file for known variables to get the dependency list
 | 
				
			||||||
 | 
					def get_required_dependencies(filename):
 | 
				
			||||||
 | 
					    import ast
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					    # Always check the Python version
 | 
				
			||||||
 | 
					    dependencies = {
 | 
				
			||||||
 | 
					        'python': 1
 | 
				
			||||||
 | 
					    }
 | 
				
			||||||
 | 
					    main_src = ""
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					    try:
 | 
				
			||||||
 | 
					        with open(sys.argv[0], 'r') as f:
 | 
				
			||||||
 | 
					            main_src = f.read()
 | 
				
			||||||
 | 
					        main_ast = ast.parse(main_src, filename=filename)
 | 
				
			||||||
 | 
					    except:
 | 
				
			||||||
 | 
					        return list(dependencies.keys())
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					    # Iterate through the top-level nodes looking for variables named
 | 
				
			||||||
 | 
					    # LX_DEPENDENCIES or LX_DEPENDENCY and get the values that are
 | 
				
			||||||
 | 
					    # assigned to them.
 | 
				
			||||||
 | 
					    for node in ast.iter_child_nodes(main_ast):
 | 
				
			||||||
 | 
					        if isinstance(node, ast.Assign):
 | 
				
			||||||
 | 
					            value = node.value
 | 
				
			||||||
 | 
					            for target in node.targets:
 | 
				
			||||||
 | 
					                if isinstance(target, ast.Name):
 | 
				
			||||||
 | 
					                    if target.id == "LX_DEPENDENCIES" or target.id == "LX_DEPENDENCY":
 | 
				
			||||||
 | 
					                        if isinstance(value, (ast.List, ast.Tuple)):
 | 
				
			||||||
 | 
					                            for elt in value.elts:
 | 
				
			||||||
 | 
					                                if isinstance(elt, ast.Str):
 | 
				
			||||||
 | 
					                                    dependencies[elt.s] = 1
 | 
				
			||||||
 | 
					                        elif isinstance(value, ast.Str):
 | 
				
			||||||
 | 
					                            dependencies[value.s] = 1
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					    # Set up sub-dependencies
 | 
				
			||||||
 | 
					    if 'riscv' in dependencies:
 | 
				
			||||||
 | 
					        dependencies['make'] = 1
 | 
				
			||||||
 | 
					    return list(dependencies.keys())
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					def get_python_path(script_path, args):
 | 
				
			||||||
 | 
					    # Python has no concept of a local dependency path, such as the C `-I``
 | 
				
			||||||
 | 
					    # switch, or the nodejs `node_modules` path, or the rust cargo registry.
 | 
				
			||||||
 | 
					    # Instead, it relies on an environment variable to append to the search
 | 
				
			||||||
 | 
					    # path.
 | 
				
			||||||
 | 
					    # Construct this variable by adding each subdirectory under the `deps/`
 | 
				
			||||||
 | 
					    # directory to the PYTHONPATH environment variable.
 | 
				
			||||||
 | 
					    python_path = []
 | 
				
			||||||
 | 
					    if os.path.isdir(script_path + DEPS_DIR):
 | 
				
			||||||
 | 
					        for dep in os.listdir(script_path + DEPS_DIR):
 | 
				
			||||||
 | 
					            dep = script_path + DEPS_DIR + os.path.sep + dep
 | 
				
			||||||
 | 
					            if os.path.isdir(dep):
 | 
				
			||||||
 | 
					                python_path.append(dep)
 | 
				
			||||||
 | 
					    return python_path
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					def fixup_env(script_path, args):
 | 
				
			||||||
 | 
					    os.environ["PYTHONPATH"] = os.pathsep.join(get_python_path(script_path, 0))
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					    # Set the "LXBUILDENV_REEXEC" variable to prevent the script from continuously
 | 
				
			||||||
 | 
					    # reinvoking itself.
 | 
				
			||||||
 | 
					    os.environ["LXBUILDENV_REEXEC"] = "1"
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					    # Python randomizes the order in which it traverses hashes, and Migen uses
 | 
				
			||||||
 | 
					    # hashes an awful lot when bringing together modules.  As such, the order
 | 
				
			||||||
 | 
					    # in which Migen generates its output Verilog will change with every run,
 | 
				
			||||||
 | 
					    # and the addresses for various modules will change.
 | 
				
			||||||
 | 
					    # Make builds deterministic so that the generated Verilog code won't change
 | 
				
			||||||
 | 
					    # across runs.
 | 
				
			||||||
 | 
					    os.environ["PYTHONHASHSEED"] = "1"
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					    # Some Makefiles are invoked as part of the build process, and those Makefiles
 | 
				
			||||||
 | 
					    # occasionally have calls to Python.  Ensure those Makefiles use the same
 | 
				
			||||||
 | 
					    # interpreter that this script is using.
 | 
				
			||||||
 | 
					    os.environ["PYTHON"] = sys.executable
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					    # Set the environment variable "V" to 1.  This causes Makefiles to print
 | 
				
			||||||
 | 
					    # the commands they run, which makes them easier to debug.
 | 
				
			||||||
 | 
					    if "lx_verbose" in args and args.lx_verbose:
 | 
				
			||||||
 | 
					        os.environ["V"] = "1"
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					    # If the user just wanted to print the environment variables, do that and quit.
 | 
				
			||||||
 | 
					    if args.lx_print_env:
 | 
				
			||||||
 | 
					        print("PYTHONPATH={}".format(os.environ["PYTHONPATH"]))
 | 
				
			||||||
 | 
					        print("PYTHONHASHSEED={}".format(os.environ["PYTHONHASHSEED"]))
 | 
				
			||||||
 | 
					        print("PYTHON={}".format(sys.executable))
 | 
				
			||||||
 | 
					        print("LXBUILDENV_REEXEC={}".format(os.environ["LXBUILDENV_REEXEC"]))
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					        sys.exit(0)
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					# Equivalent to the powershell Get-Command, and kinda like `which`
 | 
				
			||||||
 | 
					def get_command(cmd):
 | 
				
			||||||
 | 
					    if os.name == 'nt':
 | 
				
			||||||
 | 
					        path_ext = os.environ["PATHEXT"].split(os.pathsep)
 | 
				
			||||||
 | 
					    else:
 | 
				
			||||||
 | 
					        path_ext = [""]
 | 
				
			||||||
 | 
					    for ext in path_ext:
 | 
				
			||||||
 | 
					        for path in os.environ["PATH"].split(os.pathsep):
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					            if os.path.exists(path + os.path.sep + cmd + ext):
 | 
				
			||||||
 | 
					                return path + os.path.sep + cmd + ext
 | 
				
			||||||
 | 
					    return None
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					def check_python_version(args):
 | 
				
			||||||
 | 
					    import platform
 | 
				
			||||||
 | 
					    # Litex / Migen require Python 3.5 or newer.  Ensure we're running
 | 
				
			||||||
 | 
					    # under a compatible version of Python.
 | 
				
			||||||
 | 
					    if sys.version_info[:3] < (3, 5):
 | 
				
			||||||
 | 
					        return (False,
 | 
				
			||||||
 | 
					            "python: You need Python 3.5+ (version {} found)".format(sys.version_info[:3]))
 | 
				
			||||||
 | 
					    return (True, "python 3.5+: ok (Python {} found)".format(platform.python_version()))
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					def check_vivado(args):
 | 
				
			||||||
 | 
					    vivado_path = get_command("vivado")
 | 
				
			||||||
 | 
					    if vivado_path == None:
 | 
				
			||||||
 | 
					        # Look for the default Vivado install directory
 | 
				
			||||||
 | 
					        if os.name == 'nt':
 | 
				
			||||||
 | 
					            base_dir = r"C:\Xilinx\Vivado"
 | 
				
			||||||
 | 
					        else:
 | 
				
			||||||
 | 
					            base_dir = "/opt/Xilinx/Vivado"
 | 
				
			||||||
 | 
					        if os.path.exists(base_dir):
 | 
				
			||||||
 | 
					            for file in os.listdir(base_dir):
 | 
				
			||||||
 | 
					                bin_dir = base_dir + os.path.sep + file + os.path.sep + "bin"
 | 
				
			||||||
 | 
					                if os.path.exists(bin_dir + os.path.sep + "vivado"):
 | 
				
			||||||
 | 
					                    os.environ["PATH"] += os.pathsep + bin_dir
 | 
				
			||||||
 | 
					                    vivado_path = bin_dir
 | 
				
			||||||
 | 
					                    break
 | 
				
			||||||
 | 
					    if vivado_path == None:
 | 
				
			||||||
 | 
					        return (False, "toolchain not found in your PATH", "download it from https://www.xilinx.com/support/download.html")
 | 
				
			||||||
 | 
					    return (True, "found at {}".format(vivado_path))
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					def check_cmd(args, cmd, name=None, fix=None):
 | 
				
			||||||
 | 
					    if name is None:
 | 
				
			||||||
 | 
					        name = cmd
 | 
				
			||||||
 | 
					    path = get_command(cmd)
 | 
				
			||||||
 | 
					    if path == None:
 | 
				
			||||||
 | 
					        return (False, name + " not found in your PATH", fix)
 | 
				
			||||||
 | 
					    return (True, "found at {}".format(path))
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					def check_make(args):
 | 
				
			||||||
 | 
					    return check_cmd(args, "make", "GNU Make")
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					def check_riscv(args):
 | 
				
			||||||
 | 
					    riscv64 = check_cmd(args, "riscv64-unknown-elf-gcc", "riscv toolchain", "download it from https://www.sifive.com/products/tools/")
 | 
				
			||||||
 | 
					    if riscv64[0] == True:
 | 
				
			||||||
 | 
					        return riscv64
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					    riscv32 = check_cmd(args, "riscv32-unknown-elf-gcc", "riscv toolchain", "download it from https://www.sifive.com/products/tools/")
 | 
				
			||||||
 | 
					    if riscv32[0] == True:
 | 
				
			||||||
 | 
					        return riscv32
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					    return riscv64
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					def check_yosys(args):
 | 
				
			||||||
 | 
					    return check_cmd(args, "yosys")
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					def check_arachne(args):
 | 
				
			||||||
 | 
					    return check_cmd(args, "arachne-pnr")
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					def check_icestorm(args):
 | 
				
			||||||
 | 
					    return check_cmd(args, "icepack") and check_cmd(args, "nextpnr-ice40")
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					dependency_checkers = {
 | 
				
			||||||
 | 
					    'python': check_python_version,
 | 
				
			||||||
 | 
					    'vivado': check_vivado,
 | 
				
			||||||
 | 
					    'make': check_make,
 | 
				
			||||||
 | 
					    'riscv': check_riscv,
 | 
				
			||||||
 | 
					    'yosys': check_yosys,
 | 
				
			||||||
 | 
					    'arachne-pnr': check_arachne,
 | 
				
			||||||
 | 
					    'icestorm': check_icestorm,
 | 
				
			||||||
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					# Validate that the required dependencies (Vivado, compilers, etc.)
 | 
				
			||||||
 | 
					# have been installed.
 | 
				
			||||||
 | 
					def check_dependencies(args, dependency_list):
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					    dependency_errors = 0
 | 
				
			||||||
 | 
					    for dependency_name in dependency_list:
 | 
				
			||||||
 | 
					        if not dependency_name in dependency_checkers:
 | 
				
			||||||
 | 
					            print('WARNING: Unrecognized dependency "{}"'.format(dependency_name))
 | 
				
			||||||
 | 
					            continue
 | 
				
			||||||
 | 
					        result = dependency_checkers[dependency_name](args)
 | 
				
			||||||
 | 
					        if result[0] == False:
 | 
				
			||||||
 | 
					            if len(result) > 2:
 | 
				
			||||||
 | 
					                print('{}: {} -- {}'.format(dependency_name, result[1], result[2]))
 | 
				
			||||||
 | 
					            else:
 | 
				
			||||||
 | 
					                print('{}: {}'.format(dependency_name, result[1]))
 | 
				
			||||||
 | 
					            dependency_errors = dependency_errors + 1
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					        elif args.lx_check_deps or args.lx_verbose:
 | 
				
			||||||
 | 
					            print('dependency: {}: {}'.format(dependency_name, result[1]))
 | 
				
			||||||
 | 
					    if dependency_errors > 0:
 | 
				
			||||||
 | 
					        if args.lx_ignore_deps:
 | 
				
			||||||
 | 
					            print('{} missing dependencies were found but continuing anyway'.format(dependency_errors))
 | 
				
			||||||
 | 
					        else:
 | 
				
			||||||
 | 
					            raise SystemExit(str(dependency_errors) +
 | 
				
			||||||
 | 
					                             " missing dependencies were found")
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					    if args.lx_check_deps:
 | 
				
			||||||
 | 
					        sys.exit(0)
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					# Return True if the given tree needs to be initialized
 | 
				
			||||||
 | 
					def check_module_recursive(root_path, depth, verbose=False):
 | 
				
			||||||
 | 
					    if verbose:
 | 
				
			||||||
 | 
					        print('git-dep: checking if "{}" requires updating...'.format(root_path))
 | 
				
			||||||
 | 
					    # If the directory isn't a valid git repo, initialization is required
 | 
				
			||||||
 | 
					    if not os.path.exists(root_path + os.path.sep + '.git'):
 | 
				
			||||||
 | 
					        return True
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					    # If there are no submodules, no initialization needs to be done
 | 
				
			||||||
 | 
					    if not os.path.isfile(root_path + os.path.sep + '.gitmodules'):
 | 
				
			||||||
 | 
					        return False
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					    # Loop through the gitmodules to check all submodules
 | 
				
			||||||
 | 
					    gitmodules = open(root_path + os.path.sep + '.gitmodules', 'r')
 | 
				
			||||||
 | 
					    for line in gitmodules:
 | 
				
			||||||
 | 
					        parts = line.split("=", 2)
 | 
				
			||||||
 | 
					        if parts[0].strip() == "path":
 | 
				
			||||||
 | 
					            path = parts[1].strip()
 | 
				
			||||||
 | 
					            if check_module_recursive(root_path + os.path.sep + path, depth + 1, verbose=verbose):
 | 
				
			||||||
 | 
					                return True
 | 
				
			||||||
 | 
					    return False
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					# Determine whether we need to invoke "git submodules init --recurse"
 | 
				
			||||||
 | 
					def check_submodules(script_path, args):
 | 
				
			||||||
 | 
					    if check_module_recursive(script_path, 0, verbose=args.lx_verbose):
 | 
				
			||||||
 | 
					        print("Missing submodules -- updating")
 | 
				
			||||||
 | 
					        subprocess.Popen(["git", "submodule", "update",
 | 
				
			||||||
 | 
					                          "--init", "--recursive"], cwd=script_path).wait()
 | 
				
			||||||
 | 
					    elif args.lx_verbose:
 | 
				
			||||||
 | 
					        print("Submodule check: Submodules found")
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					def lx_git(cmd, *args):
 | 
				
			||||||
 | 
					    import subprocess
 | 
				
			||||||
 | 
					    git_cmd = ["git", cmd]
 | 
				
			||||||
 | 
					    if args is not None:
 | 
				
			||||||
 | 
					        for arg in args:
 | 
				
			||||||
 | 
					            git_cmd = git_cmd + [arg]
 | 
				
			||||||
 | 
					    subprocess.call(git_cmd)
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					def lx_print_deps():
 | 
				
			||||||
 | 
					    print('Known dependencies:')
 | 
				
			||||||
 | 
					    for dep in dependency_checkers.keys():
 | 
				
			||||||
 | 
					        print('    {}'.format(dep))
 | 
				
			||||||
 | 
					    print('To define a dependency, add a variable inside {} at the top level called LX_DEPENDENCIES and assign it a list or tuple.'.format(sys.argv[0]))
 | 
				
			||||||
 | 
					    print('For example:')
 | 
				
			||||||
 | 
					    print('LX_DEPENDENCIES = ("riscv", "vivado")')
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					def lx_main(args):
 | 
				
			||||||
 | 
					    if args.lx_print_env:
 | 
				
			||||||
 | 
					        fixup_env(script_path, args)
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					    elif args.lx_print_deps:
 | 
				
			||||||
 | 
					        lx_print_deps()
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					    elif args.lx_run is not None:
 | 
				
			||||||
 | 
					        script_name=args.lx_run[0]
 | 
				
			||||||
 | 
					        get_required_dependencies(script_name)
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					        fixup_env(script_path, args)
 | 
				
			||||||
 | 
					        check_submodules(script_path, args)
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					        try:
 | 
				
			||||||
 | 
					            sys.exit(subprocess.Popen(
 | 
				
			||||||
 | 
					                [sys.executable] + [script_name] + args.lx_run[1:]).wait())
 | 
				
			||||||
 | 
					        except:
 | 
				
			||||||
 | 
					            sys.exit(1)
 | 
				
			||||||
 | 
					    elif args.init:
 | 
				
			||||||
 | 
					        if args.main is None:
 | 
				
			||||||
 | 
					            main_name = os.getcwd().split(os.path.sep)[-1] + '.py'
 | 
				
			||||||
 | 
					            new_main_name = input('What would you like your main program to be called? [' + main_name + '] ')
 | 
				
			||||||
 | 
					            if new_main_name is not None and new_main_name != "":
 | 
				
			||||||
 | 
					                main_name = new_main_name
 | 
				
			||||||
 | 
					        else:
 | 
				
			||||||
 | 
					            main_name = args.main
 | 
				
			||||||
 | 
					        if not main_name.endswith('.py'):
 | 
				
			||||||
 | 
					            main_name = main_name + '.py'
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					        if args.no_git:
 | 
				
			||||||
 | 
					            print("skipping git initialization")
 | 
				
			||||||
 | 
					        else:
 | 
				
			||||||
 | 
					            if not os.path.exists(DEPS_DIR):
 | 
				
			||||||
 | 
					                os.mkdir(DEPS_DIR)
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					            if not os.path.exists(".git"):
 | 
				
			||||||
 | 
					                print("initializing git repository")
 | 
				
			||||||
 | 
					                lx_git('init')
 | 
				
			||||||
 | 
					            else:
 | 
				
			||||||
 | 
					                print("using existing git repository")
 | 
				
			||||||
 | 
					            lx_git('add', str(__file__))
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					            for dep_name, dep_url in DEFAULT_DEPS.items():
 | 
				
			||||||
 | 
					                dest_path = '{}{}{}'.format(DEPS_DIR, '/', dep_name)
 | 
				
			||||||
 | 
					                if not os.path.exists(dest_path):
 | 
				
			||||||
 | 
					                    lx_git('submodule', 'add', dep_url, dest_path)
 | 
				
			||||||
 | 
					                    lx_git('add', dest_path)
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					            lx_git('submodule', 'update', '--init', '--recursive')
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					        if args.no_bin:
 | 
				
			||||||
 | 
					            print("skipping bin/ initialization")
 | 
				
			||||||
 | 
					        elif os.path.exists("bin"):
 | 
				
			||||||
 | 
					            print("bin/ directory exists -- remove bin/ directory to re-initialize")
 | 
				
			||||||
 | 
					        else:
 | 
				
			||||||
 | 
					            bin_tools = {
 | 
				
			||||||
 | 
					                'mkmscimg':           'litex.soc.tools.mkmscimg',
 | 
				
			||||||
 | 
					                'litex_term':         'litex.utils.litex_term',
 | 
				
			||||||
 | 
					                'litex_server':       'litex.utils.litex_server',
 | 
				
			||||||
 | 
					                'litex_sim':          'litex.utils.litex_sim',
 | 
				
			||||||
 | 
					                'litex_read_verilog': 'litex.utils.litex_read_verilog',
 | 
				
			||||||
 | 
					                'litex_simple':       'litex.boards.targets.simple',
 | 
				
			||||||
 | 
					            }
 | 
				
			||||||
 | 
					            bin_template = """#!/usr/bin/env python3
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					import sys
 | 
				
			||||||
 | 
					import os
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					# This script lives in the "bin" directory, but uses a helper script in the parent
 | 
				
			||||||
 | 
					# directory.  Obtain the current path so we can get the absolute parent path.
 | 
				
			||||||
 | 
					script_path = os.path.dirname(os.path.realpath(
 | 
				
			||||||
 | 
					    __file__)) + os.path.sep + os.path.pardir + os.path.sep
 | 
				
			||||||
 | 
					sys.path.insert(0, script_path)
 | 
				
			||||||
 | 
					import lxbuildenv
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					"""
 | 
				
			||||||
 | 
					            print("Creating binaries")
 | 
				
			||||||
 | 
					            os.mkdir("bin")
 | 
				
			||||||
 | 
					            for bin_name, python_module in bin_tools.items():
 | 
				
			||||||
 | 
					                with open('bin' + os.path.sep + bin_name, 'w') as new_bin:
 | 
				
			||||||
 | 
					                    new_bin.write(bin_template)
 | 
				
			||||||
 | 
					                    new_bin.write('from ' + python_module + ' import main\n')
 | 
				
			||||||
 | 
					                    new_bin.write('main()\n')
 | 
				
			||||||
 | 
					                import stat
 | 
				
			||||||
 | 
					                os.chmod('bin' + os.path.sep + bin_name, stat.S_IRUSR | stat.S_IRGRP | stat.S_IROTH | stat.S_IXUSR | stat.S_IXGRP | stat.S_IXOTH)
 | 
				
			||||||
 | 
					                if not args.no_git:
 | 
				
			||||||
 | 
					                    lx_git('add', '--chmod=+x', 'bin' + os.path.sep + bin_name)
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					        if os.path.exists(main_name):
 | 
				
			||||||
 | 
					            print("skipping creation of {}: file exists".format(main_name))
 | 
				
			||||||
 | 
					        else:
 | 
				
			||||||
 | 
					            print("creating main program {}".format(main_name))
 | 
				
			||||||
 | 
					            with open(main_name, 'w') as m:
 | 
				
			||||||
 | 
					                program_template = """#!/usr/bin/env python3
 | 
				
			||||||
 | 
					# This variable defines all the external programs that this module
 | 
				
			||||||
 | 
					# relies on.  lxbuildenv reads this variable in order to ensure
 | 
				
			||||||
 | 
					# the build will finish without exiting due to missing third-party
 | 
				
			||||||
 | 
					# programs.
 | 
				
			||||||
 | 
					LX_DEPENDENCIES = ["riscv", "vivado"]
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					# Import lxbuildenv to integrate the deps/ directory
 | 
				
			||||||
 | 
					import lxbuildenv
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					# Disable pylint's E1101, which breaks completely on migen
 | 
				
			||||||
 | 
					#pylint:disable=E1101
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					from migen import *
 | 
				
			||||||
 | 
					from litex.build.xilinx import VivadoProgrammer, XilinxPlatform
 | 
				
			||||||
 | 
					from litex.build.generic_platform import Pins, IOStandard
 | 
				
			||||||
 | 
					from litex.soc.integration import SoCSDRAM
 | 
				
			||||||
 | 
					from litex.soc.integration.builder import Builder
 | 
				
			||||||
 | 
					from litex.soc.integration.soc_core import csr_map_update
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					_io = [
 | 
				
			||||||
 | 
					    ("clk50", 0, Pins("J19"), IOStandard("LVCMOS33")),
 | 
				
			||||||
 | 
					]
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					class Platform(XilinxPlatform):
 | 
				
			||||||
 | 
					    def __init__(self, toolchain="vivado", programmer="vivado", part="35"):
 | 
				
			||||||
 | 
					        part = "xc7a" + part + "t-fgg484-2"
 | 
				
			||||||
 | 
					    def create_programmer(self):
 | 
				
			||||||
 | 
					        if self.programmer == "vivado":
 | 
				
			||||||
 | 
					            return VivadoProgrammer(flash_part="n25q128-3.3v-spi-x1_x2_x4")
 | 
				
			||||||
 | 
					        else:
 | 
				
			||||||
 | 
					            raise ValueError("{} programmer is not supported"
 | 
				
			||||||
 | 
					                             .format(self.programmer))
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					    def do_finalize(self, fragment):
 | 
				
			||||||
 | 
					        XilinxPlatform.do_finalize(self, fragment)
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					class BaseSoC(SoCSDRAM):
 | 
				
			||||||
 | 
					    csr_peripherals = [
 | 
				
			||||||
 | 
					        "ddrphy",
 | 
				
			||||||
 | 
					#        "dna",
 | 
				
			||||||
 | 
					        "xadc",
 | 
				
			||||||
 | 
					        "cpu_or_bridge",
 | 
				
			||||||
 | 
					    ]
 | 
				
			||||||
 | 
					    csr_map_update(SoCSDRAM.csr_map, csr_peripherals)
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					    def __init__(self, platform, **kwargs):
 | 
				
			||||||
 | 
					        clk_freq = int(100e6)
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					def main():
 | 
				
			||||||
 | 
					    platform = Platform()
 | 
				
			||||||
 | 
					    soc = BaseSoC(platform)
 | 
				
			||||||
 | 
					    builder = Builder(soc, output_dir="build", csr_csv="test/csr.csv")
 | 
				
			||||||
 | 
					    vns = builder.build()
 | 
				
			||||||
 | 
					    soc.do_exit(vns)
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					if __name__ == "__main__":
 | 
				
			||||||
 | 
					    main()
 | 
				
			||||||
 | 
					"""
 | 
				
			||||||
 | 
					                m.write(program_template)
 | 
				
			||||||
 | 
					                if not args.no_git:
 | 
				
			||||||
 | 
					                    lx_git("add", main_name)
 | 
				
			||||||
 | 
					    else:
 | 
				
			||||||
 | 
					        return False
 | 
				
			||||||
 | 
					    return True
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					# For the main command, parse args and hand it off to main()
 | 
				
			||||||
 | 
					if __name__ == "__main__":
 | 
				
			||||||
 | 
					    parser = argparse.ArgumentParser(
 | 
				
			||||||
 | 
					        description="Wrap Python code to enable quickstart",
 | 
				
			||||||
 | 
					        add_help=False)
 | 
				
			||||||
 | 
					    parser.add_argument(
 | 
				
			||||||
 | 
					        "-h", "--help", '--lx-help', help="show this help message and exit", action="help"
 | 
				
			||||||
 | 
					    )
 | 
				
			||||||
 | 
					    parser.add_argument(
 | 
				
			||||||
 | 
					        '-i', '--init', '--lx-init', help='initialize a new project', action="store_true"
 | 
				
			||||||
 | 
					    )
 | 
				
			||||||
 | 
					    parser.add_argument(
 | 
				
			||||||
 | 
					        '-m', '--main', '--lx-main', help='name of main project'
 | 
				
			||||||
 | 
					    )
 | 
				
			||||||
 | 
					    parser.add_argument(
 | 
				
			||||||
 | 
					        '--no-bin', '--lx-no-bin', help="don't create a bin/ directory"
 | 
				
			||||||
 | 
					    )
 | 
				
			||||||
 | 
					    parser.add_argument(
 | 
				
			||||||
 | 
					        '--no-git', '--lx-no-git', help="Don't create a git repository"
 | 
				
			||||||
 | 
					    )
 | 
				
			||||||
 | 
					    parser.add_argument(
 | 
				
			||||||
 | 
					        '-e', '--print-env', '--lx-print-env', dest="lx_print_env", help="print environment variable listing for pycharm, vscode, or bash", action="store_true"
 | 
				
			||||||
 | 
					    )
 | 
				
			||||||
 | 
					    parser.add_argument(
 | 
				
			||||||
 | 
					        '-d', '--print-deps', '--lx-print-deps', dest="lx_print_deps", help="print all possible dependencies and then exit", action="store_true"
 | 
				
			||||||
 | 
					    )
 | 
				
			||||||
 | 
					    parser.add_argument(
 | 
				
			||||||
 | 
					        "--lx-verbose", help="increase verboseness of some processes", action="store_true"
 | 
				
			||||||
 | 
					    )
 | 
				
			||||||
 | 
					    parser.add_argument(
 | 
				
			||||||
 | 
					        '-r', '--run', '--lx-run', dest='lx_run', help="run the given script under lxbuildenv", nargs=argparse.REMAINDER
 | 
				
			||||||
 | 
					    )
 | 
				
			||||||
 | 
					    args = parser.parse_args()
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					    if not lx_main(args):
 | 
				
			||||||
 | 
					        parser.print_help()
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					elif not os.path.isfile(sys.argv[0]):
 | 
				
			||||||
 | 
					    print("lxbuildenv doesn't operate while in interactive mode")
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					elif "LXBUILDENV_REEXEC" not in os.environ:
 | 
				
			||||||
 | 
					    parser = argparse.ArgumentParser(
 | 
				
			||||||
 | 
					        description="Wrap Python code to enable quickstart",
 | 
				
			||||||
 | 
					        add_help=False)
 | 
				
			||||||
 | 
					    parser.add_argument(
 | 
				
			||||||
 | 
					        "--lx-verbose", help="increase verboseness of some processes", action="store_true"
 | 
				
			||||||
 | 
					    )
 | 
				
			||||||
 | 
					    parser.add_argument(
 | 
				
			||||||
 | 
					        "--lx-print-env", help="print environment variable listing for pycharm, vscode, or bash", action="store_true"
 | 
				
			||||||
 | 
					    )
 | 
				
			||||||
 | 
					    parser.add_argument(
 | 
				
			||||||
 | 
					        "--lx-check-deps", help="check build environment for dependencies such as compiler and fpga tools and then exit", action="store_true"
 | 
				
			||||||
 | 
					    )
 | 
				
			||||||
 | 
					    parser.add_argument(
 | 
				
			||||||
 | 
					        "--lx-print-deps", help="print all possible dependencies and then exit", action="store_true"
 | 
				
			||||||
 | 
					    )
 | 
				
			||||||
 | 
					    parser.add_argument(
 | 
				
			||||||
 | 
					        "--lx-help", action="help"
 | 
				
			||||||
 | 
					    )
 | 
				
			||||||
 | 
					    parser.add_argument(
 | 
				
			||||||
 | 
					        "--lx-ignore-deps", help="try building even if dependencies are missing", action="store_true"
 | 
				
			||||||
 | 
					    )
 | 
				
			||||||
 | 
					    (args, rest) = parser.parse_known_args()
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					    if args.lx_print_deps:
 | 
				
			||||||
 | 
					        lx_print_deps()
 | 
				
			||||||
 | 
					        sys.exit(0)
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					    deps = get_required_dependencies(sys.argv[0])
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					    fixup_env(script_path, args)
 | 
				
			||||||
 | 
					    check_dependencies(args, deps)
 | 
				
			||||||
 | 
					    check_submodules(script_path, args)
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					    try:
 | 
				
			||||||
 | 
					        sys.exit(subprocess.Popen(
 | 
				
			||||||
 | 
					            [sys.executable] + [sys.argv[0]] + rest).wait())
 | 
				
			||||||
 | 
					    except:
 | 
				
			||||||
 | 
					        sys.exit(1)
 | 
				
			||||||
 | 
					else:
 | 
				
			||||||
 | 
					    # Overwrite the deps directory.
 | 
				
			||||||
 | 
					    # Because we're running with a predefined PYTHONPATH, you'd think that
 | 
				
			||||||
 | 
					    # the DEPS_DIR would be first.
 | 
				
			||||||
 | 
					    # Unfortunately, setuptools causes the sitewide packages to take precedence
 | 
				
			||||||
 | 
					    # over the PYTHONPATH variable.
 | 
				
			||||||
 | 
					    # Work around this bug by inserting paths into the first index.
 | 
				
			||||||
 | 
					    for path in get_python_path(script_path, None):
 | 
				
			||||||
 | 
					        sys.path.insert(0, path)
 | 
				
			||||||
		Reference in New Issue
	
	Block a user