My background is in software and I'm new to (System)Verilog so when tasked with implementing a caesar shifter (shift each letter in a string by N letters, wrapping around if necessary e.g. ABCXYZ shifted by 3 becomes DEFABC), I wrote the following, hoping to be able to reduce code duplication, like I would in software:
/* every variable except 'direction' has the type 'byte' */ always_comb begin shifted_char = fresh_char; /* don't touch bytes that aren't letters */ is_lower_case = "z" >= fresh_char && fresh_char >= "a"; is_upper_case = "Z" >= fresh_char && fresh_char >= "A"; if (is_lower_case || is_upper_case) begin unique if (is_lower_case) alphabet_start = "a"; else if (is_upper_case) alphabet_start = "A"; alphabet_position = fresh_char - alphabet_start; if (direction == "f") /* direction is a module parameter: f for forwards results in a shifter, any other value results in an 'unshifter' */ new_alphabet_position = (26 + (alphabet_position + shift_by)) % 26; else new_alphabet_position = (26 + (alphabet_position - shift_by)) % 26; shifted_char = new_alphabet_position + alphabet_start; end end
My question is (assuming it's a forward shifter): regarding the "% 26" part, can I expect the synthesizer to deduce that the range of possible values it's going to get at that point is [26, 26+25+25] ([26, 76]) and so there's only 2 cases the logic needs to distinguish between (>26 and >52), rather than [whatever is the smart call when having handle all possible 256 different inputs - (would it be to consider the cases >26, >52, >78 etc...? Or is there a better way? I digress...)]?
I could always do the following:
new_alphabet_position = alphabet_position + shift_by; if (new_alphabet_position > 25) new_alpahbet_position -= 26; /* Or, for the reverse shifter: */ new_alphabet_position = alphabet_position - shift_by; if (new_alphabet_position < 0) new_alpahbet_position += 26;
...but was curious and wanted to ask that, as well as a related one (that I expect more people will be able to answer): Can it be used to make a normal non-power-of-2 counter (e.g. count <= (count + 1) % 6; )? Going by hgleamon1's response to the following thread, it seems as though (at least one) VHDL synth tool might interpret it as intended: https://forums.xilinx.com/t5/Synthesis/Modulus-synthesizable-or-non-synthesizable/td-p/747493