Weird behavior of registers on Quartus II using Verilog - verilog

I'm creating my own processor based on MIPS32 using the Quartus II and Verilog. Everything was working fine until suddenly my Registers stopped working (I don't remember making any modifications to the code). I probably made some mistake but I can't seem to find it.
I've already tried using an older version of the code (that was 100% working) but the error persists, even when I'm testing the registers isolated from the rest of the system. I've also tried deleting Quartus' temporary files and recompiling with no success.
module RegFile
(
output [31:0] Debug2, //Outputs Reg 2
output [31:0] Debug3, //Outputs Reg 3
input Reset, //Makes sure Reg 0 is always 0
input Slow_Clock, //Write Clock
input Fast_Clock, //Read Clock
input Reg_Write, //Write to Reg Flag
input [31:0] Write_Data, //Data that will be written in the Reg selected by Reg_WR
input [5:0] Reg_1, //First Register Selection (Read)
input [5:0] Reg_2, //Second Register Selection (Read)
input [5:0] Reg_WR, //Third Register Selection (Read or Write)
output reg [31:0] Data_1, //Data that will outputted by the Reg selected by Reg_1
output reg [31:0] Data_2, //Data that will outputted by the Reg selected by Reg_2
output reg [31:0] Data_3 //Data that will outputted by the Reg selected by Reg_WR
);
reg [31:0] DataReg[63:0]; //64x 32bit Register
assign Debug2 = DataReg[2]; //Hardwired Reg2 (for testing)
assign Debug3 = DataReg[3]; //Hardwired Reg3 (for testing)
always # (posedge Fast_Clock) //Reads from Registers at posedge Read Clock
begin
Data_1 <= DataReg[Reg_1];
Data_2 <= DataReg[Reg_2];
Data_3 <= DataReg[Reg_WR];
end
always # (negedge Slow_Clock) //Writes on Registers at negedge Write Clock
begin
if (Reset)
begin
DataReg[0] <= 32'b00000000_00000000_00000000_00000000; //Forces Reg0 to be 0 when Reset is activated
end
else if (Reg_Write && (Reg_WR != 0)) //If you are writing to some register and this register isn't Reg0...
begin
DataReg[Reg_WR] <= Write_Data; //...write to the register selected by Reg_WR
end
end
endmodule
I expect the ending result to be the number 3 on register 2 and the number 4 on register 3 but, as you can see, register 2 ends with the number 4 and the register 3 ends with the number 0.

