Tue Jul 8 04:33:53 PM CEST 2025

Foonotes or no footnotes

My writing is greatly influenced by Terry Pratchett. As a result, I also often include many footnotes. Rereading The Hitchhicker's Guide to the Galaxy, it does not have to be the case though.

You just need to rephase a bit. Adam can smoothly end a paragraph with the towel, then start a long paragraph going off the rail about the towel, which concludes something that connects back to the paragraph before. It's really nicely done. But sure, you have to put in more work.

Beneath that in Ford Prefect's satchel were a few ballpoints, a notepad and a largish bath towel from Marks and Spencer.

The Hitchhiker's Guide to the Galaxy has a few things to say on the subject of towels.

A towel it says, is abot the most massively useful thing an interstellar hitchhiker can have...

Hence a phrase that has passed into hitchhiking slang, as in "Hey, you sass that hoopy Ford Prefect? There's frood who really know where his towel is".


Tác giả: pclouds | Liên kết tĩnh | Sách

Wed Jul 2 08:44:04 PM CEST 2025

A, B and C

(Hitchhiker's guide to the galaxy)

Bypasses are devices that allow some people to dash from point A to point B very fast while other people from point B to point A very fast. People living at point C, being a point directly in between, are often given to wonder what's so great about point A that so many people from point B are so keen to get there, and what's so great about point B that so many people from point A are so keen to get there. They often wish that people would just once and for all work out where the hell they wanted to be.


Tác giả: pclouds | Liên kết tĩnh | Sách, Trích dẫn

Sat Jun 28 09:50:05 AM CEST 2025

Everything is still about OpenGL

Didn't occur to me until just now, after seeing glm library keep referencing back to GLU library. Frankly I don't remember what GLU libray does either, but some memory is coming back.

So there's a bunch of transformation supported by GLU, like lookAt, perspective and so on. Of course with legacy GL, you don't get to deal with matrices directly, it's all covered with some functions. With modern 3D API, you have to do it yourself, so GLU becomes GLM which exposes the same feature set, except as matrices instead, that you can send over to vertex fragments.

GLM is short for OpenGL Mathematics. Who knew? I could have if I bothered to read README.


Tác giả: pclouds | Liên kết tĩnh

Wed Jun 25 04:29:19 PM CEST 2025

Money has come. I can finally buy toothpaste again!

Aaand I forgot to buy it, yet remembered Limoncello. Brain oh brain.


Tác giả: pclouds | Liên kết tĩnh

Tue Jun 24 08:19:08 PM CEST 2025

Clipping space!

Three hours just to put this guy in the middle of the "map"

And that's with all the working code already there (in learnopengl repo).

Though the first mistake was using wrong primitive type (triangle strip instead of list) which messes up the model pretty badly (and also UV texture).

But the bigger problem, and it also took me a lot of time before, was clipping space. The lack of projection matrix, and the size of the model, means that some vertices are going to be outside the default clipping space from -1.0 to 1.0. Meaning very strange clipping. How come I keep thinking about depth testing, sigh...

It's also very strange that with wrong (identity) projection matrix, then suddenly draw order matters. Which ever is drawn last, the ground or the character, wins. Maybe the depth value is too big without projection matrix that it doesn't matter anymore. Who knows. I know I don't.

Maths are hard!


Tác giả: pclouds | Liên kết tĩnh

Tue Jun 24 06:08:44 PM CEST 2025

Resuming glBomb. Because I... want to avoid verilog for a bit


Tác giả: pclouds | Liên kết tĩnh

Mon Jun 23 02:22:28 PM CEST 2025

Minor characters in Frasier

Doctor Perry Cox plays a plumber. Karen Walker is a kitchen designer. Marly Ehrhardt (The New Adventures of Old Christine) is a coffee waiter.


Tác giả: pclouds | Liên kết tĩnh | Phim

Sun Jun 22 10:27:11 PM CEST 2025

Behind the scene of article 9080

(from Starship Troopers)

After the court-martial was over and Ted had been taken away, he stayed behind and said to Captain Frankel, "May I speak with the Battalion Commander, sir?"

"Certainly. I was intending to ask you to stay behind for a word. Sit down."

Zim flicked his eyes my way and the Captain looked at me and I didn't have to be told to get out. I faded. There was nobody in the outer office, just a couple of civilian clerks. I didn't dare go outside because the Captain might want me; I found a chair back of a row of files and sat down.

I could hear them talking, through the partition I had my head against. BHQ was a building rather than a tent, since it housed permanent communication and recording equipment, but it was a "minimum field building", a shack; the inner partitions weren't much. I doubt if the civilians could hear as they each were wearing transcriber phones and were bent over types --- besides, they didn't matter. I didn't mean to eavesdrop. Uh, well, maybe I did.

Zim said: "Sir, I request transfer to a combat team."

Frankel answered: "I can't hear you, Charlie. My tin ear is bothering me again."

Zim: "I'm quite serious, sir. This isn't my sort of duty."

Frankel said testily: "Quit bellyaching your troubles to me, Sergeant. At least wait until we've disposed of duty matters. What in the world happened?"

Zim said stiffly, "Captain, the boy doesn't rate ten lashes."

Frankel answered, "Of course he doesn't. You know who goofed --- and so do I."

"Yes, sir. I know."

"Well? You know even better than I do that these kids are wild animals at this stage. You know when it's safe to turn your back on them and when it isn't. You know the doctrine and the standing orders about article nine-oh-eight-oh --- you must never give the a chance to violate it. Of course some of them are going to try it --- if they weren't aggressive they wouldn't be material for the M.I. They're docile in ranks; it's safe enough to turn your back when they're eating, or sleeping, or sitting on their tails and being lectured. But get them out in the field in a combat exercise, or anything that gets them keyed up and full of adrenaline, and they're as explosive as a hatful of mercury fulminate. You know that, all you instructors know that; you're trained --- trained to watch for it, trained to snuff it out before it happens. Explain to me how it was possible for an untrained recruit to hang a mouse on your eye? He should never have laid hand on you; you should have knocked him cold when you saw what he was up to. So why weren't you on the bounce? Are you slowing down?"

"I don't know", Zim answered slowly. "I guess I must be."

"Hmm! If true, combat team is the last place for you. But it's not true. Or wasn't true the last time you and I worked out together, three days ago. So what slipped?"

Zim was slow in answering. "I think I had him tagged in my mind as one of the safe ones."

"There are no such."

"Yes, sir. But he was so earnest, so doggedly determined to sweat it out --- he didn't have any aptitude but he kept on trying --- that I must have done that, subconsciously." Zim was silent, then added, "I guess it was because I liked him."

Frankel snorted. "An instructor can't afford to like a man."

"I know it, sir. But I do. They're a nice bunch of kinds. We've dumped all the real twerps by now --- Hendrick's only shortcoming, aside from being clumsy, was that he thought he knew all the answers. I didn't mind that; I knew it all at that age myself. The twerps have gone home and those that are left are eager, anxious to please, and on the bounce --- as cute as a litter of collie pups. A lot of them will make soldiers."

"So that was the soft spot. You liked him... so you failed to clip him in time. So he winds up with a court and the whips and a B.C.D. Sweet."

Zim said earnestly, "I wish to heaven there were some way for me to take that flogging myself, sir."

"You'd have to take your turn, I outrank you. What do you think I've been wishing the past hour? What do you think I was afraid of from the moment I saw you come in here sporting a shiner? I did my best to brush it off with administrative punishment and the young fool wouldn't let me well enough alone. But I never thought he would be crazy enough to blurt it out that he'd hung one on you --- he's stupid; you should have eased him out of the outfit weeks ago... instead of nursing him along until he got into trouble. But blurt it out he did, to me, in front of witnesses, forcing me to take official notice of it --- and that licked us. No way to get it off the record, no way to avoid a court... just go through the whole dreary mess and take our medicine, and wind up with one more civilian who'll be against us the rest of his days. Because he has to be flogged; neither you nor I can take it for him, even though the fault was ours. Because the regiment has to see what happens when nine-oh-eight-oh is violated. Our fault... but his lumps."

"My fault, Captain. That's why I want to be transferred. Uh, sir, I think it's best for the outfit."

"You do, eh? But I decide what's best for my battalion, not you, Sergeant. Charlie, who do you think pulled your name out of the hat? And why? Think back twelve years. You were a corporal, remember? Where were you?"

"Here, as you know quite well, Captain. Right here on this same godforsaken prairie --- and I wish I had never come back to it!"

"Don't we all. But it happens to be the most important and most delicate work in the Army --- turning unspanked your cubs into soldiers. Who was the worst unspanked young cub in your section?"

"Mmm..." Zim answered slowly. "I wouldn't go so far as to say you were the worst, Captain."

"You wouldn't, eh? But you'd have to think hard to name another candidate. I hated your guts, 'Corporal' Zim."

Zim sounded surprised, and a little hurt. "You did, Captain? I didn't hate you --- I rather liked you."

"So? Well, 'hate' is the other luxury an instructor can never afford. We must not hate them, we must not like them; we must teach them. But if you liked me then --- mmm, it seemd to me that you had very strange ways of showing it. Do you still like me? Don't answer that; I don't care whether you do or not --- or, rather, I don't want to know, whichever it is. Never mind; I dispised you then and I used to dream about ways to get you. But you were always on the bounce and never gave me a chance to buy a nine-oh-eight-oh court of my own. So here I am, thanks to you. Now to handle your request: You used to have one order that you gave me over and over again when I was a boot. I got so loathed it almost more than anything else you did or said. Do you remember it? I do and now I'll give it back to you: 'Soldier, shut up and soldier!'"

"Yes, sir."

"Don't go yet. This weary mess isn't all loss; any regiment of boots needs a stern lesson in the meaning of nine-oh-eight-oh, as we both know. They haven't learned to think, they won't read, and they rarely listen --- but they can see... and young Hendrick's misfortune may save one of this mates, someday, from swinging by the neck until he's dead, dead, dead. But I'm sorry the object lesson had to come from my battalion and I certainly don't intend to let this battalion supply another one. You get your instructors together and warn them. For about tweny-four hours those kids will be in a state of shock. Then they'll turn sullen and the tension will build. Along about Thursday or Friday some boy who is about to flunk out anyhow will start thinking over the fact that Hendrick didn't get so very much, not even the number of lashes for drunken driving... and he's going to start brooding that it might be worth it, to take a swing at the instructor he hates the most. Sergeant, that blow must never land! Understand me?"

"Yes, sir."

"I want them to be eight times as cautious as they have been. I want them to keep their distance, I want them to have their eyes in the backs of their heads. I want them to be as alert as a mouse at a cat show. Bronski --- you have a special word with Bronski; he has a tendency to fraternize."

"I'll straighten Bronski out, sir."

"See that you do. Because when the next kid starts swinging, it's got to be stop-punched --- not muffed, like today. The boy has got to be knocked cold and the instructor must do so without ever being touched himself --- or I'll damned well break him for incompetence. Let them know that. They've got to teach those kids that it's not merely expensive but impossible to violate nine-oh-eight-oh... that even trying it wins a short nap, a bucket of water in the face, and a very sore jaw --- and nothing else."

"Yes, sir. It'll be done."

"It had better be done. I will not only break the instructor who slips, I will peronally take him 'way out on the prairie and give him lumps... because I will not have another of my boy strung up to that whipping post through sloppiness on the part of his teachers. Dismissed."


Tác giả: pclouds | Liên kết tĩnh | Sách, Trích dẫn

Sun Jun 22 06:54:13 PM CEST 2025

Multi-clock RISC-V CPU

ultraembedded/riscv is a tiny bit toooo advanced, so let's go back to something simpler, ultraembedded/core_uriscv.

This shows how multiple stage CPU is implemented, but a lot more obvious: state machine.

// Current state
reg [STATE_W-1:0] state_q;

//-----------------------------------------------------------------
// Next State Logic
//-----------------------------------------------------------------
reg [STATE_W-1:0] next_state_r;
always @ *
begin
    next_state_r = state_q;

    case (state_q)
    // RESET - First cycle after reset
    STATE_RESET:
    begin
        next_state_r = STATE_FETCH_WB;
    end
    // FETCH_WB - Writeback / Fetch next isn
    STATE_FETCH_WB :
    begin
        if (opcode_fetch_w)
            next_state_r    = SUPPORT_BRAM_REGFILE ? STATE_DECODE : STATE_EXEC;
    end
    // DECODE - Used to access register file if SUPPORT_BRAM_REGFILE=1
    STATE_DECODE:
    begin
        if (mem_i_valid_i)
            next_state_r = STATE_EXEC;
    end
    // EXEC - Execute instruction (when ready)
    STATE_EXEC :
    begin
        // Instruction ready
        if (opcode_valid_w)
        begin
            if (exception_w)
                next_state_r    = STATE_FETCH_WB;
            else if (type_load_w || type_store_w)
                next_state_r    = STATE_MEM;
            // Multiplication / division - stay in exec state until result ready
            else if (muldiv_inst_w)
                ;
            else
                next_state_r    = STATE_FETCH_WB;
        end
        else if (muldiv_ready_w)
            next_state_r    = STATE_FETCH_WB;
    end
    // MEM - Perform load or store
    STATE_MEM :
    begin
        // Memory access complete
        if (mem_d_ack_i)
            next_state_r = STATE_FETCH_WB;
    end
    default:
        ;
    endcase

    if (!enable_w)
        next_state_r = STATE_RESET;
end

// Update state
always @ (posedge clk_i )
if (rst_i)
    state_q   <= STATE_RESET;
else
    state_q   <= next_state_r;

The rest is just act on the right state, e.g.

always @ (posedge clk_i )
if (rst_i)
    opcode_q <= 32'b0;
else if (state_q == STATE_DECODE)
    opcode_q <= mem_i_inst_i;

Tác giả: pclouds | Liên kết tĩnh | Verilog

Fri Jun 20 09:38:34 AM CEST 2025

Real RISC-V in Verilog

Let's look at ultraembedded/riscv which can actually boot up Linux. Boy it's mightily complicated.

How instruction is decoded and delivered to ALU. Start at riscv_core.v which is supposed to be connected to some external memory bus interface, probably, then goes through a few modules (mmu, fetch, decode, issue, exec)

module riscv_core
(
    ,input  [ 31:0]  mem_i_inst_i
)

riscv_mmu
u_mmu
(
    ,.fetch_out_inst_i(mem_i_inst_i)
    ,.fetch_in_inst_o(mmu_ifetch_inst_w)
)

riscv_fetch
u_fetch
(
    ,.icache_inst_i(mmu_ifetch_inst_w)
    ,.fetch_instr_o(fetch_dec_instr_w)
)

riscv_decode
u_decode
(
    ,.fetch_in_instr_i(fetch_dec_instr_w)
    ,.fetch_out_instr_o(fetch_instr_w)
)

riscv_issue
u_issue
(
    ,.fetch_instr_i(fetch_instr_w)
    ,.opcode_opcode_o(opcode_opcode_w)
)

riscv_exec
u_exec
(
    ,.opcode_opcode_i(opcode_opcode_w)
)

riscv_exec.v decodes and delivers to riscv_alu, for example for "add"

module riscv_exec
(
    ,input  [ 31:0]  opcode_opcode_i
    ,input  [ 31:0]  opcode_ra_operand_i
    ,input  [ 31:0]  opcode_rb_operand_i
    ,output [ 31:0]  writeback_value_o
)

reg [3:0]  alu_func_r;
reg [31:0] alu_input_a_r;
reg [31:0] alu_input_b_r;
always @ *
begin
    if ((opcode_opcode_i & `INST_ADD_MASK) == `INST_ADD) // add
    begin
        alu_func_r     = `ALU_ADD;
        alu_input_a_r  = opcode_ra_operand_i;
        alu_input_b_r  = opcode_rb_operand_i;
    end
end

wire [31:0]  alu_p_w;
riscv_alu
u_alu
(
    .alu_op_i(alu_func_r),
    .alu_a_i(alu_input_a_r),
    .alu_b_i(alu_input_b_r),
    .alu_p_o(alu_p_w)
);

reg [31:0] result_q;
always @ (posedge clk_i or posedge rst_i)
if (rst_i)
    result_q  <= 32'b0;
else if (~hold_i)
    result_q <= alu_p_w;

assign writeback_value_o  = result_q;

and writeback_value_o goes back to issue:

riscv_exec
u_exec
(
    ,.writeback_value_o(writeback_exec_value_w)
);

riscv_issue
u_issue
(
    ,.writeback_exec_value_i(writeback_exec_value_w)
    ,.opcode_rd_idx_o(opcode_rd_idx_w)
)

There is a pipeline in riscv_issue.v!

riscv_pipe_ctrl
u_pipe_ctrl
(
    // Execution stage 1: ALU result
    ,.alu_result_e1_i(writeback_exec_value_i)

    // Execution stage 1
    // Execution stage 2: Other results

    // Execution stage 2
    ,.result_e2_o(pipe_result_e2_w)

    // Out of pipe: Divide Result
    // Commit
)

Naturally, I have no idea what's going on anymore. And I've been completely ignoring clk_i. And a pipeline means an instruction will be spread over multiple clocks. Exciting!


Tác giả: pclouds | Liên kết tĩnh | Verilog