Jump to content

    

Alexey87

Участник
  • Content Count

    19
  • Joined

  • Last visited

Community Reputation

0 Обычный

About Alexey87

  • Rank
    Участник

Recent Profile Visitors

187 profile views
  1. to:new123 Спасибо, посмотрю эту тему ( запись чисел ) более подробно.
  2. Здравствуйте, попробовал описать запись по протоколу I2C для EEPROM 24C04 (как я понял реализацию). В архиве, то что получилось. test.rar У меня возникли вопросы: 1. Как правильно инкрементировать значение регистра reg reg[7:0]data = 0; data <= data + 1 или data <= data + 1'b1? 2. Как правильно обнулять значение регистра reg data <= 0 или data <= 8'b0 или data <= 8'b00000000? С уважением, Алексей. p.s. Интересуют варианты реализации для 1 и 2 вопроса.
  3. Благодарю Вас, сейчас ещё жду: Токхейм Р. Основы цифровой электроники.
  4. to: AnatolySh. Спасибо за код, на данный момент я уже не пытаюсь разобраться с протоколом i2c, а приступил к базовым основам цифровой схемотехники и уже потом наверное буду пробовать свои силы. С уважением, Алексей.
  5. Вот на intel взял исходник: /************************************************************************************************************ I2C to GPIO Port expander. Date: December 21, 2006. ************************************************************************************************************/ `timescale 1us/10ns /* Top module */ module I2C_to_GPIO ( sda, sclk, GPIO_input, GPIO_output); inout sda; // Bidirectional SDA input sclk; // Bidirectional SCLK input [7:0] GPIO_input; output [7:0] GPIO_output; parameter slave_address = 7'h0; // can be changed as per the protocol это для адреса slave? parameter n = 8; reg start_stop; // Indicated if the device has detected a start and is busy in some operation reg start, stop; // Goes high temperarily when a start or stop is detectd reg some_other_device; // to reset start_stop, when the adress on the bus is different from the device address; reg repeat_start; // to reset everything if repeat start is detected. reg write_flag; // to set when write oper begins reg reset; // Used to reset the start , stop registers reg sda_out; // To force the SDA output Low. Remains tristated for sending High Logic. reg done; // To Indicate data transfer done reg [3:0]count; // Down Counter ( 7 to 0 + ack bit ) reg [n-1:0] GPIO_output; // parallel store reg [n-1:0] GPIO_input_reg; // Stores the Values at the input pins before sending to master. reg data_or_address; // high for data, low for address reg read_oper, add_is_matching; // high for master read; high for address matching /********************************************************************************************************/ /* Detecting STOP Condition on the SDA Bus */ always @ (posedge sda or posedge reset) if (reset) begin stop <= 0; end else if (sclk) begin stop <= 1; end /* Detecting START Condition on the SDA Bus */ always @ (negedge sda or posedge reset) if (reset) begin start <= 0; end else if (sclk) begin start <= 1; end /* Tracking START_STOP related status of the device */ always @ (negedge sclk) if (start_stop & start) begin repeat_start <= 1; reset <= 1; end else if (start) begin start_stop <= 1; reset <= 1; repeat_start <= 0; end else if (stop) begin start_stop <= 0; reset <= 1; repeat_start <= 0; end else if (some_other_device) begin start_stop <= 0; repeat_start <= 1; end else begin reset <= 0; repeat_start <= 0; end /***********************************************************************************************************/ /* Counting of bits. First eight bits are data and the last one is ack. */ wire sda_is_ack = count[3] & count [2]; // High for ack , count = 1111 /* Down Counter, 1111 is ack */ always @ (negedge sclk) if (start) begin count <= 4'h7; // it would decreae to 7 on the first pos edge of sclk. end else if (start_stop) begin if (sda_is_ack) begin // count is restored to 7 count <= 4'h7; end else begin count <= count - 4'h1; // count is decremented until zero. end end /***********************************************************************************************************/ /* Taking the Inputs from SDA line and Comparing with Address */это чтение? always @(posedge sclk) if (start_stop) begin if (~sda_is_ack) begin if (~data_or_address | repeat_start) begin if (repeat_start) begin add_is_matching <= 1; // high means matching data_or_address <= 0; // default is address some_other_device <= 0; // High means that device address does not match with SDA data write_flag <= 0; done <= 0; // Low means Transfer is pending end if (count == 7 & sda != slave_address[6]) add_is_matching <= 0; if (count == 6 & sda != slave_address[5]) add_is_matching <= 0; if (count == 5 & sda != slave_address[4]) add_is_matching <= 0; if (count == 4 & sda != slave_address[3]) add_is_matching <= 0; if (count == 3 & sda != slave_address[2]) add_is_matching <= 0; if (count == 2 & sda != slave_address[1]) add_is_matching <= 0; if (count == 1 & sda != slave_address[0]) add_is_matching <= 0; if (count == 0 & ~sda )begin read_oper <= 0; data_or_address <= 1; end else if (count == 0) begin read_oper <= 1; data_or_address <= 1; end end else if (~read_oper & ~done) begin if (count == 7) GPIO_output[7] <= sda; if (count == 6) GPIO_output[6] <= sda; if (count == 5) GPIO_output[5] <= sda; if (count == 4) GPIO_output[4] <= sda; if (count == 3) GPIO_output[3] <= sda; if (count == 2) GPIO_output[2] <= sda; if (count == 1) GPIO_output[1] <= sda; if (count == 0) begin GPIO_output[0] <= sda; done <= 1; end end else begin if (count == 0) done <= 1; end end else begin if (add_is_matching) begin if (read_oper) write_flag <= 1; end else begin data_or_address <= 0; some_other_device <= 1; end end end else begin add_is_matching <= 1; // high means matching data_or_address <= 0; // default is address some_other_device <= 0; write_flag <= 0; done <= 0; end /***********************************************************************************************************/ /* Writing ACK and DATA on the SDA Line*/ wire ack_flag = (count[3]|count[2]|count[1]|count[0]); //becomes low when count is 0 always@(negedge sclk) if (start_stop) begin if (~ack_flag) begin if ( add_is_matching & ~write_flag)begin sda_out <= 1'b0; end else begin sda_out <= 1'bz; end if (read_oper & ~done) GPIO_input_reg <= GPIO_input; end else if (read_oper & data_or_address & ~done) begin if (ack_flag) begin if (~GPIO_input_reg[7]) begin sda_out <= 1'b0; end else begin sda_out <= 1'bz; end GPIO_input_reg <= GPIO_input_reg << 1; end end else begin sda_out <= 1'bz; end end wire sda; assign sda = sda_out; endmodule ................................................................... как с помощью этого кода можно записывать (адрес slave 7'h50) и почему здесь нет тактовой частоты?
  6. подключил sda на pin_2, scl на pin_4, clk pin_12, не пишет... адрес (slave 24c04) 0x01010000, что неправильно в коде? прикладываю лог с Logic 1.2.18 analyzer. I2C_Logic.logicdata Logic_I2C.zip
  7. Спасибо, обязательно прочту. Также приобрёл книги: В.В. Соловьёв "Основы проектирования цифровой аппаратуры Verilog" 2017, Заиналабедин Наваби "Проектирование встраиваемых систем".
  8. если описать на си или на асме, то нормально и понятно (для меня будет), а на verilog'e не совсем укладывается в голове (это ведь проектирование устр-ва).
  9. В теории сложного вроде ничего нет. а с этим посложнее...
  10. Добрый день! Пытаюсь записать и прочитать в микросхему 24с04 (память) при помощи этого кода: module Master( input wire clk, input wire reset, output reg i2c_sda, output wire i2c_scl ); //goal is to write to device address 0x50, 0xaa localparam STATE_IDLE = 0; localparam STATE_START = 1; localparam STATE_ADDR = 2; localparam STATE_RW = 3; localparam STATE_WACK = 4; localparam STATE_DATA = 5; localparam STATE_STOP = 6; localparam STATE_WACK2 = 7; reg [7:0] state; reg [6:0] addr; reg [7:0] data; reg [7:0] count; reg i2c_scl_enable = 0; assign i2c_scl = (i2c_scl_enable == 0) ? 1 : clk; always @(negedge clk) begin if (reset == 1) begin i2c_scl_enable = 0; end else begin if ((state == STATE_IDLE) || (state == STATE_START) || (state == STATE_STOP)) begin i2c_scl_enable = 0; end else begin i2c_scl_enable = 1; end end end always @(posedge clk) begin if (reset == 1) begin state <= 0; i2c_sda <= 1; //i2c_scl <= 1; addr <= 7'h50; count <= 8'd0; end else begin case(state) STATE_IDLE: begin // idle i2c_sda <= 1; state <= STATE_START; end STATE_START: begin // start i2c_sda <= 1; state <= STATE_ADDR; count <= 6; end // end state start STATE_ADDR: begin // msb address bit i2c_sda <= addr[count]; if (count == 0) state <= STATE_RW; else count <= count - 1; end // end state addr STATE_RW: begin i2c_sda <= 1; state <= STATE_WACK; end // end state rw STATE_WACK: begin state <= STATE_DATA; count <= 7; end // end state wack STATE_DATA: begin i2c_sda <= data[count]; if (count == 0) state <= STATE_WACK; else count <= count -1; end // end state data STATE_WACK2: begin state <= STATE_STOP; end // state wack2 STATE_STOP: begin i2c_sda <= 1; state <= STATE_IDLE; end // state stop endcase end end endmodule код взят из этого I2C - Bus Master - Step 1 (and step 2) видео. Посмотрите пожалуйста, рабочий ли код?
  11. Ещё раз благодарю Вас, я пока только (как Вы поняли) начинаю изучать.
  12. Да всё отлично, благодарю Вас. поясните пожалуйста эту "конструкцию": это эквивалент?: time_cnt <= time_pulse ? 0 : (time_pulse + 1);
  13. max II epm240T100C5 (на плате генератор на 50 мгц), clk на 12 pin