2023-01-02 02:29:00 one of these days I'll settle on a list of requirements and proper extended opcodes. 2023-01-02 02:29:02 also happy new year. 2023-01-02 08:01:51 The main way to 'interpolate' in Forth is just separate out what you're doing in different words 2023-01-02 08:02:08 i.e. ." this is a full line" CR 2023-01-02 08:02:18 See I just interpolated a new line 2023-01-02 08:03:08 You've got your formatting words like .R 2023-01-02 08:03:12 <# # #> 2023-01-02 08:03:46 HOLD 2023-01-02 08:04:14 Forth200x standard has S\" 2023-01-02 08:04:24 Which lets you write an escaped string like C 2023-01-02 08:55:31 fixed, thanks! 2023-01-02 11:21:49 I swear. The world just regularly amazes me. Over time I see how weird people can get, and I think "Ok, now I've seen it all." But then this shows up in my Quora inbox: 2023-01-02 11:21:51 https://imgur.com/a/d4HXBpr 2023-01-02 11:22:24 imgur wants me to turn on javascript in w3m. maybe they need to hire some HTML programmers? 2023-01-02 12:08:27 Oh, well I just wanted it to be undeniable that someone really did post this as a Quora question. That's why I posted a pic instead of just copying the words over to here. 2023-01-02 12:08:58 That's annoying, when websites demand excessive features in your browser. 2023-01-02 12:10:40 thrig: https://i.imgur.com/rS7TPWs.png better? 2023-01-02 12:17:16 Thanks veltas - I'd already lost that question way down in my read messages. 2023-01-02 12:20:02 What IRC client do you use? 2023-01-02 13:04:43 weechat-curses, running on a remote full-time box that I have a mosh connection to from my notebook. 2023-01-02 13:05:07 I find it mildly annoying that vim 'remembers' search strings from past invocations. 2023-01-02 13:05:25 I often have to do a "dummy search" for some nonsense string just to get rid of prior session highlighting. 2023-01-02 13:08:59 RedHat does many wacky and non-standard things to their vim 2023-01-02 13:37:31 KipIngram: try :noh 2023-01-02 13:38:08 otherwise there's a viminfo file somewhere and obscure flags that change what gets saved there 2023-01-02 13:39:06 Cool. 2023-01-02 13:39:30 Ok, so it's been a LONG time since I did Verilog, and I never did MUCH. Some things are clearing up for me now. 2023-01-02 13:39:59 I started out wanting to declare the output of combinational circuits as wires. Since, you know, THAT'S WHAT THEY ARE. 2023-01-02 13:40:08 And the output of clocked registers as regs. 2023-01-02 13:40:25 But it's becoming evident to me now that sometimes you declare combinational outputs sa reg too. 2023-01-02 13:40:48 You just tell them to change on ANY input change, rather than just on posedge clk. 2023-01-02 13:41:07 So suddenly my original drawings are "porting into Verilog" a lot better than they were initially. 2023-01-02 14:06:22 Nice 2023-01-02 14:07:49 In vim use the command ":set" and just see what's set if you have weird distro settings 2023-01-02 14:08:13 There's not a lot of settings in there usually and you can scrutinise them, understand vim a bit better in process 2023-01-02 14:08:49 This is what I have to do on Windows at work if I'm using "git bash"'s vim 2023-01-02 17:28:02 Working on the return stack module now. 2023-01-02 18:23:15 Wow, that was actually pretty straightforward. 2023-01-02 18:23:57 I think it's done. I just did the return address part, but adding parallel block RAMs for the loopback and frame stuff won't be hard - same stack pointer addresses all of 'em. 2023-01-02 19:00:37 So, this module maintains the return stack pointer and the top two items of the return stack available for external use at all times. By applyng the right pattern on a 7-bit command bus, I can 1) idle, 2) load the stack pointer from external input, 3) push a new item from the external input, 4) drop the top stack item (pop, since I can also read the old top value), or 5) drop the top two items (while reading 2023-01-02 19:00:39 both former values if I need them). That's enough for everything I need to do. 2023-01-02 19:01:00 Needed a register, a block RAM, and two 4-1 muxes. 2023-01-02 19:02:25 A block RAM has 1024 32-bit words in it, when it's set up 32-bwide. I've set this up so each 32-cell range functions as a circular stack. Pushing and popping changes only the low-order five bits of the stack pointer. 2023-01-02 19:02:48 So I could support up to 32 threads. 2023-01-02 19:05:03 Well, there's also some arithmetic circuitry in there. To move the pointer properly. 2023-01-02 19:05:11 +1, -1, and -2. 2023-01-02 19:06:21 Since that arithmetic is only done on the bottom five bits, though, I don't have to wait for a ridiculous amount of ripple carry there. 2023-01-02 19:34:23 KipIngram: FPGA? 2023-01-02 19:37:08 Headed that way, yeah. I haven't tested anything in chip yet. 2023-01-02 19:37:16 Gonna make it work in Icarus Verilog first. 2023-01-02 19:37:43 It should all be synthesizable, though. At least I'm not deliberately using anything that is test-bench only. 2023-01-02 19:49:58 It'll just be a lot easier to debug in Icarus, I think. 2023-01-02 19:50:07 Since I can actually SEE what's going on in there. 2023-01-02 19:50:53 With GTKWave as a viewer it's like having a logic analyzer hooked to every signal in your design. 2023-01-02 19:55:04 I've got it rigged to a "test bench" currently that pulls reset high for a few clocks and then drops it and it runs. I'll just watch it move forward from there, adding and fixing capabilities until it's doing everything. 2023-01-02 19:56:00 Last night I had it "calling" - if the low two bits of a cell were 0, it would load that content into IP. But last night I had no return stack, so couldn't push the return address. That's why i did the return stack today. 2023-01-02 20:36:49 Next goal is to get it to do calls and push the return address or not push, depending on the bits, and return successfully from the call. Not going to actually pull any opcodes out of the words yet - I'll add that after this higher level is behaving right. 2023-01-02 20:37:51 So as far as opcodes go, I'm just going to have it return is the ret instruction is in the low order slot. Otherwise it will just increment on forward. That's enough to exercise for now. 2023-01-02 20:42:27 I'm finding that none of the parts of this thing are particularly sophisticated; most of it's turning out to be rather simple logic. But I'm also finding it has to be the RIGHT pieces - the overall functionality has to be s plit up the right way, or else they don't fit together quite right. The "wrong paths" hit deads end pretty hard. Then when I hit on the right path, everything just falls into place. 2023-01-02 20:47:57 An example - I just naturally assumed that the fetch logic would handle incrementing IP when appropriate. But that kept getting pesky in "corner cases." Finally realized that the opcode logic needs to tell it whether to do that or not. To make both rep loops and interrupts work right. IP will hold the address of the cell being repped on. Normally the execution logic will do the whole loop before going 2023-01-02 20:47:58 back, but if an interrupt occurs it needs to go back for that after the current loop iteration. 2023-01-02 20:48:41 And it needs to tell the fetch logic to push NOT the next address, but rather the address it's already holding, so that when the interrput is over, the return will take us back to that cell. So opcode will get it again and can finish the loop. 2023-01-02 20:48:51 you using hardwiredlogic or rom logic for this? 2023-01-02 21:12:48 Well, it's made using the logic resources provided by Xilinx. 2023-01-02 21:13:09 One LUT does a "just right" 4:1 mux, so I'm using those whereever I can. 2023-01-02 21:13:36 So I guess ultimately it's memory-based logic, since it's based on those LUTs. 2023-01-02 21:13:54 But the LUTs are also wired together in a "wired" kind of way. 2023-01-02 21:15:51 Maybe a good way to imagine would be as a transfer-based design, with the muxes used to bring to each transfer destination all the different sources that need to target it. 2023-01-02 21:16:10 And then there's some gate-based logic that controls those muxes. 2023-01-02 21:16:39 The idea here is for each instruction to be single-cycle, so it has to be achievable with a set of transfers that happen in parallel. 2023-01-02 21:17:45 that is a design methodology I had not considered. 2023-01-02 21:18:14 Just felt like it would work, so I've given it a try. And I do think it's going to work out. 2023-01-02 21:18:34 Those clocked RAMs gave me a fair bit of grief, though - took some thinking to see my way around that. 2023-01-02 21:18:55 Made it so I had to look ahead to the next instruction at least a little. 2023-01-02 21:19:23 Any memory read I want to do on a cycle has to have it's address clocked in at the BEGINNING edge of the cycle. 2023-01-02 21:19:54 Writes are more sensible; I just get the address and data applied to the RAM during the instruction's cycle, and the edge that ends it clock's 'em in. 2023-01-02 21:20:13 The write actually happens during the following cycle, while I'm working on the next instruction. 2023-01-02 21:22:13 So far I've not found anything to stop me from supporting all of my "unusual" primitives, like the conditional returns and conditional recursion, as single cycle instructions. Looks ok. 2023-01-02 21:23:14 I did have to give up any hope of fetching the next instruction cell ahead of time, and getting rid of that one fetch cycle overhead every five instructions. 2023-01-02 21:23:33 The clocked RAM thing put that out of each, as far as I can tell. 2023-01-02 21:23:52 each? reach? 2023-01-02 21:24:42 Each cell can hold five opcodes, so for each fetch I can have as many as five cycles of instructions. I was earlier hoping to find a way to have NOTHING but execute cycles, and pipeline the fetches in somehow. 2023-01-02 21:24:53 But now I think I'm stuck with having an explicit fetch cycle, 2023-01-02 21:25:12 so it'll be fetch {up to five executes} fetch {up to five... etc. 2023-01-02 21:25:43 but that's still pretty good - peak performance I get an instruction every 1.2 cycles. 2023-01-02 21:25:56 Faster to whatever extent I can exploit those microloops. 2023-01-02 21:26:11 hmm… how deep is your logic propagation delay wise? 2023-01-02 21:26:27 Because normally when a rep instruction comes along it sends execution back to the start of the same cell, and I don't fetch it again unless I'm recovering from an interrupt. 2023-01-02 21:31:48 And now that I'm looking ahead a cycle I might not have to actually spend a cycle on the rep instruction. If I see it coming I can probably make the right decision by the end of the cycle before it. 2023-01-02 21:32:20 So a block move could just alternate between read using A with post increment and write using B with post increment. 2023-01-02 21:33:47 I haven't actually skethed out avoidng explicit rep cycles, though - may not work out. 2023-01-02 21:34:52 It's too bad that the RAM reads are clocked the way they are - if they weren't I might even be able to implement a RAM to RAM move instruction, since I have two RAM ports.