📄 ex_319.v
字号:
// (1) GPIO (General Purpose Input and Output ports) with
// microprocessor programmable tri-state bus interface
// (2) bus interface : 1. addr_reg : address bus
// 2. rd_n_reg, wr_n_reg, and
// cs_n_reg : control bus
// 3. data : tri-state data bus
// (3) internal registers :
// 1. reg_0_r input register of gpio0
// reg_0_w output register of gpio0
// 2. reg_1_r input register of gpio1
// reg_1_w output register of gpio1
// 3. reg_2_r input register of gpio2
// reg_2_w output register of gpio2
// 4. reg_3 bit 0 : 1 => config gpio0 as output ports
// 0 => config gpio0 as input ports
// reg_3 bit 1 : 1 => config gpio1 as output ports
// 0 => config gpio1 as input ports
// reg_3 bit 2 : 1 => config gpio2 as output ports
// 0 => config gpio2 as input ports
`timescale 1 ns/1 ns
module EX_319_tristatebus_gpio(
reset, clk,
addr_reg, rd_n_reg, wr_n_reg, cs_n_reg,
data, gpio0, gpio1, gpio2);
input reset, clk;
input [1:0] addr_reg;
input rd_n_reg, wr_n_reg, cs_n_reg;
inout [7:0] data, gpio0, gpio1, gpio2;
wire [7:0] data, gpio0, gpio1, gpio2;
reg [2:0] reg_3;
reg [7:0] reg_0_r, reg_1_r, reg_2_r;
reg [7:0] reg_0_w, reg_1_w, reg_2_w;
wire reg_0_sel_r,reg_1_sel_r,reg_2_sel_r,reg_3_sel_r;
wire reg_0_sel_w,reg_1_sel_w,reg_2_sel_w,reg_3_sel_w;
wire [3:0] reg_sel_r, reg_sel_w;
// output GPIO tri-state control
assign gpio0 = (reg_3[0]==1'b1) ? reg_0_w : {8{1'bz}};
assign gpio1 = (reg_3[1]==1'b1) ? reg_1_w : 8'bz;
assign gpio2 = (reg_3[2]==1'b1) ? reg_2_w : 8'hz;
// decode for the read and write of addressed registers
assign reg_0_sel_r = (addr_reg==2'b00 && cs_n_reg==1'b0 &&
rd_n_reg==1'b0);
assign reg_1_sel_r = (addr_reg==2'b01 && cs_n_reg==1'b0 &&
rd_n_reg==1'b0);
assign reg_2_sel_r = (addr_reg==2'b10 && cs_n_reg==1'b0 &&
rd_n_reg==1'b0);
assign reg_3_sel_r = (addr_reg==2'b11 && cs_n_reg==1'b0 &&
rd_n_reg==1'b0);
assign reg_sel_r = {reg_3_sel_r, reg_2_sel_r, reg_1_sel_r,
reg_0_sel_r};
assign reg_0_sel_w = (addr_reg==2'b00 && cs_n_reg==1'b0 &&
wr_n_reg==1'b0);
assign reg_1_sel_w = (addr_reg==2'b01 && cs_n_reg==1'b0 &&
wr_n_reg==1'b0);
assign reg_2_sel_w = (addr_reg==2'b10 && cs_n_reg==1'b0 &&
wr_n_reg==1'b0);
assign reg_3_sel_w = (addr_reg==2'b11 && cs_n_reg==1'b0 &&
wr_n_reg==1'b0);
assign reg_sel_w = {reg_3_sel_w, reg_2_sel_w, reg_1_sel_w,
reg_0_sel_w};
// write of internal registers
always@(posedge clk or negedge reset)
begin
if(!reset) begin
reg_0_w <= #1 8'h00;
reg_1_w <= #1 8'h00;
reg_2_w <= #1 8'h00;
reg_3 <= #1 3'b000;
end
else
case (reg_sel_w)
4'b0001 : reg_0_w <= #1 data;
4'b0010 : reg_1_w <= #1 data;
4'b0100 : reg_2_w <= #1 data;
4'b1000 : reg_3 <= #1 data[2:0];
endcase
end
// register sampling of GPIO input ports
always@(posedge clk or negedge reset)
begin
if(!reset) begin
reg_0_r <= #1 8'h00;
reg_1_r <= #1 8'h00;
reg_2_r <= #1 8'h00;
end
else begin
reg_0_r <= #1 gpio0;
reg_1_r <= #1 gpio1;
reg_2_r <= #1 gpio2;
end
end
// read of input registers to tri-state data bus
wire data_rd_ctl;
reg [7:0] data_mux;
assign data_rd_ctl = |reg_sel_r;
assign data = (data_rd_ctl==1'b1) ? data_mux : 8'bz;
always@(reg_sel_r or reg_0_r or reg_1_r or reg_2_r or reg_3)
begin
case (reg_sel_r)
4'b0001 : data_mux = reg_0_r;
4'b0010 : data_mux = reg_1_r;
4'b0100 : data_mux = reg_2_r;
4'b1000 : data_mux = {5'b00000, reg_3};
default : data_mux = 8'h00;
endcase
end
endmodule
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -