I have a question about the meaning of having a begin
statement for each letter. Why is it necessary or is it? Also, what does the HexSeg[x] = y
mean for the letters with a begin
statement? I am having difficulty wrapping my head around it. Is all of this necessary and is there an easier way to go about this? Is it the same method for coding ASCII numbers? I am also using the DE10-Lite FPGA board.
//
// ASCII to 7-segment display conversion
//
module ASCII27Seg (input [7:0] AsciiCode, output reg [6:0] HexSeg);
always @ (*) begin
HexSeg = 7'd0; // initialization of variable HexSeg
$display("AsciiCode %b", AsciiCode);
case (AsciiCode)
// A
8'h41 : HexSeg[3] = 1;
// a
8'h61 : HexSeg[3] = 1;
// B
8'h42 : begin
HexSeg[0] = 1; HexSeg[1] = 1;
end
// b
8'h62 : begin
HexSeg[0] = 1; HexSeg[1] = 1;
end
// C
8'h43 : begin
HexSeg[1] = 1; HexSeg[2] = 1; HexSeg[6] = 1;
end
// c
8'h63 : begin
HexSeg[1] = 1; HexSeg[2] = 1; HexSeg[6] = 1;
end
//
// the rest of the code should go here
//
// D
8'h44 : begin
// d
8'h64 : begin
// E
8'h45 : begin
// e
8'h65 : begin
// F
8'h46 : begin
// f
8'h66 : begin
// G
8'h47 : begin
// g
8'h67 : begin
// H
8'h48 : begin
// h
8'h68 : begin
// I
8'h49 : begin
// i
8'h69 : begin
// J
8'h4A : begin
// j
8'h6A : begin
// K
8'h4B : begin
// k
8'h6B : begin
// L
8'h4C : begin
// l
8'h6C : begin
// M
8'h4D : begin
// m
8'h6D : begin
// N
8'h4E : begin
// n
8'h6E : begin
// O
8'h4F : begin
// o
8'h6F : begin
// P
8'h50 : begin
// p
8'h70 : begin
// Q
8'h51 : begin
// q
8'h71 : begin
// R
8'h52 : begin
// r
8'h72 : begin
// S
8'h53 : begin
// s
8'h73 : begin
// T
8'h54 : begin
// t
8'h74 : begin
// U
8'h55 : begin
// u
8'h75 : begin
// V
8'h56 : begin
// v
8'h76 : begin
// W
8'h57 : begin
// w
8'h77 : begin
// X
8'h58 : begin
// x
8'h78 : begin
// Y
8'h59 : begin
// y
8'h79 : begin
// Z
8'h5A : begin
// z
8'h7A : begin
// turn all the bits off by default
default : HexSeg = 8'b11111111; // default of variable HexSeg
// you have to finish this code using correct syntax, see begin and end, and case
// and endcase in language specification, and be careful.
endcase
end
endmodule
I tried implementing the begin
statements for every letter, but I don't understand why it wasn't necessary for 'A' and 'a'. I also don't know how to form the begin
statements with HexSeg[x]
. Any help would be appreciated.
The begin/end
keywords are required by Verilog whenever you have more than one statement in a block of code. They are optional if you only have one statement in the block. Refer to IEEE Std 1800-2017, section 12.5 Case statement.
Each case
item in the case
statement can execute a block of code. For example, 8'h41
is the 1st case
item. Since that item only has one statement (HexSeg[3] = 1;
), the begin/end
keywords are not needed. However, for the 8'h42
item, you have 2 statements (HexSeg[0] = 1; HexSeg[1] = 1;
), and the begin/end
keywords are needed.
what does the HexSeg[x] = y mean for the letters with a begin statement?
It means the same thing with or without the begin
; you are just setting bits of HexSeg
.
Since some of the items require at least 2 statements, you must use begin/end
for those items, as just described. However, from a consistent code style perspective, you might prefer to have all items look the same. Here is how that would look:
module ASCII27Seg (input [7:0] AsciiCode, output reg [6:0] HexSeg);
always @ (*) begin
HexSeg = 7'd0;
case (AsciiCode)
// A
8'h41 : begin
HexSeg[3] = 1;
end
// a
8'h61 : begin
HexSeg[3] = 1;
end
// B
8'h42 : begin
HexSeg[0] = 1; HexSeg[1] = 1;
end
// b
8'h62 : begin
HexSeg[0] = 1; HexSeg[1] = 1;
end
// C
8'h43 : begin
HexSeg[1] = 1; HexSeg[2] = 1; HexSeg[6] = 1;
end
// c
8'h63 : begin
HexSeg[1] = 1; HexSeg[2] = 1; HexSeg[6] = 1;
end
// turn all the bits off by default
default : begin
HexSeg = 8'b11111111;
end
endcase
end
endmodule
This is a little more typing, but it may be easier to read and understand using this style.
is there an easier way to go about this?
This is a good straightforward approach. Using a case
statement is a common practice for this sort of design.
Is it the same method for coding ASCII numbers?
Yes, if you need to do a similar mapping between 8-bit ASCII and 7-bit HexSeg
.
Whenever you are setting consecutive bits, you could combine them into a single statement using a range specifier. This is optional. For example:
8'h43 : begin
HexSeg[2:1] = 2'b11; HexSeg[6] = 1; // 2 statements
Whenever you execute the same statements for multiple case
items, you can combine the items, separating them by commas. For example, a
and A
execute the same statements:
module ASCII27Seg (input [7:0] AsciiCode, output reg [6:0] HexSeg);
always @ (*) begin
HexSeg = 7'd0;
case (AsciiCode)
// A, a
8'h41, 8'h61 : begin
HexSeg[3] = 1;
end
// B, b
8'h42, 8'h62 : begin
HexSeg[0] = 1; HexSeg[1] = 1;
end
// C, c
8'h43, 8'h63 : begin
HexSeg[1] = 1; HexSeg[2] = 1; HexSeg[6] = 1;
end
// turn all the bits off by default
default : begin
HexSeg = 8'b11111111;
end
endcase
end
endmodule