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

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

Related

Delay a 32-bit signal with N clock cycle in verilog

I am trying to delay a 32-bit signal using shift register. My logic is a single flip flop delay a signal by 1 clk so I use shift register as it is combination of flip flop can someone guide me what is wrong with this code.
module delay_n_cycles (
input wire [31:0] data_in,
input wire clk,
output reg [31:0] data_out,
parameter N = 5
);
reg [31:0] shift_reg;
always #(posedge clk) begin
shift_reg <= {shift_reg[30:0], data_in};
if (N == 0) begin
data_out <= shift_reg[31];
end else begin
data_out <= shift_reg[N-1];
end
end
endmodule
First of all, your code is syntactically wrong. parameter cannot be declared in a way you provided.
Your shift register is only 32 bit wide. Usually, to delay multi-bit data this way, you need to keep N copies of data in the register, shift them at one end and read at the other. I guess the following should help:
module delay_n_cycles #(parameter N = 5)(
input wire [31:0] data_in,
input wire clk,
output reg [31:0] data_out
);
reg [N-1:0][31:0] shift_reg;
always #(posedge clk) begin
shift_reg <= (shift_reg << 32) | data_in;
data_out <= shift_reg[N-1];
end
endmodule
This code will work with system verilog because it used packed multi-dimensional arrays.
You need to shift the reg by 32 (width of the data) in packed version.
Here is an example of a testbench:
module tb();
bit clk;
int clkCount;
initial
forever begin
#5 clk = ~clk;
clkCount++;
end
logic [31:0] data_in, data_out;
initial begin
$monitor("%0t (%0d) [%h]: %0d --> %0d", $time, clkCount, ds.shift_reg[4], data_in, ds.data_out);
for(int i = 0; i < 20; i++) begin
#10 data_in = i;
end
$finish;
end
delay_n_cycles ds(data_in, clk, data_out);
endmodule

How to generate random patterns using LFSR and i am using different partial seed value

