将ASCII转换为7段显示的模块,使用FPGA。

huangapple go评论57阅读模式
英文:

Module that converts ASCII to 7-segment display using FPGA

问题

关于为每个字母都使用 begin 语句的含义,以及是否必要的问题,以及 HexSeg[x] = y 对带有 begin 语句的字母的意义,以下是相关的翻译:

  • 在这段代码中,beginend 语句用于定义一段代码块,其中包含了特定字母的处理逻辑。这是一种结构化的编程方式,可以使代码更清晰易读。

  • 对于 'A' 和 'a',begin 语句之所以没有必要,是因为它们的处理逻辑非常简单,只需要设置 HexSeg[3] 为 1。在这种情况下,使用 beginend 语句会显得冗余,因此可以直接在 case 分支中执行相应的赋值操作。

  • HexSeg[x] = y 表示将 HexSeg 数组的第 x 位设置为 y。在这个代码中,HexSeg 是一个 7 位的七段数码管显示器,每一位对应于数码管的一个段,通过设置不同的位可以显示不同的数字或字符。

  • 对于 begin 语句中的代码块,它们用于设置 HexSeg 数组的不同位。例如,HexSeg[0]HexSeg[1] 设置为 1 表示字符 'B' 或 'b' 需要点亮数码管的第 0 和第 1 个段,以显示正确的字母形状。

  • 这种方式确实需要一些重复的工作,因为每个字母都需要手动设置相应的段位。如果你认为这种方式不够高效,可以考虑使用更智能的方法,比如查找表或者使用逻辑运算来简化代码。

  • 对于 ASCII 数字,也可以采用类似的方法进行处理,根据不同的数字设置相应的 HexSeg 位。原则上,可以使用相同的方法,但要根据 ASCII 数字的范围进行适当的设置。

  • 最后,这段代码似乎是用于将 ASCII 字符转换为七段数码管显示的 Verilog 模块。它还需要完善的代码来处理其他字母和字符,你需要继续完成 case 分支中的剩余部分,以确保所有字符都有正确的显示方式。

希望这些解释能帮助你更好地理解代码和 begin 语句的作用。如果有其他问题,请随时提出。

英文:

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.

答案1

得分: 0

"begin/end"关键字是Verilog中的必需部分,每当你在代码块中有多个语句时都需要它们。如果代码块中只有一个语句,它们是可选的。请参考IEEE Std 1800-2017,第12.5节的"Case statement"。

"case"语句中的每个"case"项都可以执行一个代码块。例如,"8'h41"是第一个"case"项。因为该项只有一个语句("HexSeg[3] = 1;"),所以不需要使用"begin/end"关键字。然而,对于"8'h42"项,你有两个语句("HexSeg[0] = 1; HexSeg[1] = 1;"),因此需要使用"begin/end"关键字。

对于带有"begin"的"HexSeg[x] = y"是什么意思?
对于不带"begin"的是一样的,你只是设置了"HexSeg"的位。

由于某些项需要至少2个语句,因此对于这些项,你必须使用"begin/end",如上所述。然而,从一致的代码风格角度来看,你可能更喜欢所有项看起来都一样。下面是这种方式的示例:

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
            // 默认情况下关闭所有位
            default : begin
                HexSeg = 8'b11111111;
            end
        endcase
    end
endmodule

这需要输入更多内容,但可能更容易阅读和理解。

是否有更简单的方法来做这个?

这是一个直接的方法。在这种设计中,使用"case"语句是一种常见的做法。

对于编码ASCII数字是不是使用相同的方法?

是的,如果你需要在8位ASCII码和7位"HexSeg"之间进行类似的映射。


每当你设置连续的位时,你可以使用范围限定符将它们合并成一个语句。这是可选的。例如:

8'h43 : begin
    HexSeg[2:1] = 2'b11; HexSeg[6] = 1; // 2个语句
end

每当你为多个"case"项执行相同的语句时,你可以将这些项合并,用逗号分隔它们。例如,"a"和"A"执行相同的语句:

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
            // 默认情况下关闭所有位
            default : begin
                HexSeg = 8'b11111111;
            end
        endcase
    end
endmodule
英文:

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

huangapple
  • 本文由 发表于 2023年5月29日 14:08:17
  • 转载请务必保留本文链接:https://go.coder-hub.com/76355011.html
匿名

发表评论

匿名网友

:?: :razz: :sad: :evil: :!: :smile: :oops: :grin: :eek: :shock: :???: :cool: :lol: :mad: :twisted: :roll: :wink: :idea: :arrow: :neutral: :cry: :mrgreen:

确定