210 lines
4.3 KiB
Coq
210 lines
4.3 KiB
Coq
![]() |
/* Example UART derived from: https://github.com/cr1901/migen_uart.
|
||
|
Requires 12MHz clock and runs at 19,200 baud. */
|
||
|
|
||
|
/* Machine-generated using Migen */
|
||
|
|
||
|
module top(
|
||
|
(* LOC = "14" *)
|
||
|
output tx,
|
||
|
(* LOC = "16" *)
|
||
|
input rx,
|
||
|
(* LOC = "13" *)
|
||
|
output rx_led,
|
||
|
(* LOC = "17" *)
|
||
|
output tx_led,
|
||
|
(* LOC = "20" *)
|
||
|
output load_led,
|
||
|
(* LOC = "23" *)
|
||
|
output take_led,
|
||
|
(* LOC = "25" *)
|
||
|
output empty_led,
|
||
|
(* LOC = "21" *)
|
||
|
input clk
|
||
|
);
|
||
|
|
||
|
wire [7:0] out_data;
|
||
|
wire [7:0] in_data;
|
||
|
reg wr = 1'd0;
|
||
|
reg rd = 1'd0;
|
||
|
wire tx_empty;
|
||
|
wire rx_empty;
|
||
|
wire tx_ov;
|
||
|
wire rx_ov;
|
||
|
wire sout_load;
|
||
|
wire [7:0] sout_out_data;
|
||
|
wire sout_shift;
|
||
|
reg sout_empty = 1'd1;
|
||
|
reg sout_overrun = 1'd0;
|
||
|
reg [3:0] sout_count = 4'd0;
|
||
|
reg [9:0] sout_reg = 10'd0;
|
||
|
reg sout_tx;
|
||
|
wire sin_rx;
|
||
|
wire sin_shift;
|
||
|
wire sin_take;
|
||
|
reg [7:0] sin_in_data = 8'd0;
|
||
|
wire sin_edge;
|
||
|
reg sin_empty = 1'd1;
|
||
|
reg sin_busy = 1'd0;
|
||
|
reg sin_overrun = 1'd0;
|
||
|
reg sin_sync_rx = 1'd0;
|
||
|
reg [8:0] sin_reg = 9'd0;
|
||
|
reg sin_rx_prev = 1'd0;
|
||
|
reg [3:0] sin_count = 4'd0;
|
||
|
wire out_active;
|
||
|
wire in_active;
|
||
|
reg shift_out_strobe = 1'd0;
|
||
|
reg shift_in_strobe = 1'd0;
|
||
|
reg [9:0] in_counter = 10'd0;
|
||
|
reg [9:0] out_counter = 10'd0;
|
||
|
wire sys_clk;
|
||
|
wire sys_rst;
|
||
|
wire por_clk;
|
||
|
reg int_rst = 1'd1;
|
||
|
|
||
|
// synthesis translate_off
|
||
|
reg dummy_s;
|
||
|
initial dummy_s <= 1'd0;
|
||
|
// synthesis translate_on
|
||
|
|
||
|
assign tx_led = (~tx);
|
||
|
assign rx_led = (~rx);
|
||
|
assign load_led = sout_load;
|
||
|
assign take_led = sin_take;
|
||
|
assign empty_led = sin_empty;
|
||
|
assign out_data = in_data;
|
||
|
assign in_data = sin_in_data;
|
||
|
assign sout_out_data = out_data;
|
||
|
assign sin_take = rd;
|
||
|
assign sout_load = wr;
|
||
|
assign tx = sout_tx;
|
||
|
assign sin_rx = rx;
|
||
|
assign tx_empty = sout_empty;
|
||
|
assign rx_empty = sin_empty;
|
||
|
assign tx_ov = sout_overrun;
|
||
|
assign rx_ov = sin_overrun;
|
||
|
assign sout_shift = shift_out_strobe;
|
||
|
assign sin_shift = shift_in_strobe;
|
||
|
assign out_active = (~sout_empty);
|
||
|
assign in_active = sin_busy;
|
||
|
|
||
|
// synthesis translate_off
|
||
|
reg dummy_d;
|
||
|
// synthesis translate_on
|
||
|
always @(*) begin
|
||
|
sout_tx <= 1'd0;
|
||
|
if (sout_empty) begin
|
||
|
sout_tx <= 1'd1;
|
||
|
end else begin
|
||
|
sout_tx <= sout_reg[0];
|
||
|
end
|
||
|
// synthesis translate_off
|
||
|
dummy_d <= dummy_s;
|
||
|
// synthesis translate_on
|
||
|
end
|
||
|
assign sin_edge = ((sin_rx_prev == 1'd1) & (sin_sync_rx == 1'd0));
|
||
|
assign sys_clk = clk;
|
||
|
assign por_clk = clk;
|
||
|
assign sys_rst = int_rst;
|
||
|
|
||
|
always @(posedge por_clk) begin
|
||
|
int_rst <= 1'd0;
|
||
|
end
|
||
|
|
||
|
always @(posedge sys_clk) begin
|
||
|
wr <= 1'd0;
|
||
|
rd <= 1'd0;
|
||
|
if ((~sin_empty)) begin
|
||
|
wr <= 1'd1;
|
||
|
rd <= 1'd1;
|
||
|
end
|
||
|
if (sout_load) begin
|
||
|
if (sout_empty) begin
|
||
|
sout_reg[0] <= 1'd0;
|
||
|
sout_reg[8:1] <= sout_out_data;
|
||
|
sout_reg[9] <= 1'd1;
|
||
|
sout_empty <= 1'd0;
|
||
|
sout_overrun <= 1'd0;
|
||
|
sout_count <= 1'd0;
|
||
|
end else begin
|
||
|
sout_overrun <= 1'd1;
|
||
|
end
|
||
|
end
|
||
|
if (((~sout_empty) & sout_shift)) begin
|
||
|
sout_reg[8:0] <= sout_reg[9:1];
|
||
|
sout_reg[9] <= 1'd0;
|
||
|
if ((sout_count == 4'd9)) begin
|
||
|
sout_empty <= 1'd1;
|
||
|
sout_count <= 1'd0;
|
||
|
end else begin
|
||
|
sout_count <= (sout_count + 1'd1);
|
||
|
end
|
||
|
end
|
||
|
sin_sync_rx <= sin_rx;
|
||
|
sin_rx_prev <= sin_sync_rx;
|
||
|
if (sin_take) begin
|
||
|
sin_empty <= 1'd1;
|
||
|
sin_overrun <= 1'd0;
|
||
|
end
|
||
|
if (((~sin_busy) & sin_edge)) begin
|
||
|
sin_busy <= 1'd1;
|
||
|
end
|
||
|
if ((sin_shift & sin_busy)) begin
|
||
|
sin_reg[8] <= sin_sync_rx;
|
||
|
sin_reg[7:0] <= sin_reg[8:1];
|
||
|
if ((sin_count == 4'd9)) begin
|
||
|
sin_in_data <= sin_reg[8:1];
|
||
|
sin_count <= 1'd0;
|
||
|
sin_busy <= 1'd0;
|
||
|
if ((~sin_empty)) begin
|
||
|
sin_overrun <= 1'd1;
|
||
|
end else begin
|
||
|
sin_empty <= 1'd0;
|
||
|
end
|
||
|
end else begin
|
||
|
sin_count <= (sin_count + 1'd1);
|
||
|
end
|
||
|
end
|
||
|
out_counter <= 1'd0;
|
||
|
in_counter <= 1'd0;
|
||
|
if (in_active) begin
|
||
|
shift_in_strobe <= 1'd0;
|
||
|
in_counter <= (in_counter + 1'd1);
|
||
|
if ((in_counter == 9'd311)) begin
|
||
|
shift_in_strobe <= 1'd1;
|
||
|
end
|
||
|
if ((in_counter == 10'd623)) begin
|
||
|
in_counter <= 1'd0;
|
||
|
end
|
||
|
end
|
||
|
if (out_active) begin
|
||
|
shift_out_strobe <= 1'd0;
|
||
|
out_counter <= (out_counter + 1'd1);
|
||
|
if ((out_counter == 10'd623)) begin
|
||
|
out_counter <= 1'd0;
|
||
|
shift_out_strobe <= 1'd1;
|
||
|
end
|
||
|
end
|
||
|
if (sys_rst) begin
|
||
|
wr <= 1'd0;
|
||
|
rd <= 1'd0;
|
||
|
sout_empty <= 1'd1;
|
||
|
sout_overrun <= 1'd0;
|
||
|
sout_count <= 4'd0;
|
||
|
sout_reg <= 10'd0;
|
||
|
sin_in_data <= 8'd0;
|
||
|
sin_empty <= 1'd1;
|
||
|
sin_busy <= 1'd0;
|
||
|
sin_overrun <= 1'd0;
|
||
|
sin_sync_rx <= 1'd0;
|
||
|
sin_reg <= 9'd0;
|
||
|
sin_rx_prev <= 1'd0;
|
||
|
sin_count <= 4'd0;
|
||
|
shift_out_strobe <= 1'd0;
|
||
|
shift_in_strobe <= 1'd0;
|
||
|
in_counter <= 10'd0;
|
||
|
out_counter <= 10'd0;
|
||
|
end
|
||
|
end
|
||
|
|
||
|
endmodule
|