As I said, seedValue wire is holding a 10 bit partial seed which I want to assign to a register when the rst signal is 1 it enters the block and the last statement of this block assigns the seedValue wire to the register temp so that when the if condition if((temp!=10'b0000000000) || (temp!=10'bxxxxxxxxxx)) is executed it enters the block and then the seedValue is concatenated with 12'b000000000000 and then I get my 32-bit seed value through which I am expecting to have random patterns from the LFSR after that the register temp is assigned zero values so that the else block must execute from which I am expection to get random patterns, but the following code is not working. I am new to Verilog and FPGA world, somebody please help me. The following code is written in Verilog.
module TestPatternGenerator(input wire clk, input wire rst, input wire enable,
input wire sel, input wire[9:0] seedValue, output reg[127:0] valueO);
integer i;
reg [31:0] patternGenerate[0:3],tempOne;
reg [9:0] temp;
always #(posedge clk)begin
if((sel == 1)&&(enable==1))begin
if(rst)begin
valueO = 128'b0;
patternGenerate[0]<=32'b0;
patternGenerate[1]<=32'b0;
patternGenerate[2]<=32'b0;
patternGenerate[3]<=32'b0;
tempOne <= 32'b11111111111111111111111111111111;
temp <= seedValue;
end
else if((temp!=10'b0000000000) || (temp!=10'bxxxxxxxxxx))begin
tempOne <= {12'b000000000000,seedValue};
$display("%h",tempOne);
temp <= 10'b0000000000;
end
else begin
for(i=0;i<4;i=i+1)begin
tempOne = {(tempOne[31] ^ tempOne[25] ^ tempOne[22] ^ tempOne[21] ^ tempOne[15] ^ tempOne[11] ^ tempOne[10] ^ tempOne[9] ^ tempOne[7] ^ tempOne[6] ^ tempOne[4] ^ tempOne[3] ^ tempOne[1] ^ tempOne[0]), tempOne[31:1]};
patternGenerate[i] = tempOne;
end
valueO = {patternGenerate[3],patternGenerate[2],patternGenerate[1],patternGenerate[0]};
end
end
i=i+1;
end
endmodule
code for testbench is given below
`timescale 10ns/1ns
module test_controller();
integer j;
reg [127:0] key_byte,valueI,oraI;
wire [127:0] state_byte;
wire [9:0] seedValue;
wire [47:0] result;
reg [7:0] iterate;
reg clk,rst,bistForDeternimistic,deterministicEnable,ecryptionEnable,enable,decryptionEnable,decryptionSecondEnable,bistMode,bistForEncryption,bistForDecryption,oraEnable;
wire [127:0] state_out_dec,state_out_enc,state_second_dec;
wire [31:0] state_out_ora;
reg [31:0] signatureToMatch;
wire load,ready;
TestPatternGenerator tpg (clk,rst,enable,bistMode,seedValue,state_byte);
always #3 clk = ~clk;
initial begin
bistMode <= 1;
key_byte <= 128'h5468617473206D79204B756E67204675;
bistForDecryption <= 0;
clk<=0;
rst<=1;
#5 rst<=0;
iterate<=0;
j<=0;
bistForDeternimistic<=1;
enable<=1;
end
always#(negedge clk)begin : deterministic_block
if(j==100)begin
disable deterministic_block;
end
if((bistMode==1) && (bistForDeternimistic==1))begin
#(state_byte)begin
$display("%h %d",state_byte,$time);
end
end
j=j+1;
end
endmodule
output i am getting only the first test pattern but it should generate 100 test patterns. So except the first test pattern, i am not getting the rest 99 patterns.
When I run your code, I don't see any patterns (the $display statements are not executed). This is because the enable signal is unknown when rst is 1.
If I delay the rst rising edge to occur after enable is set to 1, I see 100 patterns:
initial begin
bistMode <= 1;
key_byte <= 128'h5468617473206D79204B756E67204675;
bistForDecryption <= 0;
clk<=0;
rst<=1;
iterate<=0;
j<=0;
bistForDeternimistic<=1;
enable<=1;
#5 rst<=0;
end
This is a partial output:
00000000000000000000000000000000 3
afffffff5fffffffbfffffff7fffffff 9
2affffff55ffffffabffffff57ffffff 15
72afffffe55fffffcabfffff957fffff 21
272affff4e55ffff9cabffff3957ffff 27
4272afff84e55fff09cabfff13957fff 33
You mention the seedValue signal in your question, but it is undriven (the value z). You declared the signal as a wire, and wires default to z when they are not assigned.
To drive it with a know value for the full duration of the simulation, you could use, for example:
wire [9:0] seedValue = 1;
If you want to drive it like your other inputs, you should declare is as a reg.

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.

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

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.

verilog basic compiler error

I am tring to compile a program in verilog but there is a basic mistake. I cant figure out what.
First module:
module inst_line_buf (from_LS,clk,fetch_ctrl,dec_ctrl,hmic_ctrl,branch_ctrl,to_if1,to_if2,flush_ctrl);
//from local store and all the control signals defined. to_if sends 2 insts to fetch
input from_LS, clk, fetch_ctrl, dec_ctrl, hmic_ctrl, branch_ctrl;
output to_if1,to_if2;
output flush_ctrl;
// 16 instructions of 32 bits each.
wire [511:0] from_LS;
wire fetch_ctrl;
// dec_ctrl - 1 bit
// 0 : will tell if 2 instructions given to it are structurally dependent.
wire dec_ctrl;
// hmic_ctrl - 4 bits
// 0 : whether to stall sending the instructions.
// 1:3 : how many cycles to stall.
wire [3:0] hmic_ctrl;
// branch_ctrl - 14 bits
// 0 : whether to issue from buffer 1 or buffer 2, whether branch is taken or not.
// 1:13 : branch address. Get and store in buffer 2.
wire [13:0] branch_ctrl;
// to_if - 64 bits
// 0:63 : 2 instructions to inst fetch.
reg [31:0] to_if1;
reg [31:0] to_if2;
// flush_ctrl - 1 bit
// To three buffers in main prog, whether to flush the buffers or not.
reg flush_ctrl;
//pc is program counter
reg [12:0] pc;
// ilb stores 16 32 bit instructions from from_LS
reg [31:0] ilb[0:15];
// ilb1 is the buffer which stores all the branch instructions
reg [31:0] ilb1[0:15];
//buffer_bit - 1 bit
// buffer_bit act like a vlid bit which helps in selecting appropriate buffer
reg buffer_bit;
integer a;
integer count1,count2;
initial
begin
count1 = 0;
count2=0;
flush_ctrl=0;
buffer_bit=0;
a=hmic_ctrl[3:1];
ilb=from_LS[511:0];
program_counter pctr (
.clk(clk),
.reset(0),
.offset(branch_ctrl[13:1]),
.mux_select(branch_ctrl[0]),
.pc1(pc)
);
end
always (#posedge clk)
begin
if(!dec_ctrl && !hmic_ctrl[0] && !branch_ctrl[0])
begin
if(buffer_bit==0)
begin
to_if1<=ilb[511-(count1*32)];
to_if2<=ilb[511-((count1+1)*32)];
count1<=count1+1;
end
else
begin
to_if1<=ilb1[511-(count2*32)];
to_if2<=ilb1[511-((count2+1)*32)];
count2<=count2+1;
end
end
else if (branch_ctrl[0])
begin
flush_ctrl<=1; // to flush the 3 buffer.
// flush self.
end
else if(dec_ctrl)
begin
if(buffer_bit==0)
count1<=count1-1;
else
count2<=count2-1;
//to_if1= opcode-nop;
//to_if2= opcode-nop;
end
else if(hmic_ctrl[0])
begin
for (i=0;i<=a;i=i+1)
begin
//to_if1= opcode-nop;
//to_if2= opcode-nop;
end
end
end
endmodule
Second Module:
module program_counter (
input wire clk, reset, mux_select,
input wire [12:0] offset,
output reg [12:0] pc1
); //mux_select-> 1 bit
// offset is obtained from branch.
always # (posedge clk)
if (!reset)
begin
if (!mux_select)
pc1<= pc1+8;
else
pc1<=pc1+offset;
end
else
pc1<=0;
endmodule
I am getting te following error:
Error: C:/Modeltech_pe_edu_10.0/examples/COMP ARC/inst_line_buf.v(66): Undefined variable: program_counter.
Error: C:/Modeltech_pe_edu_10.0/examples/COMP ARC/inst_line_buf.v(66): near "pctr": syntax error, unexpected IDENTIFIER
Error: C:/Modeltech_pe_edu_10.0/examples/COMP ARC/inst_line_buf.v(68): near "(": syntax error, unexpected '('
You've a few things mis-declared:
Slices of buses should use [], not (). For example, try branch_ctrl[13:1] instead of branch_ctrl(13:1)
Your offset port needs a size
Use nonblocking assignments for sequential logic
You can save typing by using verilog-2001 style port declarations
Here's an edited version of your code. It will compile, but I've a feeling it won't work properly as I don't have the full version of your toplevel module:
module inst_line_buf (
input wire from_LS,clk,fetch_ctrl,dec_ctrl,
hmic_ctrl,to_if1,to_if2,flush_ctrl,
input wire [13:0] branch_ctrl,
output wire [12:0] pc
);
program_counter pctr (
.clk(clk),
.reset(0),
.offset(branch_ctrl[13:1]),
.mux_select(branch_ctrl[0]),
.pc1(pc)
);
endmodule
module program_counter (
input wire clk, reset, mux_select,
input wire [12:0] offset,
output reg [12:0] pc1
);
always # (posedge clk)
if (!reset)
begin
if (!mux_select)
pc1 <= pc1+8;
else
pc1 <= pc1+offset;
end
else
pc1 <= 0;
endmodule
Also, make sure your module instantiation is outside any initial or always blocks.

Resources