<swetland>
the video terminal puzzles me. The bios seems to write to the terminal as a side effect of writing UART_TX and it looks like there's a source/sink linkage there. But once my code starts running UART_TX writes only go to the uart. Am I missing something? Did the bios adjust some setting before transferring control?
Degi_ has joined #litex
Degi has quit [Ping timeout: 276 seconds]
Degi_ is now known as Degi
<swetland>
So the video_framebuffer has a depth parameter (default "rgb888", option "rgb565") which smells like it should maybe cut the fifo size in half... but changing to 565 just results in an exception and python backtrace somewhere in the bowels of verilog generation
<swetland>
reducing the fifo depth from 65536 to 16384 cuts the DP16KB usage from 32 to 8 and does not seem to impact operation (scanout works as before)
<_florent_>
swetland: Hi, just for info the OrangeCrab is almost full with the configuration provided in Linux-on-LiteX-VexRiscv. Using the SD-Card in SPI mode can indeed free up some resources.
<_florent_>
swetland: Regarding the VideoFramebuffer, you can indeed reduce the default fifo-depth
<_florent_>
swetland: not sure if switching from rgb888/rgb565 will have a real impact on resource usage, it will just use a different data-with converter
<swetland>
cool. I'll give that a look (fifo underflow) -- it certainly is not resulting in any visible artifacts in scanout at 1/4 the size
<swetland>
here's a possibly more complex question -- how involved would it be to instead of ingesting characters from the uart, just have the video terminal expose its character/attribute memory like a PC character display?
<_florent_>
this should not complicated and could be an optional mode
<swetland>
are you thinking like an address csr and data csr? I was hoping more for direct mapped like a local sram but that feels like poor fit for the csr address space
<tnt>
you can manually add a wishbone bus to it and wire it directly there as a memory zone.
<swetland>
I guess a single 32bit register that encoded { X, Y, CH, ATTR } would work
lexano has quit [Ping timeout: 240 seconds]
<swetland>
the situation I'm thinking of is having multiple threads/processes writing to their own slice of the display without stepping on each other or needing locking
<_florent_>
this could also be directly mapped as suggested by tnt yes
<swetland>
I think either solution would get the job done. guess I need to start learning migen (or nmigen)?
<swetland>
so CSRStorage() looks to be a CSR which then holds the written value in a register, is there an analogue that's more passthrough -- eg I could wire up to writing to the char/attr memory?
<tnt>
Yes CSR()
<tnt>
self._cmd = CSR(14) and then self._cmd.re is the 'write enable' and self._cmd.r is the data.
<tnt>
(And yeah ... why it's 'r' and 're' is ... confusing to me, but that's the way it is)
<_florent_>
swetland: I could provide a skeleton for this if you want, but only this afternoon (in 5-6 hours)
<_florent_>
tnt: I was discussing of the re/r situation recently with bunnie, it seems to be confusing for everyone (me included) and we'll change this
<tnt>
_florent_: isn't that going to be a maintenance nightmare ?
<_florent_>
tnt: we'll just keep retro-compatibilty for it, but will introduce new signals with more meaningful names and encourage use of them
<tnt>
Ok.
<_florent_>
with the retro-compatibility in place, it should be ok and will allow progressive switch
<swetland>
_florent_: I'm poking at the register thing now, we'll see how far I get.
<swetland>
I notice that the definition of CSR, etc have docs in the python sources -- is there a page where all the assembled docs are gathered?
<swetland>
I guess I'm hoping for a sort of "api refrence" or maybe "module reference" for the core building blocks
FabM has joined #litex
FabM has joined #litex
FabM has quit [Changing host]
lexano has joined #litex
* swetland
tries to figure out how to slice a Signal() up into subparts
<tnt>
x[0:2] ?
<tnt>
it uses the python slice thing.
<tnt>
with the same semantic and [0] is still the LSB.
<tnt>
( TBH this is the thing I absolutely _hate_ about migen and amaranth, this drives me crazy )
<tnt>
( so x[0:2] in migen/amaranth is the same as x[1:0] in verilog )
<swetland>
yeah I just read the "numbers go right to left but slices go left to right"
<swetland>
and my head already hurts
<swetland>
also my first error was spaces v tabs x.x
<swetland>
I am not a lover of python
<swetland>
I am even less a lover of using it as a DSL because instead of getting meaningful errors I stare at incomprehensible backtraces
<tnt>
Ahaha. Yeah, usually I love python _but_ I use tabs ... violating PEP8 but I don't care. But when working with code from other projects, I don't have a choice.
<swetland>
but such is life
<swetland>
I have no idea how to comment out or disable all the CSI state machine stuff
lexano has quit [Ping timeout: 272 seconds]
<tnt>
remove it ?
<swetland>
well yeah that's what I'm doing for now, but figure at some point it'd be cool to make this thing a build option. I guess I'll burn that bridge if I get there
<swetland>
what's self.specials += ... about?
<tnt>
That's for stuff that gets special cased during build. Mostly FPGA architecture specific things. (i.e. it gets translated to primitives and such)
<tnt>
(I know only has much as do it when the examples show to do it ...)
<tnt>
And to make it a build option you can just use `if with_direct_access: xxxx_your_logic_xxxx else: xxx_the_previous_logic_xxx`
<swetland>
maybe but don't think the high bit is the deal breaker
<tnt>
probably not.
<tnt>
And it doesn't work ?
<swetland>
if it were wired up right my expectation would be writing 0x30 to the register would drop a '0' in the upper left of the display x=0,y=0,ch='0'
<tnt>
sounds right
<swetland>
do I maybe have to capture the write before pushing it into the memory (eg, is wrxt.r life when wrxy.re strobes such that I can just wire it straight up to the memory like this)?
<tnt>
No, shouldn't be needed
<tnt>
Possibly only concern is ... which clock domain is the write port living in.
<swetland>
ohhhh
<swetland>
not sure how that's specified.
<tnt>
Where is the VideoTerminal created ?
<swetland>
a helper in the soc base thing
<tnt>
yeah, it's all in a 'hdmi' clock domain which isn't the 'sys' clock domain that the CSR lives in.
<tnt>
So you need to get the memory write port in the 'sys' domain
ilia__s0 has joined #litex
<tnt>
TBH no clue how to do that ... the get_port has a 'clock_domain' arg, but it does default to 'sys' already but when instanciating VideoTerminal, 'sys' domain gets renamed to 'hdmi'. No ideo how to tell it not to do that for the write port :/
<swetland>
ah the VideoFrameBuffer has the clock domain ("sys") passed in
<swetland>
before my changes the uart source thing used to write into this memory -- wouldn't that be in the sys clock domain too?
<tnt>
in the ulx3s file, clock_domain="hdmi" when alling the helper.
<swetland>
ah
<tnt>
No, if you look at the add_video_terminal, it does a CDC between the UART from the system and the signals given to VideoTerminal
<tnt>
_florent_: ping ^^
<tnt>
How can we deal with that? Is there a way to get the 'sys' domain that _stays_ 'sys' ?
zjason has quit [Ping timeout: 272 seconds]
zjason has joined #litex
<swetland>
I assume the block ram has clock-per-port so just writing in the sys domain reading in the hdmi domain certainly feels the most straightforward
<tnt>
yeah.
<tnt>
The problem is how to convince migen to do that :)
<tnt>
Because the whole "VideoTerminal" modules operates in 'sys' by default (which is the default domain when not specifying anything). But then with the "ClockDomainRenamer", the add_video_terminal helpers "moves" it all to another domain ("hdmi") in the case of ulx3s.
<tnt>
But in this case ... we want a small part of it to _stay_ in the 'sys' domain because that's where the CSR lives.
<swetland>
I wonder if the memory primitive has a way to directly specify the clock domain(s)
<tnt>
yes. get_port(clock_domain="sys")
<tnt>
but doesn't matter ... because this is _still_ going to get reassigned by the ClockDomainRenamer from add_video_terminal which is called after the port was requested and will take everything from the sys domain (even the memports) into the "hdmi" domain.
<swetland>
well that's no fun
<tnt>
The only way (very very hackish) I see to do it would be to request the memory port in a "csr" domain, then in the add_video_terminal helper, inside the ClockDomainRenamer, also ask to rename "csr" to "sys".
<tnt>
The clockdomain handling of migen/amaranth has ways to back you into a corner :/ It makes like 90% of the stuff easier, but then makes the other 10% a absolute nightmare (compared to just manually wiring 'clk' signals)
<swetland>
yeah, I kinda miss verilog for all its warts.
<swetland>
I'm a bit confused as to how get_port() knows which port to get
<swetland>
is it inferring it based on the variable you're assigning it to?
<tnt>
the ports you get are always read capable. And only write capable if 'write_capable' was set to true.
<tnt>
And if the "read side" of a write capable port isn't used, it'll be optimized out
<swetland>
ah
<tnt>
That works ?
<swetland>
synthesizing
<swetland>
we shall find out in a few
<swetland>
sadly it does not
<tnt>
:/
<tnt>
Can you post the generated verilog somewhere ?
<swetland>
radiona_ulx3s.v ?
<swetland>
do you want any of the other outputs?
<tnt>
no, just th e.v
<swetland>
frotz.net/misc/radiona_ulx3s.v.gz
<tnt>
looking at term_mem it seems right
<tnt>
I guess maybe you should assign the upper 8 bits or maybe with the 'undefined' yosys is deciding that it can optimize it all out.
* swetland
nods
<swetland>
you win
<swetland>
and I have a writeable character ram
<swetland>
thanks for the help!
<tnt>
\o/
<_florent_>
great! (sorry I'm not really working this morning since have the kids around this morning)
<swetland>
no worries
<tnt>
_florent_: no worries. But if you have a cleaner solution for the clock domain issue above later on, I'd be curious to know
<swetland>
I think I'm going to extend the LEDS peripheral with _SET and _CLR registers
* swetland
is working on a little intro-to-os-fundamentals workshop and wants to put together a friendly platform for learning things. being able to have different threads interact with hw without tripping over each other is nice for people to see what's going on
<_florent_>
tnt: I'll have a look later yes
<tnt>
Tx.
<swetland>
frotz.net/misc/colorful.jpg
<swetland>
wired the attribute byte to fg/bg RGB
<tnt>
Hey, nice.
<swetland>
calling it a night, but I think I'll add HSCROLL and VSCROLL controls to let you slide the character grid around and a way to write into the font "rom"
davebee has joined #litex
<davebee>
Fibnally seeing some JTAG io
<davebee>
Finally seeing some JTAG traffic on my ECP5 / vexriscv with external JTAG io pins. litex_server seems to shift lots of tdi=1 into the state machine. In shift-dr tap state. No sure what I should expect to see but it does not manage to get a valid IDCODE from the system.
<davebee>
Should litex-server provide a listener socket that gdb can connect to? I'm struggling a bit here.
<tnt>
Are you sure it's supposed to work that way at all ?
<davebee>
no, I'm not.
<tnt>
I'm not familiar with the ecp5 jtagg primitive. But on xilinx for instance you can't "insert" something in the chain, you can just have user IR (4 of them) and then shift data wiht the DR. But it will never add a device in the chain.
<davebee>
ok. I'm not using the JTAGG primitive - because it wouldn't do what you say it doesn't do. I've added an external 4-wire JTAG interface, with a minor mod to pass the connections to soc.add_jtagbone(). It has io, but it is not doing what I expected. And I'm not sure how to diagnose the problem.
<tnt>
ok, now I'm confused ... because jtagbone is supposed to work with the primitives I mentionned above AFAIK.
<tnt>
Like JTAGPHY instanciates XilinxJTAG / ECP5JTAG / AlteraJTAG
<davebee>
There is an optional parameter to JTAGPHY(), jtag=None, that bypasses the use of the primitive. I've set this to io lines tdi, tdo, tck, tms. And connected an FTDI JTAG interface to these pins. As I saw no effect from using the internal JTAGG primitive. But I think my problem is that I don't know what I am doing! What I want to do is to be able to connect gdb to the vexriscv.
<tnt>
well ... huh ... you can pass something as argument to jtag to use instead of the primitive. But that something needs to implement JTAG ...
<tnt>
(i.e. emulate one of the primitive and do what it does which among other things implement the scanning for id code and also decoding the states etc ...)
<tnt>
if you just wire tdi/tdo/tms/tck that's not going to do anything. It's missing the whole JTAG state machine.
<davebee>
There is a JTAGPHY and a JTAGUART created in soc.add_jtagbone(). So the JTAGG has the TAP state machine in?
<tnt>
yes
<davebee>
okay, I'll try that again. So if it doesn't add the device into the chain, how do I talk to it?
<tnt>
AFAICT the debug variant has a memeory zone 0xf00f0000 that talks to the Vex Debug unit.
<tnt>
And you can talk to it through either JTAGBone, or UARTBone, or any other bridge method of litex to read/write the soc address space.
<davebee>
I'll take another look, thanks. The csr.csv has the debug region : "memory_region,vexriscv_debug,0xf00f0000,256,io" so that looks good.
<tnt>
next step would be to get litex_server running using jtag transport.
<tnt>
and you can check that's working using litex_cli --ident and this should return the SoC identity through it.
<tnt>
Once you have that working you can try to attach gdb to it.
<davebee>
thanks.
<davebee>
The litex_server config assumes an ftdi interface, but the colorlight i9 has an STM32 on the extension board which implements a cmsisdap JTAG / USB interface. I'll see if I can get an openocd config that works with that.
<tnt>
note that you don't _have_ to use JTAGBone at all ...
<tnt>
if you have a uart you can use UARTBone.
<tnt>
(TBH that's what I do because a 2 MBaud uart is often faster just because of the overhead in jtagbone)
<davebee>
perhaps I should try that. Thanks.
<tnt>
Yeah, it's actually much easier.
<davebee>
uart connected, build running ...
<tnt>
I spent like 4 days gettings JTAG to work on the ZynqUSP, hoping that with a 30 MHz clock rate, it would blow a 2Mbaud uart out of the water ... and I was sorely disappointed.
<davebee>
Interesting. I've spent many hours trying to get JTAG working.
<davebee>
$ litex_cli --ident --port 1235
<davebee>
LiteX SoC on Colorlight I9 2022-04-27 13:06:40
zjason has quit [Remote host closed the connection]
zjason has joined #litex
<davebee>
working on that. I already had a build. Thanks for all your help.
<davebee>
Had to change the default listener port for the openocd connection to litex_server. But can now gdb the target.
<davebee>
I can set breakpoints, but my bootloader reloads clean code over it when I reboot. :) Thanks tnt, I'm now in more familiar territory.
zjason has quit [Ping timeout: 272 seconds]
zjason has joined #litex
<mithro>
davebee: Etherbone is much, much faster than either UARTBone or JTAGBone
<mithro>
davebee: If you have ethernet, use that :-)
<davebee>
Can I use it as the same time as debugging my ethernet driver ?
<mithro>
davebee: Does the colorlight i9 have two ethernet devices?
<mithro>
davebee: I know other ones do
<davebee>
Yes. I don't have them wired up though. I've got a Waveshare LAN8720 connected. Took me ages to get it working. The default Litex boot didn't enable auto negotiation, so I had to add MDIO.
xenador77 has joined #litex
<davebee>
I bought some magnetics and RJ45 for the 2 * Gbit PHYs, btg haven't ever wired them up.
<davebee>
The eventual target won't have a PHY on board.
<pepijndevos[m]>
ah I have 5A 75B V8 I think. Someone on twitter said they only support one, which seems to be confirmed by the target command line options. But yea maybe with a bit of hacking you can use both.
<_florent_>
ah yes, current target file only support one, but using two should only be a matter of duplicating things (and also of available board resources)
<pepijndevos[m]>
a ok thanks :)
josuah has joined #litex
<swetland>
can I install litex without it dumping all its python stuff in ~/.local ?
<swetland>
I'd like to keep it all contained together rather than filling my homedirectory with stuff
* swetland
learns about venv
<swetland>
yay. python successfully contained
ilia__s02 has joined #litex
ilia__s0 has quit [Ping timeout: 240 seconds]
ilia__s02 is now known as ilia__s0
ilia__s0 has quit [Ping timeout: 246 seconds]
xenador77 has quit [Remote host closed the connection]
xenador77 has joined #litex
<swetland>
tidied up my VideoTextGrid hackery a bit...