Assign multiple values to one latch - verilog

I need a latch which can take multiple bus with one enable signal for each and when this signal is high, the latch takes the value of the associated bus, something like this :
I tried this :
module Test (
input [1:0] load,
input [15:0] bus,
output reg [7:0] value
);
wire [7:0] temp;
assign temp = (load[0]) ? bus[7:0] : (load[1]) ? bus[15:8] : 8'bZZ;
always #(load or temp) begin
// Latch value
if (load) begin
value <= temp;
end
end
endmodule
and this :
module Test (
input [1:0] load,
input [15:0] bus,
output reg [7:0] value
);
always #(load or bus) begin
// Latch value
if (load[0]) begin
value <= bus[7:0];
end
else
if (load[1]) begin
value <= bus[15:8];
end
end
endmodule
And this same warning appears on both (repeated for each bit) :
Warning (13012): Latch Test:test|value[0] has unsafe behavior
Warning (13013): Ports D and ENA on the latch are fed by the same signal load[0]
The only way that I found to avoid these warnings is like this :
module Test (
input [1:0] load,
input [15:0] bus,
output [7:0] value
);
reg [15:0] temp;
reg index;
always #(load or bus) begin
if (load[0]) begin
index <= 0;
end
else
if (load[1]) begin
index <= 1;
end
// Latch value
if (load) begin
temp <= bus;
end
end
assign value = temp[8*index+7 -:8];
endmodule
But it's a waste of memory because it saves the two buses instead of one, is it possible to do it with one reg and avoiding these warnings ?

