📄 intface.v
字号:
always @(posedge clk or posedge reset) begin
if (reset)
data_8bit <= 8'b11111111;
else if (cyc_i && stb_i && ~we_i)
case (adr_i[ADDRWIDTH-1:0])
A_RBR: data_8bit <= rbr;
A_IIR: data_8bit <= {4'b0000, iir};
A_LSR: data_8bit <= {1'b0,lsr};
`ifdef MODEM
A_MSR: data_8bit <= msr;
`endif
default: data_8bit <= 8'b11111111;
endcase
end
end
endgenerate
assign dat_o = {24'h000000,data_8bit};
generate
if (FIFO == 0)
begin
always @(posedge clk or posedge reset) begin
if (reset) begin
thr_nonfifo <= 0;
`ifdef MODEM
ier <= 4'b0000;
mcr <= 2'b00;
`else
ier <= 3'b000;
`endif
lcr <= 7'h00; end
else if (cyc_i && stb_i && we_i)
case (adr_i[ADDRWIDTH-1:0])
A_THR: thr_nonfifo <= dat_i[7:0];
`ifdef MODEM
A_IER: ier <= dat_i[3:0];
A_MCR: mcr <= dat_i[1:0];
`else
A_IER: ier <= dat_i[2:0];
`endif
A_LCR: lcr <= dat_i[6:0];
default: ;
endcase
end
end
else
begin
always @(posedge clk or posedge reset) begin
if (reset) begin
`ifdef MODEM
ier <= 4'b0000;
mcr <= 2'b00;
`else
ier <= 3'b000;
`endif
lcr <= 7'h00; end
else if (cyc_i && stb_i && we_i)
case (adr_i[ADDRWIDTH-1:0])
`ifdef MODEM
A_IER: ier <= dat_i[3:0];
A_MCR: mcr <= dat_i[1:0];
`else
A_IER: ier <= dat_i[2:0];
`endif
A_LCR: lcr <= dat_i[6:0];
default: ;
endcase
end
end
endgenerate
generate
if (FIFO == 1) begin
assign fifo_wr_pulse_thr = thr_wr_strobe;
assign fifo_din_thr = dat_i[7:0];
txcver_fifo TX_FIFO(
.Data (fifo_din_thr),
.Clock (clk),
.WrEn (fifo_wr_pulse_thr),
.RdEn (thr_rd),
.Reset (reset),
.Q (thr_fifo),
.Empty (fifo_empty_thr),
.Full (fifo_full_thr),
.AlmostEmpty (fifo_almost_empty_thr),
.AlmostFull (fifo_almost_full_thr)
);
end
endgenerate
////////////////////////////////////////////////////////////////////////////////
// Line Control Register
////////////////////////////////////////////////////////////////////////////////
// databits : "00"=5-bit, "01"=6-bit, "10"=7-bit, "11"=8-bit
assign databits = lcr[1:0];
// stopbits : "00"=1-bit, "01"=1.5-bit(5-bit data), "10"=2-bit(6,7,8-bit data)
assign stopbits = (lcr[2] == 1'b0) ? 2'b00 : (lcr[2:0] == 3'b100) ? 2'b01 : 2'b10;
// parity_en : '0'=Parity Bit Enable, '1'=Parity Bit Disable
assign parity_en = lcr[3];
// parity_even : '0'=Even Parity Selected, '1'=Odd Parity Selected
assign parity_even = lcr[4];
// parity_stick : '0'=Stick Parity Disable, '1'=Stick Parity Enable
assign parity_stick = lcr[5];
// tx_break : '0'=Disable BREAK assertion, '1'=Assert BREAK
assign tx_break = lcr[6];
////////////////////////////////////////////////////////////////////////////////
// Line Status Register
////////////////////////////////////////////////////////////////////////////////
generate
if (FIFO == 1) begin
always @(posedge clk or posedge reset)
if (reset)
lsr2_r <= 1'b0;
else if (parity_err)
lsr2_r <= 1'b1;
else if (lsr_rd_strobe)
lsr2_r <= 1'b0;
always @(posedge clk or posedge reset)
if (reset)
lsr3_r <= 1'b0;
else if (frame_err)
lsr3_r <= 1'b1;
else if (lsr_rd_strobe)
lsr3_r <= 1'b0;
always @(posedge clk or posedge reset)
if (reset)
lsr4_r <= 1'b0;
else if (break_int)
lsr4_r <= 1'b1;
else if (lsr_rd_strobe)
lsr4_r <= 1'b0;
always @(posedge clk)
lsr <= {temt , thre , lsr4_r , lsr3_r , lsr2_r , overrun_err , rx_rdy};
end
else
always @(temt or thre or break_int or frame_err or parity_err or overrun_err or rx_rdy)
lsr = {temt , thre , break_int , frame_err , parity_err , overrun_err , rx_rdy};
endgenerate
////////////////////////////////////////////////////////////////////////////////
// Interrupt Arbitrator
////////////////////////////////////////////////////////////////////////////////
// Int is the common interrupt line for all internal UART events
`ifdef MODEM
assign intr = rx_rdy_int | thre_int | dataerr_int | modem_int;
`else
assign intr = rx_rdy_int | thre_int | dataerr_int;
`endif
// Receiving Data Error Flags including Overrun, Parity, Framing and Break
generate
if (FIFO == 1)
assign data_err = overrun_err | lsr2_r | lsr3_r | lsr4_r;
else
assign data_err = overrun_err | parity_err | frame_err | break_int;
endgenerate
// Whenever bit0, 1, 2,or 3 is set to '1', A_WB Modem Status Interrupt is generated
`ifdef MODEM
assign modem_stat = msr[0] | msr[1] | msr[2] | msr[3];
`endif
generate
if (FIFO == 1)
always @(posedge clk or posedge reset)
if (reset)
iir_rd_strobe_delay <= 1'b0;
else
iir_rd_strobe_delay <= iir_rd_strobe;
endgenerate
// State Machine Definition
parameter idle = 3'b000;
parameter int0 = 3'b001;
parameter int1 = 3'b010;
parameter int2 = 3'b011;
parameter int3 = 3'b100;
reg [2:0] cs_state;
generate
if (FIFO == 1) begin
always @(posedge clk or posedge reset) begin
if (reset)
cs_state <= idle;
else
case (cs_state)
idle: begin
if (ier[2] == 1'b1 && data_err == 1'b1 )
cs_state <= int0;
else if (ier[0] == 1'b1 && (fifo_almost_full || !fifo_empty) )
cs_state <= int1;
else if (ier[1] == 1'b1 && thre == 1'b1)
cs_state <= int2;
`ifdef MODEM
else if (ier[3] == 1'b1 && modem_stat == 1'b1)
cs_state <= int3;
`endif
end
int0: begin
if ((lsr_rd_strobe == 1'b1) || (ier[2] == 1'b0)) begin
if (ier[0] == 1'b1 && fifo_almost_full)
cs_state <= int1;
else
cs_state <= idle; end
end
int1: begin
if (data_err == 1'b1 && ier[2] == 1'b1)
cs_state <= int0;
else if (!fifo_almost_full || (ier[0] == 1'b0))
cs_state <= idle;
end
int2: begin
if (iir_rd_strobe_delay || (thre == 1'b0) || (ier[1] == 1'b0))
cs_state <= idle;
end
`ifdef MODEM
int3: begin
if ((msr_rd_strobe)|| (ier[3] == 1'b0))
cs_state <= idle;
end
`endif
default: cs_state <= idle;
endcase
end end
else begin
always @(posedge clk or posedge reset) begin
if (reset)
cs_state <= idle;
else
case (cs_state)
idle: begin
if (ier[2] == 1'b1 && data_err == 1'b1)
cs_state <= int0;
else if (ier[0] == 1'b1 && rx_rdy == 1'b1)
cs_state <= int1;
else if (ier[1] == 1'b1 && thre == 1'b1)
cs_state <= int2;
`ifdef MODEM
else if (ier[3] == 1'b1 && modem_stat == 1'b1)
cs_state <= int3;
`endif
end
int0: begin
if ((lsr_rd_strobe == 1'b1) || (ier[2] == 1'b0)) begin
if (ier[0] == 1'b1 && rx_rdy)
cs_state <= int1;
else
cs_state <= idle; end
end
int1: begin
if (data_err == 1'b1 && ier[2] == 1'b1)
cs_state <= int0;
else if ((rx_rdy == 1'b0) || (ier[0] == 1'b0))
cs_state <= idle;
end
int2: begin
if (iir_rd_strobe || (thre == 1'b0) || (ier[1] == 1'b0))
cs_state <= idle;
end
`ifdef MODEM
int3: begin
if ((msr_rd_strobe)|| (ier[3] == 1'b0))
cs_state <= idle;
end
`endif
default: cs_state <= idle;
endcase
end
end
endgenerate
// ACK signal generate
always @(posedge clk or posedge reset) begin
if (reset)
ack_o <= 1'b0;
else if (ack_o)
ack_o <= 1'b0;
else if (cyc_i & stb_i)
ack_o <= 1'b1;
end
// Set Receiver Line Status Interrupt
assign dataerr_int = (cs_state == int0) ? 1'b1 : 1'b0;
// Set Received Data Available Interrupt
assign rx_rdy_int = (cs_state == int1) ? 1'b1 : 1'b0;
// Set thr Empty Interrupt
assign thre_int = (cs_state == int2) ? 1'b1 : 1'b0;
// Set MODEM Status Interrupt
`ifdef MODEM
assign modem_int = (cs_state == int3) ? 1'b1 : 1'b0;
`endif
// Update IIR
assign iir = (cs_state == int0) ? 4'b0110 :
(cs_state == int1) ? 4'b0100 :
(cs_state == int2) ? 4'b0010 :
`ifdef MODEM
(cs_state == int3) ? 4'b0000 :
`endif
4'b0001 ; // No Interrupt Pending
endmodule
`endif // INTFACE_FILE
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -