User Tools


The CharDrawer_serial Module

This module is used to draw strings of characters to the serial output port, one character at a time. The module accepts only upper case characters (A-Z), digits (0-9) and space (“ ”). A null character (0) will not be drawn, and all other ASCII values are drawn as a solid rectangle.

There are several different ways to construct strings in SystemVerilog. For example, the following are all equivalent:

logic [39:0] char_string;
assign char_string = "HELLO";
logic [39:0] char_string;
assign char_string = 40'h48454C4C4F;
logic [39:0] char_string;
assign char_string = {"H", "E", "L", "L", "O"};
logic [39:0] char_string;
assign char_string = {8'h48, 8'h45, 8'h4C, 8'h4C, 8'h4F};
Module Name = CharDrawer_serial
Parameter Default Value Description
MAX_CHARS 16 The length of the string that the module can display.
Port Name Direction Width Description
clk Input 1 100 MHz Clock
reset Input 1 Active-high reset
enable Input 1 Raise this signal to start drawing. The drawing will continue until finished. To draw a new string you must lower and then raise this signal.
done Output 1 Active-high, indicating that the string is done drawing
tx Output 1 The serial out signal
string_in Input MAX_CHARS * 8 ASCII character string to draw, most-significant byte is drawn first.

Click the link below to download the CharDrawer_serial.sv file.

CharDrawer_serial.sv
module CharDrawer_serial # (parameter MAX_CHARS = 16)(
    input wire logic                            clk,        // Clock
    input wire logic                            reset,      // Active-high reset
    input wire logic                            enable,     // Start drawing
    output logic                                done,       // Done drawing
    output logic                                tx,         // Serial out
    input wire logic    [(MAX_CHARS * 8) - 1:0] string_in   // ASCII character string to draw
                                                            // MSB is drawn first
);
 
    logic clrCnt, incCnt, send, sent;
    logic[3:0] cnt;
    logic[7:0] din;
 
    // State Machine 
    typedef enum logic[1:0] {ST_WAIT, ST_WAIT_SENT, ST_SENT, ST_DONE, ERR='X} StateType;
    StateType cs, ns;
 
    assign din =    (cnt==0)?string_in[127:120]:
                    (cnt==1)?string_in[119:112]:
                    (cnt==2)?string_in[111:104]:
                    (cnt==3)?string_in[103:96]:
                    (cnt==4)?string_in[95:88]:
                    (cnt==5)?string_in[87:80]:
                    (cnt==6)?string_in[79:72]:
                    (cnt==7)?string_in[71:64]:
                    (cnt==8)?string_in[63:56]:
                    (cnt==9)?string_in[55:48]:
                    (cnt==10)?string_in[47:40]:
                    (cnt==11)?string_in[39:32]:
                    (cnt==12)?string_in[31:24]:
                    (cnt==13)?string_in[23:16]:
                    (cnt==14)?string_in[15:8]:
                              string_in[7:0];
 
    ////////////////////// Counter ////////////////////
    always_ff @(posedge clk)
        if (clrCnt)
                cnt <= 0;
        else if (incCnt)
            cnt <= cnt + 1;
 
    ////////////////////////////////// State Machine //////////////////////////////////
    always_ff @(posedge clk) 
        cs <= ns;
 
    always_comb begin
        ns = ERR;
        send = 0;
        clrCnt = 0;
        incCnt = 0;
        done = 0;
        if (reset)
            ns = ST_WAIT;
        else case (cs)
            ST_WAIT:  begin
                clrCnt = 1;
                if (enable)
                    ns = ST_WAIT_SENT;
                else
                    ns = ST_WAIT;
            end
            ST_WAIT_SENT:  begin
                send = 1;
                if (sent)
                    ns = ST_SENT;
                else
                    ns = ST_WAIT_SENT;
            end
            ST_SENT:  begin
                if (~sent && cnt != 15) begin
                    incCnt = 1;
                    ns = ST_WAIT_SENT;
                end
                else if (~sent && cnt == 15)
                    ns = ST_DONE;
                else
                    ns = ST_SENT;
            end
            ST_DONE:  begin
                done = 1;
                if (~enable)
                    ns = ST_WAIT;
                else
                    ns = ST_DONE;
            end
            default:
                ns = ERR;
        endcase
    end
 
    ///// The UART Tx
    tx TX(.clk(clk), .Reset(reset), .Send(send), .Din(din), .Sent(sent), .Sout(tx));
 
endmodule