I am attempting to create a 32-bit shift register in Verilog with two inputs, DATA0 and DATA1. DATA0 is driven low to input a 0 to the register and DATA1 is driven low to input a 1 to the register. DATA0 and DATA1 are held high when they are not being used.
The issue that I am running into is when I drive DATA0 low, it replaces all of the bits in the register with zeroes. DATA1 works fine, shifting the register and adding a one to the end. My code is as follows:
module shift(
databits, //The register
reset , // reset Input
DATA0 , //Input for a 0
DATA1 //Input for a 1
);
//------------Output Ports--------------
output [31:0] databits;
//------------Input Ports--------------
input reset, DATA0, DATA1;
//------------Internal Variables--------
reg [31:0] databits;
//-------------Code Starts Here-------
always @(posedge reset or negedge DATA0 or negedge DATA1) begin
if(reset) begin
databits <= 0;
end
//If DATA0 triggered this, write a 0
else if (~DATA0) begin
databits <= databits << 1;
end
//If DATA1 triggered this, write a 1
else if (~DATA1) begin
databits <= { databits[30:0], 1'b1 };
end
end
endmodule
I tried using DATA0 to also input ones to the register, but it overwrote the entire reigsters with ones. It is my understanding that the always block should execute once when DATA0 goes low, so I do not understand why it is doing this.
-
\$\begingroup\$ What is the purpose of this excercise? Do you expect to be able to synthesize this design? \$\endgroup\$The Photon– The Photon2016年05月07日 18:49:16 +00:00Commented May 7, 2016 at 18:49
-
1\$\begingroup\$ Your logic infers a dual clock flip-flop with DATA0 and DATA1 both being clocks. This is not synthesisable. \$\endgroup\$Tom Carpenter– Tom Carpenter2016年05月07日 18:49:17 +00:00Commented May 7, 2016 at 18:49
-
\$\begingroup\$ You should have a clock signal to synchronise all the logic and a couple of instances of a negative edge detector to sample the DATA0 and DATA1 signals. \$\endgroup\$Tom Carpenter– Tom Carpenter2016年05月07日 18:50:25 +00:00Commented May 7, 2016 at 18:50
-
\$\begingroup\$ @ThePhoton The end goal here is to read the output from a Wiegand interface. This is the first step in the process. \$\endgroup\$Confused_Engineer– Confused_Engineer2016年05月07日 18:53:35 +00:00Commented May 7, 2016 at 18:53
-
\$\begingroup\$ @TomCarpenter I looked at doing something along those lines originally, but could not figure out how to do so without driving a register from multiple always blocks. \$\endgroup\$Confused_Engineer– Confused_Engineer2016年05月07日 18:56:07 +00:00Commented May 7, 2016 at 18:56
1 Answer 1
As it stands you have a shift register whose clock is both DATA0 and DATA1. This cannot be synthesised as FPGAs don't have dual-clock flip flops.
To make it work you will need two things:
- A single clock sufficiently fast to sample the DATA0 and DATA1 signals
- Edge detection logic for the DATA0 and DATA1 signals.
Edge detection is a pretty straight forward thing to do:
module fallingEdge (
input clock,
input signal,
output reg edge
);
reg signalDly;
always @ (posedge clock) begin
signalDly <= signal; //Delay signal by one clock cycle.
edge <= signalDly && !signal; //If the signal was high in the last cycle but low now, it must be a falling edge
end
endmodule
The output of that block will be high for exactly one clock cycle when there is a falling edge of the data signal.
You will need an edge detector for each of DATA0 and DATA1 which will result in two new signals (say EDGE0 and EDGE1).
Your shift register is then clocked by your 'clock' signal (1), and you simply check the edge signals in that block. If EDGE0 is high, clock in a 0. If EDGE1 is high, clock in a 1. If they are both high at the same time, you'll need to decide whether 0 or 1 takes priority.
-
\$\begingroup\$ Thanks. I will need to learn how to use multiple modules, but that is a good thing to know how to do. \$\endgroup\$Confused_Engineer– Confused_Engineer2016年05月07日 19:11:06 +00:00Commented May 7, 2016 at 19:11