Newbie question - sharing data across modules

R

RL

Guest
Hi,

I am working on my first project in Verilog, currently in ModelSIM. The
target will most likely be a Xilinx FPGA.

This part of my project is very simple. It simply listens for commands
sent via a serial connection, decodes the packet, and responds
appropriately. I am trying to use multiple modules, one for each type of
packet that needs to be constructed, and send using a common 'serialtx'
module.

What I am unsure about is how to get the data from one location to
another when multiple modules need to write to a common buffer.

In my simplified example below, 'cmd_one' and 'cmd_two', both construct
packets to be sent by 'serialtx'. What I see when I run this in
simulation is that the local packets 'lpkt' get populated, but the value
is not reflected in 'opkt' for 'serialtx'.

I may be going about this completely the wrong way, or just missing
something simple. Your assistance is really appreciated.

Example below...

Thanks,

RL

`timescale 1ns / 100ps

module cmd_one (clk,opkt,opktready);
output [0:95] opkt;
inout opktready;
input clk;

reg [0:95] lpkt;
reg lpktready;

serialtx u0(.opkt(opkt),.opktready(opktready),.serialclk());
clk u1(.clk(clk));

assign opktready = lpktready;
assign opkt = lpkt;

always @(posedge clk) begin
lpkt = 95'd 1;
lpktready = 1;
end
endmodule

module cmd_two (clk,opkt,opktready);
output [0:95] opkt;
inout opktready;
input clk;

reg [0:95] lpkt;
reg lpktready;

serialtx u0(.opkt(opkt),.opktready(opktready),.serialclk());
clk u1(.clk(clk));

assign opktready = lpktready;
assign opkt = lpkt;

always @(negedge clk) begin
lpkt = 95'd 2;
lpktready = 1;
end
endmodule

module serialtx (opkt,opktready,serialclk);
input[0:95] opkt;
inout opktready;
input serialclk;

reg lpktready;

serialclk u0(.clk(),.serialclk(serialclk));

initial begin
lpktready = 0;
end

assign opktready = lpktready;

always @(posedge opktready) begin
// Send the packet...
lpktready = 0;
end

endmodule

module serialclk (clk,serialclk);
input clk;
output serialclk;

reg serialclk;

reg[0:15] cnt;
reg[0:15] clocks;

clk u0(.clk(clk));

initial begin
serialclk = 1'b 0;
cnt = 16'd 0;
clocks = 16'd 5;
end

always @(posedge clk) begin
if(cnt == clocks) begin
cnt=1;
serialclk = ~serialclk;
end
else begin
cnt = cnt + 1;
end
end

endmodule

module clk(clk);

output clk;
reg clk;

always
#1 clk = ~clk;

initial begin
clk = 1'b 0;
end

endmodule
 
On Oct 16, 11:54 am, RL <n...@void.test> wrote:
Hi,

I am working on my first project in Verilog, currently in ModelSIM. The
target will most likely be a Xilinx FPGA.

This part of my project is very simple. It simply listens for commands
sent via a serial connection, decodes the packet, and responds
appropriately. I am trying to use multiple modules, one for each type of
packet that needs to be constructed, and send using a common 'serialtx'
module.

What I am unsure about is how to get the data from one location to
another when multiple modules need to write to a common buffer.

In my simplified example below, 'cmd_one' and 'cmd_two', both construct
packets to be sent by 'serialtx'. What I see when I run this in
simulation is that the local packets 'lpkt' get populated, but the value
is not reflected in 'opkt' for 'serialtx'.

I may be going about this completely the wrong way, or just missing
something simple. Your assistance is really appreciated.

Example below...

Thanks,

RL

`timescale 1ns / 100ps

module cmd_one (clk,opkt,opktready);
    output [0:95] opkt;
    inout opktready;
    input clk;

    reg [0:95] lpkt;
    reg lpktready;

    serialtx u0(.opkt(opkt),.opktready(opktready),.serialclk());
    clk u1(.clk(clk));

    assign opktready = lpktready;
    assign opkt = lpkt;

    always @(posedge clk) begin
       lpkt = 95'd 1;
       lpktready = 1;
    end
endmodule

module cmd_two (clk,opkt,opktready);
    output [0:95] opkt;
    inout opktready;
    input clk;

    reg [0:95] lpkt;
    reg lpktready;

    serialtx u0(.opkt(opkt),.opktready(opktready),.serialclk());
    clk u1(.clk(clk));

    assign opktready = lpktready;
    assign opkt = lpkt;

    always @(negedge clk) begin
       lpkt = 95'd 2;
       lpktready = 1;
    end
endmodule

module serialtx (opkt,opktready,serialclk);
     input[0:95] opkt;
     inout opktready;
     input serialclk;

     reg lpktready;

     serialclk u0(.clk(),.serialclk(serialclk));

     initial begin
        lpktready = 0;
     end

     assign opktready = lpktready;

     always @(posedge opktready) begin
        // Send the packet...
        lpktready = 0;
     end

endmodule

