/******************************************************************
|
/******************************************************************
|
* *
|
* *
|
* Author: Liwei *
|
* Author: Liwei *
|
* *
|
* *
|
* This file is part of the "mips789" project. *
|
* This file is part of the "mips789" project. *
|
* Downloaded from: *
|
* Downloaded from: *
|
* http://www.opencores.org/pdownloads.cgi/list/mips789 *
|
* http://www.opencores.org/pdownloads.cgi/list/mips789 *
|
* *
|
* *
|
* If you encountered any problem, please contact me via *
|
* If you encountered any problem, please contact me via *
|
* Email:mcupro@opencores.org or mcupro@163.com *
|
* Email:mcupro@opencores.org or mcupro@163.com *
|
* *
|
* *
|
******************************************************************/
|
******************************************************************/
|
|
|
`include "mips789_defs.v"
|
`include "mips789_defs.v"
|
|
|
module rxd_d(input clr,input clk,input d,output reg q );
|
module rxd_d(input clr,input clk,input d,output reg q );
|
|
|
always @(posedge clk)
|
always @(posedge clk)
|
|
|
if (clr) q<=0;
|
if (clr) q<=0;
|
else q<=d|q;
|
else q<=d|q;
|
|
|
endmodule
|
endmodule
|
|
|
module uart0 (
|
module uart0 (
|
clk,rst,rxd_ft,ser_rxd,txd_ld,
|
clk,rst,rxd_ft,ser_rxd,txd_ld,
|
din,rxd_rdy,ser_txd,txd_busy,dout) ;
|
din,rxd_rdy,ser_txd,txd_busy,dout) ;
|
input clk;
|
input clk;
|
wire clk;
|
wire clk;
|
input rst;
|
input rst;
|
wire rst;
|
wire rst;
|
input rxd_ft;
|
input rxd_ft;
|
wire rxd_ft;
|
wire rxd_ft;
|
input ser_rxd;
|
input ser_rxd;
|
wire ser_rxd;
|
wire ser_rxd;
|
input txd_ld;
|
input txd_ld;
|
wire txd_ld;
|
wire txd_ld;
|
input [7:0] din;
|
input [7:0] din;
|
wire [7:0] din;
|
wire [7:0] din;
|
output rxd_rdy;
|
output rxd_rdy;
|
wire rxd_rdy;
|
wire rxd_rdy;
|
output ser_txd;
|
output ser_txd;
|
wire ser_txd;
|
wire ser_txd;
|
output txd_busy;
|
output txd_busy;
|
wire txd_busy;
|
wire txd_busy;
|
output [7:0] dout;
|
output [7:0] dout;
|
wire [7:0] dout;
|
wire [7:0] dout;
|
|
|
wire clk_uart=clk;
|
wire clk_uart=clk;
|
wire w_rxd_rdy;
|
wire w_rxd_rdy;
|
|
|
uart_read uart_rd_tak(
|
uart_read uart_rd_tak(
|
.sync_reset(rst),
|
.sync_reset(rst),
|
.clk(clk),
|
.clk(clk),
|
.rxd(ser_rxd),
|
.rxd(ser_rxd),
|
.buffer_reg(dout),
|
.buffer_reg(dout),
|
.int_req(w_rxd_rdy)
|
.int_req(w_rxd_rdy)
|
);
|
);
|
|
|
rxd_d rxd_rdy_hold_lw
|
rxd_d rxd_rdy_hold_lw
|
(
|
(
|
.clk(clk_uart),
|
.clk(clk_uart),
|
.clr(rxd_ft),
|
.clr(rxd_ft),
|
.d(w_rxd_rdy),
|
.d(w_rxd_rdy),
|
.q(rxd_rdy)
|
.q(rxd_rdy)
|
);
|
);
|
|
|
uart_write uart_txd
|
uart_write uart_txd
|
(
|
(
|
.sync_reset(rst),
|
.sync_reset(rst),
|
.clk(clk),
|
.clk(clk),
|
.txd(ser_txd),
|
.txd(ser_txd),
|
.data_in(din) ,
|
.data_in(din) ,
|
.write_request(txd_ld),
|
.write_request(txd_ld),
|
//.write_done(),
|
//.write_done(),
|
.write_busy(txd_busy)
|
.write_busy(txd_busy)
|
);
|
);
|
|
|
endmodule
|
endmodule
|
|
|
//These modules below are modified slight by Liwei based on YACC,an CPU core in opencores.
|
//These modules below are modified slight by Liwei based on YACC,an CPU core in opencores.
|
//Thank you TAK
|
//Thank you TAK
|
|
|
module uart_write( sync_reset, clk, txd, data_in , write_request,write_done,write_busy);
|
module uart_write( sync_reset, clk, txd, data_in , write_request,write_done,write_busy);
|
input sync_reset,clk;
|
input sync_reset,clk;
|
input [7:0] data_in;
|
input [7:0] data_in;
|
input write_request;
|
input write_request;
|
output txd,write_done;
|
output txd,write_done;
|
output write_busy;
|
output write_busy;
|
|
|
|
|
|
|
wire queue_full;
|
wire queue_full;
|
wire queing, read_request;
|
wire queing, read_request;
|
wire [7:0] queue_data;
|
wire [7:0] queue_data;
|
reg read_request_ff;
|
reg read_request_ff;
|
|
|
|
|
//________|--|___write_request (upper module : its period should be 1clock time.)
|
//________|--|___write_request (upper module : its period should be 1clock time.)
|
//__________________________|-|______write_done (Responds by this module posedge interrupt)
|
//__________________________|-|______write_done (Responds by this module posedge interrupt)
|
//With 512Bytes FIFO.
|
//With 512Bytes FIFO.
|
//No error handling is supported.
|
//No error handling is supported.
|
|
|
reg [15:0] clk_ctr;//liwei
|
reg [15:0] clk_ctr;//liwei
|
reg [2:0] bit_ctr;
|
reg [2:0] bit_ctr;
|
reg [2:0] ua_state;
|
reg [2:0] ua_state;
|
reg [7:0] tx_sr;
|
reg [7:0] tx_sr;
|
reg txd;
|
reg txd;
|
|
|
wire clk_ctr_equ15, clk_ctr_equ31, bit_ctr_equ7,
|
wire clk_ctr_equ15, clk_ctr_equ31, bit_ctr_equ7,
|
clk_ctr_enable_state, bit_ctr_enable_state ;
|
clk_ctr_enable_state, bit_ctr_enable_state ;
|
wire tx_state;
|
wire tx_state;
|
wire empty;
|
wire empty;
|
assign write_busy=queue_full;//Apr.2.2005
|
assign write_busy=queue_full;//Apr.2.2005
|
|
|
always @ (posedge clk) begin
|
always @ (posedge clk) begin
|
if (~sync_reset) read_request_ff<=1'b0;
|
if (~sync_reset) read_request_ff<=1'b0;
|
else read_request_ff<=read_request;
|
else read_request_ff<=read_request;
|
end
|
end
|
|
|
assign queing= !empty;
|
assign queing= !empty;
|
assign read_request = queing && ua_state==3'b000;//Jul.14.2004
|
assign read_request = queing && ua_state==3'b000;//Jul.14.2004
|
|
|
assign write_done=ua_state==3'b101;
|
assign write_done=ua_state==3'b101;
|
|
|
`ifdef ALTERA
|
`ifdef ALTERA
|
fifo512_cyclone alt_fifo(
|
fifo512_cyclone alt_fifo(
|
.data(data_in),
|
.data(data_in),
|
.wrreq(write_request),
|
.wrreq(write_request),
|
.rdreq(read_request),
|
.rdreq(read_request),
|
.clock(clk),
|
.clock(clk),
|
.q(queue_data),
|
.q(queue_data),
|
.full(queue_full),
|
.full(queue_full),
|
.empty(empty));
|
.empty(empty));
|
`else//debug model in simulations
|
`else//debug model in simulations
|
|
|
sim_fifo512_cyclone sim_fifo(
|
sim_fifo512_cyclone sim_fifo(
|
.data(data_in),
|
.data(data_in),
|
.wrreq(write_request),
|
.wrreq(write_request),
|
.rdreq(read_request),
|
.rdreq(read_request),
|
.clock(clk),
|
.clock(clk),
|
.q(queue_data),
|
.q(queue_data),
|
.full(queue_full),
|
.full(queue_full),
|
.empty(empty),
|
.empty(empty),
|
.rst(sync_reset));
|
.rst(sync_reset));
|
`endif
|
`endif
|
|
|
|
|
|
|
// 7bit counter
|
// 7bit counter
|
// I set the regerster lenth as 16 .Sufficent but not waste.Liwei
|
// I set the regerster lenth as 16 .Sufficent but not waste.Liwei
|
always @(posedge clk ) begin
|
always @(posedge clk ) begin
|
if (~sync_reset)
|
if (~sync_reset)
|
clk_ctr <= 0;
|
clk_ctr <= 0;
|
else if (clk_ctr_enable_state && clk_ctr_equ31) clk_ctr<=0;
|
else if (clk_ctr_enable_state && clk_ctr_equ31) clk_ctr<=0;
|
else if (clk_ctr_enable_state) clk_ctr <= clk_ctr + 1;
|
else if (clk_ctr_enable_state) clk_ctr <= clk_ctr + 1;
|
else clk_ctr <= 0;
|
else clk_ctr <= 0;
|
end
|
end
|
|
|
|
|
assign clk_ctr_equ15 = clk_ctr==`COUNTER_VALUE1;
|
assign clk_ctr_equ15 = clk_ctr==`COUNTER_VALUE1;
|
assign clk_ctr_equ31 = clk_ctr==`COUNTER_VALUE2;
|
assign clk_ctr_equ31 = clk_ctr==`COUNTER_VALUE2;
|
|
|
// 3bit counter
|
// 3bit counter
|
always @(posedge clk) begin
|
always @(posedge clk) begin
|
if (~sync_reset)
|
if (~sync_reset)
|
bit_ctr <= 0;
|
bit_ctr <= 0;
|
else if (bit_ctr_enable_state) begin
|
else if (bit_ctr_enable_state) begin
|
if (clk_ctr_equ15)
|
if (clk_ctr_equ15)
|
bit_ctr <= bit_ctr + 1;
|
bit_ctr <= bit_ctr + 1;
|
end
|
end
|
else
|
else
|
bit_ctr <= 0;
|
bit_ctr <= 0;
|
end
|
end
|
|
|
assign bit_ctr_equ7 = (bit_ctr==7);
|
assign bit_ctr_equ7 = (bit_ctr==7);
|
|
|
assign clk_ctr_enable_state = bit_ctr_enable_state ||ua_state==3'b110 || ua_state==3'b001 || ua_state==3'b100||ua_state==3'b101;
|
assign clk_ctr_enable_state = bit_ctr_enable_state ||ua_state==3'b110 || ua_state==3'b001 || ua_state==3'b100||ua_state==3'b101;
|
assign bit_ctr_enable_state = ua_state==3'b010 || ua_state==3'b011;
|
assign bit_ctr_enable_state = ua_state==3'b010 || ua_state==3'b011;
|
|
|
|
|
always @(posedge clk ) begin
|
always @(posedge clk ) begin
|
if (~sync_reset) ua_state <= 3'b000;
|
if (~sync_reset) ua_state <= 3'b000;
|
else begin
|
else begin
|
case (ua_state)
|
case (ua_state)
|
3'b000: if (queing) ua_state <= 3'b001; //wait write_request
|
3'b000: if (queing) ua_state <= 3'b001; //wait write_request
|
3'b001: if ( clk_ctr_equ15) ua_state <= 3'b010; // write start bit
|
3'b001: if ( clk_ctr_equ15) ua_state <= 3'b010; // write start bit
|
3'b010: if (bit_ctr_equ7 & clk_ctr_equ15) ua_state <= 3'b011; // start bit, bit0-7 data send
|
3'b010: if (bit_ctr_equ7 & clk_ctr_equ15) ua_state <= 3'b011; // start bit, bit0-7 data send
|
3'b011: if (clk_ctr_equ15) ua_state <= 3'b100; // bit7 data send
|
3'b011: if (clk_ctr_equ15) ua_state <= 3'b100; // bit7 data send
|
3'b100: if (clk_ctr_equ15) ua_state <= 3'b101; // stop bit // stop bit send
|
3'b100: if (clk_ctr_equ15) ua_state <= 3'b101; // stop bit // stop bit send
|
3'b101: if (clk_ctr_equ15) ua_state <= 3'b110; //LIWEI // stop bit send
|
3'b101: if (clk_ctr_equ15) ua_state <= 3'b110; //LIWEI // stop bit send
|
3'b110: if (clk_ctr_equ15) ua_state <= 3'b111; //LIWEI
|
3'b110: if (clk_ctr_equ15) ua_state <= 3'b111; //LIWEI
|
3'b111: ua_state <= 3'h0; // TAK // byte read cycle end
|
3'b111: ua_state <= 3'h0; // TAK // byte read cycle end
|
default: ua_state <= 3'h0;
|
default: ua_state <= 3'h0;
|
endcase
|
endcase
|
end
|
end
|
end
|
end
|
|
|
|
|
|
|
|
|
// tx shift reg.
|
// tx shift reg.
|
always @(posedge clk ) begin
|
always @(posedge clk ) begin
|
if (~sync_reset) tx_sr<=0;
|
if (~sync_reset) tx_sr<=0;
|
else if (read_request_ff) tx_sr <= queue_data[7:0]; //data_in[7:0]; // load
|
else if (read_request_ff) tx_sr <= queue_data[7:0]; //data_in[7:0]; // load
|
else if (tx_state ) tx_sr <= {1'b0, tx_sr[7:1]};
|
else if (tx_state ) tx_sr <= {1'b0, tx_sr[7:1]};
|
end
|
end
|
|
|
assign tx_state=( ua_state==3'h2 || ua_state==3'h3) && clk_ctr_equ15;
|
assign tx_state=( ua_state==3'h2 || ua_state==3'h3) && clk_ctr_equ15;
|
|
|
|
|
// tx
|
// tx
|
always @(posedge clk ) begin
|
always @(posedge clk ) begin
|
if (~sync_reset) txd <=1'b1;
|
if (~sync_reset) txd <=1'b1;
|
else if (~sync_reset) txd<=1'b1;
|
else if (~sync_reset) txd<=1'b1;
|
else if (ua_state==3'h0) txd<=1'b1;
|
else if (ua_state==3'h0) txd<=1'b1;
|
else if (ua_state==3'h1 && clk_ctr_equ15) txd<=1'b0; // start bit
|
else if (ua_state==3'h1 && clk_ctr_equ15) txd<=1'b0; // start bit
|
else if (ua_state==3'h2 && clk_ctr_equ15) txd<=tx_sr[0];
|
else if (ua_state==3'h2 && clk_ctr_equ15) txd<=tx_sr[0];
|
else if (ua_state==3'h3 && clk_ctr_equ15) txd<=1'b1; // stop bit
|
else if (ua_state==3'h3 && clk_ctr_equ15) txd<=1'b1; // stop bit
|
end
|
end
|
endmodule
|
endmodule
|
|
|
|
|
module uart_read( sync_reset, clk, rxd,buffer_reg, int_req);
|
module uart_read( sync_reset, clk, rxd,buffer_reg, int_req);
|
input sync_reset;
|
input sync_reset;
|
input clk, rxd;
|
input clk, rxd;
|
output [7:0] buffer_reg;
|
output [7:0] buffer_reg;
|
output int_req;
|
output int_req;
|
|
|
|
|
//________|-|______int_req (This module,, posedge interrupt)
|
//________|-|______int_req (This module,, posedge interrupt)
|
//
|
//
|
//Spec. Upper module must service within 115.2Kbpsx8bit time. Maybe enough time...
|
//Spec. Upper module must service within 115.2Kbpsx8bit time. Maybe enough time...
|
//
|
//
|
//No error handling (overrun ) is supported.
|
//No error handling (overrun ) is supported.
|
|
|
reg rxq1;
|
reg rxq1;
|
reg [15:0] clk_ctr;
|
reg [15:0] clk_ctr;
|
reg [2:0] bit_ctr;
|
reg [2:0] bit_ctr;
|
reg [2:0] ua_state;
|
reg [2:0] ua_state;
|
reg [7:0] rx_sr; //.,tx_sr;
|
reg [7:0] rx_sr; //.,tx_sr;
|
reg int_req;
|
reg int_req;
|
reg [7:0] buffer_reg;
|
reg [7:0] buffer_reg;
|
|
|
wire clk_ctr_equ15, clk_ctr_equ31, bit_ctr_equ7,
|
wire clk_ctr_equ15, clk_ctr_equ31, bit_ctr_equ7,
|
clk_ctr_enable_state, bit_ctr_enable_state ;
|
clk_ctr_enable_state, bit_ctr_enable_state ;
|
wire clk_ctr_equ0;
|
wire clk_ctr_equ0;
|
|
|
//sync_reset
|
//sync_reset
|
|
|
//synchronization
|
//synchronization
|
always @(posedge clk ) begin
|
always @(posedge clk ) begin
|
rxq1 <=rxd ;
|
rxq1 <=rxd ;
|
end
|
end
|
|
|
// 7bit counter
|
// 7bit counter
|
always @(posedge clk ) begin
|
always @(posedge clk ) begin
|
if (~sync_reset)
|
if (~sync_reset)
|
clk_ctr <= 0;
|
clk_ctr <= 0;
|
else if (clk_ctr_enable_state && clk_ctr_equ31) clk_ctr<=0;
|
else if (clk_ctr_enable_state && clk_ctr_equ31) clk_ctr<=0;
|
else if (clk_ctr_enable_state) clk_ctr <= clk_ctr + 1;
|
else if (clk_ctr_enable_state) clk_ctr <= clk_ctr + 1;
|
else clk_ctr <= 0;
|
else clk_ctr <= 0;
|
end
|
end
|
assign clk_ctr_equ15 = (clk_ctr==`COUNTER_VALUE1) ;//
|
assign clk_ctr_equ15 = (clk_ctr==`COUNTER_VALUE1) ;//
|
assign clk_ctr_equ31 = (clk_ctr==`COUNTER_VALUE2) ;//
|
assign clk_ctr_equ31 = (clk_ctr==`COUNTER_VALUE2) ;//
|
assign clk_ctr_equ0= (clk_ctr==`COUNTER_VALUE3); //
|
assign clk_ctr_equ0= (clk_ctr==`COUNTER_VALUE3); //
|
|
|
|
|
// 3bit counter
|
// 3bit counter
|
always @(posedge clk) begin
|
always @(posedge clk) begin
|
if (~sync_reset)
|
if (~sync_reset)
|
bit_ctr <= 0;
|
bit_ctr <= 0;
|
else if (bit_ctr_enable_state) begin
|
else if (bit_ctr_enable_state) begin
|
if (clk_ctr_equ15)
|
if (clk_ctr_equ15)
|
bit_ctr <= bit_ctr + 1;
|
bit_ctr <= bit_ctr + 1;
|
end
|
end
|
else
|
else
|
bit_ctr <= 0;
|
bit_ctr <= 0;
|
end
|
end
|
|
|
assign bit_ctr_equ7 = (bit_ctr==7);
|
assign bit_ctr_equ7 = (bit_ctr==7);
|
|
|
|
|
assign clk_ctr_enable_state = ua_state !=3'b000 && ua_state<=3'b011;
|
assign clk_ctr_enable_state = ua_state !=3'b000 && ua_state<=3'b011;
|
assign bit_ctr_enable_state = ua_state==3'h2;
|
assign bit_ctr_enable_state = ua_state==3'h2;
|
|
|
always @(posedge clk ) begin
|
always @(posedge clk ) begin
|
if (~sync_reset) ua_state <= 3'h0;
|
if (~sync_reset) ua_state <= 3'h0;
|
else begin
|
else begin
|
case (ua_state)
|
case (ua_state)
|
3'h0: if (rxq1==0) ua_state <= 3'h1; // if rxd==0 then goto next state and enable clock // start bit search
|
3'h0: if (rxq1==0) ua_state <= 3'h1; // if rxd==0 then goto next state and enable clock // start bit search
|
3'h1: if (clk_ctr_equ15) ua_state <= 3'h2; // start bit receive
|
3'h1: if (clk_ctr_equ15) ua_state <= 3'h2; // start bit receive
|
3'h2: if (bit_ctr_equ7 & clk_ctr_equ15) ua_state <= 3'h3;
|
3'h2: if (bit_ctr_equ7 & clk_ctr_equ15) ua_state <= 3'h3;
|
3'h3: if (clk_ctr_equ15) ua_state <=3'h4; // stop bit receive
|
3'h3: if (clk_ctr_equ15) ua_state <=3'h4; // stop bit receive
|
3'h4: ua_state <= 3'b000;
|
3'h4: ua_state <= 3'b000;
|
default: ua_state <= 3'b000;
|
default: ua_state <= 3'b000;
|
endcase
|
endcase
|
end
|
end
|
end
|
end
|
|
|
|
|
//reg_we
|
//reg_we
|
always @(posedge clk ) begin
|
always @(posedge clk ) begin
|
if (~sync_reset) buffer_reg<=8'h00;
|
if (~sync_reset) buffer_reg<=8'h00;
|
else if (ua_state==3'h3 && clk_ctr_equ0) buffer_reg<=rx_sr;
|
else if (ua_state==3'h3 && clk_ctr_equ0) buffer_reg<=rx_sr;
|
end
|
end
|
|
|
//int_req
|
//int_req
|
always @(posedge clk ) begin
|
always @(posedge clk ) begin
|
if (~sync_reset) int_req<=1'b0;
|
if (~sync_reset) int_req<=1'b0;
|
else if (ua_state==3'h4 ) int_req<=1'b1;
|
else if (ua_state==3'h4 ) int_req<=1'b1;
|
else int_req<=1'b0;
|
else int_req<=1'b0;
|
end
|
end
|
|
|
|
|
// rx shift reg.
|
// rx shift reg.
|
always @(posedge clk ) begin
|
always @(posedge clk ) begin
|
if (~sync_reset) rx_sr <= 0;
|
if (~sync_reset) rx_sr <= 0;
|
else if (clk_ctr_equ15) rx_sr <= {rxq1, rx_sr[7:1]};
|
else if (clk_ctr_equ15) rx_sr <= {rxq1, rx_sr[7:1]};
|
end
|
end
|
|
|
endmodule
|
endmodule
|
|
|