Shop OBEX P1 Docs P2 Docs Learn Events
Simplify the capture of source? — Parallax Forums

Simplify the capture of source?

SeairthSeairth Posts: 2,474
edited 2014-09-21 17:31 in Propeller 1
This is the code from "cog.v" that captures the source value.
reg [31:0] sy;
reg [31:0] s;

always @(posedge clk_cog)
if (m[1])
    sy <= ram_q;

wire [31:0] sx      = i[im]                 ? {23'b0, i[sh:sl]}
                    : i[sh:sl] == 9'h1F0    ? {16'b0, ptr[27:14], 2'b0}
                    : i[sh:sl] == 9'h1F1    ? cnt
                    : i[sh:sl] == 9'h1F2    ? pin_in
                    : i[sh:sl] == 9'h1FC    ? phsa[31:0]
                    : i[sh:sl] == 9'h1FD    ? phsb[31:0]
                                            : sy;

always @(posedge clk_cog)
if (m[2])
    s <= sx;

Why is this implemented as a two-stage process? Could the code be simplified to:
reg [31:0] s;

wire [31:0] sx      = i[im]                 ? {23'b0, i[sh:sl]}
                    : i[sh:sl] == 9'h1F0    ? {16'b0, ptr[27:14], 2'b0}
                    : i[sh:sl] == 9'h1F1    ? cnt
                    : i[sh:sl] == 9'h1F2    ? pin_in
                    : i[sh:sl] == 9'h1FC    ? phsa[31:0]
                    : i[sh:sl] == 9'h1FD    ? phsb[31:0]
                                            : ram_q;

always @(posedge clk_cog)
if (m[1])
    s <= sx;

I realize that this would move the capture of the "special" registers one clock cycle earlier. But I don't see where that would be an issue, as they will still be captured at the same time in each instruction cycle.

Comments

  • roglohrogloh Posts: 5,852
    edited 2014-09-21 17:31
    Seairth wrote: »
    This is the code from "cog.v" that captures the source value.
    reg [31:0] sy;
    reg [31:0] s;
    
    always @(posedge clk_cog)
    if (m[1])
        sy <= ram_q;
    
    wire [31:0] sx      = i[im]                 ? {23'b0, i[sh:sl]}
                        : i[sh:sl] == 9'h1F0    ? {16'b0, ptr[27:14], 2'b0}
                        : i[sh:sl] == 9'h1F1    ? cnt
                        : i[sh:sl] == 9'h1F2    ? pin_in
                        : i[sh:sl] == 9'h1FC    ? phsa[31:0]
                        : i[sh:sl] == 9'h1FD    ? phsb[31:0]
                                                : sy;
    
    always @(posedge clk_cog)
    if (m[2])
        s <= sx;
    

    Why is this implemented as a two-stage process? Could the code be simplified to:
    reg [31:0] s;
    
    wire [31:0] sx      = i[im]                 ? {23'b0, i[sh:sl]}
                        : i[sh:sl] == 9'h1F0    ? {16'b0, ptr[27:14], 2'b0}
                        : i[sh:sl] == 9'h1F1    ? cnt
                        : i[sh:sl] == 9'h1F2    ? pin_in
                        : i[sh:sl] == 9'h1FC    ? phsa[31:0]
                        : i[sh:sl] == 9'h1FD    ? phsb[31:0]
                                                : ram_q;
    
    always @(posedge clk_cog)
    if (m[1])
        s <= sx;
    

    I realize that this would move the capture of the "special" registers one clock cycle earlier. But I don't see where that would be an issue, as they will still be captured at the same time in each instruction cycle.

    Maybe (and honestly I'm just guessing here), this might be done so S and D both change at the same time. Given the ALU works on both as inputs, it may save some power to not have the ALU inputs change twice in the instruction cycle...?

    PS. Thought some more. Actually the sx mux will add a small delay from getting the ram_q output into the latched register just before latching time, eating into your timing budget slightly. That's probably the main reason here. This delay gets hidden by the two step latching design in the original P1 so it can run faster that way. The reduced ALU input transition is another resulting advantage, but is mostly a bonus I suspect.
Sign In or Register to comment.