Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

The order of "case" in verilog #91

Closed
Alaya-in-Matrix opened this issue Oct 30, 2015 · 2 comments

Comments

Projects
None yet
2 participants
@Alaya-in-Matrix
Copy link

commented Oct 30, 2015

I am trying to display numbers on segment LED, so I write such a encoder:

segEncoder :: (Integral a) => a -> SegDisp
segEncoder n = case n of
                 0 -> 0b00111111
                 1 -> 0b00000110
                 2 -> 0b01011011
                 3 -> 0b01001111
                 4 -> 0b01100110
                 5 -> 0b01101101
                 6 -> 0b01111101
                 7 -> 0b00000111
                 8 -> 0b01111111
                 9 -> 0b01101111
                 _ -> 0b00111111

segV = map segEncoder

but when I tried to encode Unsigned 3 numbers, for number 0, the displayed number is 8. I thought it was because 8==(0::Unsigned 3), so I looked at the compiled verilog code:

// Automatically generated Verilog-2001
module SegLED_segEncoder_1(ds_i1
                          ,topLet_o);
  input [3:0] ds_i1;
  output [7:0] topLet_o;
  reg [7:0] topLet_o_reg;
  always @(*) begin
    case(ds_i1)
      4'd9 : topLet_o_reg = 8'd111;
      4'd8 : topLet_o_reg = 8'd127;
      4'd7 : topLet_o_reg = 8'd7;
      4'd6 : topLet_o_reg = 8'd125;
      4'd5 : topLet_o_reg = 8'd109;
      4'd4 : topLet_o_reg = 8'd102;
      4'd3 : topLet_o_reg = 8'd79;
      4'd2 : topLet_o_reg = 8'd91;
      4'd1 : topLet_o_reg = 8'd6;
      4'd0 : topLet_o_reg = 8'd63;
      default : topLet_o_reg = 8'd63;
    endcase
  end
  assign topLet_o = topLet_o_reg;
endmodule

Why is the order in "case" from 9 to 0, instead of from 0 to 9, which matches the semantic of haskell more?

@christiaanb

This comment has been minimized.

Copy link
Contributor

commented Oct 30, 2015

When GHC goes from Haskell to its internal Core language, it puts the default pattern, _ at the top (I cannot remember right now why it does that). I subsequently translate _ in Core, to default in Verilog. However, if I would keep the order the same as it was given to me by GHC, the Verilog would always match against the default pattern, as it would be on top. That would of course be wrong. So what I do is simply reverse the alternatives that GHC gives me, hence resulting in correct Verilog, with default at the bottom.

Also note that, in Haskell, all patterns are unique, so the order in which they are put (with the exception of the default pattern) doesn't matter.

@christiaanb

This comment has been minimized.

Copy link
Contributor

commented Oct 31, 2015

Ah, I didn't realize the problem yesterday as I had a long day of travel behind me. I'm on holiday right now, and will be back on the 11th of November. I won't be able to fix it until then.

Perhaps you want to try and supply a patch? Here are some instructions on how to: https://github.com/clash-lang/clash-compiler/wiki/Getting-started

The code that needs patching is probably: https://github.com/clash-lang/clash-compiler/blob/master/clash-lib/src/CLaSH/Netlist.hs#L216
Remember though about what I said that GHC puts the default pattern at the front, and it must be put at the end.

@christiaanb christiaanb added the bug label Oct 31, 2015

christiaanb added a commit that referenced this issue Nov 17, 2015

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
You can’t perform that action at this time.