-
Notifications
You must be signed in to change notification settings - Fork 36
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
"Hello World!" becomes "Heeeeeeeeee…." #8
Comments
Here is another example. While the module is named I'm not sure if there is a bug with my code or in your library. Please advice. /*
USB Serial
Wrapping usb/usb_uart_ice40.v to create a "loopback" that toggles the case.
*/
`default_nettype none
module usbserial_toggle (
input pin_clk,
inout pin_usb_p,
inout pin_usb_n,
output pin_pu,
output pin_led,
output [3:0] debug
);
wire clk_48mhz;
wire clk_locked;
// Use an icepll generated pll
pll pll48( .clock_in(pin_clk), .clock_out(clk_48mhz), .locked( clk_locked ) );
// Generate reset signal
reg [5:0] reset_cnt = 0;
wire reset = ~reset_cnt[5];
always @(posedge clk_48mhz)
if ( clk_locked )
reset_cnt <= reset_cnt + reset;
// uart pipeline in
wire [7:0] uart_in_data;
wire uart_in_valid;
wire uart_in_ready;
// uart pipeline out
wire [7:0] uart_out_data;
wire uart_out_valid;
wire uart_out_ready;
toggle_case foo(
.clk(clk_48mhz),
.reset(reset),
.in_data(uart_out_data),
.in_valid(uart_out_valid),
.in_ready(uart_out_ready),
.out_data(uart_in_data),
.out_valid(uart_in_valid),
.out_ready(uart_in_ready)
);
// assign debug = { uart_in_valid, uart_in_ready, reset, clk_48mhz };
wire usb_p_tx;
wire usb_n_tx;
wire usb_p_rx;
wire usb_n_rx;
wire usb_tx_en;
// LED
reg [22:0] ledCounter;
wire led_nonzero = |ledCounter;
always @(posedge clk_48mhz) begin
if (led_nonzero || (uart_in_valid && !uart_in_ready))
ledCounter <= ledCounter + 1;
end
assign pin_led = led_nonzero;
// usb uart - this instanciates the entire USB device.
usb_uart uart (
.clk_48mhz (clk_48mhz),
.reset (reset),
// pins
.pin_usb_p( pin_usb_p ),
.pin_usb_n( pin_usb_n ),
// uart pipeline in
.uart_in_data( uart_in_data ),
.uart_in_valid( uart_in_valid ),
.uart_in_ready( uart_in_ready ),
.uart_out_data( uart_out_data ),
.uart_out_valid( uart_out_valid ),
.uart_out_ready( uart_out_ready )
//.debug( debug )
);
// USB Host Detect Pull Up
assign pin_pu = 1'b1;
endmodule
module toggle_case(
input wire clk,
input wire reset,
input wire [7:0] in_data,
input wire in_valid,
output reg in_ready,
output reg [7:0] out_data,
output reg out_valid,
input wire out_ready
);
always @(posedge clk) begin
if (reset) begin
in_ready <= 0;
out_valid <= 0;
end else begin
// Input only
if (in_valid && !in_ready) begin
in_ready <= 1;
out_valid <= 1;
// TODO: toggle case here
out_data <= in_data;
end
// Output only
if (out_valid && !out_ready) begin
in_ready <= 0;
out_valid <= 0;
end
end
end
endmodule
|
I figured it out myself! Here is a working example /*
USB Serial
Wrapping usb/usb_uart_ice40.v to output "hello, world".
*/
`default_nettype none
module usbserial_hello (
input pin_clk,
inout pin_usb_p,
inout pin_usb_n,
output pin_pu,
output pin_led,
output [3:0] debug
);
wire clk_48mhz;
wire clk_locked;
// Use an icepll generated pll
pll pll48( .clock_in(pin_clk), .clock_out(clk_48mhz), .locked( clk_locked ) );
// Generate reset signal
reg [5:0] reset_cnt = 0;
wire reset = ~reset_cnt[5];
always @(posedge clk_48mhz)
if ( clk_locked )
reset_cnt <= reset_cnt + reset;
// uart pipeline in
reg [7:0] uart_in_data;
reg uart_in_valid;
wire uart_in_ready;
// uart pipeline out
wire [7:0] uart_out_data;
wire uart_out_valid;
reg uart_out_ready;
// Create the text string
localparam TEXT_LEN = 13;
reg [7:0] hello [0:TEXT_LEN-1];
reg [3:0] char_count;
initial begin
hello[0] <= "h";
hello[1] <= "e";
hello[2] <= "l";
hello[3] <= "l";
hello[4] <= "o";
hello[5] <= ",";
hello[6] <= " ";
hello[7] <= "w";
hello[8] <= "o";
hello[9] <= "r";
hello[10] <= "l";
hello[11] <= "d";
hello[12] <= "\n";
end
// send text through the serial port
localparam DELAY_WIDTH = 26;
reg [DELAY_WIDTH-1:0] delay_count;
reg pardon;
always @(posedge clk_48mhz) begin
if (reset) begin
uart_in_valid <= 0;
delay_count <= 0;
char_count <= 0;
pardon <= 0;
end else begin
if (char_count < TEXT_LEN) begin
if (pardon) begin
pardon <= 0;
uart_in_valid <= 0;
char_count <= char_count + 1;
end else if (uart_in_valid) begin
if (!uart_in_ready) begin
pardon <= 1;
end
end else begin
uart_in_valid <= 1;
uart_in_data <= hello[char_count];
end
end else begin
delay_count <= delay_count + 1;
if (&delay_count) begin
char_count <= 0;
end
end
end
end
// LED
reg [23:0] ledCounter;
wire led_nonzero = |ledCounter;
always @(posedge clk_48mhz) begin
if (led_nonzero || uart_in_valid) begin
ledCounter <= ledCounter + 1;
end
end
assign pin_led = led_nonzero;
// usb uart - this instanciates the entire USB device.
usb_uart uart (
.clk_48mhz (clk_48mhz),
.reset (reset),
// pins
.pin_usb_p( pin_usb_p ),
.pin_usb_n( pin_usb_n ),
// uart pipeline in
.uart_in_data( uart_in_data ),
.uart_in_valid( uart_in_valid ),
.uart_in_ready( uart_in_ready ),
// uart pipeline out
.uart_out_data( uart_out_data ),
.uart_out_valid( uart_out_valid ),
.uart_out_ready( uart_out_ready )
//.debug( debug )
);
// USB Host Detect Pull Up
assign pin_pu = 1'b1;
endmodule The module Is this a bug? |
In your original code:
should be:
You need to wait for valid and ready to both be high before considering the byte transferred and moving on to the next byte. |
It turns out that I just connected to the wrong serial port. You are right, and it works with |
Glad I could help. I don't have an account to post, but could you update your post here also: https://discourse.tinyfpga.com/t/usbserial-hello-world-becomes-heeeeeeeeee/1361 |
@jjj11x Sure! I have updated that post. Hopefully it can help someone in the future! |
I am trying to output "Hello World!" to the serial port by using tinyfpga_bx_usbserial. Here is my source code
usbserial_hello.v
:I was expecting to see
only to get
Curiously, the following code gives the correct output, i.e.
Hello World!
:Note the three lines marked
!!!MAGIC!!!
. They are making the difference here. However, as far as I know, we should NOT changeuart_in_valid
based onuart_in_ready
, in order to avoid some kind of deadlock.Any ideas? I'm clueless...
The text was updated successfully, but these errors were encountered: