I am a beginner in the development of FPGA. I am interested in how to correctly combine several modules in the top-level file.
For example: in the top-level file, I want to connect the output of module 1 to the input of module 2, and so on.
Please see the picture below:
I am trying to create a counter from 0 to 9 that outputs a number to a seven segment display. Please let me know if I'm doing something wrong or what could be improved.
Here is my code:
File "seven_segment" (top level):
module seven_segment (
input CLK,
output [6:0] out
);
counter counter ( .CLK(CLK));
bcd bcd ( .out(out));
endmodule
File "bcd":
module bcd (
input [3:0] in,
output reg [6:0] out
);
always # (in) begin
case (in)
4'b0000 : out = 7'b1111110;
4'b0001 : out = 7'b0110000;
4'b0010 : out = 7'b1101101;
4'b0011 : out = 7'b1111001;
4'b0100 : out = 7'b0110011;
4'b0101 : out = 7'b1111011;
4'b0110 : out = 7'b1011111;
4'b0111 : out = 7'b1010000;
4'b1000 : out = 7'b1111111;
4'b1001 : out = 7'b1111011;
default : out = 7'b0000000;
endcase
end
endmodule
File "counter":
module counter (
input CLK,
output reg [3:0] count
);
always # (posedge CLK)
begin
if (count == 4'b1010)
count <= 0;
else
count <= count + 1;
end
endmodule
In the top module, you need to add a wire for the signal that you want to connect to both module instances. Then you need to add port connections for that signal to each instance. Here are the specific changes:
module seven_segment (
input CLK,
output [6:0] out
);
wire [3:0] count;
counter counter ( .CLK(CLK) , .count(count) );
bcd bcd ( .in(count), .out(out) );
endmodule
You can give the wire any name that you want. I chose to name it the same as the counter output (count), but as you can see, it is not a requirement to match the port name (.in(count)).
There are more examples in: How to instantiate a module
Related
I'm trying to build a RegisterFile that utilizes these 3 components. I just don't know how to put them all together. I have the start of the register file module but just have no clue how to top end it. Is there any way anyone could explain, I'm just so lost. I also think there may be an issue with my Register module. I really am a novice with verilog, so I'm very confused on most things.
module Decoder3To8(input enable, input[2:0] in, output[7:0] out);
assign d[0]=(~a[2])&(~a[1])&(~a[0]);
assign d[1]=(~a[2])&(~a[1])&(a[0]);
assign d[2]=(~a[2])&(a[1])&(~a[0]);
assign d[3]=(~a[2])&(a[1])&(a[0]);
assign d[4]=(a[2])&(~a[1])&(~a[0]);
assign d[5]=(a[2])&(~a[1])&(a[0]);
assign d[6]=(a[2])&(a[1])&(~a[0]);
assign d[7]=(a[2])&(a[1])&(a[0]);
endmodule
module Register4Bit(input clock, input clear, input load, input[3:0] in, output reg[3:0] out);
always#(negedge clock or posedge clear)
begin
if(clear)
out<=4′b0000;
else
out[3]<=out[2];
out[2]<=out[1];
out[1]<=out[0];
out[0]<=in[0];
end
endmodule
module Mux4Bit8To1(input[3:0] in0, input[3:0] in1, input[3:0] in2, input[3:0] in3, input[3:0] in4, input[3:0] in5, input[3:0] in6, input[3:0] in7, input[2:0] selector, output reg[3:0] out);
assign S0 = selector[0];
assign S1 = selector[1];
assign S2 = selector[2];
assign out = S2 ? (S[1] ? (S[0] ? in7 : in6) : (S[0] ? in5 : in4)) : (S[1] ? (S[0] ? in3 : in2) : (S[0] ? in1 : in0))
endmodule
module RegisterFile(input clock, input clear, input[3:0] write_data, input[2:0] write_index, input write, input[2:0] read_index, output[3:0] read_data);
reg[7:0] content[3:0]; //this line is initializing the register
integer i;
always #(posedge clear, negedge clock). //this is the senstivity list of the always block
if (clear) begin
for (i = 0; i < 4; i = i + 1)
content[i] = 0; //this line is clearing out all the memory locations
end else if (write)
content[write_index] = write_data. //this line is performing a write operation
else
endmodule
Verilog describes hardware. As a result the final product is set of connected elements. In your case you need to instantiate and connect your modules.
In verilog it looks like the following:
module in(input clk, input data, output reg value);
always #(posedge clk)
value <= data;
endmodule
The above module has clock, input data and output value;
module out(input clk, input value, output reg data);
always #(posedge clk)
data <= ~value;
endmodule
And finally you need to assemble them:
module device(input clk, input datain, output dataout);
wire val;
in in(clk, datain, val);
out out(clk, val, dataout);
endmodule
in the device, two modules are instantiated. The val plays a role of a connecting wire which connects output of module in with input of module out.
So, you can extend this scheme to your model.
module top_module(
input clk,
input reset,
input ena,
output pm,
output reg [7:0] hh,
output reg [7:0] mm,
output reg [7:0] ss);
wire [4:0] enable;
assign enable[0] = ss[3:0] == 4'd9;
assign enable[1] = ss[7:0] == 8'h59;
assign enable[2] = {mm[3:0],ss[7:0]} == 12'h959;
assign enable[3] = {mm[7:0],ss[7:0]} == 16'h5959;
assign enable[4] = {hh[3:0],mm[7:0],ss[7:0]} == 20'h95959;
bcd in1(clk, reset, ena, ss[3:0]);
bcd in2(clk, reset, enable[0], ss[7:4]);
bcd in3(clk, reset, enable[1], mm[3:0]);
bcd in4(clk, reset, enable[2], mm[7:4]);
bcd in5(clk, reset, enable[3], hh[3:0]);
bcd in6(clk, reset, enable[4], hh[7:4]);
always # (*) begin
if(reset) begin
pm <= 0;
hh <= 8'h12;
ss <= 8'h00;
mm <= 8'h00;
end
else if(ena) begin
// ss <= ss == 8'h59;
// mm <= (mm == 8'h59 & ss == 8'h59) ?? 8'h00 : mm;
// hh <= (hh == 8'h12 & mm == 8'h59 & ss == 8'h59) ?? 8'h01 : hh;
end
end
endmodule
module bcd(input clk, reset, ena,
output [3:0] q);
always # (posedge clk) begin
q <= reset ? 0 : (ena ? (q == 4'd9 ? 0 : q + 1) : q);
end
endmodule
I'm trying to understand why when I try to run this code, I'm getting this error:
Error (12014): Net "hh[7]", which fans out to "hh[7]", cannot be assigned more than one value File: /home/h/work/hdlbits.2188345/top_module.v Line: 28
Error (12015): Net is fed by "GND"
Error (12015): Net is fed by "bcd:in6|q[3]" File: /home/h/work/hdlbits.2188345/top_module.v Line: 49
I'm getting that for all of the other elements in ss, mm and hh, one by one. I'm not seeing how I'm trying to give it a value in more than one place. Very confusing.
The error message tells you that you are assigning to hh[7] in 2 places. The 1st line is:
bcd in6(clk, reset, enable[4], hh[7:4]);
and the 2nd line is:
hh <= 8'h12;
In the 1st line, hh is driven by the q output signal of the bcd module.
One way to fix the problem is to delete the always block from top_module. The only thing that code does is set the signals during reset, which is already done in the bcd module.
Here is modified code that compiles without errors for me:
module top_module(
input clk,
input reset,
input ena,
output pm,
output [7:0] hh,
output [7:0] mm,
output [7:0] ss);
wire [4:0] enable;
assign enable[0] = ss[3:0] == 4'd9;
assign enable[1] = ss[7:0] == 8'h59;
assign enable[2] = {mm[3:0],ss[7:0]} == 12'h959;
assign enable[3] = {mm[7:0],ss[7:0]} == 16'h5959;
assign enable[4] = {hh[3:0],mm[7:0],ss[7:0]} == 20'h95959;
bcd in1(clk, reset, ena, ss[3:0]);
bcd in2(clk, reset, enable[0], ss[7:4]);
bcd in3(clk, reset, enable[1], mm[3:0]);
bcd in4(clk, reset, enable[2], mm[7:4]);
bcd in5(clk, reset, enable[3], hh[3:0]);
bcd in6(clk, reset, enable[4], hh[7:4]);
endmodule
module bcd(input clk, reset, ena,
output reg [3:0] q);
always # (posedge clk) begin
q <= reset ? 0 : (ena ? (q == 4'd9 ? 0 : q + 1) : q);
end
endmodule
Note also that I removed reg from the hh, mm and ss ports, and I added reg to the q port.
I need to estimate the maximum number of 16-bit counters that a FPGA board can fit. I created a 16-bit counter module with enable (en) and terminal count (TC), and instantiated this inside a generate block in a top level module. However, I need to generate these counters in a chain where the TC output of one acts as the enable for the next counter in the chain. I'm unable to figure out the logic for this. Can anyone help me ?
16-bit counter code:
module counter_16 (clk, Q, TC, en);
input clk, en;
output [15:0] Q;
output TC;
wire clk, en;
reg [15:0] Q = 0; //initial value for the output count
reg TC;
always #(posedge clk)
begin
if(en == 1)
begin
Q <= Q+1;
end
TC = &Q; //TC is 1 when all bits of Q is high
end
endmodule
Counter generation module:
module counter_generator
#(
parameter n = 10
)
(output [15:0] cnt_out,
output TC,
input clk, en);
wire [n-1:0] temp_en;
temp_en[0] <= 0;
wire [15:0] temp_out;
generate
genvar i;
for(i=1;i<=n;i=i+1)
begin : counter_identifier
counter_16 counter_16_gen (
.clk(clk),
.Q(temp_out),
.TC(temp_en[i-1]),
.en(en));
end
endgenerate
endmodule
The first thing to do is make the loop start from 0, not 1, so that the signal indexes align.
Create a signal tc_out that is n bits wide and connect that directly to the TC port in the generate block, using the index [i]. TC of instance 0 is connected to tc_out[0], etc. This is straightforward, and it helps us with the en connections.
Create a signal temp_en that is also n bits wide and connect that directly to the en port in the generate block. The key is to assign this signal to the tc_out signal as seen below.
en of instance 0 is driven by the en input of counter_generator
en of instance 1 is driven by the TC output of instance 0
en of instance 2 is driven by the TC output of instance 1
etc.
Lastly, create an array of n 16-bit wires, temp_out, and connect that directly to the Q port in the generate block.
module counter_generator
#(
parameter n = 10
)
(
output [15:0] cnt_out,
output TC,
input clk, en
);
wire [n-1:0] tc_out;
wire [n-1:0] temp_en = {tc_out[n-2:0], en};
wire [15:0] temp_out [n];
assign TC = temp_out[n-1];
generate
genvar i;
for (i=0; i<n; i=i+1) begin : counter_identifier
counter_16 counter_16_gen (
.clk (clk),
.Q (temp_out[i]),
.TC (tc_out [i]),
.en (temp_en [i])
);
end
endgenerate
endmodule
This code should dispaly S for 1 sec then turn off for 1 sec and then dispaly G for 1 sec and then turn of for 1 sec and then display S for 1 sec and so on.
The problem is I am getting S then off then G then off then G then off and so on. I believe the error in the hex7segm module but I could not find a solution. Any help would be appreciated
Here is the code:
module asqw (output wire [6:0]a2g,output wire [3:0]AN,input wire fastclk);
wire slowclk;
slow_clock xx(fastclk,slowclk);
hex7segm zz(slowclk,a2g,AN);
endmodule
moduleslow_clock (input wire fastclk,output wire slowclk);
reg[27:0]period_count=0;
always#(posedge fastclk)
begin
period_count<=period_count+1;
end
assign slowclk=period_count[27];
endmodule
module hex7segm (input wire slowclk,
output reg [6:0]a2g,
output reg [3:0]AN
);
reg[1:0]x;
reg[1:0]y=0;
always#(*)
begin
if(slowclk)
begin
x=y;
AN= 4'b1110;
y=y+1;
if(y==2) y=0;
else
x=2;
AN= 4'b1110;
end
case(x)
0: a2g=7'b0100100;
1: a2g=7'b0100000;
2: a2g=7'b1111111;
default: a2g=7'b0100100;
endcase
end
endmodule
Hi probably a little bit late to answer but here it is: The main problem is that you are mixing combinational and sequential logic. You need to separate these two. Moreover, I couldn't see why your new clock has a duty cycle of 50%.
Top module:
module asqw (
output [6:0]a2g,
input wire fastclk);
wire slowclk;
slow_clock xx(fastclk,slowclk);
hex7segm zz(slowclk,a2g);
endmodule
Seven Segment Driver:
module hex7segm (
input wire slowclk,
output reg [6:0]a2g
);
localparam S = 7'b0100100;
localparam G = 7'b0100000;
localparam OFF = 7'b1111111;
reg [2:0] state = 0;
always # (posedge slowclk)
begin
state <= (state == 5) ? 0 : state + 3'b1;
end
always # (*)
begin
case(state)
0: a2g <= S;
2: a2g <= G;
4: a2g <= S;
default: a2g <= OFF;
endcase
end
endmodule
Slow clock:
module slow_clock (
input wire fastclk,
output reg slowclk = 0
);
reg[27:0]period_count = 0;
always#(posedge fastclk)
begin
period_count <= (period_count == 25000000) ? 0 : period_count+ 28'b1;
slowclk <= (period_count == 25000000) ? ~slowclk : slowclk;
end
endmodule
I know VHDL, and just learning verilog. I'm trying to do a simple assignment with bit shift, and I get undefined 'X' in the result. I don't understand why. This is in simulation with Xilinx ISim software.
This assignment:
assign dout = $signed(data_out >>> shift_bits);
Results in 'X' wherever a '1' should be. For example, if data_out = '00001100', and shift_bits = 1, dout will = '00000XX0'.
Below is the module definition and the assignment operation:
module SensorINV(
input clk,
input [23:0] din,
input idv,
input [4:0] shift_bits,
output [23:0] dout,
output reg odv
);
reg [47:0] data_out = 0; // initialize the output
assign dout = $signed(data_out >>> shift_bits);
// assign dout = data_out[44:21]; // this didn't work either
reg [1:0] state = 0;
always #(posedge clk) begin
case (state)
0 : begin // waiting for new data
...
end
1 : begin
...
data_out <= data_out + temp1_w;
state <= 2;
end
2 : begin
...
state <= 0;
end
default : state <= 0;
endcase
end
The problem turned out to be conflicting drivers of dout, only one of which was shown in the code above. In the next module up, where this one was instantiated (not shown), I had a line like this:
wire [23:0] dout = 0;
This created a continuous assignment, not an initialization value. This conflict didn't show up in simulation until I tried to make dout non-zero. If it were a register reg, it would be an initialization value, but in this case it was a wire. Got rid of the continuous assign = 0, and problem solved.