RECCORD
RECCORD
Module chk2(reset,clk,PROX,HBTNS_U,HBTNS_D,
CBTNS,INV1F,INV1R,BRAKE,HLBTNS_D,HLBTNS_U,
CLBTNS);
parameter N=3;
input clk;
input reset;
input[N-1:0] PROX;
input[N-2:0] HBTNS_U;
input[N-2:0] HBTNS_D;
input[N-1:0]CBTNS;
output INV1F;
output INV1R;
output BRAKE;
output [N-2:0]HLBTNS_U;
output [N-2:0]HLBTNS_D;
output [N-1:0]CLBTNS;
reg [N-1:0] status;
integer i;
reg[N-1:0]BTNS;
reg[N-1:0]HBTNS_in;
reg[N-2:0]HBTNS_U_in;
reg[N-2:0]HBTNS_D_in;
reg[N-1:0]CBTNS_in;
reg[N-1:0]BTNS_in;
reg[N-1:0]PROX_in;
reg INV1F,INV1R,BRAKE;
reg [N-2:0]HLBTNS_U;
reg [N-2:0]HLBTNS_D;
reg [N-1:0]CLBTNS;
always @(posedge clk)
if (!reset) begin
HBTNS_U_in=HBTNS_U;
HBTNS_D_in=HBTNS_D;
HBTNS_in = HBTNS_D_in*2 + HBTNS_U_in ;
CBTNS_in = CBTNS ;
if(status==1) begin
BTNS_in <=0;
CLBTNS <=0;
HLBTNS_D <=0;
HLBTNS_U <=0;
end
else begin
BTNS_in<= BTNS;
end
if(HBTNS_in> 0 || CBTNS_in> 0 ) begin
for (i = 0 ; i < N; i=i+1) begin
BTNS[i] <= HBTNS_in[i] | CBTNS_in[i] ;
HLBTNS_U <= HBTNS_U_in;
HLBTNS_D <= HBTNS_D_in ;
CLBTNS <= CBTNS_in;
end
end
end
always @(posedge clk)
if (!reset) begin
PROX_in<= PROX ;
if (PROX_in>0) begin
if (PROX_in==BTNS_in) begin
status<= 1;
end
else if (BTNS_in>PROX_in ) begin
status<= 2;
end
else if (BTNS_in<PROX_in&&BTNS_in!=0)
begin
status<= 3;
end
else begin
status<=0;
end
end
end
always @(posedge clk)
if (!reset) begin
case(status)
1: begin
INV1F_ins <=0;
INV1R_ins <=0;
BRAKE_ins<=0;
end
2: begin
INV1F_ins <=1;
BRAKE_ins<=1;
end
3: begin
INV1R_ins <=1;
BRAKE_ins<=1;
end
default: begin
INV1F_ins <=0;
INV1R_ins <=0;
BRAKE_ins<=0;
end
end case
end
end module
//----------------------------------------------------
// A four level, round-robin arbiter. This was
// orginally coded by WD Peterson in VHDL.
//----------------------------------------------------
module arbiter (
clk,
rst,
req3,
req2,
req1,
req0,
gnt3,
gnt2,
gnt1,
gnt0
);
// --------------Port Declaration-----------------------
input clk;
input rst;
input req3;
input req2;
input req1;
input req0;
output gnt3;
output gnt2;
output gnt1;
output gnt0;
//--------------Internal Registers----------------------
wire [1:0] gnt ;
wire comreq ;
wire beg ;
wire [1:0] lgnt ;
wire lcomreq ;
reg lgnt0 ;
reg lgnt1 ;
reg lgnt2 ;
reg lgnt3 ;
reg lasmask ;
reg lmask0 ;
reg lmask1 ;
reg ledge ;
//----------------------------------------------------
// lasmask state machine.
//----------------------------------------------------
assign beg = (req3 | req2 | req1 | req0) & ~lcomreq;
always @ (posedge clk)
begin
lasmask <= (beg & ~ledge & ~lasmask);
ledge <= (beg & ~ledge & lasmask)
| (beg & ledge & ~lasmask);
end
//----------------------------------------------------
// comreq logic.
//----------------------------------------------------
assign lcomreq = ( req3 & lgnt3 )
| ( req2 & lgnt2 )
| ( req1 & lgnt1 )
| ( req0 & lgnt0 );
//----------------------------------------------------
// Encoder logic.
//----------------------------------------------------
assign lgnt = {(lgnt3 | lgnt2),(lgnt3 | lgnt1)};
//----------------------------------------------------
// lmask register.
//----------------------------------------------------
always @ (posedge clk )
if( rst ) begin
lmask1 <= 0;
lmask0 <= 0;
end else if(lasmask) begin
lmask1 <= lgnt[1];
lmask0 <= lgnt[0];
end else begin
lmask1 <= lmask1;
lmask0 <= lmask0;
end
endmodule
module uart_rx
#(parameter CLKS_PER_BIT)
(
input i_Clock,
input i_Rx_Serial,
output o_Rx_DV,
output [7:0] o_Rx_Byte
);
parameter s_IDLE = 3'b000;
parameter s_RX_START_BIT = 3'b001;
parameter s_RX_DATA_BITS = 3'b010;
parameter s_RX_STOP_BIT = 3'b011;
parameter s_CLEANUP = 3'b100;
reg r_Rx_Data_R = 1'b1;
reg r_Rx_Data = 1'b1;
reg [7:0] r_Clock_Count = 0;
reg [2:0] r_Bit_Index = 0; //8 bits total
reg [7:0] r_Rx_Byte = 0;
reg r_Rx_DV = 0;
reg [2:0] r_SM_Main = 0;
// Purpose: Double-register the incoming data.
// This allows it to be used in the UART RX Clock Domain.
// (It removes problems caused by metastability)
always @(posedge i_Clock)
begin
r_Rx_Data_R <= i_Rx_Serial;
r_Rx_Data <= r_Rx_Data_R;
end
// Purpose: Control RX state machine
always @(posedge i_Clock)
begin
case (r_SM_Main)
s_IDLE :
begin
r_Rx_DV <= 1'b0;
r_Clock_Count <= 0;
r_Bit_Index <= 0;
if (r_Rx_Data == 1'b0) // Start bit detected
r_SM_Main <= s_RX_START_BIT;
else
r_SM_Main <= s_IDLE;
end
// Check middle of start bit to make sure it's still low
s_RX_START_BIT :
begin
if (r_Clock_Count == (CLKS_PER_BIT-1)/2)
begin
if (r_Rx_Data == 1'b0)
begin
r_Clock_Count <= 0; // reset counter, found the middle
r_SM_Main <= s_RX_DATA_BITS;
end
else
r_SM_Main <= s_IDLE;
end
else
begin
r_Clock_Count <= r_Clock_Count + 1;
r_SM_Main <= s_RX_START_BIT;
end
end // case: s_RX_START_BIT
// Wait CLKS_PER_BIT-1 clock cycles to sample serial data
s_RX_DATA_BITS :
begin
if (r_Clock_Count < CLKS_PER_BIT-1)
begin
r_Clock_Count <= r_Clock_Count + 1;
r_SM_Main <= s_RX_DATA_BITS;
end
else
begin
r_Clock_Count <= 0;
r_Rx_Byte[r_Bit_Index] <= r_Rx_Data;
// Check if we have received all bits
if (r_Bit_Index < 7)
begin
r_Bit_Index <= r_Bit_Index + 1;
r_SM_Main <= s_RX_DATA_BITS;
end
else
begin
r_Bit_Index <= 0;
r_SM_Main <= s_RX_STOP_BIT;
end
end
end // case: s_RX_DATA_BITS
// Receive Stop bit. Stop bit = 1
s_RX_STOP_BIT :
begin
// Wait CLKS_PER_BIT-1 clock cycles for Stop bit to finish
if (r_Clock_Count < CLKS_PER_BIT-1)
begin
r_Clock_Count <= r_Clock_Count + 1;
r_SM_Main <= s_RX_STOP_BIT;
end
else
begin
r_Rx_DV <= 1'b1;
r_Clock_Count <= 0;
r_SM_Main <= s_CLEANUP;
end
end // case: s_RX_STOP_BIT
// Stay here 1 clock
s_CLEANUP :
begin
r_SM_Main <= s_IDLE;
r_Rx_DV <= 1'b0;
end
default :
r_SM_Main <= s_IDLE;
endcase
end
assign o_Rx_DV = r_Rx_DV;
assign o_Rx_Byte = r_Rx_Byte;
endmodule // uart_rx
rec
module uart_tx
#(parameter CLKS_PER_BIT)
(
input i_Clock,
input i_Tx_DV,
input [7:0] i_Tx_Byte,
output o_Tx_Active,
output reg o_Tx_Serial,
output o_Tx_Done
);
parameter s_IDLE = 3'b000;
parameter s_TX_START_BIT = 3'b001;
parameter s_TX_DATA_BITS = 3'b010;
parameter s_TX_STOP_BIT = 3'b011;
parameter s_CLEANUP = 3'b100;
reg [2:0] r_SM_Main = 0;
reg [7:0] r_Clock_Count = 0;
reg [2:0] r_Bit_Index = 0;
reg [7:0] r_Tx_Data = 0;
reg r_Tx_Done = 0;
reg r_Tx_Active = 0;
always @(posedge i_Clock)
begin
case (r_SM_Main)
s_IDLE :
begin
o_Tx_Serial <= 1'b1; // Drive Line High for Idle
r_Tx_Done <= 1'b0;
r_Clock_Count <= 0;
r_Bit_Index <= 0;
if (i_Tx_DV == 1'b1)
begin
r_Tx_Active <= 1'b1;
r_Tx_Data <= i_Tx_Byte;
r_SM_Main <= s_TX_START_BIT;
end
else
r_SM_Main <= s_IDLE;
end // case: s_IDLE
// Send out Start Bit. Start bit = 0
s_TX_START_BIT :
begin
o_Tx_Serial <= 1'b0;
// Wait CLKS_PER_BIT-1 clock cycles for start bit to finish
if (r_Clock_Count < CLKS_PER_BIT-1)
begin
r_Clock_Count <= r_Clock_Count + 1;
r_SM_Main <= s_TX_START_BIT;
end
else
begin
r_Clock_Count <= 0;
r_SM_Main <= s_TX_DATA_BITS;
end
end // case: s_TX_START_BIT
// Wait CLKS_PER_BIT-1 clock cycles for data bits to finish
s_TX_DATA_BITS :
begin
o_Tx_Serial <= r_Tx_Data[r_Bit_Index];
if (r_Clock_Count < CLKS_PER_BIT-1)
begin
r_Clock_Count <= r_Clock_Count + 1;
r_SM_Main <= s_TX_DATA_BITS;
end
else
begin
r_Clock_Count <= 0;
// Check if we have sent out all bits
if (r_Bit_Index < 7)
begin
r_Bit_Index <= r_Bit_Index + 1;
r_SM_Main <= s_TX_DATA_BITS;
end
else
begin
r_Bit_Index <= 0;
r_SM_Main <= s_TX_STOP_BIT;
end
end
end // case: s_TX_DATA_BITS
// Send out Stop bit. Stop bit = 1
s_TX_STOP_BIT :
begin
o_Tx_Serial <= 1'b1;
// Wait CLKS_PER_BIT-1 clock cycles for Stop bit to finish
if (r_Clock_Count < CLKS_PER_BIT-1)
begin
r_Clock_Count <= r_Clock_Count + 1;
r_SM_Main <= s_TX_STOP_BIT;
end
else
begin
r_Tx_Done <= 1'b1;
r_Clock_Count <= 0;
r_SM_Main <= s_CLEANUP;
r_Tx_Active <= 1'b0;
end
end // case: s_Tx_STOP_BIT
// Stay here 1 clock
s_CLEANUP :
begin
r_Tx_Done <= 1'b1;
r_SM_Main <= s_IDLE;
end
default :
r_SM_Main <= s_IDLE;
endcase
end
assign o_Tx_Active = r_Tx_Active;
assign o_Tx_Done = r_Tx_Done;
endmodule
module single_port_sync_ram
# (parameter ADDR_WIDTH = 4,
parameter DATA_WIDTH = 32,
parameter DEPTH = 16
)
( input clk,
input [ADDR_WIDTH-1:0] addr,
inout [DATA_WIDTH-1:0] data,
input cs,
input we,
input oe
);
reg [DATA_WIDTH-1:0] tmp_data;
reg [DATA_WIDTH-1:0] mem [DEPTH];
always @ (posedge clk) begin
if (cs & we)
mem[addr] <= data;
end
always @ (posedge clk) begin
if (cs & !we)
tmp_data <= mem[addr];
end
assign data = cs & oe & !wr ? tmp_data : 'hz;
endmodule
test bench
module tb;
parameter ADDR_WIDTH = 4;
parameter DATA_WIDTH = 16;
parameter DEPTH = 16;
reg clk;
reg cs;
reg we;
reg oe;
reg [ADDR_WIDTH-1:0] addr;
wire [DATA_WIDTH-1:0] data;
reg [DATA_WIDTH-1:0] tb_data;
single_port_sync_ram #(.DATA_WIDTH(DATA_WIDTH)) u0
( .clk(clk),
.addr(addr),
.data(data),
.cs(cs),
.we(we),
.oe(oe)
);
always #10 clk = ~clk;
assign data = !oe ? tb_data : 'hz;
initial begin
{clk, cs, we, addr, tb_data, oe} <= 0;
repeat (2) @ (posedge clk);
for (integer i = 0; i < 2**ADDR_WIDTH; i= i+1) begin
repeat (1) @(posedge clk) addr <= i; we <= 1; cs <=1; oe <= 0; tb_data <=
$random;
end
for (integer i = 0; i < 2**ADDR_WIDTH; i= i+1) begin
repeat (1) @(posedge clk) addr <= i; we <= 0; cs <= 1; oe <= 1;
end
#20 $finish;
end
endmodule
module serial_adder
( input clk,reset, //clock and reset
input a,b,cin, //note that cin is used for only first iteration.
output reg s,cout //note that s comes out at every clock cycle and cout is
valid only for last clock cycle.
);
reg c,flag;
always@(posedge clk or posedge reset)
begin
if(reset == 1) begin //active high reset
s = 0;
cout = c;
flag = 0;
end else begin
if(flag == 0) begin
c = cin; //on first iteration after reset, assign cin to c.
flag = 1; //then make flag 1, so that this if statement isnt executed
any more.
end
cout = 0;
s = a ^ b ^ c; //SUM
c = (a & b) | (c & b) | (a & c); //CARRY
end
end
endmodule
xor x3(t3,B[0],In);
xor x4(t4,B[1],In);
xor x5(t5,B[2],In);
xor x6(t6,B[3],In);
fadder f5(A[0],t3,In,Res[0],t1);
fadder f6(A[1],t4,t1,Res[1],t2);
fadder f7(A[2],t5,t2,Res[2],t3);
fadder f8(A[3],t6,t3,Res[3],Out);
endmodule
module fsm(clock,reset,coin,vend,state,change);
\\these are the inputs and the outputs.
input clock;
input reset;
input [2:0]coin;
output vend;
output [2:0]state;
output [2:0]change;
NICKEL: next_state=TEN;
DIME: next_state=FIFTEEN;
QUARTER: next_state=TWENTYFIVE; //change=NICKEL
default: next_state=FIVE;
endcase
TEN: case(coin) \\THIS IS THE THIRD STATE
NICKEL: next_state=FIFTEEN;
DIME: next_state=TWENTY;
QUARTER: next_state=TWENTYFIVE; //change=DIME
default: next_state=TEN;
endcase
FIFTEEN: case(coin) \\THIS IS THE FOURTH STATE
NICKEL: next_state=TWENTY;
DIME: next_state=TWENTYFIVE;
QUARTER: next_state=TWENTYFIVE; //change==NICKEL_DIME
default: next_state=FIFTEEN;
endcase
TWENTY: case(coin) \\THIS IS THE FIFTH STATE
NICKEL: next_state=TWENTYFIVE;
DIME: next_state=TWENTYFIVE; //change=NICKEL
QUARTER: next_state=TWENTYFIVE; //change==DIME_DIME
default: next_state=TWENTY;
endcase
TWENTYFIVE: next_state=IDLE; \\THE NEXT STATE HERE IS THE RESET
default : next_state=IDLE;
endcase
end
always @(clock)
begin \\WHENEVER I GIVE A RESET I HAVE TO MAKE THE STATE TO IDLE AND
VEND TO 1
if(reset) begin
state <= IDLE;
vend <= 1’b0;
// change <= 3’b000;
end \\THE CHANGE ALSO HAS TO BECOME NONE
else state <= next_state; case (state) \\HERE WE DECIDE THE NEXT STATE
\\ALL THE STATES ARE DEFINED HERE AND THE OUTPUT IS ALSO GIVEN
IDLE: begin vend <= 1’b0; change <=3’d0; end
FIVE: begin vend <= 1’b0; if (coin==QUARTER) change <=NICKEL; else change <=3’d0;
TEN: begin vend <= 1’b0; if (coin==QUARTER) change <=DIME; else change <= 3’d0;
FIFTEEN : begin vend <= 1’b0; if (coin==QUARTER) change <=NICKEL_DIME; else
change TWENTY : begin vend <= 1’b0; if (coin==DIME) change <=NICKEL; else if
(coin==QUARTER) TWENTYFIVE : begin vend <= 1’b1; change <=3’d0; end
default: state <= IDLE;
endcase
end
endmodule