Verilog: Reading 1 bit input and Writing it to 288 bit reg - verilog

In verilog, I have a module name(input data,..., output...);
Data is only a single bit input and I need it to be displayed to reg [288:0] data_tmp; to compare the bits. How do I transfer data(input) to the reg?
I tried to handle it like an array in C using a for loop like so:
for(i=0; i<288; i=i+1) begin
data_tmp[i]=data;
end
But it doesn't appear to take any of the values from data or it is overwriting them.
Actual Code:
module inspector (
input rst_n, data, clk,
output total_cnt, skype_cnt, ftp_cnt, https_cnt, telnet_cnt, ssh_cnt, snmp_cnt, smtp_cnt,
nntp_cnt, telnet_session, skype_session, ssh_session
);
output [31:0] total_cnt;
output [7:0] skype_cnt;
output [7:0] ftp_cnt;
output [7:0] https_cnt;
output [7:0] telnet_cnt;
output [7:0] ssh_cnt;
output [7:0] snmp_cnt;
output [7:0] smtp_cnt;
output [7:0] nntp_cnt;
output [7:0] telnet_session;
output [7:0] skype_session;
output [7:0] ssh_session;
localparam INIT = 0;
localparam DATA = 1;
localparam PORT = 2;
localparam TOTAL = 3;
reg [287:0] data_tmp;
reg [3:0] Start_sequence = 32'hA5A5A5A5;
reg [1:0] state;
integer i;
always #(posedge clk)
if (rst_n) begin
total_cnt_tmp = 8'h00;
....
ssh_session_tmp = 8'h00;
end else begin
case (state)
INIT : begin
for(i=0; i<288; i=i+1) begin
data_tmp[i]=data;
end
if (data_tmp[31:0] == Start_sequence) begin
state <= DATA;
end else begin
state <= INIT;
end
end
.....

The for-loop is replicating the data; ie if data is 1 you get 288 ones, if data is 0 you get 288 zeros. What you want what is a shifter. data_tmp shift the bits to the left or right depending on the order of the bit stream.
data_tmp<={data_tmp[286:0],data}; // shift and fill left
or
data_tmp<={data,data_tmp[287:1]}; // shift and fill right
Also, remember to assign flops with non-blocking (<=). Blocking (=) for assigning combinational logic.

Related

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.

How I can find maximum number in verilog array

So, I have a reg[7:0] corr_Output[0:63]; which is filled with values in my module. How I can find maximum number in this array at one CLK cycle?
I wrote a 8 bit comparator:
module Comparator2D(
input [7:0] X1,
input [7:0] indexX1,
input [7:0] X2,
input [7:0] indexX2,
output [7:0] Y,
output [7:0] indexY
);
always begin
if (X1 > X2) begin
Y = X1;
indexY = indexX1;
end
else begin
Y = X2;
indexY = indexX2;
end
end
endmodule
But I dont know how I should instantiate this module in my top design? I think I should use "for loop", or even write another module which will concatenate my Comparator2D module in pyramid form, but as I found I cant pass whole array to input port of module, so Im a little stuck..
You can do it by using for/generate, like in this code sample, in which I can compare 8 bytes at a time.
The key point is that I cannot pass a memory as input (an array of registers), but I can pass an array of bits that hold the current values from memory.
// This is just your compare module.
module C2D (
input wire [7:0] X1,
input wire [7:0] indexX1,
input wire [7:0] X2,
input wire [7:0] indexX2,
output reg [7:0] Y,
output reg [7:0] indexY
);
always #* begin
if (X1 > X2) begin
Y = X1;
indexY = indexX1;
end
else begin
Y = X2;
indexY = indexX2;
end
end
endmodule
// Compare 8 bytes at a time
module greatest8bytes (
input wire [63:0] array, // 8 byte array
output wire [7:0] indexG,
output wire [7:0] valueG
);
wire [7:0] value_l1[0:3];
wire [7:0] index_l1[0:3];
genvar i;
generate
for (i=0;i<8;i=i+2) begin :gen_comps_l1
C2D cl1 (array[i*8+7:i*8],
i,
array[(i+1)*8+7:(i+1)*8],
(i+1),
value_l1[i/2],
index_l1[i/2]
);
end
endgenerate
wire [7:0] value_l2[0:1];
wire [7:0] index_l2[0:1];
generate
for (i=0;i<4;i=i+2) begin :gen_comps_l2
C2D cl2 (value_l1[i],
index_l1[i],
value_l1[i+1],
index_l1[i+1],
value_l2[i/2],
index_l2[i/2]
);
end
endgenerate
wire [7:0] value_l3[0:0];
wire [7:0] index_l3[0:0];
generate
for (i=0;i<2;i=i+2) begin :gen_comps_l3
C2D cl3 (value_l2[i],
index_l2[i],
value_l2[i+1],
index_l2[i+1],
value_l3[i/2],
index_l3[i/2]
);
end
endgenerate
assign indexG = index_l3[0];
assign valueG = value_l3[0];
endmodule
The greatest8bytes module is synthesized the way you expect: as a pyramid-like arrangement of comparators:
To connect an array of regs (a memory) to the input of this module, create a wire of the desired number of bits (64 in this example) and concatenate all elements of memory, like in this example module:
module findgreatest (
input wire clk,
input wire [2:0] addr,
input wire [7:0] data,
input wire we,
output wire [2:0] indexG,
output wire [7:0] valueG
);
reg [7:0] memory[0:7]; // 8 bytes
// To load data from the outside so the synthesizer won't throw away memory
always #(posedge clk) begin
if (we)
memory[addr] <= data;
end
wire [63:0] array = {memory[7],memory[6],memory[5],memory[4],
memory[3],memory[2],memory[1],memory[0]};
greatest8bytes compar (array, indexG, valueG);
endmodule
Not sure if this is synthesizable, but it is good to know that SystemVerilog has built in min and max functions:
module maximum ();
reg[7:0] corr_Output[0:63] = '{0:8'd112, 2:8'd250, 3:8'd37, 4:8'd15, default:8'd25};
reg[7:0] max_i[$];
reg[7:0] min_i[$];
initial begin
max_i = corr_Output.max;
min_i = corr_Output.min;
$display ("max=%d, min=%d", max_i[0], min_i[0]);
end
endmodule
Output:
# max=250, min= 15
Alternatively, it is probably shorter to just use this classic and synthesizable for-loop of comparisons:
always_comb begin
max = corr_Output[0];
for (c = 0; c <= 63; c++)
begin
if (corr_Output[c] > max)
begin
max = array[c];
index = c;
end
end

