Where communities thrive


  • Join over 1.5M+ people
  • Join over 100K+ communities
  • Free without limits
  • Create your own community
People
Activity
    Lawrie Griffiths
    @lawrie
    $$bits = 26
    
    algorithm main(output uint$NUM_LEDS$ leds) {
      uint$bits$ cnt = 0;
      uint5 pwm = 0;
      uint4 pwm_input := cnt[$bits-1$,1] ? cnt[$bits-5$,4] : ~cnt[$bits-5$,4];
    
      $$for i = 0, NUM_LEDS-1 do
        leds[$i$,1] := pwm[4,1];
      $$end
    
      while (1) {
        cnt = cnt + 1;
        pwm = pwm[0,4] + pwm_input;
      }
    }
    Lawrie Griffiths
    @lawrie
    I have started a repository of my Silice examples, and here is a PS/2 keyboard test that appears to read scan codes from a PS/2 keyboard using a Digilent PS/2 PMod. I know @rob-ng15 was having problems with PS/2 keyboards.
    @sylefeb To use a PS/2 keyboard on the US2 connector, we would need a new ifdef, say US2_PS2 in your top-level Verilog module for the Ulx3s, which declares the ports for the US2 connector and sets the pull-up resistors for PS/2.
    Lawrie Griffiths
    @lawrie
    PS/2 keyboard are useful, particularly for retro computer implementations on the Ulx3s, and they are most conveniently used by plugging in a USB keyboard that supports PS/2, using the US2 connector.
    USB keyboards can also be supported but it is a lot more code and not that reliable.
    sylefeb
    @sylefeb
    @lawrie just tried the led glow, great example! Nice use of the pre-processor. You could also write leds := {$NUM_LEDS${pwm[4,1]}}; (akin to Verilog replication)
    PS/2 sounds great! will add the define.
    sylefeb
    @sylefeb
    I see in the lpf that the US2 connector has six pins, two differential inputs (usb_fpga_dX) and four inouts (usb_fpga_bd_dX/usb_fpga_pu_dX). How should these be exposed for the PS/2 keyboard? (in particular, do we keep the differential pair as a true differential LVCMOS33D?)
    Rob S
    @rob-ng15
    Thanks @lawrie , that looks incredibly helpful. I still need to get another PS2 keyboard to try it with.
    Lawrie Griffiths
    @lawrie
    @sylefeb Here is an example of a PS/2 keyboard in Verilog - https://github.com/lawrie/ulx3s_z80_template/blob/main/src/top.v#L187-L202
    It uses usb_fpga_bd_dp for the clock and usb_fpga_bd_dn for the data, and both the pullups are set high.
    Lawrie Griffiths
    @lawrie
    @sylefeb I remain very confused about the semantics of Silice. I imagined that continuous assignment with the := operator were combinatorial. But in section 4.7 of the manual, you say These assignments are performed immediately after each rising clock and are order dependent., which implies they are synchronous. Which is it, or can they be either?
    You also say that the always block is combinatorial, but the examples seem to contradict that, for example increasing counters in the uart example https://github.com/sylefeb/Silice/blob/master/projects/common/uart.ice#L66
    Also, in that uart example, I am confused by the setting of uart_tx after the always block - https://github.com/sylefeb/Silice/blob/master/projects/common/uart.ice#L79
    What relationship does that have to the assignments of uart_tx within the block?
    Lawrie Griffiths
    @lawrie
    (Incidentally when I tried your uart echo example on the Ulx3s, it appeared to lose characters. Sending "Hello" echoed "Hlo").
    So, if always can contain synchronous logic, what is the difference between while (1) {...} and always [ ...]?
    When I tried changing while (1) to always in my led_glow example, I got an error message about in_run.
    emard
    @emard
    @sylefeb I applied 6 pins to USB to be able to control all pullups, have differential inputs and single ended bidirectionals at the same time as USB protocol demands all this electrically. You can use any combination you find working best (sometimes routing paths make difference). In all devices I tried, differential is not needed but provides slightly cleaner signal with less error retries
    sylefeb
    @sylefeb
    @lawrie I had made this introduction video that might help clarify: https://www.youtube.com/watch?v=_OhxEY72qxI ; your feedback made me realize it may indeed be confusing for those familiar with Verilog to transition to Silice, will add notes on that in the repo. Basically everything you write is combinatorial (ends up in a Verilog always@* with = assignments) but variables are turned into flip-flops as needed. So if you write a = a + 1 it becomes a_d = a_q + 1 with a_q <= a_d in a posedge block. Code is split into FSM states as required (with predictable rules so you can try to minimize/avoid that).
    Silice always blocks are statements applied at every clock, before any of the other states. This is useful for instance to monitor an input pulsing high, while the rest of the logic/FSM is being run. Also, the idea is to help progressively go from a FSM style (with while / ++: / subroutines ) to a more compact 'always' style.

    When I tried changing while (1) to always in my led_glow example, I got an error message about in_run

    Ah, you've just hit a bug: sylefeb/Silice#113 This would work in any algorithm other than main ... will fix!

    sylefeb
    @sylefeb
    @emard @lawrie US2: thanks, will push a first attempt on 'wip'. inout are still a bit difficult to use in Silice (requires a small Verilog glue), also something to be improved (sylefeb/Silice#19), so I'll probably specialize to PS/2 for now.

    Incidentally when I tried your uart echo example on the Ulx3s, it appeared to lose characters.

    Oh no, I thought this one was stable! will investigate sylefeb/Silice#117

    sylefeb
    @sylefeb

    What relationship does that have to the assignments of uart_tx within the block?

    The always block is specified before any other code. So besides the always block this uart_tx=1 is the only thing performed by the algorithm, and only once (while the always block remains always active). This was used to initialize the output to 1 -- no longer necessary, Silice now supports the syntax output uint1 uart_tx = 1.

    sylefeb
    @sylefeb

    @lawrie pushed the us2_ps2 addition, Makefile change: silice-make.py -s blinky.ice -b $@ -p basic,us2_ps2 ...main becomes:

    algorithm main(
      output uint$NUM_LEDS$ leds,
      input  uint1 us2_bd_dp,
      input  uint1 us2_bd_dn,

    usb_fpga_pu_dp/usb_fpga_pu_dn are assigned 1. Hope this works!

    Rob S
    @rob-ng15

    Hi Sylvain,

    I've been waiting for you to do that! I have those set in my ulx3s.v for a while during testing :)

    I'm just trying to wire in the ps2.ice from @lawrie to see how it goes. I'm wiring it to the USB pins. I'll let you know.
    sylefeb
    @sylefeb
    Hi Rob - thanks! looking forward to the PS/2 keyboard working, will be very useful (plus we can put all these old keyboards to good use!).
    Rob S
    @rob-ng15

    Well the first step is to get it to give the same output 0xaa as I get using the keyboard I have. I've got to get a working PS2 keyboard for the ulx3s. Just catching up with the changes that have been made in Silice since I last updated. Mainly, changes to the bram interface passing at the moment.

    Just looking at the audo_pwm.ice... THAT I definitely have a use for :)

    Rob S
    @rob-ng15
    Excellent news! The modified PS2 code from Lawrie that I integrated into PAWS gives the same 0xaa code as his original verilog code, so I take that as a good sign :)
    Lawrie Griffiths
    @lawrie
    @sylefeb us2_ps2 worked for me as well. I can see PS/2 scan codes from a keyboard connected to us2.
    I checked the uart_echo test on the Wip branch as it might have been the main branch I tried it on before, but I still see the problem. I run stty -F /dev/ttyUSB0 raw -echo 115200; cat /dev/ttyUSB0 on one terminal and echo Hello >/dev/ttyUSB0 on another, and every other character is lost.
    Lawrie Griffiths
    @lawrie
    @sylefeb I am familiar with languages that have different semantics to Verilog. In migen and nmigen you have to be explicit about whether every statement in synchronous or combinatorial (by adding them to the appropriate domain). In SpinalHDL you have to be explicit about which signals are flip-flops (Reg) and it then generates synchronous code for the registers. But Silice has different semantics that doesn't really conform to the combinatorial/synchronous distinction, so I think some of the references to combinatorial logic in your manual are confusing.
    Rob S
    @rob-ng15
    @lawrie @sylefeb The modified ps2.ice that I integrated into PAWS is here: https://github.com/rob-ng15/Silice-Playground/blob/master/PAWS/common/ps2.ice the main change being to remove from main and input the data and clock lines rather than the whole gpio.
    PAWS is now caught up with the Silice WIP branch :)
    Lawrie Griffiths
    @lawrie
    @rob-ng15 Yes, those are sensible changes. My version was just to test if it works. That PS/2 algorithm is from @hoglet67 (David Banks) and his Ice40Beeb and Ice40Atom projects. A version that produces an 11-bit ps2_key value in the Mist/Mister format might also be useful. That has extra bits to say whether an event has occurred, whether it is a press or release and whether it is an extended scan code, so requires processing the F0 and E0 values from the keyboard.
    Rob S
    @rob-ng15
    That's good. I'll put appropriate credits in the file.
    Lawrie Griffiths
    @lawrie
    It gets hard to know how to credit this stuff when it gets modified and rewritten in different languages.
    emard
    @emard
    https://github.com/emard/oberon/blob/master/hdl/PS2.v oberon has also some PS/2 core with only few lines of verilog
    sylefeb
    @sylefeb
    @lawrie thanks for the feedback on the documentation - I'll revise and improve!
    great news for PS/2
    Rob S
    @rob-ng15
    @sylefeb do you have an example of goto in Silice? I may have a use for it... I'll bleach the keyboard if I do! (Sadly, the softfloat c code uses gotos, and it is hard enough converting it as it is, without having to change the control flow logic).
    sylefeb
    @sylefeb
    Rob S
    @rob-ng15
    Cheers, exactly what I am unfortunately looking for!
    Lawrie Griffiths
    @lawrie
    @sylefeb One thing that I notice that you don't have with Silice is reading and writing flash memory. It can be more convenient to load risc-v programs into flash memory rather than having to write raw images to the sd card. Most risc-v implementations include the ability to run code in-place from flash memory (XIP).
    Another feature which would be useful is a read-write spi memory slave that worked with @emard's micropython code for an on-screen display (OSD) and for remote ram access. That can be very convenient for loading programs from a formatted SD card. It is used by many of the retro computer implementations on the Ulx3s.
    emard
    @emard
      assign sd_d  = R_prog_release[C_prog_release_timeout] ? 4'hz : { 3'b101, S_prog_out[0] }; // does NOT work
      assign sd_d  = R_prog_release[C_prog_release_timeout] == 0 ? { 3'b101, S_prog_out[0] } : 4'hz; // works