OpenCores
URL https://opencores.org/ocsvn/eco32/eco32/trunk

Subversion Repositories eco32

[/] [eco32/] [trunk/] [fpga/] [mc-vl/] [src/] [ser/] [ser.v] - Blame information for rev 308

Details | Compare with Previous | View Log

Line No. Rev Author Line
1 308 hellwig
//
2
// ser.v -- serial line interface
3
//
4
 
5
 
6
`timescale 1ns/10ps
7
`default_nettype none
8
 
9
 
10
`define TICKS_PER_CHAR          32'h00000200    // output speed
11
 
12
 
13
module ser(i,                           // instance number
14
           clk, rst,
15
           stb, we, addr,
16
           data_in, data_out,
17
           ack, irq_r, irq_t);
18
    input i;
19
    input clk;
20
    input rst;
21
    input stb;
22
    input we;
23
    input [3:2] addr;
24
    input [7:0] data_in;
25
    output reg [7:0] data_out;
26
    output ack;
27
    output irq_r;
28
    output irq_t;
29
 
30
  wire wr_rcv_ctrl;
31
  wire rd_rcv_data;
32
  wire wr_xmt_ctrl;
33
  wire wr_xmt_data;
34
 
35
  reg [39:0] ser_data[0:255];             // space for 256 input requests
36
  reg [7:0] ser_data_index;              // next location to read
37
  wire [39:0] next_full;         // 40 bits from ser_data
38
  wire [31:0] next_time;         // 32 bits delta clock ticks
39
  wire [7:0] next_code;                  // 8 bits character code
40
  reg [31:0] rcv_count;                  // input tick counter
41
 
42
  integer ser_out;                      // file handle for serial output
43
  reg [31:0] xmt_count;                  // output tick counter
44
 
45
  reg rcv_rdy;
46
  reg rcv_ien;
47
  reg [7:0] rcv_data;
48
  reg xmt_rdy;
49
  reg xmt_ien;
50
  reg [7:0] xmt_data;
51
 
52
  assign wr_rcv_ctrl = (stb == 1 && we == 1 && addr == 2'b00) ? 1 : 0;
53
  assign rd_rcv_data = (stb == 1 && we == 0 && addr == 2'b01) ? 1 : 0;
54
  assign wr_xmt_ctrl = (stb == 1 && we == 1 && addr == 2'b10) ? 1 : 0;
55
  assign wr_xmt_data = (stb == 1 && we == 1 && addr == 2'b11) ? 1 : 0;
56
 
57
  initial begin
58
    if (i == 0) begin
59
      $readmemh("ser0.dat", ser_data);
60
    end else begin
61
      $readmemh("ser1.dat", ser_data);
62
    end
63
  end
64
 
65
  assign next_full[39:0] = ser_data[ser_data_index];
66
  assign next_time[31:0] = next_full[39:8];
67
  assign next_code[7:0] = next_full[7:0];
68
 
69
  always @(posedge clk) begin
70
    if (rst) begin
71
      ser_data_index <= 0;
72
      rcv_count <= 0;
73
      rcv_rdy <= 0;
74
      rcv_data <= 0;
75
    end else begin
76
      if (rcv_count == 0) begin
77
        rcv_count <= next_time;
78
      end else
79
      if (rcv_count == 1) begin
80
        ser_data_index <= ser_data_index + 1;
81
        rcv_count <= rcv_count - 1;
82
        rcv_rdy <= 1;
83
        rcv_data <= next_code;
84
      end else begin
85
        if (rcv_count != 32'hFFFFFFFF) begin
86
          rcv_count <= rcv_count - 1;
87
        end
88
      end
89
    end
90
  end
91
 
92
  always @(posedge clk) begin
93
    if (rd_rcv_data == 1 && rcv_count != 1) begin
94
      rcv_rdy <= 0;
95
    end
96
  end
97
 
98
  initial begin
99
    if (i == 0) begin
100
      ser_out = $fopen("ser0.out", "w");
101
    end else begin
102
      ser_out = $fopen("ser1.out", "w");
103
    end
104
  end
105
 
106
  always @(posedge clk) begin
107
    if (rst) begin
108
      xmt_count <= 0;
109
      xmt_rdy <= 1;
110
      xmt_data <= 0;
111
    end else begin
112
      if (wr_xmt_data) begin
113
        xmt_count <= `TICKS_PER_CHAR;
114
        xmt_rdy <= 0;
115
        xmt_data <= data_in;
116
      end else begin
117
        if (xmt_count == 1) begin
118
          xmt_count <= xmt_count - 1;
119
          xmt_rdy <= 1;
120
          $fdisplay(ser_out, "char = 0x%h", xmt_data);
121
        end else begin
122
          if (xmt_count != 0) begin
123
            xmt_count <= xmt_count - 1;
124
          end
125
        end
126
      end
127
    end
128
  end
129
 
130
  always @(posedge clk) begin
131
    if (rst) begin
132
      rcv_ien <= 0;
133
      xmt_ien <= 0;
134
    end else begin
135
      if (wr_rcv_ctrl) begin
136
        rcv_ien <= data_in[1];
137
      end
138
      if (wr_xmt_ctrl) begin
139
        xmt_ien <= data_in[1];
140
      end
141
    end
142
  end
143
 
144
  always @(*) begin
145
    case (addr[3:2])
146
      2'b00:
147
        // rcv ctrl
148
        data_out = { 6'b000000, rcv_ien, rcv_rdy };
149
      2'b01:
150
        // rcv data
151
        data_out = rcv_data;
152
      2'b10:
153
        // xmt ctrl
154
        data_out = { 6'b000000, xmt_ien, xmt_rdy };
155
      2'b11:
156
        // xmt data (cannot be read)
157
        data_out = 8'hxx;
158
      default:
159
        data_out = 8'hxx;
160
    endcase
161
  end
162
 
163
  assign ack = stb;
164
  assign irq_r = rcv_ien & rcv_rdy;
165
  assign irq_t = xmt_ien & xmt_rdy;
166
 
167
endmodule

powered by: WebSVN 2.1.0

© copyright 1999-2024 OpenCores.org, equivalent to Oliscience, all rights reserved. OpenCores®, registered trademark.