Verilog logical error

module ocircuit (ooutp,s0,s1 ,clk,write,raddA,raddB,wadd,wdata);
output [3:0] ooutp;
input clk, write,s0,s1;
input [2:0] raddA;
input [2:0] wadd;
input [2:0] raddB;
input [3:0] wdata;
reg [9:0] ooutp;
wire [3:0] dataA;
wire [3:0] dataB;
reg [9:0] inner;
regfile y (dataA,dataB,clk,write,raddA,raddB,wadd,wdata);
always #(posedge clk) begin
if (s0==0) begin
assign inner = dataA [3:0]*dataB [3:0];
end
else begin
assign inner = ((dataA [3:0]*dataB [3:0])+inner [9:0]);
end
//inner=inner1;
ooutp =s1?inner [9:0]:10'd0;
end
endmodule
This is the code. regfile is a simple register file. In the testbench, s0 = 0 during the first cycle and s0 = 1.
For subsequent cycles, this code should return the value of A*B+C*D by using one adder and one multiplier. In the first cycle, when c0 = 0, the answer that is saved in inner (a register) is right but in the second cycle, when c0 = 1 the answer is wrong.
Por example: A=1; B=2; C=1; D=1;
First cycle: x=A*B=2
Second cycle (C*D)+x=5
I think there is something wrong with this statement
assign inner = ((dataA [3:0]*dataB [3:0])+inner [9:0]);
Any help or hint will be appreciated.
Although assign can be used from within an always block, I think you just wanted to store a value into inner depending upon the value of s0. To do that, use non-blocking assignments ( <= ).
Also, you can directly output to ooutp instead of saving the final result in inner, avoiding a possible glitch in the multiplexer you instantiate here:
ooutp =s1?inner [9:0]:10'd0;
Which, by the way, it should be outside the always block, in an assign line:
assign ooutp = s1? inner [9:0]:10'd0;
module ocircuit (ooutp,s0,s1 ,clk,write,raddA,raddB,wadd,wdata);
output [3:0] ooutp;
input clk, write,s0,s1;
input [2:0] raddA;
input [2:0] wadd;
input [2:0] raddB;
input [3:0] wdata;
reg [9:0] ooutp;
wire [3:0] dataA;
wire [3:0] dataB;
reg [9:0] inner;
regfile y (dataA,dataB,clk,write,raddA,raddB,wadd,wdata);
always #(posedge clk) begin
if (s0==0) begin
inner <= dataA [3:0]*dataB [3:0];
end
else begin
ooutp <= ((dataA [3:0]*dataB [3:0])+inner [9:0]);
end
end
endmodule

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

calculate how many times input is repeated verilog

I'm trying to calculate times in which input x with 8 bits is repeated on every posedge clk.
I'm thinking about creating 256b counter to each value of these 8 bit to compare x with it, but I get error when I'm trying to compare each value of these counter with each input x on rising edge.
module counter_initial(x);
input[7:0] x;
//output [7:0] y;
//reg [7:0] y;
//reg [7:0] freq_tst,gap_tst;
reg [7:0] freq_num;
endmodule
module counter_256(clk,x,out);
input [7:0] x;
input clk;
// input [7:0] in;
output [7:0] out;
reg [7:0] out;
//reg [7:0] freq_tst,gap_tst;
reg [7:0] k=0;
// reg [] t=0;
genvar i;
generate
for (i=0;i<256;i=i+1)
begin
counter_initial m(i);
//t=m(i);
end
endgenerate
always #(posedge clk)
begin
if(k<256) begin
if (x==m[i])
//counter_initial[k]==x
begin
freq_num=freq_num+1;
end
//else
//begin gap_tst=gap_tst+1; end
k=k+1;
end
end
endmodule
You don't need an additional module to count. You can use a memory array. Example:
input [WIDTH-1:0] x;
reg [7:0] mem [WIDTH-1:0];
integer i;
always #(posedge clk) begin
if (reset) begin
for (i = 0; i < 2**WIDTH; i = i+1) begin
mem[i] <= 8'b0;
end
end
else if (mem[x] < 8'd255) begin // cap counting and prevent overflow
mem[x] <= mem[x] + 1'b1;
end
end
If you want to use separate modules then pass the clock to it. Example:
module counter (output reg [7:0] count, input increment, clk, reset);
always #(posedge clk) begin
if (reset) begin
count <= 8'b0;
end
else if (count < 8'd255) begin // cap counting and prevent overflow
count <= count + increment;
end
end
endmodule
module my_device ( /* ..., */ input [7:0] x, input clk, reset );
/* ... */
genvar i;
generate
for (i=0; i<256; i=i+1) begin
counter icount( .count(/* ... */), .increment(x==i), .* );
end
endgenerate
/* ... */
endmdoule
Reminder 8'd255 + 1 is 8'd0 because the MSB of 8'd256 is out of range. I capped the counters so the will not overflow and roll back to zero.

Resources