I don't think you can get rid of the warnings in the first two examples—you have a bonafide race condition between the latch enable and the data feeding the latch. It is more obvious in your first example.
When load goes to 0, temp will be changing to Z ( a don't care most likely 0) at the same time the latch enable goes to 0. Which one happens first is clearly a race.

Related

How can I use display or monitor in verilog to check a register

I have 2 Modules. One is Register_File_Rf which is a file of 32 Registers I have created. I want to be able to see what every single register is storing.
Can I do this with $display or $monitor somehow?
Where these should be? In actual code or in Testbench, and how do I get the value in testbench when the stored Data is neither input or output?
module Register(
input Clk,
input [31:0] Data,
input WE,
output reg[31:0] Dout
);
reg [31:0] stored;
// With every Positive Edge of the Clock
always #(posedge Clk)begin
// If Write is Enabled we store the new Data
if (WE)begin
stored <= Data;
Dout <= stored;
end else
Dout <= stored;
end
module Register_File_RF(
input [4:0] Adr1,
input [4:0] Adr2,
input [4:0] Awr,
output reg[31:0] Dout1,
output reg[31:0] Dout2,
input [31:0] Din,
input WrEn,
input Clk
);
integer j;
genvar i;
wire [31:0]Temp_Dout[31:0];
reg W_E [31:0];
// Writing only in the first time R0 Register with 0
initial begin
W_E[0] = 1;
end
// Creating the R0 Register
Register register (.Clk(Clk),.WE(W_E[0]),.Data(0),.Dout(Temp_Dout[0]));
// Creating 30 Registers
for(i = 1; i < 32; i = i + 1)begin:loop
Register register (.Clk(Clk),.WE(W_E[i]),.Data(Din),.Dout(Temp_Dout[i]));
end:loop
// Assigning to Dout1 and Dout2 the Data from a spesific register
always #(Adr1, Adr2) begin
Dout1 = Temp_Dout[Adr1];
Dout2 = Temp_Dout[Adr2];
end
// Wrting Data to a specific register
always #(posedge Clk)begin
//Reseting Write Enable of the register to 0
for (j = 0; j < 32; j = j + 1)begin:loop2
W_E[j] = 0;
end:loop2
if(WrEn)begin
W_E[Awr] = WrEn;
end
end
endmodule
Yes, you can do this with either $display or $monitor.
Typically, $monitor would be called inside an initial block since it should only be called at one time in your simulation. It automatically displays values whenever one of its argument signals changes value.
Unlike $monitor, $display only displays values when it is called; it must be called whenever you want to display a signal value. It can be called in an initial block, but it is often called in an always block.
Regarding when to use either one, it is up to you to decide what you require.
If you are not planning to synthesize your modules, you could place monitor/display inside your design module directly. However, if you plan to synthesize, it might be better to place them in the testbench.
You can use hierarchical scoping to view internal signals from the testbench module. For example, assume you named the instance of the Register_File_RF module in the testbench as dut:
Register_File_RF dut (
// ports
);
always #(posedge Clk) begin
$display($time, " dout='h%x", dut.register.Dout);
end
initial begin
$monitor($time, " dout='h%x", dut.register.Dout);
end
$monitor will display a value every time Dout changes value, whereas $display will show the value at the posedge of the clock.
If your simulator supports SystemVerilog features, you can also use bind to magically add code to your design modules.

Running into errors while trying to move signal to external module

I have two modules namely main.v and signal.v.
In main.v, I have a few lines of code that update 16 bit reg tx with a value corresponding to a square wave.
reg [1:0] counter;
reg [15:0] tx;
always #(posedge clk) begin
counter = counter + 1;
if (counter[1] == 1) begin
tx[15:0] <= 16'b1010101010101010;
else
tx[15:0] <= 16'b0000000000000000;
end
This works fine. Eventually, though, I want to move this signal over to another file signal.v, because the signal that I pass to tx will grow steadily more complicated. I ran into errors when I try to do this. Initially, I tried to move all the above code to the file signal.v. Then used a wire between the two files as shown.
module signal(clk, get_tx);
input clk;
output reg get_tx;
reg [1:0] counter;
always #(posedge clk) begin
counter = counter + 1;
if (counter[1] == 1) begin
get_tx[15:0] <= 16'b1010101010101010;
else
get_tx[15:0] <= 16'b0000000000000000;
end
Then in main.v, I tried to add
wire get_tx;
reg [15:0] tx;
signal my_signal(.clk(clk), .get_tx(get_tx));
always #( get_tx ) begin
tx <= get_tx;
end
Based on what I see in the output oscilloscope, this method isn't working, and I'm not certain why this is. The first case seems to work fine, so I don't know why it is failing when I move to the second case (the signals just look completely different).
I would appreciate any help/advice!
First of all will be better to understand your connections and simulate your code if you add full code with modules declarations. The problems are in the signal types. Try to change output to wire. As well you need to declare bus, not just 1 bit signal. And give an initial value to your counter (in other case it will do follow operation 'X' +1 which gives 'X' in result and your condition if (counter[1] == 1) will never be achieved).
module signal(clk, get_tx);
input clk;
output [15:0] get_tx;
reg [15:0] tx_out;
reg [1:0] counter = 2'd0;
always #(posedge clk) begin
counter = counter + 1;
if (counter[1] == 1)
tx_out[15:0] <= 16'b1010101010101010;
else
tx_out[15:0] <= 16'b0000000000000000;
end
assign get_tx = tx_out;
endmodule
Next error in upper module, there you also need to declare bus rather than just one bit wire [15:0] get_tx;. Try to fix this errors and your modules will work.

Verilog count odd and even numbers in ram

I'm using quartus 2 9.1 .I have a program of Single-Port RAM on verilog, i added reg
Even
to check is number odd or even by first bit, its 1 or 0 in sumulation. I need to enter 16 numbers in ram by data input, then count how many odd and even numbers. But i tried something like:
output wire [4:0] count;
count = count + data[0]; //to count odd numbers, then i could take away from 16 and get even number - in simulation its just 0 or 1..
or something like that:
output wire [4:0] count;
always #*
begin
if(data[0])
even=1;
else
begin
even=0;
count = count + 1;
end
end
But count dont want show in sumaliton number of odd or even numbers.. My code:
module kok
(
input [7:0] data,
input [5:0] addr,
input we, clk,
output [7:0] q,
output reg even
);
// Declare the RAM variable
reg [7:0] ram[63:0];
// Variable to hold the registered read address
reg [5:0] addr_reg;
always # (posedge clk)
begin
// Write
if (we)
ram[addr] <= data;
addr_reg <= addr;
end
always #(posedge data)
begin
even = data[0];
end
// Continuous assignment implies read returns NEW data.
// This is the natural behavior of the TriMatrix memory
// blocks in Single Port mode.
assign q = ram[addr_reg];
endmodule
My understanding of your question is you want an output count signal that counts how many times you have an even value.
Create a top_level
module top (
input [7:0] data,
input [5:0] addr,
input we
);
reg clk= 1;
initial begin
forever #5 clk = ~clk;
end
reg reset_count = 0;
initial begin
#5 reset_count = 1'b1;
#20 reset_count = 1'b0;
end
kok u_kok (.clk(clk),
.data(data),
.addr(addr),
.we(we),
.reset_count(reset_count)
);
endmodule
Add this to module_kok:
module kok
(
input reset_count,
input [7:0] data,
input [5:0] addr,
input we, clk,
output [7:0] q,
output reg even,
output reg [4:0] count
);
// Declare the RAM variable
reg [7:0] ram[63:0];
// Variable to hold the registered read address
reg [5:0] addr_reg;
always # (posedge clk)
begin
// Write
if (we)
ram[addr] <= data;
addr_reg <= addr;
end
always #(posedge clk)
begin
even <= data[0];
end
always #(posedge even or posedge reset_count)
begin
if (reset_count) begin
count <= 'h0;
end
else begin
count <= count+1'b1;
end
end
// Continuous assignment implies read returns NEW data.
// This is the natural behavior of the TriMatrix memory
// blocks in Single Port mode.
assign q = ram[addr_reg];
endmodule
Note that you can only count to 2**5=32 before the counter overflows.
Here is a working example: https://www.edaplayground.com/x/qRs
The counter needs to be in a clocked process (i.e. inside an always #posedge clk). The counter therefore also needs to be a reg (instead of wire). You also need to figure out which condition(s) should restart your counter, and if you need to accound for overflow conditions etc. This depends on your actual use.

1second down counter with initial value verilog code

I want to write the code of 1-second down counter that get the initial value from outside and count it down till 0. but there is a problem. How can I get the initial value. i tried some ways but ....
here is the code:
module second_counter ( input clk,
input top_num,
output reg [3:0] sec_num
);
parameter clk_frequency = 25;
reg [31:0]cnt;
wire [3:0]sec;
/// how can get the top_num and count it down.
assign sec=top_num;
always #(posedge clk)
begin
if (cnt==clk_frequency)
begin
sec <= sec -1;
cnt<=0;
end
else
cnt <=cnt+1;
end
What you basically need is a reset signal. Just like clock, reset is to be added in the sensitivity list.
After instantiation of module, you must apply a reset signal to initialize all the internal variables and registers of design.
Following code gives you initial value of cnt by reset application. This is an active low reset.
module second_counter ( input clk, input reset, input top_num, output reg [3:0] sec_num );
parameter clk_frequency = 25;
reg [31:0]cnt;
// wire [3:0]sec;
reg [3:0] sec;
///
// assign sec=top_num;
always #(posedge clk, negedge reset)
begin
if(!reset)
begin
cnt<=0; // initialize all internal variables and registers
sec<=0;
end
else
begin
if(sec == 0) // latch input when previous count is completed
sec<=top_num;
if (cnt==clk_frequency)
begin
sec <= sec -1;
cnt<=0;
end
else
cnt <=cnt+1;
end
end
Note that this is an asynchronous reset, means it does not depend on clocking signal. Synchronous reset is the one which only affects the registers at the clock pulse.
Edit:
Regarding to sec, I have modified the code. Now the design latches the inputs for one clock cycle and counts down to zero. Once the counter reaches zero, it again latches the input to re-count to zero.
Note that you cannot do like latching top_num at every clock and counting through zero (since top_num can change at every pulse). For latching at every clock pulse, you need more complex logic implementation.

always module in Verilog RTL file not working, but working once included in testbench

This might seem like a very naive question, but I have just started working with Verilog (I use Xilinx ISE, if that helps).
I am trying to implement a shift register that shifts input PI by the value specified in the shft port. When I include the shifting logic in the RTL file, the shifting does not work, but when I move the always block corresponding to shifting to the testbench, it works. Please help me with this!
module shift (PI, shft, clk, PO);
input [7:0] PI;
input clk;
input [7:0] shft;
output reg [13:0] PO;
reg [7:0] shft_reg;
always #(posedge clk) begin
if (shft_reg[0]||shft_reg[1]||shft_reg[2]||shft_reg[3]||shft_reg[4]||shft_reg[5]||shft_reg[6]||shft_reg[7]) begin
PO <= {PO, 0};
shft_reg <= shft_reg-1;
end
end
endmodule
module shift (
input wire clk;
input wire load; // load shift register from input
input wire [7:0] PI;
input wire [7:0] shft; // this might need less bits
output wire [13:0] PO;
);
reg [7:0] shft_reg;
reg [13:0] value;
assign PO = value; // PO follows value
always #(posedge clk) begin
if (load) begin // initialize shift register and counter
shft_reg <= shft;
value <= {6'b0,PI};
end
else if (shft_reg) begin // if counter not reached end...
shft_reg <= shft_reg - 1; // decrement, and
value <= {value[13:1],1'b0}; // shift left value 1 bit
end
end
end
endmodule
Recall that Verilog supports the >> and << operators. For non-constants many-bit operands, this may be a waste of multiplexers, though:
module shiftcomb (
input wire [7:0] PI; // this value is left shifted
input wire [2:0] shft; // 0 to 7 bits positions
output wire [14:0] PO; // and is outputted to PO
);
assign PO = PI<<shft; // this will generate 15 mutlplexers:
// each one with 8 inputs, 3 bit select,
// and 1 output.
endmodule
Note that || is a logical or and idealy should be used with logical statments such as (shft_reg[0] == 1'b1 ) || ( shft_reg[1] == 1'b1).
Your if statment is really bitwise ORing all of the bits ie
shft_reg[0] | shft_reg[1] | shft_reg[2] | ...
You can use the OR Reduction operator :
|shft_reg
Your supplied code had typo'd PI for PO.
always #(posedge clk) begin
if (|shft_reg) begin
PO <= {PI, 0}; //PI input
shft_reg <= shft_reg-1;
end
end

Resources