• sign extension in Verilog 2001

    From TJ Edmister@21:1/5 to All on Mon Apr 13 16:32:33 2020
    Greetings, I have a question about usage of $signed in verilog 2001. I had thought this could be used for sign extension and I employed it in various places in my design. But when I simulate with Icarus verilog I find that
    it is not doing the sign extension.

    cpupc <= cpupc + $signed({branchloc2, 1'b0});

    cpupc is a 32-bit value and I wanted the branch offset (which is 10 bits
    plus a 0 bit to make it even) to be sign extended so I can branch backward
    as well as forward... :)

    Since this failed in the simulation, I replaced that code with this "old"
    way of doing sign extension, and this one does work:

    cpupc <= cpupc + {{21{branchloc2[9]}}, branchloc2, 1'b0};

    I don't like the look of this one quite as much, is it the only way to do
    sign extension? How is $signed supposed to be used?

    --- SoupGate-Win32 v1.05
    * Origin: fsxNet Usenet Gateway (21:1/5)
  • From Richard Damon@21:1/5 to TJ Edmister on Mon Apr 13 20:09:42 2020
    On 4/13/20 4:32 PM, TJ Edmister wrote:
    Greetings, I have a question about usage of $signed in verilog 2001. I
    had thought this could be used for sign extension and I employed it in various places in my design. But when I simulate with Icarus verilog I
    find that it is not doing the sign extension.

    cpupc <= cpupc + $signed({branchloc2, 1'b0});

    cpupc is a 32-bit value and I wanted the branch offset (which is 10 bits
    plus a 0 bit to make it even) to be sign extended so I can branch
    backward as well as forward... :)

    Since this failed in the simulation, I replaced that code with this
    "old" way of doing sign extension, and this one does work:

    cpupc <= cpupc + {{21{branchloc2[9]}}, branchloc2, 1'b0};

    I don't like the look of this one quite as much, is it the only way to
    do sign extension? How is $signed supposed to be used?

    I think the issue is that cpupc is probably unsigned, and an unsigned
    plus a signed is done as unsigned, so that branchloc2 isn't signed extended.

    If you made a 32 bit signed wire that you put brancedloc2 into first
    then you could get the results you want.

    Maybe you could also do:

    cpupc <= $signed(cpupc) + $signed({branchloc2, 1'b0});

    --- SoupGate-Win32 v1.05
    * Origin: fsxNet Usenet Gateway (21:1/5)
  • From Rick C@21:1/5 to Richard Damon on Mon Apr 13 18:08:18 2020
    On Monday, April 13, 2020 at 8:09:45 PM UTC-4, Richard Damon wrote:
    On 4/13/20 4:32 PM, TJ Edmister wrote:
    Greetings, I have a question about usage of $signed in verilog 2001. I
    had thought this could be used for sign extension and I employed it in various places in my design. But when I simulate with Icarus verilog I
    find that it is not doing the sign extension.

    cpupc <= cpupc + $signed({branchloc2, 1'b0});

    cpupc is a 32-bit value and I wanted the branch offset (which is 10 bits plus a 0 bit to make it even) to be sign extended so I can branch
    backward as well as forward... :)

    Since this failed in the simulation, I replaced that code with this
    "old" way of doing sign extension, and this one does work:

    cpupc <= cpupc + {{21{branchloc2[9]}}, branchloc2, 1'b0};

    I don't like the look of this one quite as much, is it the only way to
    do sign extension? How is $signed supposed to be used?

    I think the issue is that cpupc is probably unsigned, and an unsigned
    plus a signed is done as unsigned, so that branchloc2 isn't signed extended.

    If you made a 32 bit signed wire that you put brancedloc2 into first
    then you could get the results you want.

    Maybe you could also do:

    cpupc <= $signed(cpupc) + $signed({branchloc2, 1'b0});

    This is the sort of issue I have been warned about with Verilog. I would like to learn the details so I can use the language without fighting issues like this. Is there a good book on the language that explains all the default assumptions the language
    uses so as to fully understand what to expect? I've asked about this a number of times and no one seems to know of a good reference.

    --

    Rick C.

    - Get 1,000 miles of free Supercharging
    - Tesla referral code - https://ts.la/richard11209

    --- SoupGate-Win32 v1.05
    * Origin: fsxNet Usenet Gateway (21:1/5)
  • From Richard Damon@21:1/5 to Rick C on Mon Apr 13 21:51:03 2020
    On 4/13/20 9:08 PM, Rick C wrote:
    On Monday, April 13, 2020 at 8:09:45 PM UTC-4, Richard Damon wrote:
    On 4/13/20 4:32 PM, TJ Edmister wrote:
    Greetings, I have a question about usage of $signed in verilog 2001. I
    had thought this could be used for sign extension and I employed it in
    various places in my design. But when I simulate with Icarus verilog I
    find that it is not doing the sign extension.

    cpupc <= cpupc + $signed({branchloc2, 1'b0});

    cpupc is a 32-bit value and I wanted the branch offset (which is 10 bits >>> plus a 0 bit to make it even) to be sign extended so I can branch
    backward as well as forward... :)

    Since this failed in the simulation, I replaced that code with this
    "old" way of doing sign extension, and this one does work:

    cpupc <= cpupc + {{21{branchloc2[9]}}, branchloc2, 1'b0};

    I don't like the look of this one quite as much, is it the only way to
    do sign extension? How is $signed supposed to be used?

    I think the issue is that cpupc is probably unsigned, and an unsigned
    plus a signed is done as unsigned, so that branchloc2 isn't signed extended. >>
    If you made a 32 bit signed wire that you put brancedloc2 into first
    then you could get the results you want.

    Maybe you could also do:

    cpupc <= $signed(cpupc) + $signed({branchloc2, 1'b0});

    This is the sort of issue I have been warned about with Verilog. I would like to learn the details so I can use the language without fighting issues like this. Is there a good book on the language that explains all the default assumptions the
    language uses so as to fully understand what to expect? I've asked about this a number of times and no one seems to know of a good reference.


    I figured it out with a bit of google-fu, where I found this document: <https://sutherland-hdl.com/papers/2006-SNUG-Boston_standard_gotchas_presentation.pdf>

    Which explains a number of traps like that.

    --- SoupGate-Win32 v1.05
    * Origin: fsxNet Usenet Gateway (21:1/5)
  • From Rick C@21:1/5 to Richard Damon on Mon Apr 13 19:54:08 2020
    On Monday, April 13, 2020 at 9:51:06 PM UTC-4, Richard Damon wrote:
    On 4/13/20 9:08 PM, Rick C wrote:

    This is the sort of issue I have been warned about with Verilog. I would like to learn the details so I can use the language without fighting issues like this. Is there a good book on the language that explains all the default assumptions the
    language uses so as to fully understand what to expect? I've asked about this a number of times and no one seems to know of a good reference.


    I figured it out with a bit of google-fu, where I found this document: <https://sutherland-hdl.com/papers/2006-SNUG-Boston_standard_gotchas_presentation.pdf>

    Which explains a number of traps like that.

    Great guide. The one on sign extending literals is pathological. I like that they tell you to avoid this problem to "learn Verilog's sign extension rules!" but don't tell you how to do it correctly. I guess there is no "correct" way other than
    entering all the bits?

    I'm seven items into the list and it's getting a bit deep for my waders. I'll go back to this when I sit down to learn Verilog. There's one guy I know who swears up and down everyone who learns Verilog will prefer it and be more productive. So one day
    I will give it a serious try.

    Thanks.

    --

    Rick C.

    + Get 1,000 miles of free Supercharging
    + Tesla referral code - https://ts.la/richard11209

    --- SoupGate-Win32 v1.05
    * Origin: fsxNet Usenet Gateway (21:1/5)
  • From TJ Edmister@21:1/5 to Richard@Damon-Family.org on Tue Apr 14 10:09:57 2020
    On Mon, 13 Apr 2020 20:09:42 -0400, Richard Damon
    <Richard@Damon-Family.org> wrote:

    On 4/13/20 4:32 PM, TJ Edmister wrote:
    Greetings, I have a question about usage of $signed in verilog 2001. I
    had thought this could be used for sign extension and I employed it in
    various places in my design. But when I simulate with Icarus verilog I
    find that it is not doing the sign extension.

    cpupc <= cpupc + $signed({branchloc2, 1'b0});

    cpupc is a 32-bit value and I wanted the branch offset (which is 10 bits
    plus a 0 bit to make it even) to be sign extended so I can branch
    backward as well as forward... :)

    Since this failed in the simulation, I replaced that code with this
    "old" way of doing sign extension, and this one does work:

    cpupc <= cpupc + {{21{branchloc2[9]}}, branchloc2, 1'b0};

    I don't like the look of this one quite as much, is it the only way to
    do sign extension? How is $signed supposed to be used?

    I think the issue is that cpupc is probably unsigned, and an unsigned
    plus a signed is done as unsigned, so that branchloc2 isn't signed
    extended.

    If you made a 32 bit signed wire that you put brancedloc2 into first
    then you could get the results you want.

    Maybe you could also do:

    cpupc <= $signed(cpupc) + $signed({branchloc2, 1'b0});

    Thanks for posting. I'm thinking that if it is this finicky maybe I'll use
    it only for plain old assignments, and then enumerate the bits myself in
    any expression that involves computation.

    --- SoupGate-Win32 v1.05
    * Origin: fsxNet Usenet Gateway (21:1/5)
  • From Rick C@21:1/5 to TJ Edmister on Tue Apr 14 11:02:01 2020
    On Tuesday, April 14, 2020 at 10:09:46 AM UTC-4, TJ Edmister wrote:
    On Mon, 13 Apr 2020 20:09:42 -0400, Richard Damon <Richard@Damon-Family.org> wrote:

    On 4/13/20 4:32 PM, TJ Edmister wrote:
    Greetings, I have a question about usage of $signed in verilog 2001. I
    had thought this could be used for sign extension and I employed it in
    various places in my design. But when I simulate with Icarus verilog I
    find that it is not doing the sign extension.

    cpupc <= cpupc + $signed({branchloc2, 1'b0});

    cpupc is a 32-bit value and I wanted the branch offset (which is 10 bits >> plus a 0 bit to make it even) to be sign extended so I can branch
    backward as well as forward... :)

    Since this failed in the simulation, I replaced that code with this
    "old" way of doing sign extension, and this one does work:

    cpupc <= cpupc + {{21{branchloc2[9]}}, branchloc2, 1'b0};

    I don't like the look of this one quite as much, is it the only way to
    do sign extension? How is $signed supposed to be used?

    I think the issue is that cpupc is probably unsigned, and an unsigned
    plus a signed is done as unsigned, so that branchloc2 isn't signed extended.

    If you made a 32 bit signed wire that you put brancedloc2 into first
    then you could get the results you want.

    Maybe you could also do:

    cpupc <= $signed(cpupc) + $signed({branchloc2, 1'b0});

    Thanks for posting. I'm thinking that if it is this finicky maybe I'll use it only for plain old assignments, and then enumerate the bits myself in any expression that involves computation.

    Actually this is just the language asking you to explain exactly what you mean. Trust me, as a VHDL user, I get that! In fact, in VHDL you would then need to type cast the value back to unsigned before it would allow the summation! In VHDL operators
    are overloaded depending on the types of arguments and results. There is no summation operator for adding

    In VHDL the sign extension would also need to be explicit which is really the root of the problem in Verilog, the assumed sign extension that doesn't happen.

    cpupc <= cpupc + unsigned(resize((branchloc2 & "0"), cpupc'length));

    Is there no resize() operator in Verilog?

    --

    Rick C.

    -- Get 1,000 miles of free Supercharging
    -- Tesla referral code - https://ts.la/richard11209

    --- SoupGate-Win32 v1.05
    * Origin: fsxNet Usenet Gateway (21:1/5)
  • From Richard Damon@21:1/5 to Rick C on Tue Apr 14 14:58:09 2020
    On 4/13/20 10:54 PM, Rick C wrote:
    On Monday, April 13, 2020 at 9:51:06 PM UTC-4, Richard Damon wrote:
    On 4/13/20 9:08 PM, Rick C wrote:

    This is the sort of issue I have been warned about with Verilog. I would like to learn the details so I can use the language without fighting issues like this. Is there a good book on the language that explains all the default assumptions the
    language uses so as to fully understand what to expect? I've asked about this a number of times and no one seems to know of a good reference.


    I figured it out with a bit of google-fu, where I found this document:
    <https://sutherland-hdl.com/papers/2006-SNUG-Boston_standard_gotchas_presentation.pdf>

    Which explains a number of traps like that.

    Great guide. The one on sign extending literals is pathological. I like that they tell you to avoid this problem to "learn Verilog's sign extension rules!" but don't tell you how to do it correctly. I guess there is no "correct" way other than
    entering all the bits?

    Yes, because the literal is ALWAYS zero extended to its declared size.
    Sign extension of the value only happens after that, and only if the
    operation will be done as a signed operation. You only get signed
    operations if ALL the signals in the expression are signed.

    I'm seven items into the list and it's getting a bit deep for my waders. I'll go back to this when I sit down to learn Verilog. There's one guy I know who swears up and down everyone who learns Verilog will prefer it and be more productive. So one
    day I will give it a serious try.

    Thanks.


    --- SoupGate-Win32 v1.05
    * Origin: fsxNet Usenet Gateway (21:1/5)
  • From Rick C@21:1/5 to Richard Damon on Tue Apr 14 15:17:39 2020
    On Tuesday, April 14, 2020 at 2:58:12 PM UTC-4, Richard Damon wrote:
    On 4/13/20 10:54 PM, Rick C wrote:
    On Monday, April 13, 2020 at 9:51:06 PM UTC-4, Richard Damon wrote:
    On 4/13/20 9:08 PM, Rick C wrote:

    This is the sort of issue I have been warned about with Verilog. I would like to learn the details so I can use the language without fighting issues like this. Is there a good book on the language that explains all the default assumptions the
    language uses so as to fully understand what to expect? I've asked about this a number of times and no one seems to know of a good reference.


    I figured it out with a bit of google-fu, where I found this document:
    <https://sutherland-hdl.com/papers/2006-SNUG-Boston_standard_gotchas_presentation.pdf>

    Which explains a number of traps like that.

    Great guide. The one on sign extending literals is pathological. I like that they tell you to avoid this problem to "learn Verilog's sign extension rules!" but don't tell you how to do it correctly. I guess there is no "correct" way other than
    entering all the bits?

    Yes, because the literal is ALWAYS zero extended to its declared size.
    Sign extension of the value only happens after that, and only if the operation will be done as a signed operation. You only get signed
    operations if ALL the signals in the expression are signed.

    Not sure I get what you are saying. After there are zeros appended to match sizes, there is no extension. What do you mean by "Sign extension of the value only happens after that"??? It looks like there is never automatic sign extension. Once the
    zeros are appended it's too late anyway.

    --

    Rick C.

    -+ Get 1,000 miles of free Supercharging
    -+ Tesla referral code - https://ts.la/richard11209

    --- SoupGate-Win32 v1.05
    * Origin: fsxNet Usenet Gateway (21:1/5)
  • From Richard Damon@21:1/5 to Rick C on Tue Apr 14 18:46:43 2020
    On 4/14/20 6:17 PM, Rick C wrote:
    On Tuesday, April 14, 2020 at 2:58:12 PM UTC-4, Richard Damon wrote:
    On 4/13/20 10:54 PM, Rick C wrote:
    On Monday, April 13, 2020 at 9:51:06 PM UTC-4, Richard Damon wrote:
    On 4/13/20 9:08 PM, Rick C wrote:

    This is the sort of issue I have been warned about with Verilog. I would like to learn the details so I can use the language without fighting issues like this. Is there a good book on the language that explains all the default assumptions the
    language uses so as to fully understand what to expect? I've asked about this a number of times and no one seems to know of a good reference.


    I figured it out with a bit of google-fu, where I found this document: >>>> <https://sutherland-hdl.com/papers/2006-SNUG-Boston_standard_gotchas_presentation.pdf>

    Which explains a number of traps like that.

    Great guide. The one on sign extending literals is pathological. I like that they tell you to avoid this problem to "learn Verilog's sign extension rules!" but don't tell you how to do it correctly. I guess there is no "correct" way other than
    entering all the bits?

    Yes, because the literal is ALWAYS zero extended to its declared size.
    Sign extension of the value only happens after that, and only if the
    operation will be done as a signed operation. You only get signed
    operations if ALL the signals in the expression are signed.

    Not sure I get what you are saying. After there are zeros appended to match sizes, there is no extension. What do you mean by "Sign extension of the value only happens after that"??? It looks like there is never automatic sign extension. Once the
    zeros are appended it's too late anyway.


    If you take 4'sb1111 + 3'sb111 then the 3 ones will be extended to 4
    bits with sign extension, or if two signed vectors get operated on
    together, the smaller will get extended to match the size of the larger.
    (Or possibly bigger, as the size of the result can also cause the fields
    to get extended).

    In a literal of the form x'sby, if the value y takes less than x bits,
    it is zero extended to that size, and THEN if that literal needs to be
    expanded to be used in the expression, the MSB of that value is check to
    decide sign extension.

    --- SoupGate-Win32 v1.05
    * Origin: fsxNet Usenet Gateway (21:1/5)
  • From Rick C@21:1/5 to Richard Damon on Tue Apr 14 16:06:35 2020
    On Tuesday, April 14, 2020 at 6:46:46 PM UTC-4, Richard Damon wrote:
    On 4/14/20 6:17 PM, Rick C wrote:
    On Tuesday, April 14, 2020 at 2:58:12 PM UTC-4, Richard Damon wrote:
    On 4/13/20 10:54 PM, Rick C wrote:
    On Monday, April 13, 2020 at 9:51:06 PM UTC-4, Richard Damon wrote:
    On 4/13/20 9:08 PM, Rick C wrote:

    This is the sort of issue I have been warned about with Verilog. I would like to learn the details so I can use the language without fighting issues like this. Is there a good book on the language that explains all the default assumptions the
    language uses so as to fully understand what to expect? I've asked about this a number of times and no one seems to know of a good reference.


    I figured it out with a bit of google-fu, where I found this document: >>>> <https://sutherland-hdl.com/papers/2006-SNUG-Boston_standard_gotchas_presentation.pdf>

    Which explains a number of traps like that.

    Great guide. The one on sign extending literals is pathological. I like that they tell you to avoid this problem to "learn Verilog's sign extension rules!" but don't tell you how to do it correctly. I guess there is no "correct" way other than
    entering all the bits?

    Yes, because the literal is ALWAYS zero extended to its declared size.
    Sign extension of the value only happens after that, and only if the
    operation will be done as a signed operation. You only get signed
    operations if ALL the signals in the expression are signed.

    Not sure I get what you are saying. After there are zeros appended to match sizes, there is no extension. What do you mean by "Sign extension of the value only happens after that"??? It looks like there is never automatic sign extension. Once the
    zeros are appended it's too late anyway.


    If you take 4'sb1111 + 3'sb111 then the 3 ones will be extended to 4
    bits with sign extension, or if two signed vectors get operated on
    together, the smaller will get extended to match the size of the larger.
    (Or possibly bigger, as the size of the result can also cause the fields
    to get extended).

    In a literal of the form x'sby, if the value y takes less than x bits,
    it is zero extended to that size, and THEN if that literal needs to be expanded to be used in the expression, the MSB of that value is check to decide sign extension.

    Thank you, that is clear.

    I'm not very conversant in Verilog so perhaps you can explain some details.

    cpupc <= $signed(cpupc) + $signed({branchloc2, 1'b0});

    This works I assume. If branchloc2 is a signed quantity would this also work?

    cpupc <= $signed(cpupc) + {branchloc2, 1'b0};

    I assume the aggregate would then be signed and would be properly sign extended?

    --

    Rick C.

    +- Get 1,000 miles of free Supercharging
    +- Tesla referral code - https://ts.la/richard11209

    --- SoupGate-Win32 v1.05
    * Origin: fsxNet Usenet Gateway (21:1/5)
  • From Richard Damon@21:1/5 to Rick C on Tue Apr 14 23:20:02 2020
    On 4/14/20 7:06 PM, Rick C wrote:
    On Tuesday, April 14, 2020 at 6:46:46 PM UTC-4, Richard Damon wrote:
    On 4/14/20 6:17 PM, Rick C wrote:
    On Tuesday, April 14, 2020 at 2:58:12 PM UTC-4, Richard Damon wrote:
    On 4/13/20 10:54 PM, Rick C wrote:
    On Monday, April 13, 2020 at 9:51:06 PM UTC-4, Richard Damon wrote: >>>>>> On 4/13/20 9:08 PM, Rick C wrote:

    This is the sort of issue I have been warned about with Verilog. I would like to learn the details so I can use the language without fighting issues like this. Is there a good book on the language that explains all the default assumptions the
    language uses so as to fully understand what to expect? I've asked about this a number of times and no one seems to know of a good reference.


    I figured it out with a bit of google-fu, where I found this document: >>>>>> <https://sutherland-hdl.com/papers/2006-SNUG-Boston_standard_gotchas_presentation.pdf>

    Which explains a number of traps like that.

    Great guide. The one on sign extending literals is pathological. I like that they tell you to avoid this problem to "learn Verilog's sign extension rules!" but don't tell you how to do it correctly. I guess there is no "correct" way other than
    entering all the bits?

    Yes, because the literal is ALWAYS zero extended to its declared size. >>>> Sign extension of the value only happens after that, and only if the
    operation will be done as a signed operation. You only get signed
    operations if ALL the signals in the expression are signed.

    Not sure I get what you are saying. After there are zeros appended to match sizes, there is no extension. What do you mean by "Sign extension of the value only happens after that"??? It looks like there is never automatic sign extension. Once the
    zeros are appended it's too late anyway.


    If you take 4'sb1111 + 3'sb111 then the 3 ones will be extended to 4
    bits with sign extension, or if two signed vectors get operated on
    together, the smaller will get extended to match the size of the larger.
    (Or possibly bigger, as the size of the result can also cause the fields
    to get extended).

    In a literal of the form x'sby, if the value y takes less than x bits,
    it is zero extended to that size, and THEN if that literal needs to be
    expanded to be used in the expression, the MSB of that value is check to
    decide sign extension.

    Thank you, that is clear.

    I'm not very conversant in Verilog so perhaps you can explain some details.

    cpupc <= $signed(cpupc) + $signed({branchloc2, 1'b0});

    Yes, I think that would work. The term will be computed as signed, and
    the offset should be thus sign extended.


    This works I assume. If branchloc2 is a signed quantity would this also work?

    cpupc <= $signed(cpupc) + {branchloc2, 1'b0};

    you might need it to be

    cpupc <= $signed(cpupc) {branchloc2, 1'sb0 }

    so the unsigned 0 bit doesn't pollute the signedness of the computation.

    I assume the aggregate would then be signed and would be properly sign extended?


    I will confess I don't know about that. This is getting into a corner of
    the language I haven't used much of. It might work, or it might not.

    --- SoupGate-Win32 v1.05
    * Origin: fsxNet Usenet Gateway (21:1/5)
  • From Kevin Neilson@21:1/5 to TJ Edmister on Sun Apr 19 10:16:59 2020
    On Monday, April 13, 2020 at 2:32:23 PM UTC-6, TJ Edmister wrote:
    Greetings, I have a question about usage of $signed in verilog 2001. I had thought this could be used for sign extension and I employed it in various places in my design. But when I simulate with Icarus verilog I find that
    it is not doing the sign extension.

    cpupc <= cpupc + $signed({branchloc2, 1'b0});

    cpupc is a 32-bit value and I wanted the branch offset (which is 10 bits plus a 0 bit to make it even) to be sign extended so I can branch backward as well as forward... :)

    Since this failed in the simulation, I replaced that code with this "old" way of doing sign extension, and this one does work:

    cpupc <= cpupc + {{21{branchloc2[9]}}, branchloc2, 1'b0};

    I don't like the look of this one quite as much, is it the only way to do sign extension? How is $signed supposed to be used?

    I usually use an intermediate sign-extended version of the addend, which is a little clumsy.
    Below are three examples of methods that work. I was surprised to find that Richard D's method of converting cpupc to $signed before the addition was successful. Then there is my intermediate sign extension. Last is casting to an integer. I don't use
    this because it's Systemverilog and too many customers whine when you use Systemverilog because it's too "new" (2009).

    reg [31:0] cpupc;
    reg signed [9:0] branchloc2 = -4;
    wire signed [$left(cpupc):0] branchloc2_sgnext = branchloc2;

    initial begin
    // convert cpupc to signed before addition
    cpupc = 64; cpupc = $signed(cpupc) + (branchloc2<<<1);
    $display("cpupc: %0d", cpupc);

    // use sign-extended version of branchloc2
    cpupc = 64; cpupc = cpupc + (branchloc2_sgnext<<<1);
    $display("cpupc: %0d", cpupc);

    // Systemverilog casting to signed integer
    cpupc = 64; cpupc = cpupc + (int'(branchloc2))*2;
    $display("cpupc: %0d", cpupc);
    end

    ucli% run;
    cpupc: 56
    cpupc: 56
    cpupc: 56

    --- SoupGate-Win32 v1.05
    * Origin: fsxNet Usenet Gateway (21:1/5)
  • From Rick C@21:1/5 to Kevin Neilson on Sun Apr 19 23:41:00 2020
    On Sunday, April 19, 2020 at 1:17:01 PM UTC-4, Kevin Neilson wrote:
    On Monday, April 13, 2020 at 2:32:23 PM UTC-6, TJ Edmister wrote:
    Greetings, I have a question about usage of $signed in verilog 2001. I had
    thought this could be used for sign extension and I employed it in various
    places in my design. But when I simulate with Icarus verilog I find that it is not doing the sign extension.

    cpupc <= cpupc + $signed({branchloc2, 1'b0});

    cpupc is a 32-bit value and I wanted the branch offset (which is 10 bits plus a 0 bit to make it even) to be sign extended so I can branch backward
    as well as forward... :)

    Since this failed in the simulation, I replaced that code with this "old" way of doing sign extension, and this one does work:

    cpupc <= cpupc + {{21{branchloc2[9]}}, branchloc2, 1'b0};

    I don't like the look of this one quite as much, is it the only way to do sign extension? How is $signed supposed to be used?

    I usually use an intermediate sign-extended version of the addend, which is a little clumsy.
    Below are three examples of methods that work. I was surprised to find that Richard D's method of converting cpupc to $signed before the addition was successful. Then there is my intermediate sign extension. Last is casting to an integer. I don't
    use this because it's Systemverilog and too many customers whine when you use Systemverilog because it's too "new" (2009).

    reg [31:0] cpupc;
    reg signed [9:0] branchloc2 = -4;
    wire signed [$left(cpupc):0] branchloc2_sgnext = branchloc2;

    initial begin
    // convert cpupc to signed before addition
    cpupc = 64; cpupc = $signed(cpupc) + (branchloc2<<<1);
    $display("cpupc: %0d", cpupc);

    // use sign-extended version of branchloc2
    cpupc = 64; cpupc = cpupc + (branchloc2_sgnext<<<1);
    $display("cpupc: %0d", cpupc);

    // Systemverilog casting to signed integer
    cpupc = 64; cpupc = cpupc + (int'(branchloc2))*2;
    $display("cpupc: %0d", cpupc);
    end

    ucli% run;
    cpupc: 56
    cpupc: 56
    cpupc: 56

    In the second version, is the assignment to branchloc2_sgnext a regular concurrent statement or is this only executed during initialization?

    In the third case w
    hat size is an int in Verilog? Is it like VHDL, 32 bits by default? If cpupc were less than 32 bits would that be a problem? If cpupc were more than 32 bits would that be a problem?

    --

    Rick C.

    ++ Get 1,000 miles of free Supercharging
    ++ Tesla referral code - https://ts.la/richard11209

    --- SoupGate-Win32 v1.05
    * Origin: fsxNet Usenet Gateway (21:1/5)
  • From Kevin Neilson@21:1/5 to All on Mon Apr 20 09:24:47 2020

    In the second version, is the assignment to branchloc2_sgnext a regular concurrent statement or is this only executed during initialization?

    branchloc2_sgnext is a continuous assignment so it is automatically updated whenever branchloc2 is.

    In the third case w
    hat size is an int in Verilog? Is it like VHDL, 32 bits by default? If cpupc were less than 32 bits would that be a problem? If cpupc were more than 32 bits would that be a problem?

    I believe an 'int' is always 32 bits, so this case would probably not work if cpupc were bigger than 32 bits.

    --- SoupGate-Win32 v1.05
    * Origin: fsxNet Usenet Gateway (21:1/5)
  • From Rick C@21:1/5 to Kevin Neilson on Mon Apr 20 09:46:04 2020
    On Monday, April 20, 2020 at 12:24:50 PM UTC-4, Kevin Neilson wrote:

    In the second version, is the assignment to branchloc2_sgnext a regular concurrent statement or is this only executed during initialization?

    branchloc2_sgnext is a continuous assignment so it is automatically updated whenever branchloc2 is.

    Ok, I got it. I was thinking this was an assignment as part of a declaration like in VHDL. But this is a declaration which is part of a continuous assignment. I forgot you can do that in Verilog.


    In the third case w
    hat size is an int in Verilog? Is it like VHDL, 32 bits by default? If cpupc were less than 32 bits would that be a problem? If cpupc were more than 32 bits would that be a problem?

    I believe an 'int' is always 32 bits, so this case would probably not work if cpupc were bigger than 32 bits.

    What would happen if cpupc were smaller than 32 bits? In VHDL the int has a range of a 32 bit word, but it's not really a 32 bit word... it's just an int. To add an int to a signed or unsigned it has to be converted (in the "+" definition) to a size
    matching the signed or unsigned.

    It's unclear to me how ints are handled in Verilog.

    --

    Rick C.

    --- Get 1,000 miles of free Supercharging
    --- Tesla referral code - https://ts.la/richard11209

    --- SoupGate-Win32 v1.05
    * Origin: fsxNet Usenet Gateway (21:1/5)
  • From Kevin Neilson@21:1/5 to All on Mon Apr 20 13:16:06 2020
    What would happen if cpupc were smaller than 32 bits? In VHDL the int has a range of a 32 bit word, but it's not really a 32 bit word... it's just an int. To add an int to a signed or unsigned it has to be converted (in the "+" definition) to a size
    matching the signed or unsigned.

    It's unclear to me how ints are handled in Verilog.

    I think an 'int' is identical to a 32-bit signed reg. If cpupc were less than 32 bits, I don't think there would be a problem. The extra upper bits in the int will just be truncated. In Verilog, you can sum together things of different sizes with no
    conversions.

    --- SoupGate-Win32 v1.05
    * Origin: fsxNet Usenet Gateway (21:1/5)
  • From Rick C@21:1/5 to Kevin Neilson on Tue Apr 21 20:23:29 2020
    On Monday, April 20, 2020 at 4:16:09 PM UTC-4, Kevin Neilson wrote:
    What would happen if cpupc were smaller than 32 bits? In VHDL the int has a range of a 32 bit word, but it's not really a 32 bit word... it's just an int. To add an int to a signed or unsigned it has to be converted (in the "+" definition) to a
    size matching the signed or unsigned.

    It's unclear to me how ints are handled in Verilog.

    I think an 'int' is identical to a 32-bit signed reg. If cpupc were less than 32 bits, I don't think there would be a problem. The extra upper bits in the int will just be truncated. In Verilog, you can sum together things of different sizes with no
    conversions.

    Yeah, trouble is you have to know the details of what happens when it does that. What gets extended, what gets truncated and when it sign extends vs. zero padding. That's the sort of thing I expect to be noted in books on Verilog along with other "
    gotchas" and I'm told no one has written that.

    Thanks for all the info. It has been educational.

    --

    Rick C.

    --+ Get 1,000 miles of free Supercharging
    --+ Tesla referral code - https://ts.la/richard11209

    --- SoupGate-Win32 v1.05
    * Origin: fsxNet Usenet Gateway (21:1/5)