?? c_16450_v.htm
字號:
assign NEXT_STATE = ((CLOCK_DIVIDER == 4'b1111) || ((CLOCK_DIVIDER == 4'b1110) && (RECEIVING_STOP_BIT == 1'b1)) || (RECEIVER_IDLE_BREAK == 1'b1)) ? CE : 1'b0;
assign CATCH_ENABLE = (CLOCK_DIVIDER == 4'b0111) ? CE : 1'b0;
always @(posedge CLK or negedge RESET)
if (RESET == 1'b0)
RECEIVER_STATE <= `IDLE_STATE;
else
if (NEXT_STATE == 1'b1)
case (RECEIVER_STATE)
`IDLE_STATE :
if (SERIAL_IN == 1'b0)
RECEIVER_STATE <= `START_STATE;
`START_STATE :
if (START_CONFIRMED == 1'b1)
RECEIVER_STATE <= `BIT0_STATE;
else
RECEIVER_STATE <= `IDLE_STATE;
`BIT0_STATE :
RECEIVER_STATE <= `BIT1_STATE;
`BIT1_STATE :
RECEIVER_STATE <= `BIT2_STATE;
`BIT2_STATE :
RECEIVER_STATE <= `BIT3_STATE;
`BIT3_STATE :
RECEIVER_STATE <= `BIT4_STATE;
`BIT4_STATE :
if (BITS_COUNT == 2'b00)
begin
if (PARITY_ENABLE == 1'b1)
RECEIVER_STATE <= `PARITY_STATE;
else
RECEIVER_STATE <= `STOP_STATE;
end
else
RECEIVER_STATE <= `BIT5_STATE;
`BIT5_STATE :
if (BITS_COUNT[1] == 1'b0)
begin
if (PARITY_ENABLE == 1'b1)
RECEIVER_STATE <= `PARITY_STATE;
else
RECEIVER_STATE <= `STOP_STATE;
end
else
RECEIVER_STATE <= `BIT6_STATE;
`BIT6_STATE :
if (BITS_COUNT[0] == 1'b0)
begin
if (PARITY_ENABLE == 1'b1)
RECEIVER_STATE <= `PARITY_STATE;
else
RECEIVER_STATE <= `STOP_STATE;
end
else
RECEIVER_STATE <= `BIT7_STATE;
`BIT7_STATE :
if (PARITY_ENABLE == 1'b1)
RECEIVER_STATE <= `PARITY_STATE;
else
RECEIVER_STATE <= `STOP_STATE;
`PARITY_STATE :
RECEIVER_STATE <= `STOP_STATE;
`STOP_STATE :
if ((BREAK_DETECTOR == 1'b0) && (STOP_BIT == 1'b0) && (PARITY_REGISTER == 1'b0))
RECEIVER_STATE <= `BREAK_STATE;
else
RECEIVER_STATE <= `IDLE_STATE;
`BREAK_STATE :
if (SERIAL_IN == 1'b1)
RECEIVER_STATE <= `IDLE_STATE;
default :
RECEIVER_STATE <= `IDLE_STATE;
endcase
assign LINE_STATUS_INTERRUPT = (BREAK_DETECTED || FRAME_ERROR || OVERRUN_ERROR || PARITY_ERROR);
assign LSR_OUT = {BREAK_DETECTED, FRAME_ERROR, PARITY_ERROR, OVERRUN_ERROR, RHR_FULL};
endmodule
module TransmitterCore (CLK, CE, BREAK, LOOPBACK, RESET, DATA_IN, WR, RD,
IID_EN, THR_EN, SERIAL_OUT, INTERNAL_SO, TRANSMITTER_INTERRUPT_ACK,
TRANSMITTER_INTERRUPT, BITS_COUNT, PARITY_ENABLE, PARITY_EVEN_nODD,
STICK_PARITY, STOP_BITS, LSR_MSB);
input CLK;
wire CLK;
input CE;
wire CE;
input BREAK;
wire BREAK;
input LOOPBACK;
wire LOOPBACK;
input RESET;
wire RESET;
input [7:0] DATA_IN;
wire [7:0] DATA_IN;
input WR;
wire WR;
input RD;
wire RD;
input IID_EN;
wire IID_EN;
input THR_EN;
wire THR_EN;
output SERIAL_OUT;
wire SERIAL_OUT;
output INTERNAL_SO;
wire INTERNAL_SO;
input TRANSMITTER_INTERRUPT_ACK;
wire TRANSMITTER_INTERRUPT_ACK;
output TRANSMITTER_INTERRUPT;
wire TRANSMITTER_INTERRUPT;
input [1:0] BITS_COUNT;
wire [1:0] BITS_COUNT;
input PARITY_ENABLE;
wire PARITY_ENABLE;
input PARITY_EVEN_nODD;
wire PARITY_EVEN_nODD;
input STICK_PARITY;
wire STICK_PARITY;
input STOP_BITS;
wire STOP_BITS;
output [1:0] LSR_MSB;
wire [1:0] LSR_MSB;
reg [4:0] BITS_COUNTER;
reg [3:0] CLK_DIVIDER_BY_16;
wire CLK_8_CE, CLK_16_CE;
wire [3:0] TEMP;
reg [5:0] BITS_TO_TRANSFER;
reg [9:0] DATA_TO_TRANSFER;
reg [9:0] SHIFT_REGISTER;
reg TRANSMISSION_IN_PROGRESS;
reg INTERNAL_START;
wire [2:0] THR_TEMP;
wire PARITY_TEMP;
wire PARITY;
reg [7:0] THR;
reg START, RESET_START;
wire START_RESET, RESET_START_RESET;
wire RESET_INTERRUPT_RESET;
wire INTERRUPT_TEMP_RESET;
reg INTERRUPT_TEMP;
reg RESET_INTERRUPT1;
reg RESET_INTERRUPT2;
assign RESET_INTERRUPT_RESET = ((RESET == 1'b0) || (INTERRUPT_TEMP == 1'b0)) ? 1'b1 : 1'b0;
always @(posedge RD or posedge RESET_INTERRUPT_RESET)
if (RESET_INTERRUPT_RESET == 1'b1)
RESET_INTERRUPT1 <= 1'b0;
else if (IID_EN == 1'b1)
RESET_INTERRUPT1 <= TRANSMITTER_INTERRUPT_ACK;
always @(posedge WR or posedge RESET_INTERRUPT_RESET)
if (RESET_INTERRUPT_RESET == 1'b1)
RESET_INTERRUPT2 <= 1'b0;
else if (THR_EN == 1'b1)
RESET_INTERRUPT2 <= 1'b1;
assign INTERRUPT_TEMP_RESET = ((RESET == 1'b0) || (RESET_INTERRUPT1 == 1'b1) || (RESET_INTERRUPT2 == 1'b1)) ? 1'b1 : 1'b0;
always @(posedge CLK or posedge INTERRUPT_TEMP_RESET)
if (INTERRUPT_TEMP_RESET == 1'b1)
INTERRUPT_TEMP <= 1'b0;
else if (CE == 1'b1)
if (INTERNAL_START == 1'b1)
INTERRUPT_TEMP <= 1'b1;
assign TRANSMITTER_INTERRUPT = INTERRUPT_TEMP;
always @(posedge WR or negedge RESET)
if (RESET == 1'b0)
THR <= 8'b00000000;
else if (THR_EN == 1'b1)
THR <= DATA_IN;
assign START_RESET = ((RESET == 1'b0) || (RESET_START == 1'b1)) ? 1'b1 : 1'b0;
always @(posedge WR or posedge START_RESET)
if (START_RESET == 1'b1)
START <= 1'b0;
else if (THR_EN == 1'b1)
START <= 1'b1;
assign RESET_START_RESET = ((START == 1'b0) || (RESET == 1'b0)) ? 1'b1 : 1'b0;
always @(posedge CLK or posedge RESET_START_RESET)
if (RESET_START_RESET == 1'b1)
RESET_START <= 1'b0;
else if (CE == 1'b1)
RESET_START <= INTERNAL_START;
assign THR_TEMP[0] = THR[5] && (BITS_COUNT[0] || BITS_COUNT[1]);
assign THR_TEMP[1] = THR[6] && BITS_COUNT[1];
assign THR_TEMP[2] = THR[7] && BITS_COUNT[0] && BITS_COUNT[1];
assign PARITY_TEMP = THR[0] ^ THR[1] ^ THR[2] ^ THR[3] ^ THR[4] ^ THR_TEMP[0] ^ THR_TEMP[1] ^ THR_TEMP[2];
assign PARITY = (STICK_PARITY == 1'b1) ? !PARITY_EVEN_nODD : !PARITY_EVEN_nODD ^ PARITY_TEMP;
always @(posedge CLK or negedge RESET)
if (RESET == 1'b0)
CLK_DIVIDER_BY_16 <= 4'b0000;
else if (CE == 1'b1)
if (INTERNAL_START == 1'b1)
CLK_DIVIDER_BY_16 <= 4'b0000;
else
CLK_DIVIDER_BY_16 <= CLK_DIVIDER_BY_16 + 1;
assign CLK_8_CE = (CLK_DIVIDER_BY_16[2:0] == 3'b111) ? 1'b1 : 1'b0;
assign CLK_16_CE = (CLK_DIVIDER_BY_16 == 4'b1111) ? 1'b1 : 1'b0;
assign TEMP = {BITS_COUNT, PARITY_ENABLE, STOP_BITS};
always @(TEMP)
case (TEMP)
4'b0000 : BITS_TO_TRANSFER = 5'b01110;
4'b0001 : BITS_TO_TRANSFER = 5'b01111;
4'b0010 : BITS_TO_TRANSFER = 5'b10000;
4'b0011 : BITS_TO_TRANSFER = 5'b10001;
4'b0100 : BITS_TO_TRANSFER = 5'b10000;
4'b0101 : BITS_TO_TRANSFER = 5'b10010;
4'b0110 : BITS_TO_TRANSFER = 5'b10010;
4'b0111 : BITS_TO_TRANSFER = 5'b10100;
4'b1000 : BITS_TO_TRANSFER = 5'b10010;
4'b1001 : BITS_TO_TRANSFER = 5'b10100;
4'b1010 : BITS_TO_TRANSFER = 5'b10100;
4'b1011 : BITS_TO_TRANSFER = 5'b10110;
4'b1100 : BITS_TO_TRANSFER = 5'b10100;
4'b1101 : BITS_TO_TRANSFER = 5'b10110;
4'b1110 : BITS_TO_TRANSFER = 5'b10110;
4'b1111 : BITS_TO_TRANSFER = 5'b11000;
default : BITS_TO_TRANSFER = 5'b10100;
endcase
always @(posedge CLK or negedge RESET)
if (RESET == 1'b0)
BITS_COUNTER <= 5'b00000;
else if (CE == 1'b1)
if (INTERNAL_START == 1'b1)
BITS_COUNTER <= BITS_TO_TRANSFER;
else
if (CLK_8_CE == 1'b1)
BITS_COUNTER <= BITS_COUNTER - 1;
always @(posedge CLK or negedge RESET)
if (RESET == 1'b0)
INTERNAL_START <= 1'b0;
else if (CE == 1'b1)
if ((START == 1'b1 && INTERNAL_START == 1'b0) && (TRANSMISSION_IN_PROGRESS == 1'b0 || (BITS_COUNTER[4:1] == 4'b0000 && CLK_DIVIDER_BY_16[2:0] == 3'b110)))
INTERNAL_START <= 1'b1;
else
INTERNAL_START <= 1'b0;
always @(BITS_COUNT or PARITY_ENABLE or THR or PARITY)
begin
DATA_TO_TRANSFER = {1'b0, THR[0], THR[1], THR[2], THR[3], THR[4], 1'b1, 1'b1, 1'b1, 1'b1};
case (BITS_COUNT)
2'b00 :
if (PARITY_ENABLE == 1'b1)
DATA_TO_TRANSFER[3] = PARITY;
2'b01 : begin
DATA_TO_TRANSFER[3] = THR[5];
if (PARITY_ENABLE == 1'b1)
DATA_TO_TRANSFER[2] = PARITY;
end
2'b10 : begin
DATA_TO_TRANSFER[3:2] = {THR[5], THR[6]};
if (PARITY_ENABLE == 1'b1)
DATA_TO_TRANSFER[1] = PARITY;
end
2'b11 : begin
DATA_TO_TRANSFER[3:1] = {THR[5], THR[6], THR[7]};
if (PARITY_ENABLE == 1'b1)
DATA_TO_TRANSFER[0] = PARITY;
end
default : DATA_TO_TRANSFER = 10'b1111111111;
endcase
end
always @(posedge CLK or negedge RESET)
if (RESET == 1'b0)
TRANSMISSION_IN_PROGRESS <= 1'b0;
else if (CE == 1'b1)
if (INTERNAL_START == 1'b1)
TRANSMISSION_IN_PROGRESS <= 1'b1;
else if ((BITS_COUNTER[4:1] == 4'b0000) && (CLK_8_CE == 1'b1))
TRANSMISSION_IN_PROGRESS <= 1'b0;
always @(posedge CLK or negedge RESET)
if (RESET == 1'b0)
SHIFT_REGISTER <= 10'b1111111111;
else if (CE == 1'b1)
if (INTERNAL_START == 1'b1)
SHIFT_REGISTER <= DATA_TO_TRANSFER;
else
if (CLK_16_CE == 1'b1)
SHIFT_REGISTER <= {SHIFT_REGISTER[8:0], 1'b1};
assign LSR_MSB[1] = !(TRANSMISSION_IN_PROGRESS || START);
assign LSR_MSB[0] = !START;
assign INTERNAL_SO = (BREAK == 1'b1) ? 1'b0 : SHIFT_REGISTER[9];
assign SERIAL_OUT = (BREAK == 1'b1 && LOOPBACK == 1'b0) ? 1'b0 : ((LOOPBACK == 1'b1) ? 1'b1 : SHIFT_REGISTER[9]);
endmodule
module BaudGenerator (CLK, RESET, CE, CE_OUT, TRANSMITTER_CE, DIV_VAL);
input CLK;
wire CLK;
input RESET;
wire RESET;
input CE;
wire CE;
output CE_OUT;
wire CE_OUT;
output TRANSMITTER_CE;
wire TRANSMITTER_CE;
input [15:0] DIV_VAL;
wire [15:0] DIV_VAL;
reg [15:0] COUNTER;
reg DIVIDE_BY_ZERO;
reg CE_TEMP;
wire RELOAD;
always @(posedge CLK or negedge RESET)
if (RESET == 1'b0)
COUNTER <= 16'b0000000000000001;
else if (CE == 1'b1)
if (RELOAD == 1'b1)
COUNTER <= DIV_VAL;
else
COUNTER <= COUNTER - 1;
assign RELOAD = COUNTER[15:1] == 15'b000000000000000 ? 1'b1 : 1'b0;
always @(posedge CLK or negedge RESET)
if (RESET == 1'b0)
CE_TEMP <= 1'b0;
else if (CE == 1'b1)
CE_TEMP <= RELOAD;
else
CE_TEMP <= 1'b0;
always @(posedge CLK or negedge RESET)
if (RESET == 1'b0)
DIVIDE_BY_ZERO <= 1'b0;
else if (CE == 1'b1)
if (DIV_VAL == 16'b0000000000000000)
DIVIDE_BY_ZERO <= 1'b1;
else
DIVIDE_BY_ZERO <= 1'b0;
assign TRANSMITTER_CE = CE_TEMP && !DIVIDE_BY_ZERO;
assign CE_OUT = CE_TEMP;
endmodule
module InterruptControlLogic (CLK, RESET, CE, WR, RD, DATA_IN, IER_EN, IID_EN,
IER_OUT, IID_OUT, TRANSMITTER_INTERRUPT, TRANSMITTER_INTERRUPT_ACK,
RECEIVER_INTERRUPT, LINE_STATUS_INTERRUPT, MODEM_CONTROL_INTERRUPT,
INTERRUPT);
input CLK;
wire CLK;
input RESET;
wire RESET;
input CE;
wire CE;
input WR;
wire WR;
input RD;
wire RD;
input [7:0] DATA_IN;
wire [7:0] DATA_IN;
input IER_EN;
wire IER_EN;
input IID_EN;
wire IID_EN;
output [3:0] IER_OUT;
wire [3:0] IER_OUT;
output [2:0] IID_OUT;
wire [2:0] IID_OUT;
input TRANSMITTER_INTERRUPT;
wire TRANSMITTER_INTERRUPT;
output TRANSMITTER_INTERRUPT_ACK;
reg TRANSMITTER_INTERRUPT_ACK;
input RECEIVER_INTERRUPT;
wire RECEIVER_INTERRUPT;
input LINE_STATUS_INTERRUPT;
wire LINE_STATUS_INTERRUPT;
input MODEM_CONTROL_INTERRUPT;
wire MODEM_CONTROL_INTERRUPT;
output INTERRUPT;
wire INTERRUPT;
reg IER_3;
reg IER_2;
reg IER_1;
reg IER_0;
reg [2:0] IID;
wire TRANSMITTER_INT;
wire TRANSMITTER_INTERRUPT_ACK_RESET;
wire RECEIVER_INT;
wire MODEM_INT;
wire LINE_INT;
reg INTERRUPT_REG;
always @(posedge WR or negedge RESET)
if (RESET == 1'b0)
begin
IER_3 <= 1'b0;
IER_2 <= 1'b0;
IER_1 <= 1'b0;
IER_0 <= 1'b0;
end
else if (IER_EN == 1'b1)
begin
IER_3 <= DATA_IN[3];
IER_2 <= DATA_IN[2];
IER_1 <= DATA_IN[1];
IER_0 <= DATA_IN[0];
end
assign IER_OUT = {IER_3, IER_2, IER_1, IER_0};
assign RECEIVER_INT = RECEIVER_INTERRUPT && IER_0;
assign TRANSMITTER_INT = TRANSMITTER_INTERRUPT && IER_1;
assign LINE_INT = LINE_STATUS_INTERRUPT && IER_2;
assign MODEM_INT = MODEM_CONTROL_INTERRUPT && IER_3;
always @(posedge CLK or negedge RESET)
if (RESET == 1'b0)
INTERRUPT_REG <= 1'b0;
else if (CE == 1'b1)
INTERRUPT_REG <= (TRANSMITTER_INT || MODEM_INT || LINE_INT || RECEIVER_INT);
assign INTERRUPT = INTERRUPT_REG;
always @(negedge RD or negedge RESET)
if (RESET == 1'b0)
IID <= 3'b001;
else if (IID_EN == 1'b1)
IID <= {(LINE_INT || RECEIVER_INT), (LINE_INT || (TRANSMITTER_INT && !RECEIVER_INT)), !INTERRUPT_REG};
assign IID_OUT = IID;
assign TRANSMITTER_INTERRUPT_ACK_RESET = ((RESET == 1'b0) || (TRANSMITTER_INTERRUPT == 1'b0)) ? 1'b1 : 1'b0;
always @(posedge RD or posedge TRANSMITTER_INTERRUPT_ACK_RESET)
if (TRANSMITTER_INTERRUPT_ACK_RESET == 1'b1)
TRANSMITTER_INTERRUPT_ACK <= 1'b0;
else if (IID_EN == 1'b1)
if (IID == 3'b010)
TRANSMITTER_INTERRUPT_ACK <= 1'b0;
endmodule
module ChangeDetector (RESET, RD, CE, CLK, MSR_EN, INIT, INPUT, OUTPUT, DELTA_OUTPUT);
input RESET;
wire RESET;
input RD;
?? 快捷鍵說明
復制代碼
Ctrl + C
搜索代碼
Ctrl + F
全屏模式
F11
切換主題
Ctrl + Shift + D
顯示快捷鍵
?
增大字號
Ctrl + =
減小字號
Ctrl + -