I figured it out.
There was an inconsistency when writing and loading the new values in the next clock.
I fixed it by creating two aux. variables that hold Write_Data and Reg_WR until right before writing and updating the values. I used a faster clock to be able to keep these aux. variables updated.
This is the solution I found:
module RegFile
(
//output [31:0] Debug2, //Outputs Reg 2
output [31:0] Debug3, //Outputs Reg 3
input Reset, //Makes sure Reg 0 is always 0
input Slow_Clock, //Write Clock
input Fast_Clock,
input Reg_Write, //Write to Reg Flag
input [31:0] Write_Data, //Data that will be written in the Reg selected by Reg_WR
input [5:0] Reg_1, //First Register Selection (Read)
input [5:0] Reg_2, //Second Register Selection (Read)
input [5:0] Reg_WR, //Third Register Selection (Read or Write)
output [31:0] Data_1, //Data that will outputted by the Reg selected by Reg_1
output [31:0] Data_2, //Data that will outputted by the Reg selected by Reg_2
output [31:0] Data_3 //Data that will outputted by the Reg selected by Reg_WR
);
reg [31:0] RegBank[63:0];
reg [31:0] Aux_WD;
reg [5:0] Aux_Reg;
assign Data_1 = RegBank[Reg_1];
assign Data_2 = RegBank[Reg_2];
assign Data_3 = RegBank[Reg_WR];
//assign Debug2 = RegBank[2];
assign Debug3 = RegBank[3];
always # (negedge Fast_Clock)
begin
Aux_WD <= Write_Data;
Aux_Reg <= Reg_WR;
end
always # (negedge Slow_Clock)
begin
if (Reset)
begin
RegBank[0] <= {32{1'b0}};
end
else if (Reg_Write && (Aux_Reg != 6'b000000))
begin
RegBank[Aux_Reg] <= Aux_WD;
end
end
endmodule

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.

Error: Inconsistent with 'net' object

I'm getting this error when I'm trying to simulate my testbench on ModelSim. I'm just in the early stage of the testbench, and I'm just adding some values to a variable when this error appears.
I have instantiated the topmodule and created the DUT for it in the testbench. Using the instance I'm going in the hierarchy where I get my desired variable that I want to assign a value.
I have googled for an answer to this question and the only thing I have found is that I cannot make a procedural assignment to a wire. The thing is that that the variable in question is an input, not a wire.
The project I'm working on is based on the openRISC 1200 architecture. I could not find any testbench that worked properly, that's why I'm trying to write my own.
Below is the testbench code:
module testbenchOR (
);
reg cmd;
reg rst;
reg clk;
//----------------------TOP-LEVEL--------------------------------------
wire iwb_cyc_o; // cycle valid output
wire [31:0] iwb_adr_o; // address bus outputs
wire iwb_stb_o; // strobe output
wire iwb_we_o; // indicates write transfer
wire [3:0] iwb_sel_o; // byte select outputs
wire [31:0] iwb_dat_o; // output data bus
wire dwb_cyc_o; // cycle valid output
wire [31:0] dwb_adr_o; // address bus outputs
wire dwb_stb_o; // strobe output
wire dwb_we_o; // indicates write transfer
wire [3:0] dwb_sel_o; // byte select outputs
wire [31:0] dwb_dat_o; // output data bus
wire [3:0] dbg_lss_o; // External Load/Store Unit Status
wire [1:0] dbg_is_o; // External Insn Fetch Status
wire [10:0] dbg_wp_o; // Watchpoints Outputs
wire dbg_bp_o; // Breakpoint Output
wire [31:0] dbg_dat_o; // External Data Output
wire dbg_ack_o; // External Data Acknowledge (not WB compatible)
wire [3:0] pm_clksd_o;
wire pm_dc_gate_o;
wire pm_ic_gate_o;
wire pm_dmmu_gate_o;
wire pm_immu_gate_o;
wire pm_tt_gate_o;
wire pm_cpu_gate_o;
wire pm_wakeup_o;
wire pm_lvolt_o;
reg clk_i;
reg rst_i;
reg [1:0] clmode_i; // 00 WB=RISC, 01 WB=RISC/2, 10 N/A, 11 WB=RISC/4
reg [19:0] pic_ints_i;
reg iwb_clk_i; // clock input
reg iwb_rst_i; // reset input
reg iwb_ack_i; // normal termination
reg iwb_err_i; // termination w/ error
reg iwb_rty_i; // termination w/ retry
reg [31:0] iwb_dat_i; // input data bus
reg dwb_clk_i; // clock input
reg dwb_rst_i; // reset input
reg dwb_ack_i; // normal termination
reg dwb_err_i; // termination w/ error
reg dwb_rty_i; // termination w/ retry
reg [31:0] dwb_dat_i; // input data bus
reg dbg_stall_i; // External Stall Input
reg dbg_ewt_i; // External Watchpoint Trigger Input
reg dbg_stb_i; // External Address/Data Strobe
reg dbg_we_i; // External Write Enable
reg [31:0] dbg_adr_i; // External Address Input
reg [31:0] dbg_dat_i; // External Data Input
reg pm_cpustall_i;
or1200_top TOP_LEVEL(
.iwb_cyc_o(iwb_cyc_o),
.iwb_adr_o(iwb_adr_o),
.iwb_stb_o(iwb_stb_o),
.iwb_we_o(iwb_we_o),
.iwb_sel_o(iwb_sel_o),
.iwb_dat_o(iwb_dat_o),
.dwb_cyc_o(dwb_cyc_o),
.dwb_adr_o(dwb_adr_o),
.dwb_stb_o(dwb_stb_o),
.dwb_we_o(dwb_we_o),
.dwb_sel_o(dwb_sel_o),
.dwb_dat_o(dwb_dat_o),
.dbg_lss_o(dbg_lss_o),
.dbg_is_o(dbg_is_o),
.dbg_wp_o(dbg_wp_o),
.dbg_bp_o(dbg_bp_o),
.dbg_dat_o(dbg_dat_o),
.dbg_ack_o(dbg_ack_o),
.pm_clksd_o(pm_clksd_o),
.pm_dc_gate_o(pm_dc_gate_o),
.pm_ic_gate_o(pm_ic_gate_o),
.pm_dmmu_gate_o(pm_dmmu_gate_o),
.pm_immu_gate_o(pm_immu_gate_o),
.pm_tt_gate_o(pm_tt_gate_o),
.pm_cpu_gate_o(pm_cpu_gate_o),
.pm_wakeup_o(pm_wakeup_o),
.pm_lvolt_o(pm_lvolt_o),
.clk_i(clk_i),
.rst_i(rst_i),
.clmode_i(clmode_i),
.pic_ints_i(pic_ints_i),
.iwb_clk_i(iwb_clk_i),
.iwb_rst_i(iwb_rst_i),
.iwb_ack_i(iwb_ack_i),
.iwb_err_i(iwb_err_i),
.iwb_rty_i(iwb_rty_i),
.iwb_dat_i(iwb_dat_i),
.dwb_clk_i(dwb_clk_i),
.dwb_rst_i(dwb_rst_i),
.dwb_ack_i(dwb_ack_i),
.dwb_err_i(dwb_err_i),
.dwb_rty_i(dwb_rty_i),
.dwb_dat_i(dwb_dat_i),
.dbg_stall_i(dbg_stall_i),
.dbg_ewt_i(dbg_ewt_i),
.dbg_stb_i(dbg_stb_i),
.dbg_we_i(dbg_we_i),
.dbg_adr_i(dbg_adr_i),
.dbg_dat_i(dbg_dat_i),
.pm_cpustall_i(pm_cpustall_i)
);
initial begin
$display (" --- Start --- ");
clk =0;
rst <= 1;
repeat (1) # (posedge clk);
rst <= 0;
cmd <= 0;
repeat (10) # (posedge clk);
cmd <= 1;
repeat (10) # (posedge clk);
end
// Clock generator
always #10 clk = ~clk;
initial begin
#(posedge clk)
TOP_LEVEL.or1200_cpu.or1200_rf.rf_a.ce_w = 1'b0; //Chip enable input
end
endmodule
The error is as follows:
This or another usage of 'TOP_LEVEL.or1200_cpu.or1200_rf.rf_a.ce_w'
inconsistent with 'net' object.
UPDATE:
The error can be removed by doing the following:
initial begin
#(posedge clk)
force TOP_LEVEL.or1200_cpu.or1200_rf.rf_a.ce_w = 1'b0; //Chip enable input
#500
release TOP_LEVEL.or1200_cpu.or1200_rf.rf_a.ce_w;
end
You may need to use force for an input/wire:
initial begin
#(posedge clk)
force TOP_LEVEL.or1200_cpu.or1200_rf.rf_a.ce_w = 1'b0; //Chip enable input
end
Keep in mind that force will hold that value until you release the signal. Refer to IEEE Std 1800-2012, section "10.6.2 The force and release procedural statements". Also keep in mind that force/release should be used sparingly.

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

verilog- assign statement reg to output variable not being assigned

I am attempting to use an FPGA as a shift register to some LEDs with pwm, but ran into an error while trying to assign a reg containing the value shifted in to an output variable. When I upload it to the FPGA(i'm using the mojo by embedded micro), it does nothing. when I use the simulator, it reports that all of the output variables are never assigned and have the value of X, while all the other variables inside of the module work just fine. here is my code for the shifting module:
module shifting(
input clk,
input shiftingpin,//data to be shifted in
input rst,
output done,
output [3:0]data//pwm compare value output
);
reg [2: 0] ctr_d, ctr_q;
reg don;
reg [3:0]datas;
always #(*) begin
if(ctr_q == 3'b100) begin
ctr_d[2:0] = 3'b0;
don = 1'b1;
end else begin
ctr_d = ctr_q + 1'b1;
don = 1'b0;
end
end
always #(posedge clk) begin
datas[ctr_q] = shiftingpin;// assign value to the output
if (rst) begin
ctr_q <= 1'b0;
end else begin
ctr_q <= ctr_d;
end
end
assign data = datas;
assign done = don;
endmodule
done tells the containing module when to update and assign the value to pwm.
If I understood the question correctly you have a syntax error when trying to drive ports from within always blocks.
When declaring ports they are typically wire by default which can only be driven by ports or assign. Resulting in the code below
module shifting(
input clk,
input shiftingpin,
input rst,
output done,
output [3:0] data
);
reg don;
reg [3:0] datas;
assign done = don;
assign data = datas;
Solution
The solution is to define ports as reg, logic is preferred if you can support System Verilog.
logic will effectively switch between wire and reg as required to make refactoring code easier.
module shifting(
input clk,
input shiftingpin,
input rst,
output reg done,
output reg [3:0] data
);
always #(posedge clk) begin
data[ctr_q] <= shiftingpin; // <-- data port used directly
//...
NB: shift registers can be done with just
always #(posedge clk) begin
datas[3:0] <= {datas[2:0], shiftingpin};

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.

Resources