Assign ASCII character to wire in Verilog
-
14-11-2019 - |
Question
I understand that you can declare a string in a Verilog test bench as follows:
reg [8*14:1] string_value;
initial
string_value = "Hello, World!";
I can then do things with this string, like use $display
in a test bench to display it.
I haven't been successful in doing the same in a module when I flash it to my FPGA:
reg [8*14:1] string_value;
always @(reset)
begin
string_value = "Hello, World!";
// Do stuff with string value
Even assigning a single value does not work:
reg [8:1] char_value;
always @(reset)
begin
char_value = "A";
if (char_value == 8'h41)
// Do stuff!
I want to shift the individual characters on an 8-bit bus to an LCD screen for display.
How can I work with strings in Verilog?
Solution
SystemVerilog should support string assignment as mentioned in spec:
For example, to store the 12-character string "Hello world\n" requires a variable 8x12, or 96 bits wide.
bit [8*12:1] stringvar = "Hello world\n";
Not sure if the old verilog supports it or not.
OTHER TIPS
You can assign a string to a register type. Anyone who says otherwise is wrong. You might want to make your registers 0' based for it to work properly. I've done this in real FPGAs and it works.
Define an array of bytes, then assign ASCII to each array element:
wire [7:0] foo [0:11];
assign foo[0] = "H";
assign foo[1] = "e";
assign foo[2] = "l";
assign foo[3] = "l";
assign foo[4] = "o";
assign foo[5] = " ";
assign foo[6] = "W";
assign foo[7] = "o";
assign foo[8] = "r";
assign foo[9] = "l";
assign foo[10] = "d";
assign foo[11] = "!";
You now have a constant with ASCII values in it that you can index into.
reg [7:0] data_out;
reg data_out_valid;
reg [3:0] some_index;
:
// pushing data onto a bus
data_out <= foo[some_index];
data_out_valid <= 1'd1;
some_index <= some_index + 4'd1;
With appropriate index checking and control that should work.
This works for me:
reg [8*16:1] line1data = "Hello, World! ";
Both in simulation and on a Spartan-3E FPGA
Strings seem to work in a module for me:
module tb;
reg [8:1] char_value;
initial begin
char_value = "A";
$display("%h", char_value);
if (char_value == 8'h41) begin
$display("match");
end else begin
$display("no match");
end
end
endmodule
/*
Prints out:
41
match
*/
What doesn't work for you?
The string
data type was introduced into the SystemVerilog standard in 2005 (refer to IEEE 1800-2005 or 1800-2009).
output [8*14:1]string_value1;
reg [8*14:1]string_value1;
always @ (posedge BIWEn)
if (BIWEn==1'b1 ||BIREn==1'b1)
begin:START_STATE_WRITE
psW=idleW; //psW is Present State Write
string_value1= "IDLE";
end
![test bench] (c:\pictures)