module serialclk (clk,serialclk);
    input clk;
    output serialclk;

    reg serialclk;

    reg[0:15] cnt;
    reg[0:15] clocks;

    clk u0(.clk(clk));

    initial begin
       serialclk = 1'b 0;
       cnt = 16'd 0;
       clocks = 16'd 5;
    end

    always @(posedge clk) begin
       if(cnt == clocks) begin
         cnt=1;
         serialclk = ~serialclk;
        end
        else begin
          cnt = cnt + 1;
        end
    end

endmodule

module clk(clk);

output clk;
reg clk;

always
    #1 clk = ~clk;

initial begin
    clk = 1'b 0;
end

endmodule
Is following line in module serialtx correct??
serialclk u0(.clk(),.serialclk(serialclk));
Are you sure how to use inout port?
 
sandeep wrote:
Is following line in module serialtx correct??
serialclk u0(.clk(),.serialclk(serialclk));
Are you sure how to use inout port?
I haven't had to use inout for anything else, so I'm probably not using
it right, and why I'm asking here (including examples of bad code).
Examples I found on the Altera site aren't very newbie friendly.

- RL
 
On Oct 15, 11:54 pm, RL <n...@void.test> wrote:

I may be going about this completely the wrong way, or just missing
something simple.
You have some pretty fundamental misunderstandings about Verilog
modules
and module instances.

Your code does not have one shared serialtx. It has two separate
copies
of serialtx, one instantiated in cmd_one and the other in cmd_two.
You
don't have a shared buffer, you have one buffer in cmd_one.u0 and the
other in cmd_two.u0. The two are not even connected electrically,
since
you don't have a top-level module that instantiates cmd_one and
cmd_two
and wires them together. So you have two separate modules with two
separate serial transmitters that are not connected to each other in
any
way (except perhaps by their power supplies).

Even if you connected them together, you would have two separate
serial
transmitters trying to drive the same bus to different values
simultaneously.
That doesn't work. In simulation you will get x values. In hardware
you
might see smoke, if your synthesis tool didn't give you an error.

If you want a buffer shared between two modules, you will need to
instantiate
it onces separately, and design the hardware to coordinate their
writing to
it. But it is unclear why you are using two separate modules for the
different
packet types in the first place. A module is not a software
subroutine to be
called when you need it. It is a piece of hardware that is present
all the time.
If you don't want it active all the time, you will have to design the
logic to
control when it is active.
 
sharp@cadence.com wrote:
On Oct 15, 11:54 pm, RL <n...@void.test> wrote:

I may be going about this completely the wrong way, or just missing
something simple.

You have some pretty fundamental misunderstandings about Verilog
modules
and module instances.

Your code does not have one shared serialtx. It has two separate
copies
of serialtx, one instantiated in cmd_one and the other in cmd_two.
Thanks for taking the time to explain what is happening, and giving me
something to look in to. Not coming from an electrical engineering
background, much of the text on learning Verilog uses examples of which
I have no knowledge. What I'm trying to do is in theory quite simple
just by manipulating 0s and 1s, but obviously to do that correctly, I
need to know how the language works first.

Thanks,

RL
 
On Oct 15, 9:54 pm, RL <n...@void.test> wrote:
module cmd_one (clk,opkt,opktready);
    output [0:95] opkt;
    inout opktready;
    input clk;

    reg [0:95] lpkt;
    reg lpktready;

    serialtx u0(.opkt(opkt),.opktready(opktready),.serialclk());
    clk u1(.clk(clk));

    assign opktready = lpktready;
    assign opkt = lpkt;

    always @(posedge clk) begin
       lpkt = 95'd 1;
       lpktready = 1;
    end
endmodule

module serialtx (opkt,opktready,serialclk);
     input[0:95] opkt;
     inout opktready;
     input serialclk;

     reg lpktready;

     serialclk u0(.clk(),.serialclk(serialclk));

     initial begin
        lpktready = 0;
     end

     assign opktready = lpktready;

     always @(posedge opktready) begin
        // Send the packet...
        lpktready = 0;
     end

endmodule
I am not sure if the inout signal can be used the way you used in your
program. I read a document related to using IO signals in www.knowledgetreasure.com.
Here is the link for the doc http://www.knowledgetreasure.com/selvam/weblog/46.html

Hope this document may be useful for you to use IO port.
 
On Oct 17, 12:16 pm, RL <n...@void.test> wrote:
sh...@cadence.com wrote:
On Oct 15, 11:54 pm, RL <n...@void.test> wrote:

I may be going about this completely the wrong way, or just missing
something simple.

You have some pretty fundamental misunderstandings about Verilog
modules
and module instances.

Your code does not have one shared serialtx.  It has two separate
copies
of serialtx, one instantiated in cmd_one and the other in cmd_two.

Thanks for taking the time to explain what is happening, and giving me
something to look in to. Not coming from an electrical engineering
background, much of the text on learning Verilog uses examples of which
I have no knowledge. What I'm trying to do is in theory quite simple
just by manipulating 0s and 1s, but obviously to do that correctly, I
need to know how the language works first.

Thanks,

RL
I am not sure if you are using IO signal/port in a proper way. There
is a document available in www.knowledgetreasure.com which discusses
about IO port usage.

The link is http://www.knowledgetreasure.com/selvam/weblog/46.html
 

Welcome to EDABoard.com

Sponsor

Back
Top