Write to a reg's bitfields via alias names in Verilog - verilog

I have a register:
reg [7:0] dout; //output of memory bus
Groups of bits in dout represent something meaningful like:
dout[2:0] is a state
dout[3] is a flag
dout[7:4] is some data
I want to read and write to this register dout from inside an always statement. I want to address it using these labels.
This example conveys my attempt:
reg [7:0] dout; //output of memory bus
wire [2:0] dout_state;
wire dout_flag;
wire [3:0] dout_data;
//alias labels
assign dout_state[2:0] = dout[2:0];
assign dout_flag = dout[3];
assign dout_data = dout[7:4];
always(#posedge clk) begin
dout_state <= 3'b1;
dout_flag <= 1'b1;
end
The procedural assignments fail because dout_state and dout_flag are wires.
I want these labels to work as aliases that represent portions of the dout bus.
How can I achieve this?

The always block already drives dout_state and dout_flag signals, so the other assignments should be reversed. Your current code never drives dout.
//alias labels
assign dout[2:0] = dout_state;
assign dout[3] = dout_flag;
assign dout[7:4] = dout_data;
Now the signal definitions also should be updated. If dout is a port, the reg definition should be removed. If not, it should be a wire.
wire [7:0] dout; //output of memory bus
Because of the always block, dout_state and dout_flag signals should be reg.
reg [2:0] dout_state;
reg dout_flag;

Related

How to switch modules in verilog?

I want to use SW[15] to switch between module A_7seg and B_7seg but it does not work. (2 modules work separately)
module mix(input CLOCK,input [15:0]SW,output reg [15:0] led,output [3:0] an,output reg[7:0] seg);
generate
case(SW[15])
1'b0:A_7seg (.CLOCK(CLOCK),.an(an),.seg(seg));
1'b1:B_7seg (.CLOCK(CLOCK),.SW(SW),.led(led),.an(an),.seg(seg));
endcase
endgenerate
endmodule
Since '2 modules work separately', the simple way is to use SW[15] to select between 2 modules' outputs.
module mix(
input CLOCK,
input [15:0] SW,
output reg [15:0] led,
output reg [3:0] an,
output reg [7:0] seg
);
wire [15:0] B_led;
wire [3:0] A_an, B_an;
wire [7:0] A_seg, B_seg;
// if not using 'generate' block, modules are instantiated at
// the top level, not in other 'if'/'case'/... structures.
// and name the 2 instantiations
A_7seg u_A_7seg (.CLOCK(CLOCK), .an(A_an), .seg(A_seg));
B_7seg u_B_7seg (.CLOCK(CLOCK), .SW(SW), .led(B_led), .an(B_an), .seg(B_seg));
// this extra circuit is needed to select between the two
always#(*)begin
if(SW[15])begin
led = B_led;
an = B_an;
seg = B_seg;
end
else begin
led = 16'h0; // <-- I assume the inactive value for 'led' is all-zero
an = A_an;
seg = A_seg;
end
end
endmodule
You may also want to use SW[15] to gate the inputs to the one that is not currently working to reduce power consumption.
You need to figure out the schematic before you understand how to write the code.

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.

How to store input into reg from wire in verilog?

I' trying to store value from wire named 'in' into reg 'a'.
But, the problem is value of reg 'a' is showing 'xxxx' in simulator. However, value of wire 'in' is showing correctly.
My target is just to read value from input wire and store it into a register.
module test(
input [3:0] in,
output [3:0] out
);
reg [3:0] a;
initial
begin
a = in;
end
endmodule
The reason why the value of a is 'xxxx' in the simulation is probably that a is set to the value of in only a single time initially, and a may not yet have been set to any specific value at this time in the simulation.
Declaring a reg in Verilog does not necessarily mean that a hardware register is described by the code. That usually involves the use of a clock signal:
module test(
input clk,
input [3:0] in,
output [3:0] out
);
// this describes a register with input "in" and output "a"
reg [3:0] a;
always #(posedge clk) begin
a <= in;
end
// I assume you want "a" to be the output of the module
assign out = a;
endmodule
Here is a counter example where a reg is used to describe something which is not a register, but only a simple wire:
module not_a_register(
input in,
output out
);
reg a;
always #(in) begin
a <= in;
end
assign out = a;
endmodule
Also note that I have used the non-blocking assignment operator <= inside the always block, which is good practice when describing synchronous logic. You can read more about it here.

Accessing instance of one module from inside of several other modules? (verilog)

I am writing a simple system in which there is a memory module (simple reg with a read and write signals). Now this memory has to be accessed by several other modules (not simultaneously). So I create an instance of this memory and feed data to it. But I can't figure out how will my other modules access the same instance of the memory module. Any help?
Edit
Let me clarify a bit by some code. This is my memory module, simple signals.
module rom(
input [15:0] addr,
input [15:0] data_in,
input rd,
input wr,
input cs,
output reg [15:0] data_out
);
reg [15:0] mem[255:0];
integer k;
initial begin
for(k = 0;k<256;k=k+2)
mem[k] = 16'h0011;
for(k = 1;k<256;k=k+2)
mem[k] = 16'h0101;
end
always #(cs)begin
if(wr)
mem[addr] <= data_in;
if(rd)
data_out <= mem[addr];
end
endmodule
This will be instantiated in my top module, something like this
module Top;
// Inputs
reg [15:0] addr;
reg [15:0] data_in;
reg rd;
reg wr;
reg cs;
// Outputs
wire [15:0] data_out;
// Instantiate the Unit Under Test (UUT)
rom uut (
.addr(addr),
.data_in(data_in),
.rd(rd),
.wr(wr),
.cs(cs),
.data_out(data_out)
);
....
....
....
endmodule
Now this top module will also contain some other modules which would want to connect to memory. I don't really understand how I would connect them. Suppose there is one module like this
module IF_stage(
input clk,
input rst,
output reg [15:0] pc,
output [15:0] instruction
);
//pc control
always#(posedge clk or posedge rst)
begin
if(rst)
pc <= 16'hFFFF;
else
pc <= pc+1;
end
....
How would I access the memory module from here?
Answering your comment, you don't instance the memory more than once. You create one instance of the memory at some level of the hierarchy, and then connect all the consumers to it via ports/wires. So in the top level you might have 3 modules that want to access memory, and 1 memory module. The three accessors each connect to the single instance, they don't instance their own memory.
The memory should be parallel to the other modules, not inside of them, if that makes sense.
You need to modify IF_stage to add an interface that can communicate with the memory, something like this:
module IF_stage(
input clk,
input rst,
input [15:0] read_data_from_memory, //new
input read_data_from_memory_valid, //new
output reg [15:0] pc,
output [15:0] instruction
output do_memory_write //new
output do_memory_read //new
output [15:0] memory_write_data //new
output [15:0] addr //new
);
Then when an IF_stage wants to read or write memory, it puts addr/data on it's output port to issue command to the memory module, and then waits for read_data_from_memory(_valid) to be asserted on it's input port. These outputs and inputs get connected to the memory module at the top level.
You'll also have to deal with bus contention here, for instance if two instances of IF_stage try to read/write at the same time, you'll need some kind of arbiter module to acknowledge both requests, and then forward them one at a time to the memory, and return the valid data to the proper module.
First of all, the name of your memory is "rom", which is read only. I assume it is a typo, otherwise there is no need to have wr port and you can simply implement separate roms in clients and let synthesizer to optimize the design.
For your question, basically you need an arbiter to handle the contention between multiple clients. All clients can assume they occupy the memory exclusively but the memory is shared by all clients and cannot be accessed simultaneously.
Tim is right about the IF_stage. Every client must have a separate memory interface
output [15:0] addr;
output [15:0] data_out;
input [15:0] data_in;
output wr, rd, cs;
input rdy; // only when rdy == 1, the memory operation is finished
You will need a memory controller/arbiter, which behaves as a memory to all clients but actually handle the contention among clients. Assuming there are three clients and all clients access the memory less than once per three cycles, you can simply have something as follow:
module mem_ctl(
addr_c1, dw_c1, dr_c1, wr_c1, rd_c1, cs_c1,
addr_c2, dw_c2, dr_c2, wr_c2, rd_c2, cs_c2,
addr_c3, dw_c3, dr_c3, wr_c3, rd_c3, cs_c3,
addr_m, dw_m, dr_m, wr_m, rd_m, cs_m,
rdy_c1, rdy_c2, rdy_c3,
rst_n, clk
);
input clk, rst_n;
input [15:0] addr_c1, addr_c2, addr_c3, dw_c1, dw_c2, dw_c3; // addr and data_write from clients
output [15:0] dr_c1, dr_c2, dr_c3; // data read from clients
input wr_c1, wr_c2, wr_c3, rd_c1, rd_c2, rd_c3, cs_c1, cs_c2, cs_c3; // control from clients
output [15:0] addr_m, dw_m; // addr and data write to memory
input [15:0] dr_m;
output wr_m, rd_m, cs_m; // control the memory
output rdy_c1, rdy_c2, rdy_c3;
reg [15:0] dr_c1, dr_c2, dr_c3, dw_m, addr_m;
reg wr_m, rd_m, cs_m;
reg [1:0] cnt;
always #(posedge clk or negedge rst_n)
if (~rst_n)
cnt <= 0;
else if(cnt == 2'd2)
cnt <= 0;
else
cnt <= cnt + 1;
always #(*) // Verilog 2001, if not recognizable, fill in yourself
begin
case(cnt)
0: begin
dw_m = dw_c1;
wr_m = wr_c1;
cs_m = cs_c1;
rd_m = rd_c1;
dr_c1 = dr_m;
end
1: begin
dw_m = dw_c2;
wr_m = wr_c2;
cs_m = cs_c2;
rd_m = rd_c2;
dr_c2 = dr_m;
end
default: begin
dw_m = dw_c3;
wr_m = wr_c3;
cs_m = cs_c3;
rd_m = rd_c3;
dr_c3 = dr_m;
end
endcase
end
assign rdy_c1 = (cnt == 0) & cs_c1;
assign rdy_c2 = (cnt == 1) & cs_c2;
assign rdy_c3 = (cnt == 2) & cs_c3;
endmodule
However, this is only OK when the access rates of all clients are lower than once per three cycles. If the access rate is variant and higher than that, you will need a real arbiter in the mem_ctl module. I think a round-robin arbiter will be fine.
The final comment, if the accumulative access rates of all clients is larger than once per cycle, it is impossible to handle in hardware. In that case, you will need to do it in other ways.

Assign a synthesizable initial value to a reg in Verilog

I'm an FPGA noob trying to learn Verilog. How can I "assign" a value to a reg in an always block, either as an initial value, or as a constant. I'm trying to do something like this in the code below. I get an error because the 8 bit constant doesn't count as input. I also don't want to trigger the always off of a clock. I just want to assign a register to a specific value. As I want it to be synthesisable I can't use an initial block. Thanks a lot.
module top
(
input wire clk,
output wire [7:0] led
);
reg [7:0] data_reg ;
always #*
begin
data_reg = 8'b10101011;
end
assign led = data_reg;
endmodule
You can combine the register declaration with initialization.
reg [7:0] data_reg = 8'b10101011;
Or you can use an initial block
reg [7:0] data_reg;
initial data_reg = 8'b10101011;
You should use what your FPGA documentation recommends. There is no portable way to initialize register values other than using a reset net. This has a hardware cost associated with it on most synthesis targets.
The other answers are all good. For Xilinx FPGA designs, it is best not to use global reset lines, and use initial blocks for reset conditions for most logic. Here is the white paper from Ken Chapman (Xilinx FPGA guru)
http://japan.xilinx.com/support/documentation/white_papers/wp272.pdf
The always #* would never trigger as no Right hand arguments change. Why not use a wire with assign?
module top (
input wire clk,
output wire [7:0] led
);
wire [7:0] data_reg ;
assign data_reg = 8'b10101011;
assign led = data_reg;
endmodule
If you actually want a flop where you can change the value, the default would be in the reset clause.
module top
(
input clk,
input rst_n,
input [7:0] data,
output [7:0] led
);
reg [7:0] data_reg ;
always #(posedge clk or negedge rst_n) begin
if (!rst_n)
data_reg <= 8'b10101011;
else
data_reg <= data ;
end
assign led = data_reg;
endmodule
Hope this helps
When a chip gets power all of it's registers contain random values. It's not possible to have an an initial value. It will always be random.
This is why we have reset signals, to reset registers to a known value. The reset is controlled by something off chip, and we write our code to use it.
always #(posedge clk) begin
if (reset == 1) begin // For an active high reset
data_reg = 8'b10101011;
end else begin
data_reg = next_data_reg;
end
end

Resources