What's wrong with my "parallel to serial" verilog code - verilog

I'm trying to design a parallel to serial converter. But my final waveform look like this:
Here is my code, thanks in advance.
module parallel2serial#(parameter size=4)(pin, clk, load, rst, sout, finish);
input [size-1 :0] pin;
input clk, rst, load;
output reg finish;
output sout;
reg [2:0]count;
reg [size-1 :0] data;
reg dout;
always#(posedge clk)begin
if(!rst)begin dout<=0; end
else if(!load)begin
data<=data>>1;
dout<=data[size-1];
end
else data<=pin;
end
always#(posedge clk)begin
if(!rst)begin count<=0; finish<=0;end
else begin
if(count==2'b11) begin count<=0; finish<=1;end
else begin count<=count+1; finish<=0;end
end
end
assign sout=dout;
endmodule

There's at least one mistake. You're shifting data towards the least significant bit (to the right), while taking the output from the most significant bit. You should either output lsb instead of msb, or change the direction of register shifting.

Related

verilog code is working in isim(xilinx 14.2) but is not working onspartan6

i have written a simple counter code in verilog (xilix 14.2). The code is working properly in the isim but i am not able to dump it onto spartan6. When I try to do dump the code, a red light is ON , on the spartan 6 and the code is not dumped . Please let me know the changes i need to make.
module clk(int_clk,ext_pulse,reset,pos_count,neg_count);
input int_clk;
input ext_pulse;
input reset;
output reg [7:0] pos_count;
output reg [7:0] neg_count;
reg [7:0] count;
always#(posedge int_clk)
if(reset)
begin
pos_count<=0;
neg_count<=0;
end
else if(ext_pulse)
begin
neg_count<=neg_count+1;
pos_count<=0;
end
else
begin
pos_count<=pos_count+1;
neg_count<=0;
end
endmodule
Hey you haven't put a begin..end in the always block. Moreover you have used a synchronous reset which is generally not advisable. I made some changes to your code. By the way did you generate the bitstream?
module clk(int_clk,ext_pulse,reset,pos_count,neg_count);
input int_clk;
input ext_pulse;
input reset;
output reg [7:0] pos_count;
output reg [7:0] neg_count;
reg [7:0] count; //This reg is unused
always#(posedge int_clk or posedge reset) //I am assuming you want active high reset
begin
if(reset)
begin
pos_count<=0;
neg_count<=0;
end
else if(ext_pulse)
begin
neg_count<=neg_count+1;
pos_count<=0;
end
else
begin
pos_count<=pos_count+1;
neg_count<=0;
end
end
endmodule

Optimizing the registerfile code in systemverilog

I am implementing a 32bit RegFile(containing 32 registers). Now, for the combinational part, I am planning to use the switch case to out the read value of the 32registers based on the input register number. This is resulting in a switch case with 32cases and a default case. Is there any other way to optimize the code? Constraint is that my output needs to be a register and hence I am unable to use the following statement(containing assign):
assign rdDataA = rdAddrA == 0 ? reg0
Code:
module RegFile(input [4:0] src_rd_1,
input [4:0] src_rd_2,
input [4:0] des_wr_1,
input [31:0] data,
input clk,
input reset,
input wr_en,
output reg rd_val_1,
output reg rd_val_2
);
reg [31:0] register[31:0];
always_comb begin
case(src_rd_1)
5'd0:begin
rd_val_1=register[0];
end
5'd1:begin
rd_val_1=register[1];
end
5'd2:begin
rd_val_1=register[2];
end
5'd3:begin
rd_val_1=register[3];
end
5'd4:begin
rd_val_1=register[4];
//and so on...
end
Update:
I found out a way to optimize the code. I hope this would work...Any other suggestions are welcome
if(src_rd_1>=0)
begin
if(src_rd_1==0)
begin
rd_val_1=32'd0;
end
else
begin
rd_val_1=register[src_rd_1];
end
end
Any advise will helpful. TIA
The following is allowed by simulation tools:
always_comb begin
rd_val_1 = register[src_rd_1];
end
You'll have to try it out and see if your synthesis tool supports this.
Using reg doesn't mean it will synthesize to a register. To synthesize to a register a reg (or for SystemVerilogpreferablylogic`) should be assigned in a sequential always block.
always_ff #(posedge clk) begin
rd_val_1 <= register[src_rd_1];
end
Flopping the output makes it a clean, glitch-free output and doesn't add to the combinational propagation delay to any receiving modules.

LC-3 16 bit processor wrong simulation in Verilog

I am working on designing a LC-3(Little Computer) CPU. I have designed PC unit, Control Unit(as Finite State Machine), Instruction Memory, ALU unit and Data Memory in Modules. There is also a Register File unit which works as Main, module calls are done in this unit.
I want the program to work as when PCread is 1, get the variable that going to be assigned to out from in variable, and when PCwrite is 1, just increment the out variable. out is the address that sent to the Instruction Memory.
The problem is when I simulate, instruction never loads to the Instruction Memory. Because PCwrite does not work for the first state of the Control Unit, because I reset both PCread and PCread variables in the first state. I do this because I do not want the instruction to load until one instruction finishes it work. I could not find a way to handle this.
I know if this is solved, processor will work because when I try it for one instruction with initialized values, it works.
module reg_fileandMain();
parameter B=16, W=3;
reg Clk;
wire wr_en;
wire [W-1:0] w_addr, r_addr1, r_addr2;
wire [B-1:0] inData;
wire [B-1:0] r_data1;
wire [B-1:0] r_data2;
wire [B-1:0] address;
wire Dataout;
wire InsMemRead;
reg [15:0] extended, mux1out, mux2out, mux3out, mux4out, mux5out;
wire ALUout, incrementer;
wire [15:0] instruction;
reg [B-1:0] array_reg[2**W-1:0];
wire mux1,mux3,mux4,mux5;
wire [1:0] mux2;
initial begin
mux5out=16'hFFFF;
end
wire MemRead,PCwrite,ALUcontrol,MemWrite,PCread;
always#(posedge Clk)
begin
if(wr_en)begin
array_reg[w_addr]<=inData;
end
end
assign r_data1=array_reg[r_addr1];
assign r_data2=array_reg[r_addr2];
controlUnit controlUnit0(Clk,instruction,mux1,mux2,mux3,mux4,mux5,InsMemRead,MemRead,PCwrite,wr_en,ALUcontrol,MemWrite,PCread,r_addr1,r_addr2,w_addr);
PCunit PCunit0(Clk,PCwrite,PCread,mux5out,address);
DataMem DataMem0(Clk,mux2out,r_data1,MemRead,MemWrite,Dataout);
ALU ALU0(mux1out,r_data2,ALUout,ALUcontrol);
InstructionMemory InstructionMemory0(Clk,address,InsMemRead,instruction);
always #* begin
if(mux1)begin
extended = { {11{instruction[4]}}, instruction[4:0] };
mux1out=extended;
end
else begin
mux1out=r_data1;
end
if(mux2==2'b00)begin
mux2out=ALUout;
end
else if(mux2==2'b01)begin
extended = instruction[8:0];
mux2out=extended;
end
else if(mux2==2'b11)begin
extended = instruction[8:0];
mux2out=extended;
end
if(mux3)begin
mux3out<=mux2out;
end
else begin
mux3out<=Dataout;
end
if(mux4)begin
mux4out<=address;
end
else begin
mux4out<=mux3out;
end
if(mux5)begin
mux5out<=address;
end
else begin
mux5out<=mux3out;
end
end
assign inData=mux4out;
always begin
#20 Clk<=0;
#20 Clk<=1;
end
endmodule
module controlUnit(Clk,in,mux1,mux2,mux3,mux4,mux5,InsMemRead,MemRead,PCwrite,WE,ALUcontrol,MemWrite,PCread,rd1,rd2,wr);
input Clk;
input [15:0] in;
output reg mux1,mux3,mux4,mux5,InsMemRead,MemRead,PCwrite,WE,ALUcontrol,MemWrite,PCread;
output reg [1:0] mux2;
reg [3:0] state,stateNext;
reg counter;
output wire [2:0] rd1,rd2,wr;
initial begin
state=4'b0000;
stateNext=4'b0001;
MemRead=0;
PCwrite=1;
end
assign rd1=in[2:0];
assign rd2=in[8:6];
assign wr=in[11:9];
always #* begin
if (state==4'b0000)begin
stateNext=4'b0001;
PCwrite=0;
PCread=0;
end
if(state==4'b0001)
begin
InsMemRead<=1;
if(in[15:12]==4'b0100)begin
stateNext=4'b0100;
InsMemRead=1'b1;
end
else if( in[15:12]==4'b1000)begin
stateNext=4'b0100;
InsMemRead=1;
end
else if(in[15:12]==4'b0010)begin
stateNext=4'b0010;
InsMemRead=1;
end
else if(in[15:12]==4'b1100)begin
stateNext=4'b1100;
InsMemRead=1;
end
else if(in[15:12]==1010)begin
stateNext=4'b1010;
InsMemRead=1;
end
end
else if(state==4'b0100)begin
stateNext=4'b0101;
end
else if(state==4'b0101)begin
stateNext=4'b0000;
mux3=0;
mux4=0;
WE=1;
mux2=2'b01;
MemRead=1;
mux5=1;
PCwrite=1;
end
else if(state==4'b1000)begin
stateNext=4'b0000;
mux1=in[5];
ALUcontrol=0;
mux3=1;
mux4=0;
WE=1;
PCwrite=1;
end
else if(state==4'b0010)begin
stateNext=4'b0000;
mux1=in[5];
ALUcontrol=1;
mux3=1;
mux4=0;
WE=1;
PCwrite=1;
end
else if(state==4'b1100)begin
stateNext=4'b0000;
mux2=2'b01;
MemWrite=1;
PCwrite=1;
end
else if(state==4'b1010)begin
stateNext=4'b0000;
mux2=2'b11;
mux3=1;
mux5=0;
PCread=1;
end
end
always #(posedge Clk) begin
state = stateNext;
end
endmodule
module PCunit(Clk,PCwrite,PCread,in,out);
input Clk,PCread,PCwrite;
input wire [15:0] in;
output reg [15:0] out;
always #(posedge Clk) begin
if(PCwrite)
begin
out<=out+1;
end
else
begin
if(PCread)
begin
out<=in;
end
end
end
endmodule
module ALU(in1,in2,ALUout,ALUcontrol);
input ALUcontrol;
input wire [15:0] in1, in2;
output reg [15:0] ALUout;
always #* begin
if(ALUcontrol)
ALUout = in1 + in2;
else
ALUout = in1 & in2;
end
endmodule
module DataMem(Clk,AddrReg,in,MemRead,MemWrite,out);
input Clk, MemRead, MemWrite;
input [15:0] AddrReg, in;
output reg [15:0] out;
reg[15:0] Mem[2**9:0];
always #(posedge Clk) begin
if(MemWrite)begin
Mem[AddrReg]=in;
end
end
always #* begin
if(MemRead) begin
out=Mem[AddrReg];
end
end
endmodule
module InstructionMemory(Clk,address,InsMemRead,instruction);
input Clk;
input [15:0] address;
input InsMemRead;
output reg [15:0] instruction;
reg [15:0] InstructionMemory [15:0];
initial begin
$readmemh("AssemblerOutput.hex", InstructionMemory);
end
always#(posedge Clk)begin
if(InsMemRead)
instruction=InstructionMemory[address];
end
endmodule
Always use #* for sensitivity lists for combinational logic. Change:
always #(MemRead) begin
to:
always #* begin
Your always block is not sensitive to changes in AddrReg.
I found that one way to solve this is sending a signal from the PC unit to control unit that the instruction adress is sent to instruction memory with an output reg variable, and check if this variable is changed in control unit, if it is, reset the PCwrite variable. Thanks to all tried to help.

Verilog Random Number Generator

I'm new to Verilog and I'm trying to create a 4-bit binary Random Number Generator. The program is as follows, could anyone help me by mentioning the errors?
I initially tried out this:
module rng (d);
inout[3:0]d;
//wire[3:0]d;
//input clk, rst;
//wire [3:0] w;
dff f1(a[0],clk,d[0],rst);
dff f2(a[1],clk,d[1],rst);
dff f3(a[2],clk,d[2],rst);
dff f4(a[3],clk,d[3],rst);
xorper p(d[0],d[1],d[2],d[3],a[0],a[1],a[2],a[3]);//permutations
//dff f1(a,clk,q,rst);
dff x(d,clk,q,rst);
endmodule
I also tried out this:
module re(b,q,clk,rst);
input [3:0]q;
input clk,rst;
wire [3:0]q,a;
output [3:0]b;
reg [3:0]b;
rox f1(q[0],q[1],q[2],q[3],a[0],a[1],a[2],a[3]);//permutations
rod f2(a,clk,b,rst);//dff
always#(posedge clk) begin
if (rst==1'b0) begin
b[0]=q[0];
b[1]=q[1];
b[2]=q[2];
b[3]=q[3];
end else if(rst==1'b1)
b[0]=1'bx;
b[1]=1'bx;
b[2]=1'bx;
b[3]=1'bx;
end
endmodule
I would suggest starting with an LFSR for random number generation. They are a straight forward shift register, with taps back to a mutlibit XOR to create the feedback bit.
Your implementation of a flop could be better.
1) Add negedge rst to the sensitivity list
2) You do not want to assign x's
3) use non-blocking assignments (<=)
reg [3:0] b;
//LFSR feedback bit
wire feedback
assign feedback = b[0] ^ b[3];
// Add active low reset to sensitivity list
always#(posedge clk or negedge rst) begin
if (rst==1'b0) begin
b[3:0]<=4'hF; //reset condition first
end
else begin
b[0]<=feedback;
b[1]<=b[0];
b[2]<=b[1];
b[3]<=b[2];
//Alternative Verilog might be
// b = {b[2:0], feedback};
end
For choosing tap point for an LFSR search for a maximal length LFSR. A maximal LFSR will have the longest number sequence before it repeats for a given length of register and tap points.

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