I am trying to make a clock in verilog on my Altera DE2 board. As of now I can count from 00:00:00 to 23:59:59 using flipflops as a clock. Now I need to be able to set Switches to some value, say 12:56:00 then have it count up from there. I am trying to set a wire variable to be the initial switches input then use that as a starting point for my counter.
module part3(HEX0,HEX1,HEX2,HEX3,HEX4,HEX5,HEX6,HEX7,SW,KEY,LEDR,CLOCK_50);
input [17:0] LEDR, SW;
input [3:0] KEY;
input CLOCK_50;
output [0:6] HEX0,HEX1,HEX2,HEX3,HEX4,HEX5,HEX6,HEX7;
parameter clock_speed = 50000000;
parameter clock_divisor = 8;
wire [26:0] Q,Q2,Q3,Q4;
wire [3:0] one,two,three,four;
reg SecInc,MinInc,HrInc;
one = SW[3:0];
This is my code up to where it crashes. I do not understand why
wire in = SW[0];
is legal but assigning it the way I have done it not legal. I need to store the switch input in a register or a wire so I can increment that register or wire based on a condition.
Note: I have no formal intro to verilog, our prof gave us a board and a link to the altera university program labs and said have fun.
You need to use the assign keyword. Change:
one = SW[3:0];
to:
assign one = SW[3:0];
That is known as a continuous assignment in Verilog. You don't need the assign keyword if you are making a procedural assignment (inside an always block, for example).
Related
Note this question is not for when I am simulating. I have found numerous resources as to how to use readmemh which does not solve my problem. What I am trying to do is load the RAM for a processor that I designed with the program data. I believe that the FPGA is not getting any of the program data, just the HDL description of the processor.
I tried using Verilog's readmemh function, which I now realize is only useful for simulation. I have also tried using the /* synthesis ram_init_file = "file.mif" */; instruction (?). Either way, there was no difference in how the device worked. I simulated all these cases in ModelSim so I know the design works. I just am stumped as to how I can preload the data.
The answer is going to be tool specific because the initial blocks are, in general, not synthezisable. If you can do it, it is just because the tool has a specific template that is matched with your initial block. Initializing a memory is one of these special cases, where the 'initial' block is discarded from your logic but it is used to generate the initialization data passed along the bitstream.
From the Intel Quartus documentation we can see that there are slightly differences on the actual implementation of the two kinds of memories, dedicated RAM and MLABs, however the general idea is to use an initial block:
module ram_with_init(
output reg [7:0] q,
input [7:0] d,
input [4:0] write_address, read_address,
input we, clk
);
reg [7:0] mem [0:31];
integer i;
// Init the memory with these values
initial begin
for (i = 0; i < 32; i = i + 1)
mem[i] = i[7:0];
end
always # (posedge clk) begin
if (we)
mem[write_address] <= d;
q <= mem[read_address];
end
endmodule
Or, for the quartus pro, you can use readmemh, readmemb:
reg [7:0] ram[0:15];
initial
begin
$readmemb("ram.txt", ram);
end
I suggest you look at the documentation linked as the most updated reference.
I just started learning hardware programming using Verilog, and I feel lost because I can't understand what errors mean.
Here, I am calling the module reg31
module nbit_register(input clk, input [31:0]in, input reset, input L,
input load, input shift, output reg[31:0] out);
always#(*)begin
if(load==1)
reg32 add(clk, in, reset,L, out);
else
out={ in[30:0],1'b0};
end
endmodule
But, I get this error:
error: syntax error near "reg32"
This is what the module looks like
module reg32(
input clk,
input [31:0] in,
input rst,
input L,
output [31:0] out
);
Can someone point out the mistake here?
Because you want to "select" and make module reg32 "work" in a if branch.
Imaging a cell phone PCB board. The speaker unit is just out there, even if it's in silent mode. So instantiate reg32 separately, then use your own logic to deal with the nets connected to reg32.
wire [31:0] add_out;
reg32 add(clk, in, reset,L, add_out); // here the 4 inputs are connected to top inputs
// directly. but if you want, you can use 'load'
// to control them similar to the code below.
always#(*)begin
if(load==1)
out = add_out;
else
out = { in[30:0],1'b0};
end
If you're mainly working on software, you need to be familiar to thinking in a "hardware" way.
I'm trying to design a fifo that accepts a maximum of N=4 words and has a M=2 bit width of each word.
I first designed a 1 bit width word fifo and I'm trying to use it for the wider one. I'm having an issue debugging the line
single_fifo fArr[M-1:0]({M*{clk}},{M*{reset}},in,{M*{push}},{M*{pop}},out,full_string);
While getting the following error:
ncelab: *E,PCAVDM (./fifo.v,85|27): Vector length of port connection expression (32) in array of instances does not match product of number of instances (2) and port length (1).
single_fifo fArrM-1:0;
My code has nothing that's 32 bits long so I'm quite confused by this error.
My code:
module fifo(clk, reset, in, push, pop, out, full);
parameter N=4; // determines the maximum number of words in queue.
parameter M=2; // determines the bit-width of each word, stored in the queue.
input clk, reset, push, pop;
input [M-1:0] in;
output [M-1:0] out;
wire [M-1:0] full_string;
output full;
wire full;
single_fifo fArr[M-1:0]({M*{clk}},{M*{reset}},in,{M*{push}},{M*{pop}},out,full_string);
assign full=|full_string;
endmodule
I'll also add the list of ports for single_fifo in case it's required:
module single_fifo(clk,reset,in_bit,push,pop,out_bit,full);
parameter N=4; // determines the maximum number of words in queue.
input clk, reset, push, pop;
input in_bit;
output out_bit;
reg [N-1:0] bit_list;
reg [N-1:0] n;
reg out_bit;
output full;
reg full;
Sorry if my question seems noobish, I'm still new to verilog. Help will be appriciated!
Although you probably meant to use replication {M{clk}} instead of multiplication {M*{clk}}, there is no need for any of this with an array of instances. Verilog automatically replicates the signals you connect to an array of instances so you can just write
single_fifo fArr[M-1:0](clk,reset,in,push,pop,out,full_string);
P.S. I should know because I was responsible for added this feature to Verilog way back in 1990.
See section 23.3.3.5 Unpacked array ports and arrays of instances in the IEEE 1800-2017 LRM
In verilog for Cyclone 3 I want to declare a port where some pins are inputs and some are outputs, in many examples in web i see that a port is defined like
input wire [0:10]p;
but what to do if i need bit0 being an input of the IC, while others be an output. Tried like this and some other different variants, but every time i get errors from the compiler. Notice that IO[1] unused in code but present in "Assignment editor".
module main(
tx,
rx,
IO[0],
IO[2]
);
output wire tx;
input wire rx;
input wire IO[0];
output wire IO[2];
assign IO[2] = rx;
assign tx = IO[0];
endmodule
You can use a port_expression. This separates the name of the port from the signals (or expression of signals) connected to the port. You might recognize this syntax when creating a module instance, but it has always been available for a module declaration as well in Verilog
module m(input .rx(a[0]), output .tx(a[1]));
wire [1:0] a;
endmodule
module top;
wire a,b;
m m1(.rx(a),.tx(b));
endmodule
there is no way in verilog to declare different directions to different bits of a single vector port. The direction works on the whole declaration of a port. The only way to do it is to split the single port into multiple ports with different names, e.g.
module main(
output wire tx,
input wire rx,
output wire out,
input wire in
);
Then, when you instantiate it, you can define which bits goes where:
main inst(.tx(tx), .rx(rx), .out(IN[0]), .in(IN[2]);
Since the top level module is not instantiated per se, it doesn't seem using port expressions can work here.
One thing you should try is to change the name of the pins in the pin assignment file (.csv I think) you are loading into Quartus to program your fpga. Give the different pins different names there, e.g. not In[0] or In[1], but rather in0, in1 and so on.
module data_path(
input clk,
input rst,
input inc_pc,
input load_mar,
input load_mbr,
input load_ir,
input r_w,
input [7:0] data_in,
input load_ac,
input mux_sel,
output [7:0] ir_out);
reg [3:0]var;
reg [2:0]opcode;
wire [3:0] w1,w2,w6;
wire [7:0] w3,w4,w5;
pc pc1(.rst(rst),.clk(clk),.inc_pc(inc_pc),.pc_out(w1));
register1 mar(.rst(rst),.clk(clk),.load(load_mar),.in(w1),.out(w2));
memory memory1(.add_in(w2),.data_in(data_in),.data_out(w3),.r_w(r_w));
register2 mbr(.rst(rst),.clk(clk),.load(load_mbr),.in(w3),.out(w4));
register1 ir(.rst(rst),.clk(clk),.load(load_ir),.in(w4),.out(w5));
assign opcode=w4[7:5];
if(opcode==3'b000)
register1 ac(.rst(rst),.clk(clk),.load(load_ac),.in(w4[4:0]),.out(w6));
else
if(opcode==3'b001)
begin
assign var=w6+w4[4:0];
register1 ac(.rst(rst),.clk(clk),.load(load_ac),.in(var),.out(w6));
end
endmodule
Getting error:
data_path.v line 52 expecting 'endmodule', found 'if'
if usually used in the always or initial block (Procedural Blocks; so you can't check opcode with if outside of procedural block. Try to move if inside always # (posedge clk).
You also should move register1 ac(.rst(rst),.clk(clk),.load(load_ac),.in(w4[4:0]),.out(w6)); instantiation outside of if, because you describe hardware and there is no Conditional instantiation of verilog modules
If 'register1' is another Verilog module, this logic will not work. In your code, you are using the output of a Verilog module (something that is not known at static-run time but that instead my change every clock cycle) to determine which of two instances to instantiate.
Instances will exist from the start of run time, and cannot be brought in and out of existence every clock cycle. Instead, you will have to create both instances of 'register1 ac' as two separate instances (with different names, and with their outputs named differently). And then use a mux (multiplexor) to select between the two output busses depending on the value of 'opcode'.
Both prior answers correctly capture some information. You're trying to mux an input to register1 based on the opcode. A little weirdness in that you're sending in either 4b or 5b based on the if-else. I'll let it slide and assume 5b without sign extension for now. Also your output is 4b.
One other thing. Overflow in the opcode 3'b001 add (which doesn't add up in your assign) - how would one add 4b(w6) + 5b(w4[4:0]) into 4b (var) reliably?
Here's the (untested, caution) code revision (snippet of your code above).
Declare a wire that you mux per the opcode.
wire [7:0] tmpin;
Now correctly write the always to capture the behavior
always #(*) begin
if(opcode==3'b000) tmpin = {3'b0,w4[4:0]};
elsif (opcode == 3'b001) tmpin = {4'b0,w6} + w4;
end
Then you just follow with the muxed variable into a concurrent statement - the register declaration.
register1 ac(.rst(rst),.clk(clk),.load(load_ac),.in(tmpin[4:0]),.out(w6));
Have fun!