rtl: utils: add full handshake CDC source

Signed-off-by: liangkangnan <liangkangnan@163.com>
pull/1/head
liangkangnan 2020-09-23 21:39:20 +08:00
parent 386ba909ba
commit 4876225f60
4 changed files with 277 additions and 2 deletions

View File

@ -0,0 +1,128 @@
/*
Copyright 2020 Blue Liang, liangkangnan@163.com
Licensed under the Apache License, Version 2.0 (the "License");
you may not use this file except in compliance with the License.
You may obtain a copy of the License at
http://www.apache.org/licenses/LICENSE-2.0
Unless required by applicable law or agreed to in writing, software
distributed under the License is distributed on an "AS IS" BASIS,
WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
See the License for the specific language governing permissions and
limitations under the License.
*/
//
// ()
// req = 1
// ack_o = 1
// req = 0
// ack_o = 0
module full_handshake_rx #(
parameter DW = 32)( // RX
input wire clk, // RX
input wire rst_n, // RX
// from tx
input wire req_i, // TX
input wire[DW-1:0] req_data_i, // TX
// to tx
output wire ack_o, // RXTX
// to rx
output wire[DW-1:0] recv_data_o,// RX
output wire recv_rdy_o // RX
);
localparam STATE_IDLE = 2'b01;
localparam STATE_DEASSERT = 2'b10;
reg[1:0] state;
reg[1:0] state_next;
always @ (posedge clk or negedge rst_n) begin
if (!rst_n) begin
state <= STATE_IDLE;
end else begin
state <= state_next;
end
end
always @ (*) begin
case (state)
// TXreq=1
STATE_IDLE: begin
if (req == 1'b1) begin
state_next = STATE_DEASSERT;
end else begin
state_next = STATE_IDLE;
end
end
// req=0
STATE_DEASSERT: begin
if (req) begin
state_next = STATE_DEASSERT;
end else begin
state_next = STATE_IDLE;
end
end
default: begin
state_next = STATE_IDLE;
end
endcase
end
reg req_d;
reg req;
//
always @ (posedge clk or negedge rst_n) begin
if (!rst_n) begin
req_d <= 1'b0;
req <= 1'b0;
end else begin
req_d <= req_i;
req <= req_d;
end
end
reg[DW-1:0] recv_data;
reg recv_rdy;
reg ack;
always @ (posedge clk or negedge rst_n) begin
if (!rst_n) begin
ack <= 1'b0;
recv_rdy <= 1'b0;
recv_data <= {(DW){1'b0}};
end else begin
case (state)
STATE_IDLE: begin
if (req == 1'b1) begin
ack <= 1'b1;
recv_rdy <= 1'b1; //
recv_data <= req_data_i; //
end
end
STATE_DEASSERT: begin
recv_rdy <= 1'b0;
recv_data <= {(DW){1'b0}};
// reqack
if (req == 1'b0) begin
ack <= 1'b0;
end
end
endcase
end
end
assign ack_o = ack;
assign recv_rdy_o = recv_rdy;
assign recv_data_o = recv_data;
endmodule

View File

@ -0,0 +1,147 @@
/*
Copyright 2020 Blue Liang, liangkangnan@163.com
Licensed under the Apache License, Version 2.0 (the "License");
you may not use this file except in compliance with the License.
You may obtain a copy of the License at
http://www.apache.org/licenses/LICENSE-2.0
Unless required by applicable law or agreed to in writing, software
distributed under the License is distributed on an "AS IS" BASIS,
WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
See the License for the specific language governing permissions and
limitations under the License.
*/
//
// ()
// req_o = 1
// ack = 1
// req_o = 0
// ack = 0
module full_handshake_tx #(
parameter DW = 32)( // TX
input wire clk, // TX
input wire rst_n, // TX
// from rx
input wire ack_i, // RX
// from tx
input wire req_i, // TX
input wire[DW-1:0] req_data_i, // TX
// to tx
output wire idle_o, // TX
// to rx
output wire req_o, // TX
output wire[DW-1:0] req_data_o // TX
);
localparam STATE_IDLE = 3'b001;
localparam STATE_ASSERT = 3'b010;
localparam STATE_DEASSERT = 3'b100;
reg[2:0] state;
reg[2:0] state_next;
always @ (posedge clk or negedge rst_n) begin
if (!rst_n) begin
state <= STATE_IDLE;
end else begin
state <= state_next;
end
end
always @ (*) begin
case (state)
STATE_IDLE: begin
if (req_i == 1'b1) begin
state_next = STATE_ASSERT;
end else begin
state_next = STATE_IDLE;
end
end
// ack=1
STATE_ASSERT: begin
if (!ack) begin
state_next = STATE_ASSERT;
end else begin
state_next = STATE_DEASSERT;
end
end
// ack=0
STATE_DEASSERT: begin
if (!ack) begin
state_next = STATE_IDLE;
end else begin
state_next = STATE_DEASSERT;
end
end
default: begin
state_next = STATE_IDLE;
end
endcase
end
reg ack_d;
reg ack;
//
always @ (posedge clk or negedge rst_n) begin
if (!rst_n) begin
ack_d <= 1'b0;
ack <= 1'b0;
end else begin
ack_d <= ack_i;
ack <= ack_d;
end
end
reg req;
reg[DW-1:0] req_data;
reg idle;
always @ (posedge clk or negedge rst_n) begin
if (!rst_n) begin
idle <= 1'b1;
req <= 1'b0;
req_data <= {(DW){1'b0}};
end else begin
case (state)
// TXack
STATE_IDLE: begin
if (req_i == 1'b1) begin
idle <= 1'b0;
req <= req_i;
req_data <= req_data_i;
end else begin
idle <= 1'b1;
req <= 1'b0;
end
end
// RXackTX
STATE_ASSERT: begin
if (ack == 1'b1) begin
req <= 1'b0;
req_data <= {(DW){1'b0}};
end
end
STATE_DEASSERT: begin
if (!ack) begin
idle <= 1'b1;
end
end
endcase
end
end
assign idle_o = idle;
assign req_o = req;
assign req_data_o = req_data;
endmodule

View File

@ -1,2 +1,2 @@
iverilog -o out.vvp -I ..\rtl\core ..\tb\tinyriscv_soc_tb.v ..\rtl\core\defines.v ..\rtl\core\ex.v ..\rtl\core\id.v ..\rtl\core\tinyriscv.v ..\rtl\core\pc_reg.v ..\rtl\core\id_ex.v ..\rtl\core\ctrl.v ..\rtl\core\regs.v ..\rtl\perips\ram.v ..\rtl\perips\rom.v ..\rtl\perips\spi.v ..\rtl\core\if_id.v ..\rtl\core\div.v ..\rtl\core\rib.v ..\rtl\core\clint.v ..\rtl\core\csr_reg.v ..\rtl\debug\jtag_dm.v ..\rtl\debug\jtag_driver.v ..\rtl\debug\jtag_top.v ..\rtl\debug\uart_debug.v ..\rtl\perips\timer.v ..\rtl\perips\uart.v ..\rtl\perips\gpio.v ..\rtl\utils\gen_dff.v ..\rtl\utils\gen_buf.v ..\rtl\soc\tinyriscv_soc_top.v iverilog -o out.vvp -I ..\rtl\core ..\tb\tinyriscv_soc_tb.v ..\rtl\core\defines.v ..\rtl\core\ex.v ..\rtl\core\id.v ..\rtl\core\tinyriscv.v ..\rtl\core\pc_reg.v ..\rtl\core\id_ex.v ..\rtl\core\ctrl.v ..\rtl\core\regs.v ..\rtl\perips\ram.v ..\rtl\perips\rom.v ..\rtl\perips\spi.v ..\rtl\core\if_id.v ..\rtl\core\div.v ..\rtl\core\rib.v ..\rtl\core\clint.v ..\rtl\core\csr_reg.v ..\rtl\debug\jtag_dm.v ..\rtl\debug\jtag_driver.v ..\rtl\debug\jtag_top.v ..\rtl\debug\uart_debug.v ..\rtl\perips\timer.v ..\rtl\perips\uart.v ..\rtl\perips\gpio.v ..\rtl\utils\gen_dff.v ..\rtl\utils\gen_buf.v ..\rtl\utils\full_handshake_rx.v ..\rtl\utils\full_handshake_tx.v ..\rtl\soc\tinyriscv_soc_top.v
vvp out.vvp vvp out.vvp

View File

@ -1,3 +1,3 @@
..\tools\BinToMem_CLI.exe %1 %2 ..\tools\BinToMem_CLI.exe %1 %2
iverilog -o out.vvp -I ..\rtl\core ..\tb\tinyriscv_soc_tb.v ..\rtl\core\defines.v ..\rtl\core\ex.v ..\rtl\core\id.v ..\rtl\core\tinyriscv.v ..\rtl\core\pc_reg.v ..\rtl\core\id_ex.v ..\rtl\core\ctrl.v ..\rtl\core\regs.v ..\rtl\perips\ram.v ..\rtl\perips\rom.v ..\rtl\perips\spi.v ..\rtl\core\if_id.v ..\rtl\core\div.v ..\rtl\core\rib.v ..\rtl\core\clint.v ..\rtl\core\csr_reg.v ..\rtl\debug\jtag_dm.v ..\rtl\debug\jtag_driver.v ..\rtl\debug\jtag_top.v ..\rtl\debug\uart_debug.v ..\rtl\perips\timer.v ..\rtl\perips\uart.v ..\rtl\perips\gpio.v ..\rtl\utils\gen_dff.v ..\rtl\utils\gen_buf.v ..\rtl\soc\tinyriscv_soc_top.v iverilog -o out.vvp -I ..\rtl\core ..\tb\tinyriscv_soc_tb.v ..\rtl\core\defines.v ..\rtl\core\ex.v ..\rtl\core\id.v ..\rtl\core\tinyriscv.v ..\rtl\core\pc_reg.v ..\rtl\core\id_ex.v ..\rtl\core\ctrl.v ..\rtl\core\regs.v ..\rtl\perips\ram.v ..\rtl\perips\rom.v ..\rtl\perips\spi.v ..\rtl\core\if_id.v ..\rtl\core\div.v ..\rtl\core\rib.v ..\rtl\core\clint.v ..\rtl\core\csr_reg.v ..\rtl\debug\jtag_dm.v ..\rtl\debug\jtag_driver.v ..\rtl\debug\jtag_top.v ..\rtl\debug\uart_debug.v ..\rtl\perips\timer.v ..\rtl\perips\uart.v ..\rtl\perips\gpio.v ..\rtl\utils\gen_dff.v ..\rtl\utils\gen_buf.v ..\rtl\utils\full_handshake_rx.v ..\rtl\utils\full_handshake_tx.v ..\rtl\soc\tinyriscv_soc_top.v
vvp out.vvp vvp out.vvp