My current task is to create a memory driver. The specific issue is that I have a shift register designed to concatenate four 8-bit words into one 32-bit and then send that to the output. The module works when being simulated by itself but it fails to respond when connected to other modules. Here's the code :
The shift register code :
module shiftReg (
data_8,
clk,
valid1,
rstn,
data_32,
valid_fifo,
count,
REGA,
REGB,
REGC,
REGD
);
input wire [7:0] data_8;
input wire valid1;
input wire clk;
input wire rstn;
output reg [31:0] data_32;
output reg valid_fifo;
output reg [3:0] count;
output reg [7:0] REGA;
output reg [7:0] REGB;
output reg [7:0] REGC;
output reg [7:0] REGD;
initial
begin
count <= 4'b0001;
REGA <= 8'b0;
REGB <= 8'b0;
REGC <= 8'b0;
REGD <= 8'b0;
valid_fifo <= 1'b0;
end
always #(posedge valid1)
begin
if(~rstn)
begin
count = 4'b0001;
REGA = 0;
REGB = 0;
REGC = 0;
REGD = 0;
end
else if(valid1 == 1'b1)
begin
case (count)
4'b0001: REGA = data_8;
4'b0010: REGB = data_8;
4'b0100: REGC = data_8;
4'b1000: REGD = data_8;
endcase
valid_fifo = 1'b0;
end
if(count == 4'b1000)
begin
data_32 = {REGD,REGC,REGB,REGA};
valid_fifo = 1'b1;
count = 4'b0001;
end
else
begin
count = count << 1;
end
end
endmodule
The module where I am instantiating it is called altogether.
Here is the code :
module altogether (
input wire BUTTON_AT,
input wire CLK_AT,
input wire RSTN_AT,
output wire MEM_FULL_AT,
output wire EMPTY_AT,
inout wire VALID_IN_AT,
inout wire [7:0] DATA_8_AT,
inout wire VALID1_AT,
inout wire [31:0] DATA_32_AT,
inout wire STOP_AT,
inout wire VALID_FIFO_AT,
inout wire [31:0] DATA_AT,
inout wire WR_AT,
inout wire [6:0] ADDR_AT,
output wire [7:0] REG_A_AT,
output wire [7:0] REG_B_AT,
output wire [7:0] REG_C_AT,
output wire [7:0] REG_D_AT,
output wire [3:0] COUNT_AT
);
shiftReg shift_register (
.data_8(DATA_8_AT),
.clk(CLK_AT),
.valid1(VALID_1_AT),
.rstn(RSTN_AT),
.data_32(DATA_32_AT),
.valid_fifo(VALID_FIFO_AT),
.REGA(REG_A_AT),
.REGB(REG_B_AT),
.REGC(REG_C_AT),
.REGD(REG_D_AT),
.count(COUNT_AT)
);
For some reason, the valid == 1'b1 condition is not executed when I put the shift register along with everything else. I have really run out of ideas, hope someone manages to look at it and give me an insight.
Somewhere during synthesis you probably got warning that you're using VALID_1_AT signal, which has no driver. That's because in altogether module declaration you define VALID1_AT signal (notice _ missing in signal name). That's why valid1 in your shift register is not driven at all.
You should change:
.valid1(VALID_1_AT)
into:
.valid1(VALID1_AT)
to make it works.
Related
Closed. This question needs debugging details. It is not currently accepting answers.
Edit the question to include desired behavior, a specific problem or error, and the shortest code necessary to reproduce the problem. This will help others answer the question.
Closed yesterday.
Improve this question
i tried to do it in two ways, and each time i got stuck by the same problem Error (10031): Net "copy_data_in[183]" at RotateText.sv(16) is already driven by input port "data_in[183]", and cannot be driven by another signal.
Hi , i have input of 23 elements that each one is 8 bits.i have output of 6 elements that each one is 8 bits.The input should get change each time. in the end it should be like circular printing. Excuse me but ENABLE should be CLK.
i tried to do it in two ways, and each time i got stuck by the same problem Error (10031): Net "copy_data_in[183]" at RotateText.sv(16) is already driven by input port "data_in[183]", and cannot be driven by another signal.
This first try :
module RotateText( data_in,HEX0S,HEX1S,HEX2S,HEX3S,HEX4S,HEX5S,ENABLE);
input [7:0] data_in [22:0];
input ENABLE;
output reg [7:0] HEX0S;
output reg [7:0] HEX1S;
output reg [7:0] HEX2S;
output reg [7:0] HEX3S;
output reg [7:0] HEX4S;
output reg [7:0] HEX5S;
reg [7:0] tmp;
reg [7:0] copy_data_in [22:0];
reg [7:0] tmp2;
integer i;
integer j=0;
always#(posedge ENABLE)begin
if(j==0)begin
for(i = 0; i < 23; i=i+1) begin
copy_data_in[i] <= data_in[i];
end
end
HEX5S<=copy_data_in[22];
HEX4S<=copy_data_in[21];
HEX3S<=copy_data_in[20];
HEX2S<=copy_data_in[19];
HEX1S<=copy_data_in[18];
HEX0S<=copy_data_in[17];
tmp<= copy_data_in[22];
copy_data_in[22:1]<=copy_data_in[21:0];
copy_data_in[0]<=tmp;
j=j+1;
end
endmodule
This is another approch :
module RotateText( data_in,HEX0S,HEX1S,HEX2S,HEX3S,HEX4S,HEX5S,ENABLE);
input [183:0] data_in ;
input ENABLE;
output reg [7:0] HEX0S;
output reg [7:0] HEX1S;
output reg [7:0] HEX2S;
output reg [7:0] HEX3S;
output reg [7:0] HEX4S;
output reg [7:0] HEX5S;
reg [7:0] tmp;
reg [183:0] copy_data_in;
integer i;
integer j=0;
integer index;
assign copy_data_in=data_in;
always#(posedge ENABLE)begin
HEX5S<=copy_data_in[183:176];
HEX4S<=copy_data_in[175:168];
HEX3S<=copy_data_in[167:160];
HEX2S<=copy_data_in[159:152];
HEX1S<=copy_data_in[151:144];
HEX0S<=copy_data_in[143:136];
tmp<=data_in[183:176];
copy_data_in<=copy_data_in<<8;
copy_data_in[7:0]<=tmp;
end
endmodule
glad to get help .
The post has a circular shift register (sr).
An sr accepts input from the previous stage or from a module input for loading; not both at the same time. Loading & shifting are mutually exclusive behaviors in the same clock clock cycle. The design needs a input control signal to decide load or shift.
The posted code errors out, because its trying to drive the sr internally, and from inputs at the same time.
Here is a solution based on the posted code.
Variable load_shiftn determines load or shift .
module rot(
input logic clk,
input [7:0] data_in [22:0],
input logic load_shiftn,
output reg [7:0] HEX0S,
output reg [7:0] HEX1S,
output reg [7:0] HEX2S,
output reg [7:0] HEX3S,
output reg [7:0] HEX4S,
output reg [7:0] HEX5S
);
// internal
reg [7:0] sr [22:0];
always#(posedge clk)begin
if(load_shiftn)
sr <= data_in;
else begin
sr[22:1] <= sr[21:0];
sr[0] <= sr[22];
end
end
always # * begin
HEX5S =sr[22];
HEX4S =sr[21];
HEX3S =sr[20];
HEX2S =sr[19];
HEX1S =sr[18];
HEX0S =sr[17];
end
endmodule
Testbench
module tb ();
bit clk;
logic [7:0] data_in [22:0];
bit load_shiftn;
logic [7:0] HEX0S;
logic [7:0] HEX1S;
logic [7:0] HEX2S;
logic [7:0] HEX3S;
logic [7:0] HEX4S;
logic [7:0] HEX5S;
always #5 clk = !clk;
initial begin
#270;
$finish;
end
rot u1 (.*);
initial begin
$dumpfile("dump.vcd");
$dumpvars;
end
initial begin
foreach(data_in[i])
data_in[i] = i;
end
initial begin
#(posedge clk)
load_shiftn <= 1;
repeat(2) #(posedge clk);
load_shiftn <= 0;
end
endmodule
Waves
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
I have created the following module for Data_Mem:
module Data_Mem(
input clk,
input memWrite,
input [5:0] addr,
input [31:0] writeData,
output [31:0] readData
);
reg [31:0] readData;
reg [31:0] addrSpace [0:63];
integer i;
initial begin
for (i=0;i<64;i=i+1)
addrSpace[i] = 0;
end
always # (*) begin
if (memWrite == 1)
begin
addrSpace[addr] <= writeData;
end
readData <= addrSpace[addr];
end
endmodule
Now, I have written the following testbench to see if I can get values to stay in a specified location or address. The testbench is as follows:
reg [5:0] addr;
reg [31:0] writeData;
reg memWrite, clk;
wire [31:0] readData;
//
Data_Mem datamem_testUnit1(.clk(clk), .memWrite(memWrite), .writeData(writeData), .readData(readData));
initial
begin
#10 a = 6'b001111; writeData = 32'h000A; memWrite = 0;
#10 a = 6'b000001; writeData = 32'h000C; memWrite = 1;
#10 a = 6'b000001;
#10 $finish;
end
endmodule
For the simulation results, I see that its taking in my desired values just fine, but dataRead is just XXXX for the whole time. I have included a second addr 00011 as to see whether this result is because of any sort of overlap while writing, but I do not see the desired "000C" for readData even when the addr is still declared as 000001. Please help!
I have included a screenshot of my simulation results.
It looks like you simply forgot to connect the addr signal in your testbench to the addr port of your Data_Mem module. Try
Data_Mem datamem_testUnit1(.clk(clk), .memWrite(memWrite), .addr(addr), .writeData(writeData), .readData(readData));
Also, your always-block will infer latches. I think you probably want it to be clocked, like this:
always # (posedge clk) begin
This involves having to drive the clk port in your testbench, however.
I am trying to assign ADDR to pcOut but ADDR is showing up as xxxxxxxx in GTKWave.
Here is my code:
module processor (
input CLK,
// Memory
input [31:0] DATAOUT, // Memory data out
output [31:0] DATAIN, // Memory data in
output [31:0] ADDR, // Memory address
output WE // Memory write enable
);
wire [3:0] aluSel;
wire [4:0] regSel1, regSel2, regDataSel;
wire regLoad, aluEnable, pcLoad, pcNext;
wire [31:0] regDataIn, regDataOut1, regDataOut2, aluOut, pcOut, pcIn, aluA, aluB;
assign ADDR = pcOut;
controlUnit controlUnit (
.CLK(CLK), // Clock
// Outputs
.memDataOut(DATAOUT),
.regDataOut1(regDataOut1),
.regDataOut2(regDataOut2),
.aluOut(aluOut),
.pcOut(pcOut),
// Load and enable
.pcLoad(pcLoad),
.regLoad(regLoad),
.aluEnable(aluEnable),
.pcNext(pcNext),
// Selects
.aluSel(aluSel),
.regSel1(regSel1),
.regSel2(regSel2),
.regDataSel(regDataSel),
// Inputs
.pcIn(pcIn),
.regDataIn(regDataIn),
.aluA(aluA),
.aluB(aluB),
.memDataIn(DATAIN),
.memAddr(ADDR)
);
datapath datapath (
.pcNext(pcNext),
// Load and enable
.pcLoad(pcLoad),
.regLoad(regLoad),
.aluEnable(aluEnable),
// Selects
.aluSel(aluSel),
.regSel1(regSel1),
.regSel2(regSel2),
.regDataSel(regDataSel),
// Inputs
.regDataIn(regDataIn),
.pcIn(pcIn),
.aluA(aluA),
.aluB(aluB),
// Outputs
.regDataOut1(regDataOut1),
.regDataOut2(regDataOut2),
.aluOut(aluOut),
.pcOut(pcOut)
);
endmodule
Can anyone help?
Thanks in advance.
Edit:
pcOut is outputting the correct value but ADDR is not being set that same value.
Edit 2:
Here is the code for the controlUnit module:
module controlUnit (
input CLK,
input [31:0] memDataOut, regDataOut1, regDataOut2, aluOut, pcOut,
output reg [0:0] pcLoad, regLoad, aluEnable, pcNext,
output reg [3:0] aluSel,
output reg [4:0] regSel1, regSel2, regDataSel,
output reg [31:0] pcIn, regDataIn, aluA, aluB, memDataIn, memAddr
);
reg cycle = 0;
wire [10:0] opcode;
wire [4:0] rs1, rs2, rd;
decoder decoder (
.cycle(cycle),
.instruction(memDataOut),
.rs1(rs1),
.rs2(rs2),
.rd(rd),
.opcode(opcode)
);
always #(posedge CLK) begin
case (cycle)
1'b0: begin
regLoad <= 0;
aluEnable <= 0;
pcNext <= 0;
end
1'b1: begin
pcNext <= 1;
case (opcode)
11'b00000110011: begin // Add
regSel1 <= rs1;
regSel2 <= rs2;
regDataSel <= rd;
aluSel <= 0;
aluEnable <= 1;
regDataIn <= aluOut;
regLoad <= 1;
end
11'b10000110011: begin // Sub
end
endcase
end
endcase
cycle <= !cycle;
end
endmodule
Your controlUnit doesn't seem to have any logic attached to memAddr, but memAddr is still an output of controlUnit. At the top level, you port map ADDR to .memAddr, and you also assign ADDR = pcOut. You're trying to drive ADDR in two different locations.
I am new in Xilinx.
Here's my code,and i want to add clock in it.
Please tell me how to add clock. Thanks
code
module Traffic(
output reg red1,
output reg red2,
output reg red3,
output reg red4,
output reg yel1,
output reg yel2,
output reg yel3,
output reg yel4,
output reg gr1,
output reg gr2,
output reg gr3,
output reg gr4,
input [1:0] c1,
input [1:0] c2
);
always #(c1,c2,red1,red2,red3,red4,yel1,yel2,yel3,yel4,gr1,gr2,gr3,gr4)
begin
case({c1,c2})
4'b0000:begin red1=0;red2=1;red3=1;red4=0; yel1=1;yel2=0;yel3=0;yel4=1; gr1=0;gr2=0;gr3=0;gr4=0; end
4'b0001:begin red1=1;red2=1;red3=1;red4=0; yel1=0;yel2=0;yel3=0;yel4=0; gr1=0;gr2=0;gr3=0;gr4=1; end
4'b0010:begin red1=0;red2=1;red3=1;red4=0; yel1=1;yel2=1;yel3=0;yel4=0; gr1=0;gr2=0;gr3=0;gr4=0; end
4'b0011:begin red1=1;red2=1;red3=1;red4=1; yel1=0;yel2=0;yel3=0;yel4=0; gr1=0;gr2=1;gr3=0;gr4=0; end
4'b0100:begin red1=1;red2=0;red3=0;red4=1; yel1=0;yel2=1;yel3=1;yel4=0; gr1=0;gr2=0;gr3=0;gr4=0; end
4'b0101:begin red1=1;red2=1;red3=0;red4=1; yel1=0;yel2=0;yel3=0;yel4=0; gr1=0;gr2=0;gr3=1;gr4=0; end
4'b0110:begin red1=1;red2=1;red3=0;red4=0; yel1=0;yel2=0;yel3=1;yel4=1; gr1=0;gr2=0;gr3=0;gr4=0; end
4'b0111:begin red1=1;red2=1;red3=1;red4=0; yel1=0;yel2=0;yel3=0;yel4=0; gr1=0;gr2=0;gr3=0;gr4=1; end
endcase
end
endmodule
-------------
Text Fixture
-------------
module tf;
// Inputs
reg [1:0] c1;
reg [1:0] c2;
// Outputs
wire red1;
wire red2;
wire red3;
wire red4;
wire yel1;
wire yel2;
wire yel3;
wire yel4;
wire gr1;
wire gr2;
wire gr3;
wire gr4;
// Instantiate the Unit Under Test (UUT)
Traffic uut (
.red1(red1),
.red2(red2),
.red3(red3),
.red4(red4),
.yel1(yel1),
.yel2(yel2),
.yel3(yel3),
.yel4(yel4),
.gr1(gr1),
.gr2(gr2),
.gr3(gr3),
.gr4(gr4),
.c1(c1),
.c2(c2)
);
initial begin
c1 = 2'b00;c2 = 2'b00;
#100 c1 = 2'b00;c2 = 2'b01;
#100 c1 = 2'b00;c2 = 2'b10;
#100 c1 = 2'b00;c2 = 2'b11;
#100 c1 = 2'b01;c2 = 2'b00;
#100 c1 = 2'b01;c2 = 2'b01;
#100 c1 = 2'b01;c2 = 2'b10;
#100 c1 = 2'b01;c2 = 2'b11;
end
If I understand your question correctly, you would like the outputs of your module to be synchronous to a clock. you need to declare the clock as in input wire, and alter the always block to use the posedge clk. It's also good to add a reset -- you can have a synchronous reset or an asynchronous reset. Here's how such a block would be structured, with an asynchronous reset:
module Traffic(
input wire clk,
input wire resetb, // negative edge asynchronous reset
output reg red1,
output reg red2,
output reg red3,
output reg red4,
output reg yel1,
output reg yel2,
output reg yel3,
output reg yel4,
output reg gr1,
output reg gr2,
output reg gr3,
output reg gr4,
input [1:0] c1,
input [1:0] c2
);
always #(posedge clk or negedge resetb)
begin
if (!resetb) begin
red1 <= 'd0;
// etc....
end else begin
case({c1,c2})
4'b0000:begin
red1<=0;red2<=1;red3<=1;red4<=0;
yel1<=1;yel2<=0;yel3<=0;yel4<=1;
gr1<=0;gr2<=0;gr3<=0;gr4<=0;
end
4'b0001:begin
red1<=1;red2<=1;red3<=1;red4<=0;
yel1<=0;yel2<=0;yel3<=0;yel4<=0;
gr1<=0;gr2<=0;gr3<=0;gr4<=1;
end
// etc...
endcase
end
end
endmodule