2
\$\begingroup\$

I have a module to display a base 10 number on my 7-Segment display.

module displayN(input [13:0] n, input clk, input [3:0] an, input [6:0] seg);

    wire [3:0] d1 = n % 10;
    wire [3:0] d2 = (n / 10) % 10;
    wire [3:0] d3 = (n / 100) % 10;
    wire [3:0] d4 = (n / 1000) % 10;

    display4(d4, d3, d2, d1, clk, an, seg);

endmodule

It takes in a 14 bit number and computes the digits and hands it off to another module which actually displays it.

Right now I am working on a program which uses a USB-UART connection and displays the value of the last byte sent on my 7-Seg. Here is my top level module.

module uart_top(input clk,
                input rx,
                output tx,
                output [3:0] an,
                output [6:0] seg);

    wire [63:0] count;
    wire [7:0] out;

    uart_receive r(clk, rx, count, out);

    reg [7:0] oreg;
    always @(out) oreg = out;
    displayN d4(oreg, clk, an, seg);

    ila_0 i(clk, rx, out);
endmodule

This code is currently working. When the output of my uart receiver changes I copy the output to a register, and then send it to my display module. This seems to work correctly when I try it on my card. I am assuming that even though the module is expecting 14 bit it just fills 0 for the upper 14. However, when I try to pass "out" directly to the module like displayN d4(oreg, clk, an, seg); I get some error about a black box. Why can I do this for a register but not a wire?

Here is the exact error message I get during synthesis.

 [Project 1-486] Could not resolve non-primitive black box cell 'displayN' instantiated as 'd4' [/home/chase/vivado-workspace/UART/UART.srcs/sources_1/new/uart_top.v:37]

Here is the schematic. enter image description here

Also here is the uart_receive.

module uart_receive#(parameter BAUD_RATE = 9600,
                     parameter CLOCK_SPEED_MHZ = 100)
                    (input clk,
                     input rx,
                     output reg [63:0] read_count = 0,
                     output reg [7:0] data);

    localparam SAMPLE_BAUD_RATE = BAUD_RATE * 8;

    reg reading = 0;
    reg [8:0] bit_stream = 0;
    reg [3:0] bit_index = 0;

    wire sample_tick;
    baud_gen#(SAMPLE_BAUD_RATE, CLOCK_SPEED_MHZ) s(clk,, sample_tick);

    wire baud_tick;
    baud_gen#(BAUD_RATE, CLOCK_SPEED_MHZ) b(clk, !reading, baud_tick);


    always @(posedge clk) begin
        if(sample_tick && !reading && !rx) begin
            reading <= 1;
            bit_index <= 0;
        end
        else if(baud_tick) begin
            bit_index <= bit_index + 1;
            bit_stream[bit_index] <= rx;

            if(bit_index == 8) begin
                reading <= 0;
                read_count <= read_count + 1;
                data <= bit_stream[7:0];
            end
        end
    end
endmodule

It seems to work if I remove the ila_0 i(clk, rx, out); which is the Integrated Logic Analyser I was using for debugging. I always had out hooked directly up to it even when I was using the resister in displayN. I wonder why out could not be connected to both of them at a time.

\$\endgroup\$
  • \$\begingroup\$ Can you paste the exact error? Is it synthesis or compilation/implementation? \$\endgroup\$ – Krunal Desai Dec 25 '15 at 23:16
2
\$\begingroup\$

Have you looked at what is being synthesized? You are performing some math (modulo) operations on the output. Inside your UART RX module, the received byte is probably in a buffer of some type. If you don't have a storage / stated up element of some type, you're asking your FPGA code to combinatorially operate on your receive data and complete all operations before the next byte comes in. Using 'out' there passes 8-bits of data raw to your display module and probably infers quite a few latches.

By registering your data (I note you used the word 'copy' -- I take it you are a computer programmer branching into FPGA?), you are increasing latency slightly but you have now stored data in a stateful manner and provided a clocked, synchronous system during which things can be done.

\$\endgroup\$
  • \$\begingroup\$ I forgot to mention that when I passed count to the display it worked. I thought it might have something to do with it being a larger size. And yes I am a computer programmer. \$\endgroup\$ – chasep255 Dec 25 '15 at 23:16
  • \$\begingroup\$ What's count? Don't see it used anywhere in there. \$\endgroup\$ – Krunal Desai Dec 25 '15 at 23:17
  • \$\begingroup\$ Also why does it need to infer latches. Wouldn't it just pass output directly to the input of the displayN \$\endgroup\$ – chasep255 Dec 25 '15 at 23:19
  • \$\begingroup\$ count is another output which displays the number of bytes read so far so you can detect when the output changes. I had it hooked up to the display at one point to see the count of the bytes. \$\endgroup\$ – chasep255 Dec 25 '15 at 23:20
  • \$\begingroup\$ (About latches) Based on what else is in this design, it may not be possible for you to get all your signals from A to B without adding additional logic in the way to try and meet timing, fanout requirements, etc. Posting the netlist / schematic output would help also in explaining, I think. \$\endgroup\$ – Krunal Desai Dec 25 '15 at 23:21

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service, privacy policy and cookie policy

Not the answer you're looking for? Browse other questions tagged or ask your own question.