1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 109 110 111 112 113 114 115 116 117 118 119 120 121 122 123 124 125 126 127 128 129 130 131 132 133 134 135 136 137 138 139 140 141 142 143 144 145 146 147 148 149 150 151 152 153 154 155 156 157 158 159 160 161 162 163 164 165 166 167 168 169 170 171 172 173 174 175 176 177 178 179 180 181 182 183 184 185 186 187 188 189 190 191 192 193 194 195 196 197 198 199 200 201 202 203 204 205 206 207
|
/* 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(
input serial_rx,
output serial_tx,
output user_led,
output user_led_1,
output user_led_2,
output user_led_3,
output user_led_4,
input clk12
);
wire [7:0] out_data;
wire [7:0] in_data;
wire tx;
wire rx;
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;
// Adding a dummy event (using a dummy signal 'dummy_s') to get the simulator
// to run the combinatorial process once at the beginning.
// synthesis translate_off
reg dummy_s;
initial dummy_s <= 1'd0;
// synthesis translate_on
assign user_led_1 = (~serial_tx);
assign user_led = (~serial_rx);
assign user_led_2 = sout_load;
assign user_led_3 = sin_take;
assign user_led_4 = sin_empty;
assign serial_tx = tx;
assign rx = serial_rx;
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 = clk12;
assign por_clk = clk12;
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
|